| | 1 | | #pragma rtGlobals=3 |
| | 2 | | #pragma TextEncoding="UTF-8" |
| | 3 | | #pragma rtFunctionErrors=1 |
| | 4 | | #pragma version=1.10 |
| | 5 | | #pragma ModuleName=IUTF_Test_MD_Gen |
| | 6 | |
|
| | 7 | | ///@cond HIDDEN_SYMBOL |
| | 8 | |
|
| | 9 | | /// @brief Returns a global wave that stores the results of the DataGenerators of this testrun |
| 22 | 10 | | static Function/WAVE GetDataGeneratorWaves() |
| | 11 | |
|
| 22 | 12 | | string name = "DataGeneratorWaves" |
| | 13 | |
|
| 22 | 14 | | DFREF dfr = GetPackageFolder() |
| 22 | 15 | | WAVE/Z/WAVE wv = dfr:$name |
| 22 | 16 | | if(WaveExists(wv)) |
| 11 | 17 | | return wv |
| 11 | 18 | | endif |
| | 19 | |
|
| 11 | 20 | | Make/WAVE/N=(IUTF_WAVECHUNK_SIZE) dfr:$name/WAVE=wv |
| 11 | 21 | | IUTF_Utils_Vector#SetLength(wv, 0) |
| | 22 | |
|
| 11 | 23 | | return wv |
| 22 | 24 | | End |
| | 25 | |
|
| | 26 | | /// @brief Returns a global wave that stores the references for DataGeneratorWaves. |
| 5 | 27 | | static Function/WAVE GetDataGeneratorRefs() |
| | 28 | |
|
| 5 | 29 | | string name = "DataGeneratorRefs" |
| | 30 | |
|
| 5 | 31 | | DFREF dfr = GetPackageFolder() |
| 5 | 32 | | WAVE/Z/T wv = dfr:$name |
| 5 | 33 | | if(WaveExists(wv)) |
| 0 | 34 | | return wv |
| 5 | 35 | | endif |
| | 36 | |
|
| 5 | 37 | | Make/T/N=(IUTF_WAVECHUNK_SIZE) dfr:$name/WAVE=wv |
| 5 | 38 | | IUTF_Utils_Vector#SetLength(wv, 0) |
| | 39 | |
|
| 5 | 40 | | return wv |
| 5 | 41 | | End |
| | 42 | |
|
| | 43 | | /// @brief Find the current index in the global data generator wave reference wave. |
| | 44 | | /// |
| | 45 | | /// @param fullFuncName the full function name |
| | 46 | | /// |
| | 47 | | /// @returns The index inside the data generate wave reference wave. -1 if not found. |
| 0 | 48 | | static Function GetDataGeneratorRef(fullFuncName) |
| | 49 | | string fullFuncName |
| | 50 | |
|
| 0 | 51 | | WAVE/T dgRefs = GetDataGeneratorRefs() |
| | 52 | |
|
| 0 | 53 | | return IUTF_Utils_Vector#FindText(dgRefs, fullFuncName) |
| 0 | 54 | | End |
| | 55 | |
|
| | 56 | | /// Returns the functionName of the specified DataGenerator. The priority is first local then ProcGlobal. |
| | 57 | | /// If funcName is specified with Module then in all procedures is looked. No ProcGlobal function is returned in that ca |
| 0 | 58 | | static Function/S GetDataGeneratorFunctionName(err, funcName, procName) |
| | 59 | | variable &err |
| | 60 | | string funcName, procName |
| | 61 | |
|
| 0 | 62 | | string infoStr, modName, pName, errMsg |
| | 63 | |
|
| 0 | 64 | | err = 0 |
| 0 | 65 | | if(ItemsInList(funcName, "#") > 2) |
| 0 | 66 | | sprintf errMsg, "Data Generator Function %s is specified with Independent Module, this is not supported.", funcName |
| 0 | 67 | | err = 1 |
| 0 | 68 | | return errMsg |
| 0 | 69 | | endif |
| 0 | 70 | | // if funcName is specified without Module then FunctionInfo looks in procedure procName only. |
| 0 | 71 | | // if funcName is specified with Module then FunctionInfo looks in all procedures of current compile unit, independent |
| 0 | 72 | | infoStr = FunctionInfo(funcName, procName) |
| 0 | 73 | | if(!IUTF_Utils#IsEmpty(infoStr)) |
| 0 | 74 | | modName = StringByKey("MODULE", infoStr) |
| 0 | 75 | | pName = StringByKey("NAME", infoStr) |
| 0 | 76 | | if(!CmpStr(StringByKey("SPECIAL", infoStr), "static") && IUTF_Utils#IsEmpty(modName)) |
| 0 | 77 | | sprintf errMsg, "Data Generator Function %s is declared static but the procedure file %s is missing a \"#pragma Mo |
| 0 | 78 | | err = 1 |
| 0 | 79 | | return errMsg |
| 0 | 80 | | endif |
| 0 | 81 | | if(IUTF_Utils#IsEmpty(modName)) |
| 0 | 82 | | return pName |
| 0 | 83 | | endif |
| 0 | 84 | | return modName + "#" + pName |
| 0 | 85 | | else |
| 0 | 86 | | // look in ProcGlobal of current compile unit |
| 0 | 87 | | infoStr = FunctionInfo(funcName) |
| 0 | 88 | | if(!IUTF_Utils#IsEmpty(infoStr)) |
| 0 | 89 | | pName = StringByKey("NAME", infoStr) |
| 0 | 90 | | return pName |
| 0 | 91 | | endif |
| 0 | 92 | | endif |
| 0 | 93 | | infoStr = GetIndependentModuleName() |
| 0 | 94 | | if(!CmpStr(infoStr, "ProcGlobal")) |
| 0 | 95 | | sprintf errMsg, "Data Generator Function %s not found in %s or ProcGlobal.", funcName, procName |
| 0 | 96 | | else |
| 0 | 97 | | sprintf errMsg, "In Independent Module %s, data Generator Function %s not found in %s or globally in IM.", infoStr, |
| 0 | 98 | | endif |
| 0 | 99 | | err = 1 |
| | 100 | |
|
| 0 | 101 | | return errMsg |
| 0 | 102 | | End |
| | 103 | |
|
| | 104 | | ///@endcond // HIDDEN_SYMBOL |
| | 105 | |
|
| 0 | 106 | | static Function/S GetDataGenFullFunctionName(procWin, fullTestCase) |
| | 107 | | string fullTestCase |
| | 108 | | string procWin |
| | 109 | |
|
| 0 | 110 | | variable err |
| 0 | 111 | | string dgen, msg |
| | 112 | |
|
| 0 | 113 | | dgen = IUTF_FunctionTags#GetFunctionTagValue(fullTestCase, UTF_FTAG_TD_GENERATOR, err) |
| 0 | 114 | | if(err) |
| 0 | 115 | | sprintf msg, "Could not find data generator specification for multi data test case %s. %s", fullTestCase, dgen |
| 0 | 116 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 117 | | endif |
| | 118 | |
|
| 0 | 119 | | dgen = GetDataGeneratorFunctionName(err, dgen, procWin) |
| 0 | 120 | | if(err) |
| 0 | 121 | | sprintf msg, "Could not get full function name of data generator: %s", dgen |
| 0 | 122 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 123 | | endif |
| | 124 | |
|
| 0 | 125 | | return dgen |
| 0 | 126 | | End |
| | 127 | |
|
| 0 | 128 | | static Function/S GetDataGeneratorForMMD(procWin, fullFuncName) |
| | 129 | | string procWin, fullFuncName |
| | 130 | |
|
| 0 | 131 | | variable i, j, numTypes |
| 0 | 132 | | string msg, dgen |
| 0 | 133 | | string dgenList = "" |
| | 134 | |
|
| 0 | 135 | | WAVE/T templates = IUTF_Test_MD_MMD#GetMMDVarTemplates() |
| 0 | 136 | | Make/FREE/D wType0 = {0xff %^ IUTF_WAVETYPE0_CMPL %^ IUTF_WAVETYPE0_INT64, NaN, NaN, NaN, IUTF_WAVETYPE0_CMPL, IUTF_WA |
| 0 | 137 | | Make/FREE/D wType1 = {IUTF_WAVETYPE1_NUM, IUTF_WAVETYPE1_TEXT, IUTF_WAVETYPE1_DFR, IUTF_WAVETYPE1_WREF, IUTF_WAVETYPE1 |
| | 138 | |
|
| 0 | 139 | | numTypes = DimSize(templates, UTF_ROW) |
| 0 | 140 | | for(i = 0; i < numTypes; i += 1) |
| 0 | 141 | | for(j = 0; j < IUTF_DGEN_NUM_VARS; j += 1) |
| 0 | 142 | | dgen = GetSingleDataGeneratorForMMD(procWin, fullFuncName, templates[i], j) |
| 0 | 143 | | if(!IUTF_Utils#IsEmpty(dgen)) |
| 0 | 144 | | dgenList = AddListItem(dgen, dgenList, ";", Inf) |
| 0 | 145 | | endif |
| 0 | 146 | | endfor |
| 0 | 147 | | endfor |
| | 148 | |
|
| 0 | 149 | | if(IUTF_Utils#IsEmpty(dgenList)) |
| 0 | 150 | | sprintf msg, "No data generator functions specified for test case %s in test suite %s.", fullFuncName, procWin |
| 0 | 151 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 152 | | endif |
| | 153 | |
|
| 0 | 154 | | return dgenList |
| 0 | 155 | | End |
| | 156 | |
|
| 0 | 157 | | static Function CheckFunctionSignatureMDgen(procWin, fullFuncName, markSkip) |
| | 158 | | string procWin, fullFuncName |
| | 159 | | variable &markSkip |
| | 160 | |
|
| 0 | 161 | | variable i, j, numTypes |
| | 162 | |
|
| 0 | 163 | | WAVE/T templates = IUTF_Test_MD_MMD#GetMMDVarTemplates() |
| 0 | 164 | | Make/FREE/D wType0 = {0xff %^ IUTF_WAVETYPE0_CMPL %^ IUTF_WAVETYPE0_INT64, NaN, NaN, NaN, IUTF_WAVETYPE0_CMPL, IUTF_WA |
| 0 | 165 | | Make/FREE/D wType1 = {IUTF_WAVETYPE1_NUM, IUTF_WAVETYPE1_TEXT, IUTF_WAVETYPE1_DFR, IUTF_WAVETYPE1_WREF, IUTF_WAVETYPE1 |
| | 166 | |
|
| 0 | 167 | | numTypes = DimSize(templates, UTF_ROW) |
| 0 | 168 | | for(i = 0; i < numTypes; i += 1) |
| 0 | 169 | | for(j = 0; j < IUTF_DGEN_NUM_VARS; j += 1) |
| 0 | 170 | | markSkip = markSkip | CheckMDgenOutput(procWin, fullFuncName, templates[i], j, wType0[i], wType1[i]) |
| 0 | 171 | | endfor |
| 0 | 172 | | endfor |
| 0 | 173 | | End |
| | 174 | |
|
| | 175 | | /// Get a single data generator for a MMD test case. This returns an empty string if no data |
| | 176 | | /// generator could be found. |
| 0 | 177 | | static Function/S GetSingleDataGeneratorForMMD(procWin, fullFuncName, varTemplate, index) |
| | 178 | | string procWin, fullFuncName, varTemplate |
| | 179 | | variable index |
| | 180 | |
|
| 0 | 181 | | string varName, tagName, dgen, msg |
| 0 | 182 | | variable err |
| | 183 | |
|
| 0 | 184 | | varName = varTemplate + num2istr(index) |
| 0 | 185 | | tagName = UTF_FTAG_TD_GENERATOR + " " + varName |
| 0 | 186 | | dgen = IUTF_FunctionTags#GetFunctionTagValue(fullFuncName, tagName, err) |
| 0 | 187 | | if(err == UTF_TAG_NOT_FOUND) |
| 0 | 188 | | return "" |
| 0 | 189 | | endif |
| 0 | 190 | | dgen = GetDataGeneratorFunctionName(err, dgen, procWin) |
| 0 | 191 | | if(err) |
| 0 | 192 | | sprintf msg, "Could not get full function name of data generator: %s", dgen |
| 0 | 193 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 194 | | endif |
| | 195 | |
|
| 0 | 196 | | EvaluateDgenTagResult(err, fullFuncName, varName) |
| | 197 | |
|
| 0 | 198 | | return dgen |
| 0 | 199 | | End |
| | 200 | |
|
| | 201 | | /// Check Multi-Multi Data Generator output |
| | 202 | | /// return 1 if one data generator has a zero sized wave, 0 otherwise |
| 0 | 203 | | static Function CheckMDgenOutput(procWin, fullFuncName, varTemplate, index, wType0, wType1) |
| | 204 | | string procWin, fullFuncName, varTemplate |
| | 205 | | variable index, wType0, wType1 |
| | 206 | |
|
| 0 | 207 | | string varName, tagName, dgen, msg |
| 0 | 208 | | variable err |
| | 209 | |
|
| 0 | 210 | | varName = varTemplate + num2istr(index) |
| 0 | 211 | | tagName = UTF_FTAG_TD_GENERATOR + " " + varName |
| 0 | 212 | | dgen = IUTF_FunctionTags#GetFunctionTagValue(fullFuncName, tagName, err) |
| 0 | 213 | | if(err == UTF_TAG_NOT_FOUND) |
| 0 | 214 | | return 0 |
| 0 | 215 | | endif |
| 0 | 216 | | dgen = GetDataGeneratorFunctionName(err, dgen, procWin) |
| 0 | 217 | | if(err) |
| 0 | 218 | | sprintf msg, "Could not get full function name of data generator: %s", dgen |
| 0 | 219 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 220 | | endif |
| | 221 | |
|
| 0 | 222 | | EvaluateDgenTagResult(err, fullFuncName, varName) |
| | 223 | |
|
| 0 | 224 | | WAVE wGenerator = CheckDGenOutput(fullFuncName, dgen, wType0, wType1, NaN) |
| | 225 | |
|
| 0 | 226 | | IUTF_Test_MD_MMD#AddMMDTestCaseData(fullFuncName, dgen, varName, DimSize(wGenerator, UTF_ROW)) |
| | 227 | |
|
| 0 | 228 | | return CheckDataGenZeroSize(wGenerator, fullFuncName, dgen) |
| 0 | 229 | | End |
| | 230 | |
|
| 0 | 231 | | static Function CheckDataGenZeroSize(wGenerator, fullFuncName, dgen) |
| | 232 | | WAVE wGenerator |
| | 233 | | string fullFuncName, dgen |
| | 234 | |
|
| 0 | 235 | | string msg |
| | 236 | |
|
| 0 | 237 | | if(!DimSize(wGenerator, UTF_ROW)) |
| 0 | 238 | | sprintf msg, "Note: In test case %s data generator function \"%s\" returns a zero sized wave. Test case marked SKIP. |
| 0 | 239 | | IUTF_Reporting#ReportError(msg, incrGlobalErrorCounter = 0) |
| 0 | 240 | | return 1 |
| 0 | 241 | | endif |
| | 242 | |
|
| 0 | 243 | | return 0 |
| 0 | 244 | | End |
| | 245 | |
|
| 0 | 246 | | static Function EvaluateDgenTagResult(err, fullFuncName, varName) |
| | 247 | | variable err |
| | 248 | | string fullFuncName, varName |
| | 249 | |
|
| 0 | 250 | | string msg |
| | 251 | |
|
| 0 | 252 | | if(err == UTF_TAG_EMPTY) |
| 0 | 253 | | sprintf msg, "No data generator function specified for function \"%s\" data generator variable \"%s\".", fullFuncNam |
| 0 | 254 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 255 | | endif |
| 0 | 256 | | if(err != UTF_TAG_OK) |
| 0 | 257 | | sprintf msg, "Problem determining data generator function specified for function \"%s\" data generator variable \"%s |
| 0 | 258 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 259 | | endif |
| 0 | 260 | | End |
| | 261 | |
|
| 0 | 262 | | static Function/WAVE GetGeneratorWave(dgen) |
| | 263 | | string dgen |
| | 264 | |
|
| 0 | 265 | | variable dimPos |
| | 266 | |
|
| 0 | 267 | | WAVE/WAVE wDgen = GetDataGeneratorWaves() |
| 0 | 268 | | dimPos = GetDataGeneratorRef(dgen) |
| 0 | 269 | | if(dimPos == -1) |
| 0 | 270 | | return $"" |
| 0 | 271 | | endif |
| 0 | 272 | | WAVE wGenerator = wDgen[dimPos] |
| | 273 | |
|
| 0 | 274 | | return wGenerator |
| 0 | 275 | | End |
| | 276 | |
|
| 0 | 277 | | static Function/WAVE CheckDGenOutput(fullFuncName, dgen, wType0, wType1, wRefSubType) |
| | 278 | | string fullFuncName, dgen |
| | 279 | | variable wType0, wType1, wRefSubType |
| | 280 | |
|
| 0 | 281 | | string msg |
| | 282 | |
|
| 0 | 283 | | WAVE/Z wGenerator = GetGeneratorWave(dgen) |
| 0 | 284 | | if(!WaveExists(wGenerator)) |
| 0 | 285 | | // wave is not stored |
| 0 | 286 | | sprintf msg, "Data Generator function \"%s\" has no suitable data for test case \"%s\".", dgen, fullFuncName |
| 0 | 287 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 288 | | elseif(!((wType1 == IUTF_WAVETYPE1_NUM && WaveType(wGenerator, 1) == wType1 && WaveType(wGenerator) & wType0) || (wTyp |
| 0 | 289 | | sprintf msg, "Data Generator \"%s\" functions returned wave format does not fit to expected test case parameter. It |
| 0 | 290 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 291 | | elseif(!IUTF_Utils#IsNaN(wRefSubType) && wType1 == IUTF_WAVETYPE1_WREF && !IUTF_Utils#HasConstantWaveTypes(wGenerator, |
| 0 | 292 | | sprintf msg, "Test case \"%s\" expects specific wave type1 %u from the Data Generator \"%s\". The wave type from the |
| 0 | 293 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 294 | | endif |
| | 295 | |
|
| 0 | 296 | | return wGenerator |
| 0 | 297 | | End |
| | 298 | |
|
| 0 | 299 | | static Function ExecuteAllDataGenerators(debugMode) |
| | 300 | | variable debugMode |
| | 301 | |
|
| 0 | 302 | | variable i, j, size, length, dimPos, err |
| 0 | 303 | | string dgenList, dgen, fullFuncName, endTime, msg, procWin |
| 0 | 304 | | variable DGENLIST_Index |
| | 305 | |
|
| 0 | 306 | | WAVE/T testRunData = IUTF_Basics#GetTestRunData() |
| 0 | 307 | | size = DimSize(testRunData, UTF_ROW) |
| 0 | 308 | | DGENLIST_Index = FindDimLabel(testRunData, UTF_COLUMN, "DGENLIST") |
| | 309 | |
|
| 0 | 310 | | if(!size) |
| 0 | 311 | | return NaN |
| 0 | 312 | | endif |
| | 313 | |
|
| 0 | 314 | | WAVE/WAVE wDgen = GetDataGeneratorWaves() |
| | 315 | |
|
| 0 | 316 | | IUTF_Debug#SetDebugger(debugMode) |
| 0 | 317 | | IUTF_Reporting_Control#TestSuiteBegin("@DGEN_SUITE") |
| | 318 | |
|
| 0 | 319 | | for(i = 0; i < size; i += 1) |
| 0 | 320 | | dgenList = testRunData[i][DGENLIST_Index] |
| 0 | 321 | | WAVE/T dgenWave = ListToTextWave(dgenList, ";") |
| 0 | 322 | | length = DimSize(dgenWave, UTF_ROW) |
| | 323 | |
|
| 0 | 324 | | for(j = 0; j < length; j += 1) |
| 0 | 325 | | dgen = dgenWave[j] |
| 0 | 326 | | dimPos = GetDataGeneratorRef(dgen) |
| 0 | 327 | | if(dimPos != -1) |
| 0 | 328 | | continue |
| 0 | 329 | | endif |
| 0 | 330 | | procWin = StringByKey("PROCWIN", FunctionInfo(dgen)) |
| | 331 | |
|
| 0 | 332 | | FUNCREF TEST_CASE_PROTO_DGEN fDgen = $dgen |
| 0 | 333 | | if(!IUTF_FuncRefIsAssigned(FuncRefInfo(fDgen))) |
| 0 | 334 | | fullFuncName = testRunData[i][%FULLFUNCNAME] |
| 0 | 335 | | sprintf msg, "Data Generator function \"%s\" has wrong format. It is referenced by test case \"%s\".", dgen, ful |
| 0 | 336 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 337 | | endif |
| | 338 | |
|
| 0 | 339 | | IUTF_Reporting_Control#TestCaseBegin(dgen, 0) |
| 0 | 340 | | try |
| 0 | 341 | | IUTF_Basics#ClearRTError() |
| 0 | 342 | | WAVE/Z wGenerator = fDgen(); AbortOnRTE |
| 0 | 343 | | catch |
| 0 | 344 | | msg = GetRTErrMessage() |
| 0 | 345 | | err = GetRTError(1) |
| 0 | 346 | | IUTF_Basics#EvaluateRTE(err, msg, V_AbortCode, dgen, IUTF_DATA_GEN_TYPE, procWin) |
| | 347 | |
|
| 0 | 348 | | sprintf msg, "Invalid Data Generator \"%s\"", dgen |
| 0 | 349 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 350 | | endtry |
| 0 | 351 | | endTime = IUTF_Reporting#GetTimeString() |
| | 352 | |
|
| 0 | 353 | | if(!WaveExists(wGenerator)) |
| 0 | 354 | | sprintf msg, "Data Generator function \"%s\" (%s) returns a null wave.", dgen, procWin |
| 0 | 355 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 356 | | elseif(DimSize(wGenerator, UTF_COLUMN) > 0) |
| 0 | 357 | | sprintf msg, "Data Generator function \"%s\" (%s) returns not a 1D wave.", dgen, procWin |
| 0 | 358 | | IUTF_Reporting#ReportErrorAndAbort(msg) |
| 0 | 359 | | endif |
| | 360 | |
|
| 0 | 361 | | IUTF_Reporting_Control#TestCaseEnd(endTime) |
| | 362 | |
|
| 0 | 363 | | AddDataGeneratorWave(dgen, wGenerator) |
| 0 | 364 | | endfor |
| 0 | 365 | | endfor |
| | 366 | |
|
| 0 | 367 | | IUTF_Reporting_Control#TestSuiteEnd() // of @DGEN_SUITE |
| 0 | 368 | | IUTF_Debug#RestoreDebugger() |
| 0 | 369 | | End |
| | 370 | |
|
| 0 | 371 | | static Function AddDataGeneratorWave(name, generator) |
| | 372 | | string name |
| | 373 | | WAVE generator |
| | 374 | |
|
| 0 | 375 | | variable index |
| | 376 | |
|
| 0 | 377 | | WAVE/WAVE wv = GetDataGeneratorWaves() |
| 0 | 378 | | WAVE/T wvRefs = GetDataGeneratorRefs() |
| | 379 | |
|
| 0 | 380 | | index = IUTF_Utils_Vector#AddRow(wv) |
| 0 | 381 | | wv[index] = generator |
| 0 | 382 | | IUTF_Utils_Vector#EnsureCapacity(wvRefs, index) |
| 0 | 383 | | wvRefs[index] = name |
| 0 | 384 | | IUTF_Utils_Vector#SetLength(wvRefs, IUTF_Utils_Vector#GetLength(wv)) |
| 0 | 385 | | End |