mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(test-impact): build and run on Linux GCC, git before 2.44, LeakSanitizer
PR CI on the first push of these commits found what no local leg had
built yet:
- test_impact_result_validate.c: initialize the count GCC's
-Wmaybe-uninitialized flags (-Werror on every Linux build: smoke,
shadow, analyze).
- tests: split one-line `if` chains GCC reports as misleading
indentation, and drop a redundant `= {0}` it reads as missing braces
(the GCC test runner did not compile).
- tests/test_test_impact_engine.c: realpath() into a PATH_MAX buffer;
glibc's _FORTIFY_SOURCE aborts on anything smaller, as
test_index_resilience.c already notes.
- test_impact_git.c: pass --no-lazy-fetch only when the git executable
takes it (git 2.44+, probed once per session with the option on
--version). Older git rejected it and every engine command failed;
Ubuntu 24.04 ships git 2.43. `-c protocol.allow=never` already turns a
lazy fetch into an error there, which is what the option asks for.
- test_impact_engine.c: the selection and publish job threads release
their thread-local node-type bitset cache before they end, as the
parallel workers and the MCP index thread do. LeakSanitizer reported it
(488 bytes in 13 allocations, test-diag); the Linux arm64 ASan leg
reproduced exactly that and is clean with the fix.
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
1 parent
867e5f883d
commit
6a29a19c23
7 files changed
+46
-9
No files matched your search
@@ -13,6 +13,7 @@
|
||||
#include "foundation/sha256.h"
|
||||
#include "store/store_graph_digest.h"
|
||||
#include "store/store_impact.h"
|
||||
#include "helpers.h" /* cbm_kind_in_set_free_cache — the job thread's cache teardown */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -621,6 +622,10 @@ static void *te_job_main(void *arg) {
|
||||
status = CBM_TEST_IMPACT_CANCELLED;
|
||||
}
|
||||
te_free(&c);
|
||||
/* The snapshot build extracted on THIS thread, which ends here: its
|
||||
* thread-local node-type bitset cache goes with it (as the MCP index
|
||||
* thread and the parallel workers release theirs). */
|
||||
cbm_kind_in_set_free_cache();
|
||||
job->status = status;
|
||||
return NULL;
|
||||
}
|
||||
@@ -678,6 +683,7 @@ static void *te_publish_main(void *arg) {
|
||||
bool ok = te_publish(&c, p);
|
||||
job->status = c.oom ? CBM_TEST_IMPACT_OOM : ok ? CBM_TEST_IMPACT_OK : CBM_TEST_IMPACT_INVALID;
|
||||
te_free(&c);
|
||||
cbm_kind_in_set_free_cache(); /* this thread's extraction cache, as in te_job_main */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ struct cbm_git_facts {
|
||||
cbm_git_facts_error_t stopped;
|
||||
gf_batch_budget_t *batch_budget; /* borrowed stack state during one serialized call */
|
||||
gf_inventory_cache_t inventory_cache[2];
|
||||
bool no_lazy_fetch; /* the executable takes --no-lazy-fetch (gf_probe_no_lazy_fetch) */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -486,7 +487,6 @@ static bool gf_run_input(cbm_git_facts_t *facts, const char *const *arguments, i
|
||||
"--no-replace-objects",
|
||||
"--no-pager",
|
||||
"--literal-pathspecs",
|
||||
"--no-lazy-fetch",
|
||||
"-C",
|
||||
facts->options.root,
|
||||
"-c",
|
||||
@@ -496,11 +496,13 @@ static bool gf_run_input(cbm_git_facts_t *facts, const char *const *arguments, i
|
||||
size_t prefix_count = sizeof(prefix) / sizeof(prefix[0]);
|
||||
size_t directory_count = facts->command_git_dir ? 4 : 0;
|
||||
if (count < 1 || count >= GF_ARG_CAP ||
|
||||
(size_t)count + prefix_count + directory_count + (size_t)facts->git_pin_count + 1 >
|
||||
(size_t)count + prefix_count + directory_count + (size_t)facts->git_pin_count + 2 >
|
||||
GF_ARG_CAP)
|
||||
return gf_error(error, CBM_GIT_FACTS_INVALID, "Invalid internal Git command");
|
||||
for (size_t i = 0; i < prefix_count; i++)
|
||||
argv[argc++] = prefix[i];
|
||||
if (facts->no_lazy_fetch)
|
||||
argv[argc++] = "--no-lazy-fetch";
|
||||
if (facts->command_git_dir) {
|
||||
argv[argc++] = "--git-dir";
|
||||
argv[argc++] = facts->command_git_dir;
|
||||
@@ -907,6 +909,22 @@ static bool gf_open_identity(cbm_git_facts_t *facts, cbm_git_facts_error_t *erro
|
||||
return gf_gate(facts, error);
|
||||
}
|
||||
|
||||
/* --no-lazy-fetch (git 2.44) keeps an object missing from a partial clone
|
||||
* from being fetched. Older git rejects the option, which failed every engine
|
||||
* command (Ubuntu 24.04 ships git 2.43). There `-c protocol.allow=never`
|
||||
* already turns such a fetch into an error, which is what the option asks
|
||||
* for, so it is passed only when the executable accepts it: one probe per
|
||||
* facts session, outside the command budget, output discarded. */
|
||||
static bool gf_probe_no_lazy_fetch(const char *git) {
|
||||
const char *argv[] = {git, "--no-lazy-fetch", "--version", NULL};
|
||||
cbm_proc_opts_t options = {.bin = git,
|
||||
.argv = argv,
|
||||
.cancel_grace_ms = CBM_SUBPROCESS_DEFAULT_CANCEL_GRACE_MS,
|
||||
.strip_git_repo_env = true};
|
||||
cbm_proc_result_t result = {0};
|
||||
return cbm_subprocess_run(&options, &result) == 0 && result.outcome == CBM_PROC_CLEAN;
|
||||
}
|
||||
|
||||
cbm_git_facts_t *cbm_git_facts_open(const cbm_git_facts_options_t *options,
|
||||
cbm_git_facts_error_t *error) {
|
||||
cbm_git_facts_error_t local;
|
||||
@@ -959,6 +977,7 @@ cbm_git_facts_t *cbm_git_facts_open(const cbm_git_facts_options_t *options,
|
||||
cbm_git_facts_free(facts);
|
||||
return NULL;
|
||||
}
|
||||
facts->no_lazy_fetch = gf_probe_no_lazy_fetch(facts->options.git_executable);
|
||||
if (!gf_open_identity(facts, error)) {
|
||||
cbm_git_facts_free(facts);
|
||||
return NULL;
|
||||
|
||||
@@ -27,7 +27,7 @@ static bool tir_label(tir_context *c, const char *s, tir_bytes *out) {
|
||||
|
||||
static bool tir_string_array(tir_context *c, const char *const *strings, int count,
|
||||
tir_bytes **saved) {
|
||||
size_t n;
|
||||
size_t n = 0;
|
||||
if (!tir_count(c, strings, count, &n))
|
||||
return false;
|
||||
tir_bytes *copy = saved ? tir_alloc(c, n, sizeof(*copy)) : NULL;
|
||||
|
||||
@@ -258,7 +258,6 @@ static cbm_pipeline_frozen_inputs_t pf_inputs(pf_fixture_t *f, const char *confi
|
||||
.config_bytes = config,
|
||||
.config_len = config ? strlen(config) : 0,
|
||||
.pinned_git = git,
|
||||
.resource_policy = {0},
|
||||
.cancelled = cancelled};
|
||||
}
|
||||
static cbm_pipeline_frozen_status_t pf_create(pf_fixture_t *f, const char *config,
|
||||
|
||||
@@ -420,9 +420,12 @@ TEST(store_graph_digest_invalid_arguments_missing_project_and_initial_latches) {
|
||||
int opened=s && collation?cbm_store_read_scope_open(s,NULL,NULL,&scope):CBM_STORE_ERR;
|
||||
cbm_store_graph_digest_limits_t lim=gd_room;cbm_store_graph_digest_t out;memset(&out,0xa5,sizeof(out));
|
||||
const unsigned char *p=(const unsigned char *)"p";size_t len=1;
|
||||
if(which==2)p=NULL;if(which==3)len=0;if(which==4)len=(size_t)INT_MAX+1;
|
||||
if(which==2)p=NULL;
|
||||
if(which==3)len=0;
|
||||
if(which==4)len=(size_t)INT_MAX+1;
|
||||
if(which==5){p=(const unsigned char *)"p\0q";len=3;}
|
||||
if(which==7)lim.max_rows=0;if(which==8)lim.max_framed_bytes=0;
|
||||
if(which==7)lim.max_rows=0;
|
||||
if(which==8)lim.max_framed_bytes=0;
|
||||
if(which==9)lim.max_framed_bytes=UINT64_MAX/8+1;
|
||||
if(which==10)p=(const unsigned char *)"P";
|
||||
int rc=opened==CBM_STORE_OK?cbm_store_graph_digest(which==0?NULL:scope,p,len,which==6?NULL:&lim,which==1?NULL:&out):-1;
|
||||
|
||||
@@ -16,11 +16,18 @@
|
||||
#include "foundation/subprocess.h"
|
||||
#include "mcp/test_impact_engine.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
/* glibc's _FORTIFY_SOURCE realpath() aborts unless the output buffer is at
|
||||
* least PATH_MAX bytes, independent of the actual path length. */
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char git[1024];
|
||||
char home[1024];
|
||||
@@ -126,7 +133,7 @@ static bool tie_open_with(tie_fixture_t *fx, const char *extra_path, const char
|
||||
memset(fx, 0, sizeof(*fx));
|
||||
const char *git = cbm_find_cli("git", cbm_get_home_dir());
|
||||
const char *home = th_mktempdir("cbm-ti-engine");
|
||||
char real[1024];
|
||||
char real[PATH_MAX];
|
||||
if (!git || !home || !realpath(home, real) || strlen(git) >= sizeof(fx->git)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2002,7 +2002,9 @@ TEST(test_git_blob_batch_validates_full_selection_and_empty_requests) {
|
||||
gfb_error(facts,&request,NULL,CBM_GIT_FACTS_INVALID) && ok;
|
||||
for(int i=0;control && i<3;i++) {
|
||||
cbm_git_blob_batch_limits_t zero=limits;
|
||||
if(i==0)zero.max_entries=0;if(i==1)zero.max_input_bytes=0;if(i==2)zero.max_arena_bytes=0;
|
||||
if(i==0)zero.max_entries=0;
|
||||
if(i==1)zero.max_input_bytes=0;
|
||||
if(i==2)zero.max_arena_bytes=0;
|
||||
ok=gfb_error(facts,&request,&zero,CBM_GIT_FACTS_INVALID) && ok;
|
||||
}
|
||||
bool no_out=control && !cbm_git_facts_read_blob_batch(facts,&request,&limits,NULL,&error) &&
|
||||
@@ -2265,7 +2267,8 @@ static cbm_git_bytes_t gfb_concat(CBMArena *arena,cbm_git_bytes_t a,cbm_git_byte
|
||||
if(a.length>SIZE_MAX-b.length)return (cbm_git_bytes_t){NULL,0};
|
||||
size_t size=a.length+b.length;unsigned char *bytes=cbm_arena_alloc(arena,size?size:1);
|
||||
if(!bytes)return (cbm_git_bytes_t){NULL,0};
|
||||
if(a.length)memcpy(bytes,a.data,a.length);if(b.length)memcpy(bytes+a.length,b.data,b.length);
|
||||
if(a.length)memcpy(bytes,a.data,a.length);
|
||||
if(b.length)memcpy(bytes+a.length,b.data,b.length);
|
||||
return (cbm_git_bytes_t){bytes,size};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user