1#!/usr/bin/env python3
2import argparse
3import multiprocessing
4import os
5import sys
6
7import nose2
8
9from infra.basetest import BRConfigTest
10
11import infra
12
13
14def main():
15    parser = argparse.ArgumentParser(description='Run Buildroot tests')
16    parser.add_argument('testname', nargs='*',
17                        help='list of test cases to execute')
18    parser.add_argument('-l', '--list', action='store_true',
19                        help='list of available test cases')
20    parser.add_argument('-a', '--all', action='store_true',
21                        help='execute all test cases')
22    parser.add_argument('-s', '--stdout', action='store_true',
23                        help='log everything to stdout')
24    parser.add_argument('-o', '--output',
25                        help='output directory')
26    parser.add_argument('-d', '--download',
27                        help='download directory')
28    parser.add_argument('-p', '--prepare-only', action='store_true',
29                        help='download emulator builtin binaries')
30    parser.add_argument('-k', '--keep',
31                        help='keep build directories',
32                        action='store_true')
33    parser.add_argument('-t', '--testcases', type=int, default=1,
34                        help='number of testcases to run simultaneously')
35    parser.add_argument('-j', '--jlevel', type=int,
36                        help='BR2_JLEVEL to use for each testcase')
37    parser.add_argument('--timeout-multiplier', type=int, default=1,
38                        help='increase timeouts (useful for slow machines)')
39
40    args = parser.parse_args()
41
42    script_path = os.path.realpath(__file__)
43    test_dir = os.path.dirname(script_path)
44
45    if args.stdout:
46        BRConfigTest.logtofile = False
47
48    if args.list:
49        print("List of tests")
50        nose2.discover(argv=[script_path,
51                             "-s", test_dir,
52                             "-v",
53                             "--collect-only"],
54                       plugins=["nose2.plugins.collect"])
55        return 0
56
57    if args.download is None:
58        args.download = os.getenv("BR2_DL_DIR")
59        if args.download is None:
60            print("Missing download directory, please use -d/--download")
61            print("")
62            parser.print_help()
63            return 1
64
65    BRConfigTest.downloaddir = os.path.abspath(args.download)
66
67    if args.prepare_only:
68        emulator_builtin_binaries = ["kernel-vexpress-5.10.202",
69                                     "vexpress-v2p-ca9-5.10.202.dtb",
70                                     "kernel-versatile-5.10.202",
71                                     "versatile-pb-5.10.202.dtb"]
72        print("Downloading emulator builtin binaries")
73        for binary in emulator_builtin_binaries:
74            infra.download(BRConfigTest.downloaddir, binary)
75        return 0
76
77    if args.output is None:
78        print("Missing output directory, please use -o/--output")
79        print("")
80        parser.print_help()
81        return 1
82
83    if not os.path.exists(args.output):
84        os.mkdir(args.output)
85
86    BRConfigTest.outputdir = os.path.abspath(args.output)
87
88    if args.all is False and not args.testname:
89        print("No test selected")
90        print("")
91        parser.print_help()
92        return 1
93
94    BRConfigTest.keepbuilds = args.keep
95
96    if args.testcases != 1:
97        if args.testcases < 1:
98            print("Invalid number of testcases to run simultaneously")
99            print("")
100            parser.print_help()
101            return 1
102        # same default BR2_JLEVEL as package/Makefile.in
103        br2_jlevel = 1 + multiprocessing.cpu_count()
104        each_testcase = int((br2_jlevel + args.testcases) / args.testcases)
105        BRConfigTest.jlevel = each_testcase
106
107    if args.jlevel:
108        if args.jlevel < 0:
109            print("Invalid BR2_JLEVEL to use for each testcase")
110            print("")
111            parser.print_help()
112            return 1
113        # the user can override the auto calculated value
114        BRConfigTest.jlevel = args.jlevel
115
116    if args.timeout_multiplier < 1:
117        print("Invalid multiplier for timeout values")
118        print("")
119        parser.print_help()
120        return 1
121    BRConfigTest.timeout_multiplier = args.timeout_multiplier
122
123    nose2_args = ["-v",
124                  "-N", str(args.testcases),
125                  "-s", test_dir,
126                  "-c", os.path.join(test_dir, "conf/unittest.cfg")]
127
128    if args.testname:
129        nose2_args += args.testname
130
131    nose2.discover(argv=nose2_args)
132
133
134if __name__ == "__main__":
135    sys.exit(main())
136