Skip to content

Commit 1b84943

Browse files
committed
Separate perf tests from CI, fix cross-platform build issues
- Add CBM_SKIP_PERF=1 env var to skip incremental/perf test suite - CI and Docker test targets skip perf by default (run.sh perf for manual) - Convert all perf assertions to warnings (log timing, never block) - Fix store.h anonymous enum in struct (GCC rejects, clang accepts) - Fix test_store_search.c mkstemp on non-template path - Add ca-certificates to Docker test image for git HTTPS - Add cbm_gmtime_r shim in compat.h (Windows gmtime_s wrapper) - Fix compat.c missing constants.h include (Windows build) - Fix platform.c _environ redeclaration on mingw - Rename trace_call_path -> trace_path in smoke/soak/fuzz scripts
1 parent 7f83593 commit 1b84943

File tree

15 files changed

+71
-39
lines changed

15 files changed

+71
-39
lines changed

.github/workflows/dry-run.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,10 @@ jobs:
189189
if: startsWith(matrix.os, 'ubuntu')
190190
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
191191

192-
- name: Test
192+
- name: Test (unit + integration, no perf)
193193
run: scripts/test.sh CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
194+
env:
195+
CBM_SKIP_PERF: 1
194196

195197
test-windows:
196198
if: ${{ inputs.skip_tests != true && always() && (needs.lint.result == 'success' || needs.lint.result == 'skipped') }}

scripts/security-fuzz.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ test_payload "index nonexistent path" '{"jsonrpc":"2.0","id":2,"method":"tools/c
112112

113113
# Negative/zero values for numeric params
114114
test_payload "negative limit" '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_graph","arguments":{"name_pattern":"test","limit":-1}}}'
115-
test_payload "zero max_depth" '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"trace_call_path","arguments":{"function_name":"test","max_depth":0}}}'
115+
test_payload "zero max_depth" '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"trace_path","arguments":{"function_name":"test","max_depth":0}}}'
116116
test_payload "huge max_rows" '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"query_graph","arguments":{"query":"MATCH (n) RETURN n","max_rows":999999999}}}'
117117

118118
echo ""

scripts/smoke-test.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,14 @@ if [ "$TOTAL" -lt 1 ]; then
138138
fi
139139
echo "OK: search_graph found $TOTAL result(s) for 'compute'"
140140

141-
# 3b: trace_call_path — verify compute has callers
142-
TRACE=$(cli trace_call_path "{\"project\":\"$PROJECT\",\"function_name\":\"compute\",\"direction\":\"inbound\",\"depth\":1}")
141+
# 3b: trace_path — verify compute has callers
142+
TRACE=$(cli trace_path "{\"project\":\"$PROJECT\",\"function_name\":\"compute\",\"direction\":\"inbound\",\"depth\":1}")
143143
CALLERS=$(echo "$TRACE" | python3 -c "import json,sys; d=json.loads(json.loads(sys.stdin.read())['content'][0]['text']); print(len(d.get('callers',[])))" 2>/dev/null || echo "0")
144144
if [ "$CALLERS" -lt 1 ]; then
145-
echo "FAIL: trace_call_path found 0 callers for 'compute'"
145+
echo "FAIL: trace_path found 0 callers for 'compute'"
146146
exit 1
147147
fi
148-
echo "OK: trace_call_path found $CALLERS caller(s) for 'compute'"
148+
echo "OK: trace_path found $CALLERS caller(s) for 'compute'"
149149

150150
# 3c: get_graph_schema — verify labels exist
151151
SCHEMA=$(cli get_graph_schema "{\"project\":\"$PROJECT\"}")
@@ -271,7 +271,7 @@ fi
271271
echo "OK: tools/list response received (id:2)"
272272

273273
# 5c: Verify expected tools are present
274-
for TOOL in index_repository search_graph trace_call_path get_code_snippet search_code; do
274+
for TOOL in index_repository search_graph trace_path get_code_snippet search_code; do
275275
if ! grep -q "\"$TOOL\"" "$MCP_OUTPUT"; then
276276
echo "FAIL: tool '$TOOL' not found in tools/list response"
277277
rm -f "$MCP_INPUT" "$MCP_OUTPUT"

scripts/soak-test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ while [ "$(date +%s)" -lt "$END_TIME" ]; do
289289

290290
# Queries every 2 seconds
291291
mcp_call search_graph "{\"project\":\"$PROJ_NAME\",\"name_pattern\":\".*compute.*\"}"
292-
mcp_call trace_call_path "{\"project\":\"$PROJ_NAME\",\"function_name\":\"compute\",\"direction\":\"both\"}"
292+
mcp_call trace_path "{\"project\":\"$PROJ_NAME\",\"function_name\":\"compute\",\"direction\":\"both\"}"
293293

294294
# File mutation every 2 minutes
295295
if [ $((NOW - LAST_MUTATE)) -ge 120 ]; then

src/foundation/compat.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* macros in compat.h. On Windows, we implement them here.
66
*/
77
#include "foundation/compat.h"
8+
#include "foundation/constants.h"
89

910
#include <stdlib.h>
1011
#include <string.h>

src/foundation/compat.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,15 @@ static inline int cbm_nanosleep(const struct timespec *req, struct timespec *rem
8888
#define cbm_nanosleep nanosleep
8989
#endif
9090

91+
/* ── gmtime_r (Windows lacks it) ─────────────────────────────── */
92+
#ifdef _WIN32
93+
static inline struct tm *cbm_gmtime_r(const time_t *timep, struct tm *result) {
94+
return gmtime_s(result, timep) == 0 ? result : NULL;
95+
}
96+
#else
97+
#define cbm_gmtime_r gmtime_r
98+
#endif
99+
91100
/* ── mkdtemp (Windows lacks it) ──────────────────────────────── */
92101
#ifdef _WIN32
93102
/* Translates /tmp/ to %TEMP%\ and copies result back to tmpl.

src/foundation/platform.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ char *cbm_normalize_path_sep(char *path) {
249249
* can be invalidated by setenv/putenv in another thread. We copy to a
250250
* caller-owned buffer immediately. */
251251
#ifdef _WIN32
252-
extern char **_environ;
252+
#include <stdlib.h>
253253
#define CBM_ENVIRON _environ
254254
#elif defined(__APPLE__)
255255
#include <crt_externs.h>

src/graph_buffer/graph_buffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1182,7 +1182,7 @@ int cbm_gbuf_dump_to_sqlite(cbm_gbuf_t *gb, const char *path) {
11821182
/* Generate ISO 8601 timestamp */
11831183
time_t now = time(NULL);
11841184
struct tm tm_buf;
1185-
struct tm *tm_val = gmtime_r(&now, &tm_buf);
1185+
struct tm *tm_val = cbm_gmtime_r(&now, &tm_buf);
11861186
char indexed_at[CBM_SZ_64];
11871187
if (strftime(indexed_at, sizeof(indexed_at), "%Y-%m-%dT%H:%M:%SZ", tm_val) == 0) {
11881188
snprintf(indexed_at, sizeof(indexed_at), "1970-01-01T00:00:00Z");

src/store/store.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,7 @@ static sqlite3_stmt *prepare_cached(cbm_store_t *s, sqlite3_stmt **slot, const c
197197
static void iso_now(char *buf, size_t sz) {
198198
time_t t = time(NULL);
199199
struct tm tm;
200-
#ifdef _WIN32
201-
gmtime_s(&tm, &t); /* Windows: reversed arg order */
202-
#else
203-
gmtime_r(&t, &tm);
204-
#endif
200+
cbm_gmtime_r(&t, &tm);
205201
(void)strftime(buf, sz, "%Y-%m-%dT%H:%M:%SZ",
206202
&tm); // cert-err33-c: strftime only fails if buffer is too small — 21-byte ISO
207203
// timestamp always fits in caller-provided buffers

src/store/store.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,9 @@ void cbm_store_adr_free(cbm_adr_t *adr);
534534

535535
/* ADR section parsing/rendering (pure functions, no store needed) */
536536

537+
enum { PROPS_MAX = 16 };
538+
537539
typedef struct {
538-
enum { PROPS_MAX = 16 };
539540
char *keys[PROPS_MAX];
540541
char *values[PROPS_MAX];
541542
int count;

0 commit comments

Comments
 (0)