ATLAS Offline Software
Tools/WorkflowTestRunner/python/Test.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 from enum import Enum
3 from logging import Logger
4 from os import environ
5 from pathlib import Path
6 from typing import List, Optional
7 from uuid import uuid4
8 import subprocess
9 
10 from .Helpers import get_release_setup, list_changed_packages
11 from .Inputs import references_CVMFS_path, references_override_url
12 from .References import references_map
13 
14 
15 class TestSetup:
16  """Test setup."""
17 
18  def __init__(self, logger: Logger) -> None:
19  self.logger = logger
20  self.validation_run_path = Path.cwd()
21  self.reference_run_path = Path("/tmp")
22  self.diff_rules_path = None
23  self.unique_ID = str(uuid4())
24  self.disable_release_setup = False
25  self.validation_only = False
26  self.run_only = False
27  self.checks_only = False
30  self.release_ID = "main" # The following is not flexible enough, can probably be hardcoded: environ["AtlasVersion"][0:4]
31  self.parallel_execution = False
32  self.disable_output_checks = False
33  self.custom_threads = None
34  self.detailed_comparison = False
35 
36  def setup_release(self, reference=None, validation=None) -> None:
37  if reference and validation:
38  self.release_reference = reference
39  self.release_validation = validation
40  self.logger.info(f"WARNING: You have specified a dedicated release as reference {reference} and as validation {validation} release.")
41  self.logger.info("Your local setup area will not be considered!!!")
42  self.logger.info("this option is mainly designed for comparing release versions!!")
43  elif reference:
44  self.release_reference = reference
45  self.release_validation = ''
46  self.logger.info(f"You have specified a dedicated release as reference {reference}.")
47  else:
50  try:
52  except Exception:
53  self.logger.warning("Cannot list changed packages...\n")
54 
55 
56 class WorkflowRun(Enum):
57  Run2 = "Run2"
58  Run3 = "Run3"
59  Run4 = "Run4"
60 
61  def __str__(self):
62  return self.name
63 
64 
65 class WorkflowType(Enum):
66  Generation = "Generation"
67  FullSim = "FullSim"
68  AF3 = "AF3"
69  HitsMerge = "HitsMerge"
70  HitsFilter = "HitsFilter"
71  MCOverlay = "MCOverlay"
72  DataOverlay = "DataOverlay"
73  MCReco = "MCReco"
74  MCPileUpReco = "MCPileUpReco"
75  DataReco = "DataReco"
76  PileUpPresampling = "PileUpPresampling"
77  Derivation = "Derivation"
78 
79  def __str__(self):
80  return self.name
81 
82 
84  """Workflow check base class."""
85 
86  def __init__(self, setup: TestSetup) -> None:
87  self.setup = setup
88  self.logger = setup.logger
89 
90  def reference_file(self, test: "WorkflowTest", file_name: str) -> Optional[Path]:
91  reference_path: Path = test.reference_path
92  reference_file = reference_path / file_name
93 
94  # Read references from CVMFS
95  if self.setup.validation_only:
96  # Resolve the subfolder first. Results are stored like: main_folder/branch/test/version/.
97  reference_revision = references_map[f"{test.ID}"]
98  cvmfs_path = Path(references_CVMFS_path)
99  rel_path = Path(self.setup.release_ID) / test.ID / reference_revision
100  reference_path = cvmfs_path / rel_path
101  reference_file = reference_path / file_name
102 
103  if not reference_path.exists():
104  self.logger.error(f"CVMFS reference location {reference_path} does not exist!")
105  return None
106 
107  if references_override_url is not None:
108  import requests
109 
110  url = references_override_url
111  if not url.endswith("/"): url += "/"
112  url += str(rel_path / file_name)
113  self.logger.info("Checking for reference override at %s", url)
114  if requests.head(url).ok: # file exists at url
115  reference_file = Path.cwd() / f"reference_{file_name}"
116  self.logger.info("Downloading reference from %s to %s", url, reference_file)
117  r = requests.get(url, stream=True)
118  with reference_file.open('wb') as f:
119  for chunk in r.iter_content(chunk_size=1024):
120  if chunk: # filter out keep-alive new chunks
121  f.write(chunk)
122  else:
123  self.logger.info("No reference override found")
124 
125  return reference_file
126 
127 
129  """Workflow test base class."""
130 
131  def __init__(self, ID: str, run: WorkflowRun, type: WorkflowType, steps: List[str], setup: TestSetup) -> None:
132  if not hasattr(self, "ID"):
133  self.ID = ID
134 
135  if not hasattr(self, "tag"):
136  self.tag = ID
137 
138  if not hasattr(self, "steps"):
139  self.steps = steps
140 
141  if not self.command:
142  raise NotImplementedError("Command needs to be defined")
143 
144  if not hasattr(self, "output_checks"):
145  self.output_checks = []
146 
147  if not hasattr(self, "digest_checks"):
148  self.digest_checks = []
149 
150  if not hasattr(self, "skip_performance_checks"):
152 
153  self.run = run
154  self.type = type
155  self.setup = setup
156  self.logger = setup.logger
157  self.validation_path: Path = self.setup.validation_run_path / f"run_{self.ID}"
158  self.reference_path: Path = self.setup.reference_run_path / f"run_{self.ID}"
159 
160  def run_reference(self) -> None:
161  self.logger.info(f"Running reference in rel {self.setup.release_reference}")
162  self.logger.info(f"\"{self.command}\"")
163 
164  self.reference_path.mkdir(parents=True, exist_ok=True)
165 
166  cmd = (f"cd {self.reference_path};"
167  f"source $AtlasSetup/scripts/asetup.sh {self.setup.release_reference} >& /dev/null;")
168  cmd += f"TRF_NOECHO=1 {self.command} > {self.ID}.log 2>&1"
169 
170  subprocess.call(cmd, shell=True)
171 
172  self.logger.info(f"Finished clean in rel {self.setup.release_reference}")
173  self.logger.info(f"\"{self.command}\"")
174 
175  def run_validation(self) -> None:
176  self.logger.info(f"Running validation in rel {self.setup.release_validation}")
177  self.logger.info(f"\"{self.command}\"")
178 
179  self.validation_path.mkdir(parents=True, exist_ok=True)
180 
181  cmd = f"cd {self.validation_path};"
182  if self.setup.disable_release_setup or not self.setup.release_validation:
183  pass
184  elif "WorkDir_DIR" in environ:
185  cmake_build_dir = environ["WorkDir_DIR"]
186  cmd += (f"source $AtlasSetup/scripts/asetup.sh {self.setup.release_validation} >& /dev/null;"
187  f"source {cmake_build_dir}/setup.sh;")
188  else:
189  cmd += f"source $AtlasSetup/scripts/asetup.sh {self.setup.release_validation} >& /dev/null;"
190  cmd += f"TRF_NOECHO=1 {self.command} > {self.ID}.log 2>&1"
191 
192  subprocess.call(cmd, shell=True)
193 
194  self.logger.info(f"Finished validation in rel {self.setup.release_validation}")
195  self.logger.info(f"\"{self.command}\"")
196 
197  def run_checks(self, performance_checks: List[WorkflowCheck]) -> bool:
198  self.logger.info("-----------------------------------------------------")
199  self.logger.info(f"----------- Post-processing of {self.ID} Test -----------")
200  result = True
201 
202  # digest checks
203  for check in self.digest_checks:
204  result = check.run(self) and result
205 
206  # output checks
207  if not self.setup.disable_output_checks:
208  for check in self.output_checks:
209  result = check.run(self) and result
210 
211  if self.setup.validation_only or self.skip_performance_checks:
212  return result # Performance checks against static references not possible
213 
214  # performance checks
215  for check in performance_checks:
216  result = check.run(self) and result
217 
218  return result
grepfile.info
info
Definition: grepfile.py:38
python.Helpers.get_release_setup
str get_release_setup(Logger logger, no_setup=False)
Definition: Tools/WorkflowTestRunner/python/Helpers.py:9
python.Test.TestSetup.logger
logger
Definition: Tools/WorkflowTestRunner/python/Test.py:19
python.Test.WorkflowCheck
Definition: Tools/WorkflowTestRunner/python/Test.py:83
python.Test.TestSetup.custom_threads
custom_threads
Definition: Tools/WorkflowTestRunner/python/Test.py:33
plot_material.mkdir
def mkdir(path, recursive=True)
Definition: plot_material.py:16
python.Test.WorkflowCheck.setup
setup
Definition: Tools/WorkflowTestRunner/python/Test.py:87
python.Helpers.list_changed_packages
None list_changed_packages(Logger logger, no_setup=False)
Definition: Tools/WorkflowTestRunner/python/Helpers.py:41
python.Test.TestSetup.validation_run_path
validation_run_path
Definition: Tools/WorkflowTestRunner/python/Test.py:20
python.Test.TestSetup
Definition: Tools/WorkflowTestRunner/python/Test.py:15
python.Test.TestSetup.detailed_comparison
detailed_comparison
Definition: Tools/WorkflowTestRunner/python/Test.py:34
python.Test.TestSetup.checks_only
checks_only
Definition: Tools/WorkflowTestRunner/python/Test.py:27
python.Test.TestSetup.disable_release_setup
disable_release_setup
Definition: Tools/WorkflowTestRunner/python/Test.py:24
python.Test.WorkflowTest.skip_performance_checks
skip_performance_checks
Definition: Tools/WorkflowTestRunner/python/Test.py:151
python.Test.TestSetup.release_ID
release_ID
Definition: Tools/WorkflowTestRunner/python/Test.py:30
python.Test.WorkflowTest.output_checks
output_checks
Definition: Tools/WorkflowTestRunner/python/Test.py:145
python.Test.TestSetup.__init__
None __init__(self, Logger logger)
Definition: Tools/WorkflowTestRunner/python/Test.py:18
python.Test.TestSetup.validation_only
validation_only
Definition: Tools/WorkflowTestRunner/python/Test.py:25
python.Test.WorkflowType.__str__
def __str__(self)
Definition: Tools/WorkflowTestRunner/python/Test.py:79
python.Test.WorkflowRun.__str__
def __str__(self)
Definition: Tools/WorkflowTestRunner/python/Test.py:61
python.Test.WorkflowCheck.logger
logger
Definition: Tools/WorkflowTestRunner/python/Test.py:88
python.Test.TestSetup.release_reference
release_reference
Definition: Tools/WorkflowTestRunner/python/Test.py:28
python.Test.WorkflowTest.digest_checks
digest_checks
Definition: Tools/WorkflowTestRunner/python/Test.py:148
python.Test.WorkflowType
Definition: Tools/WorkflowTestRunner/python/Test.py:65
python.Test.TestSetup.run_only
run_only
Definition: Tools/WorkflowTestRunner/python/Test.py:26
python.Test.TestSetup.unique_ID
unique_ID
Definition: Tools/WorkflowTestRunner/python/Test.py:23
python.Test.TestSetup.diff_rules_path
diff_rules_path
Definition: Tools/WorkflowTestRunner/python/Test.py:22
python.Test.WorkflowTest.run_checks
bool run_checks(self, List[WorkflowCheck] performance_checks)
Definition: Tools/WorkflowTestRunner/python/Test.py:197
python.Test.WorkflowRun
Definition: Tools/WorkflowTestRunner/python/Test.py:56
python.Test.WorkflowTest.tag
tag
Definition: Tools/WorkflowTestRunner/python/Test.py:136
python.Test.TestSetup.disable_output_checks
disable_output_checks
Definition: Tools/WorkflowTestRunner/python/Test.py:32
python.Test.WorkflowTest.run_validation
None run_validation(self)
Definition: Tools/WorkflowTestRunner/python/Test.py:175
python.Test.TestSetup.parallel_execution
parallel_execution
Definition: Tools/WorkflowTestRunner/python/Test.py:31
python.Test.TestSetup.release_validation
release_validation
Definition: Tools/WorkflowTestRunner/python/Test.py:29
python.Test.WorkflowTest
Definition: Tools/WorkflowTestRunner/python/Test.py:128
python.Test.WorkflowTest.run_reference
None run_reference(self)
Definition: Tools/WorkflowTestRunner/python/Test.py:160
python.Test.WorkflowCheck.reference_file
Optional[Path] reference_file(self, "WorkflowTest" test, str file_name)
Definition: Tools/WorkflowTestRunner/python/Test.py:90
python.Test.TestSetup.reference_run_path
reference_run_path
Definition: Tools/WorkflowTestRunner/python/Test.py:21
python.Test.WorkflowTest.__init__
None __init__(self, str ID, WorkflowRun run, WorkflowType type, List[str] steps, TestSetup setup)
Definition: Tools/WorkflowTestRunner/python/Test.py:131
python.Test.WorkflowTest.ID
ID
Definition: Tools/WorkflowTestRunner/python/Test.py:133
python.Test.WorkflowTest.logger
logger
Definition: Tools/WorkflowTestRunner/python/Test.py:156
str
Definition: BTagTrackIpAccessor.cxx:11
python.Test.WorkflowTest.type
type
Definition: Tools/WorkflowTestRunner/python/Test.py:154
error
Definition: IImpactPoint3dEstimator.h:70
python.Test.TestSetup.setup_release
None setup_release(self, reference=None, validation=None)
Definition: Tools/WorkflowTestRunner/python/Test.py:36
python.Test.WorkflowTest.setup
setup
Definition: Tools/WorkflowTestRunner/python/Test.py:155
python.Test.WorkflowCheck.__init__
None __init__(self, TestSetup setup)
Definition: Tools/WorkflowTestRunner/python/Test.py:86
python.Test.WorkflowTest.steps
steps
Definition: Tools/WorkflowTestRunner/python/Test.py:139
python.Test.WorkflowTest.run
run
Definition: Tools/WorkflowTestRunner/python/Test.py:153