summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/adx.c14
-rw-r--r--test/awesome_oscillator.c5
-rw-r--r--test/bench.c1
-rw-r--r--test/bollinger_bands.c2
-rw-r--r--test/cv.c3
-rw-r--r--test/edge_cases.c1
-rw-r--r--test/fuzz.c6
-rw-r--r--test/gen_test_data.c7
-rw-r--r--test/hurst_exponent.c14
-rw-r--r--test/main.c4
-rw-r--r--test/nextafter.c6
-rw-r--r--test/nexttoward.c6
-rw-r--r--test/nvi.c2
-rw-r--r--test/test_python.py52
14 files changed, 84 insertions, 39 deletions
diff --git a/test/adx.c b/test/adx.c
index e8df67e..aac452d 100644
--- a/test/adx.c
+++ b/test/adx.c
@@ -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 };
diff --git a/test/cv.c b/test/cv.c
index 2c41604..45cf635 100644
--- a/test/cv.c
+++ b/test/cv.c
@@ -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 };
diff --git a/test/nvi.c b/test/nvi.c
index 87b3ddb..8a8f300 100644
--- a/test/nvi.c
+++ b/test/nvi.c
@@ -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