📄 test_util.c
字号:
/* TA-LIB Copyright (c) 1999-2007, Mario Fortier * All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * - Neither name of author nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* List of contributors: * * Initial Name/description * ------------------------------------------------------------------- * MF Mario Fortier * * * Change history: * * MMDDYY BY Description * ------------------------------------------------------------------- * 112400 MF First version. * *//* Description: * Provide utility function internally used in ta_regtest only. *//**** Headers ****/#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"/**** External functions declarations. ****//* None *//**** External variables declarations. ****/extern int nbProfiledCall;extern double timeInProfiledCall;extern double worstProfiledCall;extern int insufficientClockPrecision;/**** Global variables definitions. ****//* Global temporary buffers used while testing. */#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; /* Magic number to detect problem. */TA_Real buf[NB_GLOBAL_BUFFER][TA_NB_OUT_IN][TA_BUF_SIZE]; /* The global buffers. */TA_Real memoryGuard2 = RESV_PATTERN_MEMGUARD_2; /* Magic number to detect problem. */#define NB_TOTAL_ELEMENTS (sizeof(buf)/sizeof(TA_Real))TestBuffer gBuffer[5]; /* See initGlobalBuffer. *//**** Local declarations. ****//* None *//**** Local functions declarations. ****/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 );/**** Local variables definitions. ****//* None *//**** Global functions definitions. ****/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; /* Initialize the library. */ 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; /* For testing purpose */ /* TA_FATAL_RET( "Test again", 100, 200, 0 ); */ 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 );}/* Need to be called only once. */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];}/* Will set some values in the buffers allowing * to detect later if the function is writing * out-of-bound (and to make sure the * function is writing exactly the number * of values it pretends to do). */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;}/* Check that a buffer (within a TestBuffer) is not containing * NAN (or any reserved "impossible" value) within the specified * range (it also checks that all out-of-bound values are untouch). * * Return 1 on success. */ErrorNumber checkForNAN( const TA_Real *buffer, unsigned int nbElement ){ unsigned int i; unsigned int idx; const TA_Real *theBuffer; theBuffer = buffer - TA_BUF_PREFIX; /* Check that the prefix are all still untouch. */ 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; } /* Check that no NAN (or reserved "impossible" value) exist * in the specified range. */ for( i=0; i < nbElement; i++,idx++ ) { /* TODO Add back some nan/inf checking if( trio_isnan(theBuffer[idx]) ) { printf( "Fail: Not a number find within the data (%d,%f)\n", i, theBuffer[idx] ); return TA_TEST_TFRR_OVERLAP_OR_NAN_1; } if( trio_isinf(theBuffer[idx]) ) { printf( "Fail: Not a number find within the data (%d,%f)\n", i, theBuffer[idx] ); return TA_TEST_TFRR_OVERLAP_OR_NAN_2; }*/ 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; } } /* Make sure that the remaining of the buffer is untouch. */ 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++; } /* Make sure the global memory guard are untouch. */ 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; } /* Everything looks good! */ return TA_TEST_PASS;}/* Return 1 on success */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++ ) { /* TODO Add back nan/inf checking (!trio_isnan(theBuffer1[i])) && (!trio_isinf(theBuffer1[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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -