#ifdef WIN32
#include "windows.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "ta_test_priv.h"
#include "ta_utility.h"
#include "ta_memory.h"
extern int nbProfiledCall;
extern double timeInProfiledCall;
extern double worstProfiledCall;
extern int insufficientClockPrecision;
#define RESV_PATTERN_MEMGUARD_1 (2.4789205E-150)
#define RESV_PATTERN_MEMGUARD_2 (4.2302468E-165)
#define RESV_PATTERN_PREFIX (9.1349043E-200)
#define RESV_PATTERN_SUFFIX (8.1489031E-158)
#define RESV_PATTERN_IMPROBABLE (-2.849284E-199)
#define RESV_PATTERN_PREFIX_INT (TA_INTEGER_DEFAULT)
#define RESV_PATTERN_SUFFIX_INT (TA_INTEGER_DEFAULT)
#define RESV_PATTERN_IMPROBABLE_INT (TA_INTEGER_DEFAULT)
#define TA_BUF_PREFIX 100
#define TA_BUF_SUFFIX 100
#define TA_BUF_SIZE (TA_BUF_PREFIX+MAX_NB_TEST_ELEMENT+TA_BUF_SUFFIX)
#define TA_NB_OUT 3
#define TA_NB_IN 1
#define TA_NB_OUT_IN (TA_NB_OUT+TA_NB_IN)
TA_Real memoryGuard1 = RESV_PATTERN_MEMGUARD_1;
TA_Real buf[NB_GLOBAL_BUFFER][TA_NB_OUT_IN][TA_BUF_SIZE];
TA_Real memoryGuard2 = RESV_PATTERN_MEMGUARD_2;
#define NB_TOTAL_ELEMENTS (sizeof(buf)/sizeof(TA_Real))
TestBuffer gBuffer[5];
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 );
static int dataWithinReasonableRange( TA_Real val1, TA_Real val2,
unsigned int outputPosition,
TA_FuncUnstId unstId,
unsigned int integerTolerance );
static ErrorNumber doRangeTestForOneOutput( RangeTestFunction testFunction,
TA_FuncUnstId unstId,
void *opaqueData,
unsigned int outputNb,
unsigned int integerTolerance );
static TA_RetCode CallTestFunction( RangeTestFunction testFunction,
TA_Integer startIdx,
TA_Integer endIdx,
TA_Real *outputBuffer,
TA_Integer *outputBufferInt,
TA_Integer *outBegIdx,
TA_Integer *outNbElement,
TA_Integer *lookback,
void *opaqueData,
unsigned int outputNb,
unsigned int *isOutputInteger );
static int ta_g_val = 0;
static const char *ta_g_wheel = "-\\|/";
void showFeedback()
{
if( ta_g_wheel[ta_g_val] == '\0' )
ta_g_val = 0;
putchar('\b');
putchar(ta_g_wheel[ta_g_val]);
fflush(stdout);
ta_g_val++;
}
void hideFeedback()
{
putchar('\b');
fflush(stdout);
ta_g_val = 0;
}
ErrorNumber allocLib()
{
TA_RetCode retCode;
retCode = TA_Initialize();
if( retCode != TA_SUCCESS )
{
printf( "TA_Initialize failed [%d]\n", retCode );
return TA_TESTUTIL_INIT_FAILED;
}
return TA_TEST_PASS;
}
ErrorNumber freeLib()
{
TA_RetCode retCode;
retCode = TA_Shutdown();
if( retCode != TA_SUCCESS )
{
printf( "TA_Shutdown failed [%d]\n", retCode );
return TA_TESTUTIL_SHUTDOWN_FAILED;
}
return TA_TEST_PASS;
}
void reportError( const char *str, TA_RetCode retCode )
{
TA_RetCodeInfo retCodeInfo;
TA_SetRetCodeInfo( retCode, &retCodeInfo );
printf( "%s,%d==%s\n", str, retCode, retCodeInfo.enumStr );
printf( "[%s]\n", retCodeInfo.infoStr );
}
void initGlobalBuffer( void )
{
gBuffer[0].in = &buf[0][0][TA_BUF_PREFIX];
gBuffer[0].out0 = &buf[0][1][TA_BUF_PREFIX];
gBuffer[0].out1 = &buf[0][2][TA_BUF_PREFIX];
gBuffer[0].out2 = &buf[0][3][TA_BUF_PREFIX];
gBuffer[1].in = &buf[1][0][TA_BUF_PREFIX];
gBuffer[1].out0 = &buf[1][1][TA_BUF_PREFIX];
gBuffer[1].out1 = &buf[1][2][TA_BUF_PREFIX];
gBuffer[1].out2 = &buf[1][3][TA_BUF_PREFIX];
gBuffer[2].in = &buf[2][0][TA_BUF_PREFIX];
gBuffer[2].out0 = &buf[2][1][TA_BUF_PREFIX];
gBuffer[2].out1 = &buf[2][2][TA_BUF_PREFIX];
gBuffer[2].out2 = &buf[2][3][TA_BUF_PREFIX];
gBuffer[3].in = &buf[3][0][TA_BUF_PREFIX];
gBuffer[3].out0 = &buf[3][1][TA_BUF_PREFIX];
gBuffer[3].out1 = &buf[3][2][TA_BUF_PREFIX];
gBuffer[3].out2 = &buf[3][3][TA_BUF_PREFIX];
gBuffer[4].in = &buf[4][0][TA_BUF_PREFIX];
gBuffer[4].out0 = &buf[4][1][TA_BUF_PREFIX];
gBuffer[4].out1 = &buf[4][2][TA_BUF_PREFIX];
gBuffer[4].out2 = &buf[4][3][TA_BUF_PREFIX];
}
void clearAllBuffers( void )
{
unsigned int i,j,k;
for( i=0; i < NB_GLOBAL_BUFFER; i++ )
{
for( j=0; j < TA_NB_OUT_IN; j++ )
{
for( k=0; k < TA_BUF_PREFIX; k++ )
buf[i][j][k] = RESV_PATTERN_PREFIX;
for( ; k < TA_BUF_SIZE; k++ )
buf[i][j][k] = RESV_PATTERN_SUFFIX;
}
}
}
void setInputBuffer( unsigned int i, const TA_Real *data, unsigned int nbElement )
{
unsigned int j;
for( j=0; j < nbElement; j++ )
buf[i][0][j+TA_BUF_PREFIX] = data[j];
}
void setInputBufferValue( unsigned int i, const TA_Real data, unsigned int nbElement )
{
unsigned int j;
for( j=0; j < nbElement; j++ )
buf[i][0][j+TA_BUF_PREFIX] = data;
}
ErrorNumber checkForNAN( const TA_Real *buffer,
unsigned int nbElement )
{
unsigned int i;
unsigned int idx;
const TA_Real *theBuffer;
theBuffer = buffer - TA_BUF_PREFIX;
for( idx=0; idx < TA_BUF_PREFIX; idx++ )
{
if( theBuffer[idx] != RESV_PATTERN_PREFIX )
{
printf( "Fail: Out of range writing in prefix buffer (%d,%f)\n", idx, theBuffer[idx] );
return TA_TEST_TFRR_OVERLAP_OR_NAN_0;
}
}
if( nbElement > MAX_NB_TEST_ELEMENT )
{
printf( "Fail: outNbElement is out of range 0 (%d)\n", nbElement );
return TA_TEST_TFRR_NB_ELEMENT_OUT_OF_RANGE;
}
for( i=0; i < nbElement; i++,idx++ )
{
if( theBuffer[idx] == RESV_PATTERN_PREFIX )
{
printf( "Fail: Not a number find within the data (%d,%f)\n", i, theBuffer[idx] );
return TA_TEST_TFRR_OVERLAP_OR_NAN_3;
}
if( theBuffer[idx] == RESV_PATTERN_SUFFIX )
{
printf( "Fail: Not a number find within the data (%d,%f)\n", i, theBuffer[idx] );
return TA_TEST_TFRR_OVERLAP_OR_NAN_4;
}
}
for( ; idx < TA_BUF_SIZE; idx++ )
{
if( theBuffer[idx] != RESV_PATTERN_SUFFIX )
{
printf( "Fail: Out of range writing in suffix buffer (%d,%f)\n", idx, theBuffer[idx] );
return TA_TEST_TFRR_OVERLAP_OR_NAN_5;
}
idx++;
}
if( memoryGuard1 != RESV_PATTERN_MEMGUARD_1 )
{
printf( "Fail: MemoryGuard1 have been modified (%f,%f)\n", memoryGuard1, RESV_PATTERN_MEMGUARD_1 );
return TA_TEST_TFRR_OVERLAP_OR_NAN_6;
}
if( memoryGuard2 != RESV_PATTERN_MEMGUARD_2 )
{
printf( "Fail: MemoryGuard2 have been modified (%f,%f)\n", memoryGuard2, RESV_PATTERN_MEMGUARD_2 );
return TA_TEST_TFRR_OVERLAP_OR_NAN_7;
}
return TA_TEST_PASS;
}
ErrorNumber checkSameContent( TA_Real *buffer1,
TA_Real *buffer2 )
{
const TA_Real *theBuffer1;
const TA_Real *theBuffer2;
unsigned int i;
theBuffer1 = buffer1 - TA_BUF_PREFIX;
theBuffer2 = buffer2 - TA_BUF_PREFIX;
for( i=0; i < TA_BUF_SIZE; i++ )
{
if( (theBuffer1[i] != RESV_PATTERN_SUFFIX) &&
(theBuffer1[i] != RESV_PATTERN_PREFIX) )
{
if(!TA_REAL_EQ( theBuffer1[i], theBuffer2[i], 0.000001))
{
printf( "Fail: Large difference found between two value expected identical (%f,%f,%d)\n",
theBuffer1[i], theBuffer2[i], i );
return TA_TEST_TFRR_CHECK_SAME_CONTENT;
}
}
}
return TA_TEST_PASS;
}
ErrorNumber checkDataSame( const TA_Real *data,
const TA_Real *originalInput,
unsigned int nbElement )
{
unsigned int i;
ErrorNumber errNb;
errNb = checkForNAN( data, nbElement );
if( errNb != TA_TEST_PASS )
return errNb;
if( nbElement > MAX_NB_TEST_ELEMENT )
{
printf( "Fail: outNbElement is out of range 1 (%d)\n", nbElement );
return TA_TEST_TFRR_NB_ELEMENT_OUT_OF_RANGE;
}
for( i=0; i < nbElement; i++ )
{
if( originalInput[i] != data[i] )
{
printf( "Fail: Data was wrongly modified (%f,%f,%d)\n",
originalInput[i],
data[i], i );
return TA_TEST_TFRR_INPUT_HAS_BEEN_MODIFIED;
}
}
return TA_TEST_PASS;
}
ErrorNumber checkExpectedValue( const TA_Real *data,
TA_RetCode retCode, TA_RetCode expectedRetCode,
unsigned int outBegIdx, unsigned int expectedBegIdx,
unsigned int outNbElement, unsigned int expectedNbElement,
TA_Real oneOfTheExpectedOutReal,
unsigned int oneOfTheExpectedOutRealIndex )
{
if( retCode != expectedRetCode )
{
printf( "Fail: RetCode %d different than expected %d\n", retCode, expectedRetCode );
return TA_TESTUTIL_TFRR_BAD_RETCODE;
}
if( retCode != TA_SUCCESS )
{
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;
}
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;
}
}
return TA_TEST_PASS;
}
ErrorNumber doRangeTest( RangeTestFunction testFunction,
TA_FuncUnstId unstId,
void *opaqueData,
unsigned int nbOutput,
unsigned int integerTolerance )
{
unsigned int outputNb;
ErrorNumber errNb;
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 );
}
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();
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 )
{
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;
}
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;
}
for( fixSize=1; fixSize <= MAX_RANGE_SIZE; fixSize++ )
{
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;
}
if( (unstablePeriod > 5) && (unstablePeriod < 240) )
{
temp = (rand() % 240);
unstablePeriod += temp;
if( unstablePeriod > 240 )
unstablePeriod = 240;
}
}
if( (fixSize > 5) && (fixSize < 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;
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;
for( i=1; i <= fixSize; i++ )
{
outputBuffer[i] = RESV_PATTERN_IMPROBABLE;
outputBufferInt[i] = RESV_PATTERN_IMPROBABLE_INT;
}
for( startIdx=0; startIdx <= (MAX_RANGE_SIZE-fixSize); startIdx++ )
{
endIdx = startIdx+fixSize-1;
retCode = CallTestFunction( testFunction, startIdx, endIdx,
&outputBuffer[1], &outputBufferInt[1],
&outputBegIdx, &outputNbElement, &lookback,
opaqueData, outputNb, &outputIsInteger );
if( retCode != TA_SUCCESS )
{
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
{
if( outputNbElement == 0 )
{
if( (startIdx > lookback) || (endIdx > lookback) )
{
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
{
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;
}
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;
}
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;
}
}
if( outputNbElement > 30 )
{
temp = outputNbElement-20;
if( (i > 20) && (i < temp) )
{
i += (rand() % 200);
if( i > temp )
i = temp;
}
}
}
outputSizeByOptimalLogic = max(lookback,startIdx);
if( outputSizeByOptimalLogic > endIdx )
outputSizeByOptimalLogic = 0;
else
outputSizeByOptimalLogic = endIdx-outputSizeByOptimalLogic+1;
if( (fixSize != outputNbElement) && (outputBuffer[1+outputSizeByOptimalLogic] != RESV_PATTERN_IMPROBABLE) )
{
printf( "Fail: doRangeTestFixSize out-of-bound output (%e)\n", outputBuffer[1+outputSizeByOptimalLogic] );
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_OUT_OF_BOUND_OUT;
}
if( (fixSize != outputNbElement) && (outputBufferInt[1+outputSizeByOptimalLogic] != RESV_PATTERN_IMPROBABLE_INT) )
{
printf( "Fail: doRangeTestFixSize out-of-bound output (%d)\n", outputBufferInt[1+outputSizeByOptimalLogic] );
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_OUT_OF_BOUND_OUT_INT;
}
if( outputBuffer[0] != RESV_PATTERN_PREFIX )
{
printf( "Fail: doRangeTestFixSize bad RESV_PATTERN_PREFIX (%e)\n", outputBuffer[0] );
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_PREFIX;
}
if( outputBufferInt[0] != RESV_PATTERN_PREFIX_INT )
{
printf( "Fail: doRangeTestFixSize bad RESV_PATTERN_PREFIX_INT (%d)\n", outputBufferInt[0] );
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_PREFIX;
}
if( outputBuffer[fixSize+1] != RESV_PATTERN_SUFFIX )
{
printf( "Fail: doRangeTestFixSize bad RESV_PATTERN_SUFFIX (%e)\n", outputBuffer[fixSize+1] );
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_SUFFIX;
}
if( outputBufferInt[fixSize+1] != RESV_PATTERN_SUFFIX_INT )
{
printf( "Fail: doRangeTestFixSize bad RESV_PATTERN_SUFFIX_INT (%d)\n", outputBufferInt[fixSize+1] );
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_SUFFIX;
}
if( outputIsInteger )
{
for( i=1; i <= fixSize; i++ )
outputBufferInt[i] = RESV_PATTERN_IMPROBABLE_INT;
}
else
{
for( i=1; i <= fixSize; i++ )
outputBuffer[i] = RESV_PATTERN_IMPROBABLE;
}
}
if( (startIdx > 30) && ((startIdx+100) <= (MAX_RANGE_SIZE-fixSize)) )
{
temp = (rand() % 100)+40;
startIdx += temp;
}
}
}
TA_Free( outputBuffer );
TA_Free( outputBufferInt );
return TA_TEST_PASS;
}
static int dataWithinReasonableRange( TA_Real val1, TA_Real val2,
unsigned int outputPosition,
TA_FuncUnstId unstId,
unsigned int integerTolerance )
{
TA_Real difference, tolerance, temp;
unsigned int val1_int, val2_int, tempInt, periodToIgnore;
if( integerTolerance == TA_DO_NOT_COMPARE )
return 1;
if( unstId == TA_FUNC_UNST_NONE )
return TA_REAL_EQ( val1, val2, 0.000000001 );
if( (val1 < 0.00001) && (val2 < 0.00001) )
return 1;
switch( unstId )
{
case TA_FUNC_UNST_T3:
periodToIgnore = 200;
break;
default:
periodToIgnore = 100;
break;
}
if( integerTolerance == 1000 )
{
if( val1 > val2 )
difference = (val1-val2);
else
difference = (val2-val1);
difference *= 1000.0;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else if( (int)difference > 1 )
{
printf( "\nFail: Value diffferent by more than 1/1000 (%f)\n", difference );
return 0;
}
}
else if( integerTolerance == 100 )
{
if( val1 > val2 )
difference = (val1-val2);
else
difference = (val2-val1);
difference *= 100.0;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else if( (int)difference > 1 )
{
printf( "\nFail: Value diffferent by more than 1/100 (%f)\n", difference );
return 0;
}
}
else if( integerTolerance == 10 )
{
if( val1 > val2 )
difference = (val1-val2);
else
difference = (val2-val1);
difference *= 10.0;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else if( (int)difference > 1 )
{
printf( "\nFail: Value diffferent by more than 1/10 (%f)\n", difference );
return 0;
}
}
else if( integerTolerance == 360 )
{
val1_int = (unsigned int)val1;
val2_int = (unsigned int)val2;
if( val1_int > val2_int )
tempInt = val1_int - val2_int;
else
tempInt = val2_int - val1_int;
if( val1 > val2 )
difference = (val1-val2)/val1;
else
difference = (val2-val1)/val2;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else if( (tempInt > 1) && (difference > 0.10) )
{
printf( "\nFail: Value diffferent by more than 10 percent over 1 degree (%d)\n", tempInt );
return 0;
}
}
else if( integerTolerance )
{
val1_int = (unsigned int)val1;
val2_int = (unsigned int)val2;
if( val1_int > val2_int )
tempInt = val1_int - val2_int;
else
tempInt = val2_int - val1_int;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else if( temp < 100 )
{
if( tempInt >= 3*integerTolerance )
{
printf( "\nFail: Value out of 3*tolerance range (%d,%d)\n", tempInt, integerTolerance );
return 0;
}
}
else if( temp < 150 )
{
if( tempInt >= 2*integerTolerance )
{
printf( "\nFail: Value out of 2*tolerance range (%d,%d)\n", tempInt, integerTolerance );
return 0;
}
}
else if( temp < 200 )
{
if( tempInt >= integerTolerance )
{
printf( "\nFail: Value out of tolerance range (%d,%d)\n", tempInt, integerTolerance );
return 0;
}
}
else if( tempInt >= 1 )
{
printf( "\nFail: Value not equal (difference is %d)\n", tempInt );
return 0;
}
}
else
{
if( val1 > val2 )
difference = (val1-val2)/val1;
else
difference = (val2-val1)/val2;
temp = outputPosition+TA_GetUnstablePeriod(unstId)+1;
if( temp <= periodToIgnore )
{
return 1;
}
else
{
temp -= periodToIgnore;
tolerance = 0.5/temp;
}
if( difference > tolerance )
{
printf( "\nFail: Value out of tolerance range (%g,%g)\n", difference, tolerance );
return 0;
}
}
return 1;
}
static TA_RetCode CallTestFunction( RangeTestFunction testFunction,
TA_Integer startIdx,
TA_Integer endIdx,
TA_Real *outputBuffer,
TA_Integer *outputBufferInt,
TA_Integer *outBegIdx,
TA_Integer *outNbElement,
TA_Integer *lookback,
void *opaqueData,
unsigned int outputNb,
unsigned int *isOutputInteger )
{
TA_RetCode retCode;
double clockDelta;
#ifdef WIN32
LARGE_INTEGER startClock;
LARGE_INTEGER endClock;
#else
clock_t startClock;
clock_t endClock;
#endif
#ifdef WIN32
QueryPerformanceCounter(&startClock);
#else
startClock = clock();
#endif
retCode = testFunction( startIdx,
endIdx,
outputBuffer,
outputBufferInt,
outBegIdx,
outNbElement,
lookback,
opaqueData,
outputNb,
isOutputInteger );
if( *outNbElement < 20 )
{
return retCode;
}
#ifdef WIN32
QueryPerformanceCounter(&endClock);
clockDelta = (double)((__int64)endClock.QuadPart - (__int64) startClock.QuadPart);
#else
endClock = clock();
clockDelta = (double)(endClock - startClock);
#endif
if( clockDelta <= 0 )
{
insufficientClockPrecision = 1;
}
else
{
if( clockDelta > worstProfiledCall )
worstProfiledCall = clockDelta;
timeInProfiledCall += clockDelta;
nbProfiledCall++;
}
return retCode;
}