Belle II Software  release-08-01-10
test_backends.py
1 #!/usr/bin/env python3
2 
3 
10 
11 """
12 Script that tests the various `caf.backends` and some options that are available.
13 This cannot be run as a normal unit test because not all backends are available on the
14 DESY cloud servers. So the only think we can do is test them individually on machines that
15 do have the backends installed.
16 """
17 
18 from caf import cli
19 from caf.backends import Job, monitor_jobs, Local
20 from pathlib import Path
21 import basf2
22 from basf2 import find_file
23 
24 # Prevent ROOT inserting its own help text and arguments
25 import ROOT
26 ROOT.PyConfig.IgnoreCommandLineOptions = True
27 
28 
29 test_script = Path(
30  find_file("calibration/examples/job_submission/test_script.sh"))
31 test_basf2_script = Path(
32  find_file("calibration/examples/job_submission/basic_basf2.py"))
33 test_data = Path(find_file("calibration/examples/job_submission/test_data"))
34 
35 
36 def test_path_exists(path):
37  if not path.exists():
38  raise FileNotFoundError(
39  f"The expected file {test_script.as_posix()} does not exist.")
40 
41 
42 def create_jobs(args):
43  test_path_exists(test_data)
44  test_path_exists(test_script)
45  test_path_exists(test_basf2_script)
46  output_dir = Path("test_backends_jobs")
47  j1 = Job(name="test_job1")
48  # Working directory that will be sent to the backend and used as the
49  # current working directory
50  j1.working_dir = Path(output_dir, j1.name, "working_dir").absolute()
51  # Output directory, where the stdout and stderr will be sent.
52  j1.output_dir = Path(output_dir, j1.name, "output_dir").absolute()
53  # The command we want to run
54  j1.cmd = ["bash", test_script.name]
55  j1.args = ["first_arg_example", "\"Do quotes work?\""]
56  # We add the script we want to run to the input sandbox so that it is available locally in the working directory.
57  # We could instead simply change the 'cmd' above to always call the same file, but I prefer having the
58  # script copied into the working directory.
59  j1.input_sandbox_files.append(test_script.absolute())
60 
61  j2 = Job(name="test_job2")
62  # Working directory that will be sent to the backend and used as the
63  # current working directory
64  j2.working_dir = Path(output_dir, j2.name).absolute()
65  # Output directory, where the stdout and stderr will be sent. We have set
66  # this to be the same as the working dir
67  j2.output_dir = Path(output_dir, j2.name).absolute()
68  # The command we want to run
69  j2.cmd = ["basf2", test_basf2_script.name]
70  # Setup basf2 in the job the same way as our current basf2 environment
71  j2.append_current_basf2_setup_cmds()
72  j2.input_sandbox_files.append(test_basf2_script.absolute())
73  j2.input_files = sorted(p.as_posix() for p in Path(test_data).glob("*.root"))
74  if args.files_per_subjob:
75  j2.max_files_per_subjob = args.files_per_subjob
76  elif args.max_subjobs:
77  j2.max_subjobs = args.max_subjobs
78  return [j1, j2]
79 
80 
81 def get_argparser():
82  """Setup the argparser for this script"""
83  import argparse
84  parser = argparse.ArgumentParser(
85  formatter_class=argparse.RawTextHelpFormatter)
86 
87  subparsers = cli.add_backends_subparsers(parser)
88  for subparser in subparsers:
89  cli.add_basf2_options(subparser)
90  cli.add_monitor_options(subparser)
91  cli.add_job_options(subparser)
92  return parser
93 
94 
95 def main():
96  parser = get_argparser()
97  args = parser.parse_args()
98  basf2.set_log_level(basf2.LogLevel.names[args.log_level])
99  if args.debug_level:
100  basf2.set_log_level(basf2.LogLevel.DEBUG) # Override
101  basf2.set_debug_level(args.debug_level)
102  jobs = create_jobs(args)
103  backend = args.func(args)
104  backend.submit(jobs)
105  monitor_jobs(args, jobs)
106  if isinstance(backend, Local):
107  backend.join()
108 
109 
110 if __name__ == "__main__":
111  import sys
112  sys.exit(main())
def add_basf2_options(parser, default_log_level="INFO")
Definition: cli.py:98
def add_backends_subparsers(parser, default_max_processes=4, default_global_job_limit=Batch.default_global_job_limit, default_submission_check_heartbeat=Batch.default_sleep_between_submission_checks, local_func=command_local, lsf_func=command_lsf, pbs_func=command_pbs, condor_func=command_condor)
Definition: cli.py:138
def add_job_options(parser)
Definition: cli.py:120
def add_monitor_options(parser, default_heartbeat=10)
Definition: cli.py:109
Definition: main.py:1
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:91