< Summary - Igor Pro Universal Testing Framework

Information
Class: procedures.igortest-hooks
Assembly: procedures
File(s): /builds/mirror/igortest/procedures/igortest-hooks.ipf
Tag: 74147b3
Line coverage
75%
Covered lines: 312
Uncovered lines: 102
Coverable lines: 414
Total lines: 637
Line coverage: 75.3%
Branch coverage
51%
Covered branches: 29
Total branches: 56
Branch coverage: 51.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/mirror/igortest/procedures/igortest-hooks.ipf

#LineLine coverage
 1#pragma rtGlobals=3
 2#pragma TextEncoding="UTF-8"
 3#pragma rtFunctionErrors=1
 4#pragma version=1.10
 5#pragma ModuleName=IUTF_Hooks
 6
 7///@cond HIDDEN_SYMBOL
 8
 9/// @name Hook execution level
 10/// @{
 11static Constant HOOK_LEVEL_TEST_RUN   = 0
 12static Constant HOOK_LEVEL_TEST_SUITE = 1
 13static Constant HOOK_LEVEL_TEST_CASE  = 2
 14/// @}
 15
 16/// Groups all hooks which are executed at test case/suite begin/end
 17Structure IUTF_TestHooks
 18  string testBegin
 19  string testEnd
 20  string testSuiteBegin
 21  string testSuiteEnd
 22  string testCaseBegin
 23  string testCaseEnd
 24EndStructure
 25
 26/// @brief initialize all strings in TestHook structure to be non <null>
 2027static Function InitHooks(s)
 28  STRUCT IUTF_TestHooks &s
 29
 2030  s.testBegin      = ""
 2031  s.testEnd        = ""
 2032  s.testSuiteBegin = ""
 2033  s.testSuiteEnd   = ""
 2034  s.testCaseBegin  = ""
 2035  s.testCaseEnd    = ""
 2036End
 37
 38/// @brief Execute the provided user hook and catches all runtime errors. If the name of the hook
 39/// function doesn't end in "_OVERRIDE" this hook will be considered as prototype and won't be
 40/// executed. The return is still 0 as if no error happened.
 41///
 42/// @param name      name of the test run/suite/case
 43/// @param userHook  the function reference to the user hook
 44/// @param procWIn   name of the procedure window
 22445static Function ExecuteUserHook(name, userHook, procWin, level)
 46  FUNCREF USER_HOOK_PROTO userHook
 47  string name, procWin
 48  variable level
 49
 22450  variable err
 22451  string errorMessage, endTime
 22452  string hookName = StringByKey("Name", FuncRefInfo(userHook))
 53
 22454  if(!StringMatch(hookName, "*_OVERRIDE"))
 21855    return NaN
 656  endif
 57
 658  switch(level)
 659    case HOOK_LEVEL_TEST_RUN:
 660      IUTF_Reporting_Control#TestSuiteBegin("@HOOK_SUITE")
 661      IUTF_Reporting_Control#TestCaseBegin(hookName, 0)
 662      break;
 063    case HOOK_LEVEL_TEST_SUITE:
 064      IUTF_Reporting_Control#TestCaseBegin(hookName, 0)
 065      break;
 066    case HOOK_LEVEL_TEST_CASE:
 067      IUTF_Reporting_Control#TestCaseBegin(hookName, 0)
 068      break;
 069    default:
 070      sprintf errorMessage, "Unknown hook level: %d", level
 071      IUTF_Reporting#ReportErrorAndAbort(errorMessage)
 072      return NaN
 673  endswitch
 74
 675  StartWaveTracking(name)
 76
 677  try
 678    IUTF_Basics#ClearRTError()
 679    userHook(name); AbortOnRTE
 580  catch
 081    errorMessage = GetRTErrMessage()
 082    err          = GetRTError(1)
 083    IUTF_Basics#EvaluateRTE(err, errorMessage, V_AbortCode, hookName, IUTF_USER_HOOK_TYPE, procWin)
 84
 085    IUTF_Basics#setAbortFlag()
 086  endtry
 87
 588  endTime = IUTF_Reporting#GetTimeString()
 89
 590  FinishWaveTracking(name)
 91
 592  switch(level)
 593    case HOOK_LEVEL_TEST_RUN:
 594      IUTF_Reporting_Control#TestCaseEnd(endTime)
 595      IUTF_Reporting_Control#TestSuiteEnd()
 596      break
 097    case HOOK_LEVEL_TEST_SUITE:
 098      IUTF_Reporting_Control#TestCaseEnd(endTime)
 099      break
 0100    case HOOK_LEVEL_TEST_CASE:
 0101      IUTF_Reporting_Control#TestCaseEnd(endTime)
 0102      break
 0103    default:
 0104      sprintf errorMessage, "Unknown hook level: %d", level
 0105      IUTF_Reporting#ReportErrorAndAbort(errorMessage)
 0106      return NaN
 5107  endswitch
 224108End
 109
 110/// @brief Execute the builtin and user hooks
 111///
 112/// @param hookType One of @ref HookTypes
 113/// @param hooks    hooks structure
 114/// @param enableTAP set this to a value other than 0 to enable TAP output
 115/// @param enableJU set this to a value other than 0 to enable JUnit output
 116/// @param name     name of the test run/suite/case
 117/// @param procWin  name of the procedure window
 118/// @param tcIndex  current index of TestRunData
 119/// @param param    parameter for the builtin hooks
 120///
 121/// Catches runtime errors in the user hooks as well.
 122/// Takes care of correct bracketing of user and builtin functions as well. For
 123/// `begin` functions the order is builtin/user and for `end` functions user/builtin.
 224124static Function ExecuteHooks(hookType, hooks, enableTAP, enableJU, name, procWin, tcIndex, [param])
 125  variable               hookType
 126  STRUCT IUTF_TestHooks &hooks
 127  variable enableTAP, enableJU
 128  string name, procWin
 129  variable tcIndex
 130  variable param
 131
 224132  variable err, skip, tcOutIndex
 224133  string errorMessage, hookName, endTime
 134
 224135  WAVE/T testRunData = IUTF_Basics#GetTestRunData()
 224136  skip = str2num(testRunData[tcIndex][%SKIP])
 137
 224138  switch(hookType)
 6139    case IUTF_TEST_BEGIN_CONST:
 6140      AbortOnValue ParamIsDefault(param), 1
 141
 6142      FUNCREF USER_HOOK_PROTO userHook = $hooks.testBegin
 143
 6144      TestBegin(name, param)
 6145      ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_RUN)
 6146      break
 27147    case IUTF_TEST_SUITE_BEGIN_CONST:
 27148      AbortOnValue !ParamIsDefault(param), 1
 149
 27150      FUNCREF USER_HOOK_PROTO userHook = $hooks.testSuiteBegin
 151
 27152      TestSuiteBegin(name)
 27153      ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_SUITE)
 27154      break
 79155    case IUTF_TEST_CASE_BEGIN_CONST:
 79156      AbortOnValue !ParamIsDefault(param), 1
 157
 79158      FUNCREF USER_HOOK_PROTO userHook = $hooks.testCaseBegin
 159
 79160      if(!skip)
 79161        TestCaseBegin(name)
 79162        ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_CASE)
 79163      endif
 79164      BeforeTestCase(name, skip)
 79165      break
 79166    case IUTF_TEST_CASE_END_CONST:
 79167      AbortOnValue ParamIsDefault(param), 1
 168
 79169      // get the end time of the test case as fast as possible
 79170      endTime = IUTF_Reporting#GetTimeString()
 79171      // cache the current index in the results wave as a hook can change it
 79172      WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 79173      tcOutIndex = FindDimLabel(wvTestCase, UTF_ROW, "CURRENT")
 174
 79175      AfterTestCase(name, skip)
 176
 79177      if(!skip)
 79178        FUNCREF USER_HOOK_PROTO userHook = $hooks.testCaseEnd
 79179        ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_CASE)
 79180      endif
 79181      AfterTestCaseUserHook(name, param)
 182
 79183      if(!skip)
 79184        // finalize the normal test case at tcOutIndex and reset the test case index to the
 79185        // one after the hook
 79186        TestCaseEnd(name, tcOutIndex, endTime)
 79187      endif
 79188      break
 27189    case IUTF_TEST_SUITE_END_CONST:
 27190      AbortOnValue !ParamIsDefault(param), 1
 191
 27192      FUNCREF USER_HOOK_PROTO userHook = $hooks.testSuiteEnd
 193
 27194      ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_SUITE)
 27195      TestSuiteEnd(name)
 27196      break
 6197    case IUTF_TEST_END_CONST:
 6198      AbortOnValue ParamIsDefault(param), 1
 199
 6200      FUNCREF USER_HOOK_PROTO userHook = $hooks.testEnd
 201
 6202      ExecuteUserHook(name, userHook, procWin, HOOK_LEVEL_TEST_RUN)
 5203      TestEnd(name, param)
 5204      if(enableJU)
 5205        IUTF_JUnit#JU_WriteOutput()
 5206      endif
 5207      if(enableTAP)
 0208        IUTF_TAP#TAP_Write()
 5209      endif
 5210      break
 0211    default:
 0212      IUTF_Reporting#ReportErrorAndAbort("Unknown hookType")
 0213      break
 223214  endswitch
 224215End
 216
 217/// Internal Setup for Testrun
 218/// @param name   name of the test suite group
 6219static Function TestBegin(name, debugMode)
 220  string   name
 221  variable debugMode
 222
 6223  string msg
 224
 6225  IUTF_Reporting_Control#TestBegin()
 6226  IUTF_Basics#InitAbortFlag()
 6227  IUTF_Debug#SetDebugger(debugMode)
 228
 6229  WAVE/T wvFailed = IUTF_Reporting#GetFailedProcWave()
 6230  IUTF_Utils_Vector#SetLength(wvFailed, 0)
 231
 6232  ClearBaseFilename()
 233
 6234  sprintf msg, "Start of test \"%s\"", name
 6235  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 6236End
 237
 238/// Internal Cleanup for Testrun
 239/// @param name   name of the test suite group
 5240static Function TestEnd(name, debugMode)
 241  string   name
 242  variable debugMode
 243
 5244  string msg
 5245  variable i, index
 5246  DFREF  dfr       = GetPackageFolder()
 5247  WAVE/T wvFailed  = IUTF_Reporting#GetFailedProcWave()
 5248  WAVE/T wvTestRun = IUTF_Reporting#GetTestRunWave()
 249
 5250  if(str2num(wvTestRun[%CURRENT][%NUM_ASSERT_ERROR]) == 0)
 5251    sprintf msg, "Test finished with no errors"
 0252  else
 0253    sprintf msg, "Test finished with %s errors", wvTestRun[%CURRENT][%NUM_ASSERT_ERROR]
 5254  endif
 255
 5256  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 257
 5258  index = IUTF_Utils_Vector#GetLength(wvFailed)
 5259  for(i = 0; i < index; i += 1)
 5260    msg = "  " + TC_ASSERTION_LIST_INDICATOR + " " + wvFailed[i]
 5261    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 5262  endfor
 263
 5264  sprintf msg, "End of test \"%s\"", name
 5265  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 266
 5267  IUTF_Reporting_Control#TestEnd()
 5268  IUTF_Debug#RestoreDebugger()
 5269End
 270
 271/// Internal Setup for Test Suite
 272/// @param testSuite name of the test suite
 27273static Function TestSuiteBegin(testSuite)
 274  string testSuite
 275
 27276  string msg
 277
 27278  IUTF_Reporting_Control#TestSuiteBegin(testSuite)
 279
 27280  sprintf msg, "Entering test suite \"%s\"", testSuite
 27281  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 27282End
 283
 284/// Internal Cleanup for Test Suite
 285/// @param testSuite name of the test suite
 27286static Function TestSuiteEnd(testSuite)
 287  string testSuite
 288
 27289  string msg
 290
 27291  WAVE/T wvTestSuite = IUTF_Reporting#GetTestSuiteWave()
 292
 27293  if(str2num(wvTestSuite[%CURRENT][%NUM_ASSERT_ERROR]) == 0)
 27294    sprintf msg, "Finished with no errors"
 0295  else
 0296    sprintf msg, "Failed with %s errors", wvTestSuite[%CURRENT][%NUM_ASSERT_ERROR]
 27297  endif
 298
 27299  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 300
 27301  IUTF_Reporting_Control#TestSuiteEnd()
 302
 27303  sprintf msg, "Leaving test suite \"%s\"", testSuite
 27304  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 27305End
 306
 307/// Internal Setup for Test Case
 308/// @param testCase name of the test case
 79309static Function TestCaseBegin(testCase)
 310  string testCase
 311
 79312  string msg
 313
 79314  // create a new unique folder as working folder
 79315  DFREF    dfr            = GetPackageFolder()
 79316  string/G dfr:lastFolder = GetDataFolder(1)
 79317  SetDataFolder root:
 79318  string/G dfr:workFolder = "root:" + UniqueName("tempFolder", 11, 0)
 79319  SVAR/SDFR=dfr workFolder
 79320  NewDataFolder/O/S $workFolder
 321
 79322  sprintf msg, "Entering test case \"%s\"", testCase
 79323  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 79324End
 325
 326/// @brief Called after the test case begin user hook and before the test case function
 79327static Function BeforeTestCase(name, skip)
 328  string   name
 329  variable skip
 330
 331#if IgorVersion() >= 9.0
 79332  if(!skip)
 79333    StartWaveTracking(name)
 79334  endif
 335#endif
 336
 79337  IUTF_Reporting_Control#TestCaseBegin(name, skip)
 338
 79339End
 340
 341/// @brief Called after the test case and after the test case end user hook
 79342static Function AfterTestCaseUserHook(name, keepDataFolder)
 343  string   name
 344  variable keepDataFolder
 345
 79346  string msg
 347
 79348  DFREF dfr = GetPackageFolder()
 79349  SVAR/Z/SDFR=dfr lastFolder
 79350  SVAR/Z/SDFR=dfr workFolder
 351
 79352  if(SVAR_Exists(lastFolder) && DataFolderExists(lastFolder))
 79353    SetDataFolder $lastFolder
 79354  endif
 79355  if(!keepDataFolder)
 79356    if(SVAR_Exists(workFolder) && DataFolderExists(workFolder))
 79357      KillDataFolder/Z $workFolder
 79358    endif
 79359  endif
 79360End
 361
 362/// Internal Cleanup for Test Case
 363/// @param testCase name of the test case
 79364static Function TestCaseEnd(testCase, tcIndex, endTime)
 365  string testCase, endTime
 366  variable tcIndex
 367
 79368  string   msg
 79369  variable oldIndex
 370
 79371  WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 79372  oldIndex = IUTF_Utils_Waves#MoveDimLabel(wvTestCase, UTF_ROW, "CURRENT", tcIndex)
 373
 79374  IUTF_Reporting_Control#TestCaseEnd(endTime)
 375
 79376  IUTF_Utils_Waves#MoveDimLabel(wvTestCase, UTF_ROW, "CURRENT", oldIndex)
 377
 79378  sprintf msg, "Leaving test case \"%s\"", testCase
 79379  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 79380End
 381
 382/// @brief Called after the test case and before the test case end user hook
 79383static Function AfterTestCase(name, skip)
 384  string   name
 385  variable skip
 386
 79387  string msg
 388
 79389  IUTF_Reporting#CleanupInfoMsg()
 390
 79391  WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 392
 79393  if(skip)
 0394    return NaN
 79395  endif
 396
 79397  FinishWaveTracking(name)
 398
 79399  if(IsExpectedFailure())
 0400    if(str2num(wvTestCase[%CURRENT][%NUM_ASSERT_ERROR]) == 0)
 0401      sprintf msg, "Test case \"%s\" doesn't contain at least one assertion error", name
 0402      IUTF_Reporting#TestCaseFail(msg, isFailure = 1)
 0403    else
 0404      // reset the assertion error counter as all previous errors are intended
 0405      wvTestCase[%CURRENT][%NUM_ASSERT_ERROR] = "0"
 0406      if(!CmpStr(wvTestCase[%CURRENT][%STATUS], IUTF_STATUS_FAIL))
 0407        wvTestCase[%CURRENT][%STATUS] = IUTF_STATUS_RUNNING
 0408      endif
 0409    endif
 79410  else
 79411    if(str2num(wvTestCase[%CURRENT][%NUM_ASSERT]) == 0)
 0412      sprintf msg, "Test case \"%s\" doesn't contain at least one assertion", name
 0413      IUTF_Reporting#TestCaseFail(msg)
 79414    endif
 79415  endif
 79416End
 417
 418/// Sets the hooks to the builtin defaults
 6419static Function setDefaultHooks(hooks)
 420  STRUCT IUTF_TestHooks &hooks
 421
 6422  hooks.testBegin      = "TEST_BEGIN"
 6423  hooks.testEnd        = "TEST_END"
 6424  hooks.testSuiteBegin = "TEST_SUITE_BEGIN"
 6425  hooks.testSuiteEnd   = "TEST_SUITE_END"
 6426  hooks.testCaseBegin  = "TEST_CASE_BEGIN"
 6427  hooks.testCaseEnd    = "TEST_CASE_END"
 6428End
 429
 430/// Check that all hook functions, default and override,
 431/// have the expected signature and abort if not.
 106432static Function abortWithInvalidHooks(hooks)
 433  STRUCT IUTF_TestHooks &hooks
 434
 106435  variable i, numEntries
 106436  string msg
 437
 106438  Make/T/N=6/FREE wvInfo
 439
 106440  wvInfo[0] = FunctionInfo(hooks.testBegin)
 106441  wvInfo[1] = FunctionInfo(hooks.testEnd)
 106442  wvInfo[2] = FunctionInfo(hooks.testSuiteBegin)
 106443  wvInfo[3] = FunctionInfo(hooks.testSuiteEnd)
 106444  wvInfo[4] = FunctionInfo(hooks.testCaseBegin)
 106445  wvInfo[5] = FunctionInfo(hooks.testCaseEnd)
 446
 106447  numEntries = DimSize(wvInfo, 0)
 106448  for(i = 0; i < numEntries; i += 1)
 636449    if(NumberByKey("N_PARAMS", wvInfo[i]) != 1 || NumberByKey("N_OPT_PARAMS", wvInfo[i]) != 0 || NumberByKey("PARAM_0_TY
 0450      sprintf msg, "The override test hook \"%s\" must accept exactly one string parameter.", StringByKey("NAME", wvInfo
 0451      IUTF_Reporting#ReportErrorAndAbort(msg)
 636452    endif
 453
 636454    if(NumberByKey("RETURNTYPE", wvInfo[i]) != 0x4)
 0455      sprintf msg, "The override test hook \"%s\" must return a numeric variable.", StringByKey("NAME", wvInfo[i])
 0456      IUTF_Reporting#ReportErrorAndAbort(msg)
 636457    endif
 636458  endfor
 106459End
 460
 461/// Looks for global override hooks in the same indpendent module as the framework itself
 462/// is running in.
 6463static Function getGlobalHooks(hooks)
 464  STRUCT IUTF_TestHooks &hooks
 465
 6466  string userHooks = FunctionList("*_OVERRIDE", ";", "KIND:2,WIN:[" + GetIndependentModuleName() + "]")
 467
 6468  variable i
 6469  for(i = 0; i < ItemsInList(userHooks); i += 1)
 6470    string userHook = StringFromList(i, userHooks)
 6471    strswitch(userHook)
 0472      case "TEST_BEGIN_OVERRIDE":
 0473        hooks.testBegin = userHook
 0474        break
 6475      case "TEST_END_OVERRIDE":
 6476        hooks.testEnd = userHook
 6477        break
 0478      case "TEST_SUITE_BEGIN_OVERRIDE":
 0479        hooks.testSuiteBegin = userHook
 0480        break
 0481      case "TEST_SUITE_END_OVERRIDE":
 0482        hooks.testSuiteEnd = userHook
 0483        break
 0484      case "TEST_CASE_BEGIN_OVERRIDE":
 0485        hooks.testCaseBegin = userHook
 0486        break
 0487      case "TEST_CASE_END_OVERRIDE":
 0488        hooks.testCaseEnd = userHook
 0489        break
 0490      default:
 0491        // ignore unknown functions
 0492        break
 6493    endswitch
 6494  endfor
 495
 6496  abortWithInvalidHooks(hooks)
 6497End
 498
 499/// Looks for local override hooks in a specific procedure file
 100500static Function getLocalHooks(hooks, procName)
 501  string                 procName
 502  STRUCT IUTF_TestHooks &hooks
 503
 100504  variable err
 100505  string userHooks = FunctionList("*_OVERRIDE", ";", "KIND:18,WIN:" + procName)
 506
 100507  variable i
 100508  for(i = 0; i < ItemsInList(userHooks); i += 1)
 0509    string userHook = StringFromList(i, userHooks)
 510
 0511    string fullFunctionName = IUTF_Basics#getFullFunctionName(err, userHook, procName)
 0512    strswitch(userHook)
 0513      case "TEST_SUITE_BEGIN_OVERRIDE":
 0514        hooks.testSuiteBegin = fullFunctionName
 0515        break
 0516      case "TEST_SUITE_END_OVERRIDE":
 0517        hooks.testSuiteEnd = fullFunctionName
 0518        break
 0519      case "TEST_CASE_BEGIN_OVERRIDE":
 0520        hooks.testCaseBegin = fullFunctionName
 0521        break
 0522      case "TEST_CASE_END_OVERRIDE":
 0523        hooks.testCaseEnd = fullFunctionName
 0524        break
 0525      default:
 0526        // ignore unknown functions
 0527        break
 0528    endswitch
 0529  endfor
 530
 100531  abortWithInvalidHooks(hooks)
 100532End
 533
 534/// @brief Stores the state of TestHook structure to DF dfr with key as template
 10535static Function StoreHooks(dfr, s, key)
 536  DFREF                  dfr
 537  STRUCT IUTF_TestHooks &s
 538  string                 key
 539
 10540  key = "S" + key
 10541  string/G dfr:$(key + "testBegin")      = s.testBegin
 10542  string/G dfr:$(key + "testEnd")        = s.testEnd
 10543  string/G dfr:$(key + "testSuiteBegin") = s.testSuiteBegin
 10544  string/G dfr:$(key + "testSuiteEnd")   = s.testSuiteEnd
 10545  string/G dfr:$(key + "testCaseBegin")  = s.testCaseBegin
 10546  string/G dfr:$(key + "testCaseEnd")    = s.testCaseEnd
 10547End
 548
 549/// @brief Restores the state of TestHook structure from DF dfr with key as template
 20550static Function RestoreHooks(dfr, s, key)
 551  DFREF                  dfr
 552  STRUCT IUTF_TestHooks &s
 553  string                 key
 554
 20555  key = "S" + key
 20556  SVAR testBegin      = dfr:$(key + "testBegin")
 20557  SVAR testEnd        = dfr:$(key + "testEnd")
 20558  SVAR testSuiteBegin = dfr:$(key + "testSuiteBegin")
 20559  SVAR testSuiteEnd   = dfr:$(key + "testSuiteEnd")
 20560  SVAR testCaseBegin  = dfr:$(key + "testCaseBegin")
 20561  SVAR testCaseEnd    = dfr:$(key + "testCaseEnd")
 20562  s.testBegin      = testBegin
 20563  s.testEnd        = testEnd
 20564  s.testSuiteBegin = testSuiteBegin
 20565  s.testSuiteEnd   = testSuiteEnd
 20566  s.testCaseBegin  = testCaseBegin
 20567  s.testCaseEnd    = testCaseEnd
 20568End
 569
 85570static Function StartWaveTracking(name)
 571  string name
 572
 573#if IgorVersion() >= 9.0
 85574  DFREF dfr = GetPackageFolder()
 85575  NVAR/SDFR=dfr/Z waveTrackingMode
 576
 85577  if(NVAR_Exists(waveTrackingMode))
 85578    WaveTracking/LOCL stop
 85579    WaveTracking/FREE stop
 85580    if(!IUTF_FunctionTags#HasFunctionTag(name, UTF_FTAG_NO_WAVE_TRACKING))
 85581      if((waveTrackingMode & UTF_WAVE_TRACKING_FREE) == UTF_WAVE_TRACKING_FREE)
 5582        WaveTracking/FREE counter
 85583      endif
 85584      if((waveTrackingMode & UTF_WAVE_TRACKING_LOCAL) == UTF_WAVE_TRACKING_LOCAL)
 5585        WaveTracking/LOCL counter
 85586      endif
 85587    endif
 85588  endif
 589#endif
 85590End
 591
 84592static Function FinishWaveTracking(name)
 593  string name
 594
 84595  string msg
 596
 597#if IgorVersion() >= 9.0
 84598  DFREF dfr = GetPackageFolder()
 84599  NVAR/SDFR=dfr waveTrackingMode
 600
 84601  if(NVAR_Exists(waveTrackingMode))
 84602    if((waveTrackingMode & UTF_WAVE_TRACKING_LOCAL) == UTF_WAVE_TRACKING_LOCAL)
 4603      WaveTracking/LOCL count
 4604      if(V_Flag == IUTF_WVTRACK_COUNT_MODE)
 4605        if(V_numWaves)
 0606          sprintf msg, "Local wave leak detected (leaked waves: %d) in \"%s\"", V_numWaves, name
 0607          IUTF_Reporting#TestCaseFail(msg)
 4608        endif
 4609        WaveTracking/LOCL stop
 0610      elseif(V_Flag != IUTF_WVTRACK_INACTIVE_MODE)
 0611        // do nothing for IUTF_WVTRACK_INACTIVE_MODE.
 0612        // Most likely the user has used a tag to opt out this test case for wave tracking.
 0613        sprintf msg, "Test case \"%s\" modified WaveTracking mode to %d. IUTF can not track at the same time.", name, V_
 0614        IUTF_Reporting#TestCaseFail(msg)
 4615      endif
 84616    endif
 617
 84618    if((waveTrackingMode & UTF_WAVE_TRACKING_FREE) == UTF_WAVE_TRACKING_FREE)
 4619      WaveTracking/FREE count
 4620      if(V_Flag == IUTF_WVTRACK_COUNT_MODE)
 4621        if(V_numWaves)
 0622          sprintf msg, "Free wave leak detected (leaked waves: %d) in \"%s\"", V_numWaves, name
 0623          IUTF_Reporting#TestCaseFail(msg)
 4624        endif
 4625        WaveTracking/FREE stop
 0626      elseif(V_Flag != IUTF_WVTRACK_INACTIVE_MODE)
 0627        // do nothing for IUTF_WVTRACK_INACTIVE_MODE.
 0628        // Most likely the user has used a tag to opt out this test case for wave tracking.
 0629        sprintf msg, "Test case \"%s\" modified WaveTracking mode to %d. IUTF can not track at the same time.", name, V_
 0630        IUTF_Reporting#TestCaseFail(msg)
 4631      endif
 84632    endif
 84633  endif
 634#endif
 84635End
 636
 637///@endcond // HIDDEN_SYMBOL