Skip to content

Commit a90ab5d

Browse files
fix(k8s): add k8s pass to incremental pipeline
cbm_pipeline_pass_k8s() was called in the full pipeline (pipeline.c) but absent from pipeline_incremental.c. This meant k8s Resource nodes and kustomize Module nodes were never created or updated during incremental re-indexing — only after a fresh full index. Add the pass after the semantic pass, following the same timing-log pattern as the other incremental passes. Pass changed_files (not the full file list) so only modified/added YAML files are re-processed. Add two regression tests: - incremental_k8s_manifest_indexed: full index + add manifest via incremental, verifies Resource node appears in the DB - incremental_kustomize_module_indexed: same for kustomization.yaml Module node Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 340862c commit a90ab5d

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

src/pipeline/pipeline_incremental.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ int cbm_pipeline_run_incremental(cbm_pipeline_t *p, const char *db_path, cbm_fil
265265
cbm_log_info("pass.timing", "pass", "incr_semantic", "elapsed_ms",
266266
itoa_buf((int)elapsed_ms(t)));
267267

268+
cbm_clock_gettime(CLOCK_MONOTONIC, &t);
269+
cbm_pipeline_pass_k8s(&ctx, changed_files, ci);
270+
cbm_log_info("pass.timing", "pass", "incr_k8s", "elapsed_ms", itoa_buf((int)elapsed_ms(t)));
271+
268272
/* Merge new nodes/edges from gbuf into disk DB */
269273
int new_nodes = cbm_gbuf_node_count(gbuf);
270274
int new_edges = cbm_gbuf_edge_count(gbuf);

tests/test_pipeline.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5079,6 +5079,141 @@ TEST(incremental_new_file_added) {
50795079
PASS();
50805080
}
50815081

5082+
TEST(incremental_k8s_manifest_indexed) {
5083+
/* Full index with a k8s manifest, then add a new manifest via incremental.
5084+
* Verifies that cbm_pipeline_pass_k8s() runs during incremental re-index. */
5085+
char tmpdir[256];
5086+
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_k8s_incr_XXXXXX");
5087+
if (!cbm_mkdtemp(tmpdir)) {
5088+
SKIP("tmpdir");
5089+
}
5090+
char dbpath[512];
5091+
snprintf(dbpath, sizeof(dbpath), "%s/test.db", tmpdir);
5092+
char path[512];
5093+
FILE *f;
5094+
5095+
/* Initial manifest */
5096+
snprintf(path, sizeof(path), "%s/deploy.yaml", tmpdir);
5097+
f = fopen(path, "w");
5098+
ASSERT_NOT_NULL(f);
5099+
fprintf(f, "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-app\n");
5100+
fclose(f);
5101+
5102+
/* Full index */
5103+
cbm_pipeline_t *p = cbm_pipeline_new(tmpdir, dbpath, CBM_MODE_FULL);
5104+
ASSERT_NOT_NULL(p);
5105+
ASSERT_EQ(cbm_pipeline_run(p), 0);
5106+
char *project = strdup(cbm_pipeline_project_name(p));
5107+
cbm_pipeline_free(p);
5108+
5109+
/* Verify Resource node created by full index */
5110+
cbm_store_t *s = cbm_store_open_path(dbpath);
5111+
ASSERT_NOT_NULL(s);
5112+
cbm_node_t *nodes = NULL;
5113+
int count = 0;
5114+
cbm_store_find_nodes_by_label(s, project, "Resource", &nodes, &count);
5115+
ASSERT_GT(count, 0);
5116+
cbm_store_free_nodes(nodes, count);
5117+
cbm_store_close(s);
5118+
5119+
/* Add a second manifest — incremental should pick it up */
5120+
snprintf(path, sizeof(path), "%s/svc.yaml", tmpdir);
5121+
f = fopen(path, "w");
5122+
ASSERT_NOT_NULL(f);
5123+
fprintf(f, "apiVersion: v1\nkind: Service\nmetadata:\n name: my-svc\n");
5124+
fclose(f);
5125+
5126+
/* Incremental re-index */
5127+
p = cbm_pipeline_new(tmpdir, dbpath, CBM_MODE_FULL);
5128+
ASSERT_NOT_NULL(p);
5129+
ASSERT_EQ(cbm_pipeline_run(p), 0);
5130+
cbm_pipeline_free(p);
5131+
5132+
/* Verify both Resource nodes now present */
5133+
s = cbm_store_open_path(dbpath);
5134+
ASSERT_NOT_NULL(s);
5135+
nodes = NULL;
5136+
count = 0;
5137+
cbm_store_find_nodes_by_label(s, project, "Resource", &nodes, &count);
5138+
ASSERT_GTE(count, 2);
5139+
cbm_store_free_nodes(nodes, count);
5140+
cbm_store_close(s);
5141+
5142+
free(project);
5143+
char cmd[512];
5144+
snprintf(cmd, sizeof(cmd), "rm -rf '%s'", tmpdir);
5145+
(void)system(cmd);
5146+
PASS();
5147+
}
5148+
5149+
TEST(incremental_kustomize_module_indexed) {
5150+
/* Verifies that a kustomization.yaml added after the initial full index
5151+
* gets a Module node via the incremental k8s pass. */
5152+
char tmpdir[256];
5153+
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_kust_incr_XXXXXX");
5154+
if (!cbm_mkdtemp(tmpdir)) {
5155+
SKIP("tmpdir");
5156+
}
5157+
char dbpath[512];
5158+
snprintf(dbpath, sizeof(dbpath), "%s/test.db", tmpdir);
5159+
char path[512];
5160+
FILE *f;
5161+
5162+
/* Initial resource manifest (gives full index something to find) */
5163+
snprintf(path, sizeof(path), "%s/deploy.yaml", tmpdir);
5164+
f = fopen(path, "w");
5165+
ASSERT_NOT_NULL(f);
5166+
fprintf(f, "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-app\n");
5167+
fclose(f);
5168+
5169+
/* Full index */
5170+
cbm_pipeline_t *p = cbm_pipeline_new(tmpdir, dbpath, CBM_MODE_FULL);
5171+
ASSERT_NOT_NULL(p);
5172+
ASSERT_EQ(cbm_pipeline_run(p), 0);
5173+
char *project = strdup(cbm_pipeline_project_name(p));
5174+
cbm_pipeline_free(p);
5175+
5176+
/* Add kustomization.yaml */
5177+
snprintf(path, sizeof(path), "%s/kustomization.yaml", tmpdir);
5178+
f = fopen(path, "w");
5179+
ASSERT_NOT_NULL(f);
5180+
fprintf(f, "apiVersion: kustomize.config.k8s.io/v1beta1\n"
5181+
"kind: Kustomization\n"
5182+
"resources:\n"
5183+
" - deploy.yaml\n");
5184+
fclose(f);
5185+
5186+
/* Incremental re-index */
5187+
p = cbm_pipeline_new(tmpdir, dbpath, CBM_MODE_FULL);
5188+
ASSERT_NOT_NULL(p);
5189+
ASSERT_EQ(cbm_pipeline_run(p), 0);
5190+
cbm_pipeline_free(p);
5191+
5192+
/* Verify Module node created for the kustomization overlay */
5193+
cbm_store_t *s = cbm_store_open_path(dbpath);
5194+
ASSERT_NOT_NULL(s);
5195+
cbm_node_t *nodes = NULL;
5196+
int count = 0;
5197+
cbm_store_find_nodes_by_label(s, project, "Module", &nodes, &count);
5198+
bool found_kust = false;
5199+
for (int i = 0; i < count; i++) {
5200+
if (nodes[i].properties_json &&
5201+
strstr(nodes[i].properties_json, "kustomize")) {
5202+
found_kust = true;
5203+
break;
5204+
}
5205+
}
5206+
cbm_store_free_nodes(nodes, count);
5207+
cbm_store_close(s);
5208+
ASSERT_TRUE(found_kust);
5209+
5210+
free(project);
5211+
char cmd[512];
5212+
snprintf(cmd, sizeof(cmd), "rm -rf '%s'", tmpdir);
5213+
(void)system(cmd);
5214+
PASS();
5215+
}
5216+
50825217
SUITE(pipeline) {
50835218
/* Lifecycle */
50845219
RUN_TEST(pipeline_create_free);
@@ -5269,4 +5404,6 @@ SUITE(pipeline) {
52695404
RUN_TEST(incremental_detects_changed_file);
52705405
RUN_TEST(incremental_detects_deleted_file);
52715406
RUN_TEST(incremental_new_file_added);
5407+
RUN_TEST(incremental_k8s_manifest_indexed);
5408+
RUN_TEST(incremental_kustomize_module_indexed);
52725409
}

0 commit comments

Comments
 (0)