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