diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/adx.c | 14 | ||||
| -rw-r--r-- | test/awesome_oscillator.c | 5 | ||||
| -rw-r--r-- | test/bench.c | 1 | ||||
| -rw-r--r-- | test/bollinger_bands.c | 2 | ||||
| -rw-r--r-- | test/cv.c | 3 | ||||
| -rw-r--r-- | test/edge_cases.c | 1 | ||||
| -rw-r--r-- | test/fuzz.c | 6 | ||||
| -rw-r--r-- | test/gen_test_data.c | 7 | ||||
| -rw-r--r-- | test/hurst_exponent.c | 14 | ||||
| -rw-r--r-- | test/main.c | 4 | ||||
| -rw-r--r-- | test/nextafter.c | 6 | ||||
| -rw-r--r-- | test/nexttoward.c | 6 | ||||
| -rw-r--r-- | test/nvi.c | 2 | ||||
| -rw-r--r-- | test/test_python.py | 52 |
14 files changed, 84 insertions, 39 deletions
@@ -13,6 +13,11 @@ bool ts_test_adx( void ) x[1] = malloc( n * sizeof( fp_t ) ); x[2] = malloc( n * sizeof( fp_t ) ); x[3] = malloc( n * sizeof( fp_t ) ); + if ( !x[0 ] || !x[1] || !x[2] || !x[3] ) + { + free( x[0] ); free( x[1] ); free( x[2] ); free( x[3] ); + return false; + } for ( uint_t i = 0; i < n; ++i ) { @@ -36,7 +41,16 @@ bool ts_test_adx( void ) * indices [offset..n-1], not compacted [0..y_n-1] */ fp_t *y[4]; for ( uint_t i = 0; i < 4; ++i ) + { y[i] = calloc( n, sizeof( fp_t ) ); + if ( !y[i] ) + { + for ( uint_t j = 0; j < i; ++j ) + free( y[j] ); + free( x[0] ); free( x[1] ); free( x[2] ); free( x[3] ); + return false; + } + } uint8_t c[TS_CONSTANT_SIZE] = { 0 }; *( uint_t * )c = k; diff --git a/test/awesome_oscillator.c b/test/awesome_oscillator.c index 205bf78..08947c2 100644 --- a/test/awesome_oscillator.c +++ b/test/awesome_oscillator.c @@ -26,6 +26,11 @@ bool ts_test_awesome_oscillator( void ) } fp_t *result = calloc( n, sizeof( fp_t ) ); + if ( !result ) + { + free( o ); free( h ); free( l ); free( c ); + return false; + } ts_awesome_oscillator(&result, 1, (fp_t const * const []){ o, h, l, c }, 4, n, NULL); diff --git a/test/bench.c b/test/bench.c index 83330aa..19023d4 100644 --- a/test/bench.c +++ b/test/bench.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #define TS_IMPLEMENTATION #include "ts.h" #include <stdio.h> diff --git a/test/bollinger_bands.c b/test/bollinger_bands.c index 37bc138..153b8a7 100644 --- a/test/bollinger_bands.c +++ b/test/bollinger_bands.c @@ -14,7 +14,7 @@ bool ts_test_bollinger_bands( void ) fp_t const em[] = { 11, 12, 13, 14, 15, 16, 17, 18 }; fp_t const eu[] = { 12.632993, 13.632993, 14.632993, 15.632993, 16.632993, 17.632993, 18.632993, 19.632993 }; fp_t const el[] = { 9.367007, 10.367007, 11.367007, 12.367007, 13.367007, 14.367007, 15.367007, 16.367007 }; - fp_t const * const exp[3] = { em, eu, el }; + fp_t const * const exp[3] = { eu, em, el }; typedef struct { uint_t k; fp_t std_mult; } c_t; c_t c = { .k = 3, .std_mult = 2.0 }; @@ -7,9 +7,8 @@ bool ts_test_cv( void ) fp_t const h[] = { 12, 13, 14, 12, 14, 15, 16, 14, 16, 17, 16 }; fp_t const l[] = { 8, 9, 10, 9, 10, 11, 12, 11, 12, 13, 12 }; fp_t const c[] = { 11, 12, 10, 11, 11, 14, 15, 13, 15, 16, 15 }; - fp_t const v[] = { 100, 200, 300, 400, 500, 150, 250, 350, 450, 550, 650 }; - fp_t const * const x[] = { o, h, l, c, v }; + fp_t const * const x[] = { o, h, l, c }; fp_t fast = 3; fp_t slow = 5; diff --git a/test/edge_cases.c b/test/edge_cases.c index ce47f72..46c19d4 100644 --- a/test/edge_cases.c +++ b/test/edge_cases.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include <math.h> #include <stdbool.h> #include <stddef.h> diff --git a/test/fuzz.c b/test/fuzz.c index 3f11d9d..49964b1 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include "ts.h" #include <stdint.h> #include <stdlib.h> @@ -62,7 +63,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) if (xn > 5) xn = 5; if (yn > 3) yn = 3; - (void)entry.func(y_arrays, yn, (fp_t const * const *)x_arrays, xn, n, (ts_constant_t *)&period); + ts_constant_t c; + memset(&c, 0, sizeof(c)); + memcpy(c.data, &period, sizeof(period)); + (void)entry.func(y_arrays, yn, (fp_t const * const *)x_arrays, xn, n, &c); return 0; } diff --git a/test/gen_test_data.c b/test/gen_test_data.c index 6ef54af..30bb7ff 100644 --- a/test/gen_test_data.c +++ b/test/gen_test_data.c @@ -1,6 +1,7 @@ /* gen_test_data.c - Validate all ts functions run without error. * Note: excluded from default build. Fix and add target to use. */ +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -41,7 +42,11 @@ int main(void) { size_t nsamples = sizeof(samples) / sizeof(samples[0]); for (size_t fi = 0; fi < nsamples; fi++) { - typeof(samples[fi]) f = samples[fi]; + struct { + const char *name; + int (*func)(fp_t * const y[], fp_t const * const x[], uint_t, ts_constant_t const *); + uint_t x_n, y_n; + } f = samples[fi]; /* Allocate input arrays */ fp_t **x = calloc(f.x_n, sizeof(fp_t *)); diff --git a/test/hurst_exponent.c b/test/hurst_exponent.c index ccf54c8..a200de9 100644 --- a/test/hurst_exponent.c +++ b/test/hurst_exponent.c @@ -1,3 +1,4 @@ +#include <math.h> #include <stddef.h> #include "ts.h" @@ -6,6 +7,17 @@ bool ts_test_hurst_exponent( void ) uint_t const c[] = { 5 }; fp_t const x0[] = { 1,2,3,4,5,6,7,8,9,10 }; fp_t e0[10]; - ts_hurst_exponent((fp_t*[]){e0}, 1, (fp_t const *[]){x0}, 1, 10, (ts_constant_t *)&c); + int ret = ts_hurst_exponent((fp_t*[]){e0}, 1, (fp_t const *[]){x0}, 1, 10, (ts_constant_t *)&c); + if ( ret != 0 ) + return false; + + /* Verify output is finite (no NaN/Inf for valid input) */ + for ( uint_t i = 0; i < 10; ++i ) + { + fp_t v = e0[i]; + if ( v != v ) return false; + if ( v == (fp_t)INFINITY || v == (fp_t)-INFINITY ) return false; + } + return true; } diff --git a/test/main.c b/test/main.c index 2854d1c..0e14d44 100644 --- a/test/main.c +++ b/test/main.c @@ -42,7 +42,9 @@ int main(void) if (result < 0) { if (errno == EINTR) { kill(pid, SIGKILL); - waitpid(pid, &status, 0); + if (waitpid(pid, &status, 0) < 0) { + fprintf(stderr, " CRASH %s (waitpid after SIGKILL failed: %s)\n", tests[i].name, strerror(errno)); + } fprintf(stderr, " CRASH %s (timeout)\n", tests[i].name); crashed++; } else { diff --git a/test/nextafter.c b/test/nextafter.c index c7e882b..eaa1f21 100644 --- a/test/nextafter.c +++ b/test/nextafter.c @@ -3,9 +3,9 @@ bool ts_test_nextafter( void ) { - fp_t const x0[] = { 1.000000, 1.000000, 0.000000 }; - fp_t const x1[] = { 2.000000, 0.000000, 1.000000 }; - fp_t const e0[] = { 1.000000, 1.000000, 0.000000 }; + fp_t const x0[] = { 1.000000, 2.000000, 10.000000 }; + fp_t const x1[] = { 2.000000, 1.000000, 20.000000 }; + fp_t const e0[] = { 1.0000000000000002, 1.9999999999999998, 10.000000000000002 }; fp_t const * const x[2] = { x0, x1 }; fp_t const * const e[1] = { e0 }; diff --git a/test/nexttoward.c b/test/nexttoward.c index 32d41cc..97935d7 100644 --- a/test/nexttoward.c +++ b/test/nexttoward.c @@ -3,9 +3,9 @@ bool ts_test_nexttoward( void ) { - fp_t const x0[] = { 1.000000, 1.000000, 0.000000 }; - fp_t const x1[] = { 2.000000, 0.000000, 1.000000 }; - fp_t const e0[] = { 1.000000, 1.000000, 0.000000 }; +fp_t const x0[] = { 1.000000, 2.000000, 10.000000 }; + fp_t const x1[] = { 2.000000, 1.000000, 20.000000 }; + fp_t const e0[] = { 1.0000000000000002, 1.9999999999999998, 10.000000000000002 }; fp_t const * const x[2] = { x0, x1 }; fp_t const * const e[1] = { e0 }; @@ -12,8 +12,6 @@ bool ts_test_nvi( void ) fp_t const * const x[] = { o, h, l, c, v }; fp_t nvi = 1000; - - nvi = 1000; fp_t e[5] = { nvi }; e[1] = nvi; diff --git a/test/test_python.py b/test/test_python.py index a4aa7e2..cfa983b 100644 --- a/test/test_python.py +++ b/test/test_python.py @@ -429,16 +429,21 @@ def parse_test_file(test_path): params = resolved if params is None: - scalar_match = re.search( + # Extract ALL scalar variables (not just the first) + scalar_matches = re.finditer( r"(?:uint_t|fp_t|int)\s+(?:const\s+)?(\w+)\s*=\s*([^;]+);", content ) - if scalar_match: - var_name = scalar_match.group(1) - if var_name not in ("n", "offset", "y_n", "i", "j"): - val_text = scalar_match.group(2).strip() - result = _safe_float(val_text) - if result is not None: - params = {var_name: result} + collected = {} + for sm in scalar_matches: + var_name = sm.group(1) + if var_name in ("n", "offset", "y_n", "i", "j"): + continue + val_text = sm.group(2).strip() + result = _safe_float(val_text) + if result is not None: + collected[var_name] = result + if collected: + params = collected return { "inputs": inputs, @@ -565,12 +570,6 @@ def _run_tests(): if not parsed: # Fallback: random inputs + default params from binding signature rng.seed(SEED) - rng.jumpahead(rng_offsets.get(fname, 0)) if hasattr( - rng, "jumpahead" - ) else None - for _ in range(x_n * N): - rng.uniform(0, 100) - rng.seed(SEED) if hasattr(rng, "jumpahead"): rng.jumpahead(rng_offsets.get(fname, 0)) inputs = [[rng.uniform(0, 100) for _ in range(N)] for _ in range(x_n)] @@ -595,7 +594,7 @@ def _run_tests(): py_params = binding_params else: c_params = params - py_params = None + py_params = params # Call Python binding func = getattr(ts, fname, None) @@ -620,16 +619,21 @@ def _run_tests(): else: py_result = func(*np_inputs) py_result = normalize_result(py_result, y_n, n) - except Exception as e: - err_msg = str(e) - if ( - re.search(r"ts_\w+\s+error", err_msg) - and not binding_params - and c_params - ): - skipped += 1 - print(f" SKIP {fname} (binding missing params, C needs them)") + except TypeError as e: + # Param name mismatch: retry with no params (binding defaults) + if py_params: + try: + py_result = func(*np_inputs) + py_result = normalize_result(py_result, y_n, n) + except Exception as e2: + failed += 1 + print(f" FAIL {fname}: {e2}") + continue + else: + failed += 1 + print(f" FAIL {fname}: {e}") continue + except Exception as e: failed += 1 print(f" FAIL {fname}: {e}") continue |