ATLAS Offline Software
Loading...
Searching...
No Matches
python.ConfigText_merge_unitTest Namespace Reference

Functions

 _load_yaml (pathlib.Path p)
 _assert (cond, msg)
 _run_merge (dict top_cfg, pathlib.Path base_dir)
 case_earlier_wins (pathlib.Path base_dir)
 case_earlier_wins_between_fragments (pathlib.Path base_dir)
 case_list_concat (pathlib.Path base_dir)
 case_single_string_include (pathlib.Path base_dir)
 run_case (str name, pathlib.Path base_dir)
 main ()

Detailed Description

Merge tests for multi-include semantics (no pytest), using neutral keys foo/bar.

Usage:
  python ConfigText_merge_unitTest.py --dir AnalysisAlgorithmsConfig
  python ConfigText_merge_unitTest.py --case all --dir path/to/yamls

Function Documentation

◆ _assert()

python.ConfigText_merge_unitTest._assert ( cond,
msg )
protected

Definition at line 26 of file ConfigText_merge_unitTest.py.

26def _assert(cond, msg):
27 if not cond:
28 raise AssertionError(msg)
29

◆ _load_yaml()

python.ConfigText_merge_unitTest._load_yaml ( pathlib.Path p)
protected

Definition at line 22 of file ConfigText_merge_unitTest.py.

22def _load_yaml(p: pathlib.Path):
23 with p.open("r") as f:
24 return yaml.safe_load(f)
25

◆ _run_merge()

python.ConfigText_merge_unitTest._run_merge ( dict top_cfg,
pathlib.Path base_dir )
protected

Definition at line 30 of file ConfigText_merge_unitTest.py.

30def _run_merge(top_cfg: dict, base_dir: pathlib.Path):
31 # Round-trip copy for parity with production behavior
32 top = yaml.safe_load(yaml.safe_dump(top_cfg))
33 changed = combineConfigFiles(top, base_dir, fragment_key="include")
34 _assert(changed is True, "combineConfigFiles reported no changes")
35 _assert("include" not in top, "include key should be removed after merging")
36 return top
37

◆ case_earlier_wins()

python.ConfigText_merge_unitTest.case_earlier_wins ( pathlib.Path base_dir)
Nested include: earlier wins inside test_merge_mid, local overrides afterward.

Definition at line 38 of file ConfigText_merge_unitTest.py.

38def case_earlier_wins(base_dir: pathlib.Path):
39 """
40 Nested include: earlier wins inside test_merge_mid, local overrides afterward.
41 """
42 top_cfg = _load_yaml(base_dir / "test_merge_top.yaml")
43 merged = _run_merge(top_cfg, base_dir)
44
45 # From override.json (only there), should be present
46 _assert(merged["a"] == 2, "Expected 'a' == 2 from override.json")
47
48 # From override.json (new key) and local override
49 _assert(merged["nested"]["y"] == 20, "Expected nested.y == 20 from override.json")
50 _assert(merged["nested"]["x"] == 999, "Local override of nested.x should win")
51
52 # Carry-through from frag_a (since mid includes frag_a first and no frag_b)
53 _assert(abs(merged["bar"]["rate"] - 0.1) < 1e-12, "Expected bar.rate from frag_a (0.1)")
54 _assert(merged["foo"]["alpha"] == 1 and merged["foo"]["beta"] == "A",
55 "Expected foo.{alpha,beta} from frag_a")
56
57 # Local override over fragments
58 _assert(merged["bar"]["size"] == 32, "Local bar.size should override frag_a (32 vs 64)")
59
60 # Presence of local-only key
61 _assert(merged["local_only"] is True, "Local-only key should remain")
62

◆ case_earlier_wins_between_fragments()

python.ConfigText_merge_unitTest.case_earlier_wins_between_fragments ( pathlib.Path base_dir)
Direct include [frag_a, frag_b]: earlier (a) wins on scalar conflicts; lists concat.

Definition at line 63 of file ConfigText_merge_unitTest.py.

63def case_earlier_wins_between_fragments(base_dir: pathlib.Path):
64 """
65 Direct include [frag_a, frag_b]: earlier (a) wins on scalar conflicts; lists concat.
66 """
67 top_cfg = {
68 "include": ["test_merge_frag_a.yaml", "test_merge_frag_b.yaml"]
69 }
70 merged = _run_merge(top_cfg, base_dir)
71
72 # Earlier wins on conflicts
73 _assert(merged["foo"]["alpha"] == 1, "Earlier frag_a should win foo.alpha")
74 _assert(merged["foo"]["beta"] == "A", "Earlier frag_a should win foo.beta")
75 _assert(abs(merged["bar"]["rate"] - 0.1) < 1e-12, "Earlier frag_a should win bar.rate")
76
77 # Values only in earlier remain
78 _assert(merged["bar"]["size"] == 64, "bar.size should come from frag_a")
79
80 # Lists concatenate
81 _assert(merged["nums"] == [1, 2, 3], "Expected nums concatenation [1,2,3]")
82
83 # Keys unique to later survive
84 _assert(merged["only_in_b"] is True, "Key unique to later fragment should be present")
85

◆ case_list_concat()

python.ConfigText_merge_unitTest.case_list_concat ( pathlib.Path base_dir)
Lists concatenate without deduplication.

Definition at line 86 of file ConfigText_merge_unitTest.py.

86def case_list_concat(base_dir: pathlib.Path):
87 """Lists concatenate without deduplication."""
88 top_cfg = _load_yaml(base_dir / "test_merge_list_top.yaml")
89 merged = _run_merge(top_cfg, base_dir)
90 _assert(merged["items"] == [1, 2, 3], "items should concatenate")
91 _assert(merged["dups"] == [1, 1, 1], "dups should concatenate without dedup")
92

◆ case_single_string_include()

python.ConfigText_merge_unitTest.case_single_string_include ( pathlib.Path base_dir)
Single-string include path is supported, but should warn for deprecation.

Definition at line 93 of file ConfigText_merge_unitTest.py.

93def case_single_string_include(base_dir: pathlib.Path):
94 """Single-string include path is supported, but should warn for deprecation."""
95 top_cfg = _load_yaml(base_dir / "test_merge_single_top.yaml")
96
97 # Capture warnings of the specific type
98 with warnings.catch_warnings(record=True) as w:
99 warnings.simplefilter("always", TextConfigWarning) # ensure it’s recorded
100
101 merged = _run_merge(top_cfg, base_dir)
102
103 # Pull only the TextConfigWarning messages
104 msgs = [
105 str(rec.message) for rec in w
106 if issubclass(rec.category, TextConfigWarning)
107 ]
108
109 # Assert that the expected deprecation message appeared
110 _assert(
111 any("should be followed with a list of files" in m for m in msgs),
112 "Expected TextConfigWarning about include needing a list",
113 )
114
115 # Keep your existing assertions
116 _assert(merged["foo"]["alpha"] == 1, "Single include should resolve frag_a (foo.alpha)")
117 _assert(merged["only_in_a"] is True, "Value from frag_a should appear")
118

◆ main()

python.ConfigText_merge_unitTest.main ( )

Definition at line 143 of file ConfigText_merge_unitTest.py.

143def main():
144 ap = argparse.ArgumentParser()
145 ap.add_argument("--dir", dest="yamldir", required=True,
146 help="Directory where the test_merge_*.yaml/json files live")
147 ap.add_argument("--case", default="all",
148 choices=[
149 "all", "earlier_wins", "earlier_wins_between_fragments",
150 "list_concat", "single_string_include"],
151 help="Which case to run (default: all)")
152 args = ap.parse_args()
153
154 # Avoid DATAPATH interference (your _find_fragment should handle empty)
155 os.environ["DATAPATH"] = ""
156 from PathResolver import PathResolver
157 base_dir = PathResolver.FindCalibDirectory(args.yamldir)
158 base_dir = pathlib.Path(base_dir)
159 if not base_dir.is_dir():
160 sys.exit(f"--dir {base_dir} is not a directory")
161
162 run_case(args.case, base_dir)
163
static std::string FindCalibDirectory(const std::string &logical_file_name)
int main()
Definition hello.cxx:18

◆ run_case()

python.ConfigText_merge_unitTest.run_case ( str name,
pathlib.Path base_dir )

Definition at line 119 of file ConfigText_merge_unitTest.py.

119def run_case(name: str, base_dir: pathlib.Path):
120 mapping = {
121 "earlier_wins": case_earlier_wins,
122 "earlier_wins_between_fragments": case_earlier_wins_between_fragments,
123 "list_concat": case_list_concat,
124 "single_string_include": case_single_string_include,
125 }
126 if name == "all":
127 for k in mapping:
128 print(f"→ {k} ... ", end="", flush=True)
129 try:
130 mapping[k](base_dir)
131 print("OK")
132 except Exception:
133 print("FAIL")
134 traceback.print_exc()
135 sys.exit(1)
136 else:
137 if name not in mapping:
138 sys.exit(f"Unknown case '{name}'. Choose from: all, " + ", ".join(mapping))
139 print(f"→ {name} ... ", end="", flush=True)
140 mapping[name](base_dir)
141 print("OK")
142
void print(char *figname, TCanvas *c1)