@@ -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+
50825217SUITE (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