ATLAS Offline Software
Functions
python.ConfigText_merge_unitTest Namespace Reference

Functions

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

Function Documentation

◆ _assert()

def python.ConfigText_merge_unitTest._assert (   cond,
  msg 
)
private

Definition at line 26 of file ConfigText_merge_unitTest.py.

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

◆ _load_yaml()

def python.ConfigText_merge_unitTest._load_yaml ( pathlib.Path  p)
private

Definition at line 22 of file ConfigText_merge_unitTest.py.

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

◆ _run_merge()

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

Definition at line 30 of file ConfigText_merge_unitTest.py.

30 def _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()

def 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.

38 def 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()

def 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.

63 def 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()

def 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.

86 def 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()

def 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.

93 def 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()

def python.ConfigText_merge_unitTest.main ( )

Definition at line 143 of file ConfigText_merge_unitTest.py.

143 def 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 

◆ run_case()

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

Definition at line 119 of file ConfigText_merge_unitTest.py.

119 def 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 
python.ConfigText.combineConfigFiles
def combineConfigFiles(local, config_path, fragment_key="include")
Definition: ConfigText.py:373
python.ConfigText_merge_unitTest.case_earlier_wins
def case_earlier_wins(pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:38
python.ConfigText_merge_unitTest.case_earlier_wins_between_fragments
def case_earlier_wins_between_fragments(pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:63
PathResolver::FindCalibDirectory
static std::string FindCalibDirectory(const std::string &logical_file_name)
Definition: PathResolver.h:64
python.ConfigText_merge_unitTest.case_list_concat
def case_list_concat(pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:86
python.ConfigText_merge_unitTest._assert
def _assert(cond, msg)
Definition: ConfigText_merge_unitTest.py:26
python.ConfigText_merge_unitTest._load_yaml
def _load_yaml(pathlib.Path p)
Definition: ConfigText_merge_unitTest.py:22
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.ConfigText_merge_unitTest._run_merge
def _run_merge(dict top_cfg, pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:30
python.ConfigText_merge_unitTest.case_single_string_include
def case_single_string_include(pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:93
str
Definition: BTagTrackIpAccessor.cxx:11
python.ConfigText_merge_unitTest.run_case
def run_case(str name, pathlib.Path base_dir)
Definition: ConfigText_merge_unitTest.py:119
python.ConfigText_merge_unitTest.main
def main()
Definition: ConfigText_merge_unitTest.py:143