📄 test_util.c
字号:
{ /* An error did occured, but it * was expected. No need to go * further. */ return TA_TEST_PASS; } if( outNbElement > MAX_NB_TEST_ELEMENT ) { printf( "Fail: outNbElement is out of range 2 (%d)\n", outNbElement ); return TA_TEST_TFRR_NB_ELEMENT_OUT_OF_RANGE; } /* Make sure the range of output does not contains NAN. */ /* TODO Add back nan/inf checking for( i=0; i < outNbElement; i++ ) { if( trio_isnan(data[i]) ) { printf( "Fail: Not a number find within the data (%d,%f)\n", i, data[i] ); return TA_TEST_TFRR_OVERLAP_OR_NAN_3; } }*/ /* Verify that the expected output is there. */ if( outNbElement != expectedNbElement ) { printf( "Fail: outNbElement expected %d but got %d\n", expectedNbElement, outNbElement ); return TA_TESTUTIL_TFRR_BAD_OUTNBELEMENT; } if( expectedNbElement > 0 ) { if( !TA_REAL_EQ( oneOfTheExpectedOutReal, data[oneOfTheExpectedOutRealIndex], 0.01 ) ) { printf( "Fail: For index %d, Expected value = %f but calculate value is %f\n", oneOfTheExpectedOutRealIndex, oneOfTheExpectedOutReal, data[oneOfTheExpectedOutRealIndex] ); return TA_TESTUTIL_TFRR_BAD_CALCULATION; } if( expectedBegIdx != outBegIdx ) { printf( "Fail: outBegIdx expected %d but got %d\n", expectedBegIdx, outBegIdx ); return TA_TESTUTIL_TFRR_BAD_BEGIDX; } } /* Succeed. */ return TA_TEST_PASS;}ErrorNumber doRangeTest( RangeTestFunction testFunction, TA_FuncUnstId unstId, void *opaqueData, unsigned int nbOutput, unsigned int integerTolerance ){ unsigned int outputNb; ErrorNumber errNb; /* Test all the outputs individually. */ for( outputNb=0; outputNb < nbOutput; outputNb++ ) { errNb = doRangeTestForOneOutput( testFunction, unstId, opaqueData, outputNb, integerTolerance ); if( errNb != TA_TEST_PASS ) { printf( "Failed: For output #%d of %d\n", outputNb+1, nbOutput ); return errNb; } } return TA_TEST_PASS;}void printRetCode( TA_RetCode retCode ){ TA_RetCodeInfo retCodeInfo; TA_SetRetCodeInfo( retCode, &retCodeInfo ); printf( "\nFailed: ErrorCode %d=%s:[%s]\n", retCode, retCodeInfo.enumStr, retCodeInfo.infoStr );}/**** Local functions definitions. ****/static ErrorNumber doRangeTestForOneOutput( RangeTestFunction testFunction, TA_FuncUnstId unstId, void *opaqueData, unsigned int outputNb, unsigned int integerTolerance ){ TA_RetCode retCode; TA_Integer refOutBeg, refOutNbElement, refLookback; TA_Integer fixSize; TA_Real *refBuffer; TA_Integer *refBufferInt; ErrorNumber errNb; TA_Integer unstablePeriod, temp; unsigned int outputIsInteger; showFeedback(); /* Caculate the whole range. This is going * to be the reference for all subsequent test. */ refBuffer = (TA_Real *)TA_Malloc( MAX_RANGE_SIZE * sizeof( TA_Real ) ); if( !refBuffer ) return TA_TESTUTIL_DRT_ALLOC_ERR; refBufferInt = (TA_Integer *)TA_Malloc( MAX_RANGE_SIZE * sizeof( TA_Integer ) ); if( !refBufferInt ) { TA_Free( refBuffer ); return TA_TESTUTIL_DRT_ALLOC_ERR; } if( unstId != TA_FUNC_UNST_NONE ) { /* Caller wish to test for a range of unstable * period values. But the reference is calculated * on the whole range by keeping that unstable period * to zero. */ TA_SetUnstablePeriod( unstId, 0 ); } outputIsInteger = 0; retCode = CallTestFunction( testFunction, 0, MAX_RANGE_END, refBuffer, refBufferInt, &refOutBeg, &refOutNbElement, &refLookback, opaqueData, outputNb, &outputIsInteger ); if( retCode != TA_SUCCESS ) { printf( "Fail: doRangeTest whole range failed (%d)\n", retCode ); TA_Free( refBuffer ); TA_Free( refBufferInt ); return TA_TESTUTIL_DRT_REF_FAILED; } /* When calculating for the whole range, the lookback and the * refOutBeg are supppose to be equal. */ if( refLookback != refOutBeg ) { printf( "Fail: doRangeTest refLookback != refOutBeg (%d != %d)\n", refLookback, refOutBeg ); TA_Free( refBuffer ); TA_Free( refBufferInt ); return TA_TESTUTIL_DRT_LOOKBACK_INCORRECT; } temp = MAX_RANGE_SIZE-refLookback; if( temp != refOutNbElement ) { printf( "Fail: doRangeTest either refOutNbElement or refLookback bad (%d,%d)\n", temp, refOutNbElement ); TA_Free( refBuffer ); TA_Free( refBufferInt ); return TA_TESTUTIL_DRT_REF_OUTPUT_INCORRECT; } /* Calculate each value ONE by ONE and make sure it is identical * to the reference. * * Then repeat the test but calculate TWO by TWO and so on... */ for( fixSize=1; fixSize <= MAX_RANGE_SIZE; fixSize++ ) { /* When a function has an unstable period, verify some * unstable period between 0 and MAX_RANGE_SIZE. */ if( unstId == TA_FUNC_UNST_NONE ) { errNb = doRangeTestFixSize( testFunction, opaqueData, refOutBeg, refOutNbElement, refLookback, refBuffer, refBufferInt, unstId, fixSize, outputNb, integerTolerance ); if( errNb != TA_TEST_PASS) { TA_Free( refBuffer ); TA_Free( refBufferInt ); return errNb; } } else { for( unstablePeriod=0; unstablePeriod <= MAX_RANGE_SIZE; unstablePeriod++ ) { TA_SetUnstablePeriod( unstId, unstablePeriod ); errNb = doRangeTestFixSize( testFunction, opaqueData, refOutBeg, refOutNbElement, refLookback, refBuffer, refBufferInt, unstId, fixSize, outputNb, integerTolerance ); if( errNb != TA_TEST_PASS) { printf( "Fail: Using unstable period %d\n", unstablePeriod ); TA_Free( refBuffer ); TA_Free( refBufferInt ); return errNb; } /* Randomly skip the test of some unstable period (limit case are * always tested though). */ if( (unstablePeriod > 5) && (unstablePeriod < 240) ) { /* Randomly skips from 0 to 239 tests. Never * make unstablePeriod exceed 240. */ temp = (rand() % 240); unstablePeriod += temp; if( unstablePeriod > 240 ) unstablePeriod = 240; } } /* Because the tests with an unstable period are very intensive * and kinda repetitive, skip the test of some fixSize (limit * case are always tested though). */ if( (fixSize > 5) && (fixSize < 240) ) { /* Randomly skips from 0 to 239 tests. Never * make fixSize exceed 240. */ temp = (rand() % 239); fixSize += temp; if( fixSize > 240 ) fixSize = 240; } } } TA_Free( refBuffer ); TA_Free( refBufferInt ); return TA_TEST_PASS;}static ErrorNumber doRangeTestFixSize( RangeTestFunction testFunction, void *opaqueData, TA_Integer refOutBeg, TA_Integer refOutNbElement, TA_Integer refLookback, const TA_Real *refBuffer, const TA_Integer *refBufferInt, TA_FuncUnstId unstId, TA_Integer fixSize, unsigned int outputNb, unsigned int integerTolerance ){ TA_RetCode retCode; TA_Real *outputBuffer; TA_Real val1, val2; TA_Integer i, temp; TA_Integer outputBegIdx, outputNbElement, lookback; TA_Integer startIdx, endIdx, relativeIdx, outputSizeByOptimalLogic; TA_Integer *outputBufferInt; unsigned int outputIsInteger; (void)refLookback; /* Allocate the output buffer (+prefix and suffix memory guard). */ outputBuffer = (TA_Real *)TA_Malloc( (fixSize+2) * sizeof( TA_Real ) ); if( !outputBuffer ) return TA_TESTUTIL_DRT_ALLOC_ERR; outputBufferInt = (TA_Integer *)TA_Malloc( (fixSize+2) * sizeof( TA_Integer ) ); if( !refBufferInt ) { TA_Free( outputBuffer ); return TA_TESTUTIL_DRT_ALLOC_ERR; } outputBuffer[0] = RESV_PATTERN_PREFIX; outputBuffer[fixSize+1] = RESV_PATTERN_SUFFIX; outputBufferInt[0] = RESV_PATTERN_PREFIX_INT; outputBufferInt[fixSize+1] = RESV_PATTERN_SUFFIX_INT; /* Initialize the outputs with improbable values. */ for( i=1; i <= fixSize; i++ ) { outputBuffer[i] = RESV_PATTERN_IMPROBABLE; outputBufferInt[i] = RESV_PATTERN_IMPROBABLE_INT; } /* Test for a large number of possible startIdx */ for( startIdx=0; startIdx <= (MAX_RANGE_SIZE-fixSize); startIdx++ ) { /* Call the TA function. */ endIdx = startIdx+fixSize-1; retCode = CallTestFunction( testFunction, startIdx, endIdx, &outputBuffer[1], &outputBufferInt[1], &outputBegIdx, &outputNbElement, &lookback, opaqueData, outputNb, &outputIsInteger ); if( retCode != TA_SUCCESS ) { /* No call shall never fail here. When the range * is "out-of-range" the function shall still return * TA_SUCCESS with the outNbElement equal to zero. */ printf( "Fail: doRangeTestFixSize testFunction return error=(%d) (%d,%d)\n", retCode, fixSize, startIdx ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_RETCODE_ERR; } else { /* Possible startIdx gap of the output shall be always the * same regardless of the range. */ if( outputNbElement == 0 ) { /* Trap cases where there is no output. */ if( (startIdx > lookback) || (endIdx > lookback) ) { /* Whenever startIdx is greater than lookback, some data * shall be return. Same idea with endIdx. * * Note: * some output will never start at the startIdx, particularly * when a TA function have multiple output. Usually, the first output * will be between startIdx/endIdx and other outputs may have a "gap" * from the startIdx. * * Example: * Stochastic %K is between startIdx/endIdx, but %D output will * have less data because it is a MA of %K. A gap will then * exist for the %D output. */ printf( "Fail: doRangeTestFixSize data missing (%d,%d,%d)\n", startIdx, endIdx, lookback ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_MISSING_DATA; } } else { /* Some output was returned. Are the returned index correct? */ if( (outputBegIdx < startIdx) || (outputBegIdx > endIdx) || (outputBegIdx < refOutBeg)) { printf( "Fail: doRangeTestFixSize bad outBegIdx\n" ); printf( "Fail: doRangeTestFixSize (%d,%d,%d,%d,%d)\n", startIdx, endIdx, outputBegIdx, outputNbElement, fixSize ); printf( "Fail: doRangeTestFixSize refOutBeg,refOutNbElement (%d,%d)\n", refOutBeg, refOutNbElement ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_BAD_OUTBEGIDX; } if( (outputNbElement > fixSize) || (outputNbElement > refOutNbElement) ) { printf( "Fail: doRangeTestFixSize Incorrect outputNbElement\n" ); printf( "Fail: doRangeTestFixSize (%d,%d,%d,%d,%d)\n", startIdx, endIdx, outputBegIdx, outputNbElement, fixSize ); printf( "Fail: doRangeTestFixSize refOutBeg,refOutNbElement (%d,%d)\n", refOutBeg, refOutNbElement ); TA_Free( outputBuffer ); return TA_TESTUTIL_DRT_BAD_OUTNBLEMENT; } /* Is the calculated lookback too high? */ if( outputBegIdx < lookback ) { printf( "Fail: doRangeTestFixSize Lookback calculation too high? (%d)\n", lookback ); printf( "Fail: doRangeTestFixSize (%d,%d,%d,%d,%d)\n", startIdx, endIdx, outputBegIdx, outputNbElement, fixSize ); printf( "Fail: doRangeTestFixSize refOutBeg,refOutNbElement (%d,%d)\n", refOutBeg, refOutNbElement ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_LOOKBACK_TOO_HIGH; } /* Is the output identical to the reference? */ relativeIdx = outputBegIdx-refOutBeg; for( i=0; i < outputNbElement; i++ ) { if( outputIsInteger ) { if( outputBufferInt[1+i] != refBufferInt[relativeIdx+i] ) { printf( "Fail: doRangeTestFixSize diff data for idx=%d (%d,%d)\n", i, outputBufferInt[1+i], refBufferInt[relativeIdx+i] ); printf( "Fail: doRangeTestFixSize (%d,%d,%d,%d,%d)\n", startIdx, endIdx, outputBegIdx, outputNbElement, fixSize ); printf( "Fail: doRangeTestFixSize refOutBeg,refOutNbElement (%d,%d)\n", refOutBeg, refOutNbElement ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_DATA_DIFF_INT; } } else { val1 = outputBuffer[1+i]; val2 = refBuffer[relativeIdx+i]; if( !dataWithinReasonableRange( val1, val2, i, unstId, integerTolerance ) ) { printf( "Fail: doRangeTestFixSize diff data for idx=%d (%e,%e)\n", i, val1, val2 ); printf( "Fail: doRangeTestFixSize (%d,%d,%d,%d,%d)\n", startIdx, endIdx, outputBegIdx, outputNbElement, fixSize ); printf( "Fail: doRangeTestFixSize refOutBeg,refOutNbElement (%d,%d)\n", refOutBeg, refOutNbElement ); if( val1 != 0.0 ) printf( "Fail: Diff %g %%\n", ((val2-val1)/val1)*100.0 ); TA_Free( outputBuffer ); TA_Free( outputBufferInt ); return TA_TESTUTIL_DRT_DATA_DIFF; } } /* Randomly skip the verification of some value. Limit * cases are always checked though. */ if( outputNbElement > 30 ) { temp = outputNbElement-20; if( (i > 20) && (i < temp) ) { /* Randomly skips from 0 to 200 verification. * Never make it skip the last 20 values. */ i += (rand() % 200); if( i > temp ) i = temp; } } } /* Verify out-of-bound writing in the output buffer. */ outputSizeByOptimalLogic = max(lookback,startIdx); if( outputSizeByOptimalLogic > endIdx ) outputSizeByOptimalLogic = 0; else outputSizeByOptimalLogic = endIdx-outputSizeByOptimalLogic+1; if( (fixSize != outputNbElement) && (outputBuffer[1+outputSizeByOptimalLogic] != RESV_PATTERN_IMPROBABLE) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -