Belle II Software development
test_backends.py
1#!/usr/bin/env python3
2
3
10
11"""
12Script that tests the various `caf.backends` and some options that are available.
13This cannot be run as a normal unit test because not all backends are available on the
14DESY cloud servers. So the only think we can do is test them individually on machines that
15do have the backends installed.
16"""
17
18from caf import cli
19from caf.backends import Job, monitor_jobs, Local
20from pathlib import Path
21import basf2
22from basf2 import find_file
23
24# Prevent ROOT inserting its own help text and arguments
25import ROOT
26ROOT.PyConfig.IgnoreCommandLineOptions = True
27
28
29test_script = Path(
30 find_file("calibration/examples/job_submission/test_script.sh"))
31test_basf2_script = Path(
32 find_file("calibration/examples/job_submission/basic_basf2.py"))
33test_data = Path(find_file("calibration/examples/job_submission/test_data"))
34
35
36def 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
42def 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
81def 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)
91 cli.add_job_options(subparser)
92 return parser
93
94
95def 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
110if __name__ == "__main__":
111 import sys
112 sys.exit(main())
def add_monitor_options(parser, default_heartbeat=10)
Definition: cli.py:109
def add_job_options(parser)
Definition: cli.py:120
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
Definition: main.py:1