581
spinlock_unlock(&labels->spinlock);
582
}
583
584
+void rrdlabels_mark_source_as_old(RRDLABELS *labels, RRDLABEL_SRC src_match)
585
+{
586
+ if (!labels) return;
587
+
588
+ Pvoid_t *PValue;
589
+ Word_t Index = 0;
590
+ bool first_then_next = true;
591
+
592
+ spinlock_lock(&labels->spinlock);
593
+
594
+ while ((PValue = JudyLFirstThenNext(labels->JudyL, &Index, &first_then_next))) {
595
+ if ((*((RRDLABEL_SRC *)PValue)) & src_match)
596
+ *((RRDLABEL_SRC *)PValue) |= RRDLABEL_FLAG_OLD;
597
+ }
598
+
599
+ spinlock_unlock(&labels->spinlock);
600
+}
601
+
602
// ----------------------------------------------------------------------------
603
// rrdlabels_walkthrough_read()
604
1455
return rc;
1456
}
1457
1458
+// Exercises the unmark + re-add + remove_all_unmarked cycle that
1459
+// reload_host_labels() relies on, plus the rrdlabels_mark_source_as_old()
1460
+// preservation path used when the kubernetes loader fails.
1461
+static int rrdlabels_unittest_mark_source_as_old(void) {
1462
+ fprintf(stderr, "\n%s() tests\n", __FUNCTION__);
1463
+ int errors = 0;
1464
+
1465
+ // Subtest A: the prune drops entries that no loader re-added.
1466
+ {
1467
+ RRDLABELS *l = rrdlabels_create();
1468
+ rrdlabels_add(l, "cfg_key", "cv", RRDLABEL_SRC_CONFIG);
1469
+ rrdlabels_add(l, "k8s_key", "kv", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_K8S);
1470
+ rrdlabels_add(l, "aclk_key", "av", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_ACLK);
1471
+
1472
+ rrdlabels_unmark_all(l);
1473
+ // simulate a successful config + aclk loader; the k8s loader added nothing
1474
+ rrdlabels_add(l, "cfg_key", "cv", RRDLABEL_SRC_CONFIG);
1475
+ rrdlabels_add(l, "aclk_key", "av", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_ACLK);
1476
+ rrdlabels_remove_all_unmarked(l);
1477
+
1478
+ if (rrdlabels_exist(l, "k8s_key")) {
1479
+ fprintf(stderr, " FAIL (A): k8s_key should have been pruned (not re-added, not preserved)\n");
1480
+ errors++;
1481
+ }
1482
+ if (!rrdlabels_exist(l, "cfg_key") || !rrdlabels_exist(l, "aclk_key")) {
1483
+ fprintf(stderr, " FAIL (A): re-added labels should have survived the prune\n");
1484
+ errors++;
1485
+ }
1486
+ rrdlabels_destroy(l);
1487
+ }
1488
+
1489
+ // Subtest B: mark_source_as_old(K8S) preserves k8s entries through the prune
1490
+ // (the k8s-loader-failure preservation path in reload_host_labels()).
1491
+ {
1492
+ RRDLABELS *l = rrdlabels_create();
1493
+ rrdlabels_add(l, "cfg_key", "cv", RRDLABEL_SRC_CONFIG);
1494
+ rrdlabels_add(l, "k8s_key", "kv", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_K8S);
1495
+ rrdlabels_add(l, "k8s_key2", "kv2", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_K8S);
1496
+
1497
+ rrdlabels_unmark_all(l);
1498
+ // simulate successful config loader; k8s loader failed
1499
+ rrdlabels_add(l, "cfg_key", "cv", RRDLABEL_SRC_CONFIG);
1500
+ rrdlabels_mark_source_as_old(l, RRDLABEL_SRC_K8S);
1501
+ rrdlabels_remove_all_unmarked(l);
1502
+
1503
+ if (!rrdlabels_exist(l, "k8s_key") || !rrdlabels_exist(l, "k8s_key2")) {
1504
+ fprintf(stderr, " FAIL (B): K8S labels should be preserved via mark_source_as_old\n");
1505
+ errors++;
1506
+ }
1507
+ if (!rrdlabels_exist(l, "cfg_key")) {
1508
+ fprintf(stderr, " FAIL (B): cfg_key should still be present after the prune\n");
1509
+ errors++;
1510
+ }
1511
+ rrdlabels_destroy(l);
1512
+ }
1513
+
1514
+ // Subtest C: mark_source_as_old(K8S) only preserves labels whose source
1515
+ // mask intersects K8S; entries with other-only sources are still pruned.
1516
+ {
1517
+ RRDLABELS *l = rrdlabels_create();
1518
+ rrdlabels_add(l, "aclk_key", "av", RRDLABEL_SRC_AUTO | RRDLABEL_SRC_ACLK);
1519
+ rrdlabels_add(l, "cfg_key", "cv", RRDLABEL_SRC_CONFIG);
1520
+
1521
+ rrdlabels_unmark_all(l);
1522
+ rrdlabels_mark_source_as_old(l, RRDLABEL_SRC_K8S);
1523
+ rrdlabels_remove_all_unmarked(l);
1524
+
1525
+ if (rrdlabels_exist(l, "aclk_key") || rrdlabels_exist(l, "cfg_key")) {
1526
+ fprintf(stderr, " FAIL (C): non-K8S labels must not be preserved by mark_source_as_old(K8S)\n");
1527
+ errors++;
1528
+ }
1529
+ rrdlabels_destroy(l);
1530
+ }
1531
+
1532
+ fprintf(stderr, "%s: %d errors\n", __FUNCTION__, errors);
1533
+ return errors;
1534
+}
1535
+
1536
struct pattern_array *trim_and_add_key_to_values(struct pattern_array *pa, const char *key, STRING *input);
1537
static int rrdlabels_unittest_check_pattern_list(RRDLABELS *labels, const char *pattern, bool expected) {
1538
fprintf(stderr, "rrdlabels_match_simple_pattern(labels, \"%s\") ... ", pattern);
1715
errors += rrdlabels_unittest_host_chart_labels();
1716
errors += rrdlabels_unittest_double_check();
1717
errors += rrdlabels_unittest_migrate_check();
1718
+ errors += rrdlabels_unittest_mark_source_as_old();
1719
errors += rrdlabels_unittest_pattern_check();
1720
1721
fprintf(stderr, "%d errors found\n", errors);