20
20
import kunit_kernel
21
21
import kunit_parser
22
22
23
- KunitResult = namedtuple ('KunitResult' , ['status' ,'result' ])
23
+ KunitResult = namedtuple ('KunitResult' , ['status' ,'result' , 'elapsed_time' ])
24
24
25
+ KunitConfigRequest = namedtuple ('KunitConfigRequest' ,
26
+ ['build_dir' , 'defconfig' , 'make_options' ])
27
+ KunitBuildRequest = namedtuple ('KunitBuildRequest' ,
28
+ ['jobs' , 'build_dir' , 'alltests' ,
29
+ 'make_options' ])
30
+ KunitExecRequest = namedtuple ('KunitExecRequest' ,
31
+ ['timeout' , 'build_dir' , 'alltests' ])
32
+ KunitParseRequest = namedtuple ('KunitParseRequest' ,
33
+ ['raw_output' , 'input_data' ])
25
34
KunitRequest = namedtuple ('KunitRequest' , ['raw_output' ,'timeout' , 'jobs' ,
26
35
'build_dir' , 'defconfig' ,
27
36
'alltests' , 'make_options' ])
@@ -46,14 +55,25 @@ def get_kernel_root_path():
46
55
sys .exit (1 )
47
56
return parts [0 ]
48
57
49
- def run_tests (linux : kunit_kernel .LinuxSourceTree ,
50
- request : KunitRequest ) -> KunitResult :
58
+ def config_tests (linux : kunit_kernel .LinuxSourceTree ,
59
+ request : KunitConfigRequest ) -> KunitResult :
60
+ kunit_parser .print_with_timestamp ('Configuring KUnit Kernel ...' )
61
+
51
62
config_start = time .time ()
63
+ if request .defconfig :
64
+ create_default_kunitconfig ()
52
65
success = linux .build_reconfig (request .build_dir , request .make_options )
53
66
config_end = time .time ()
54
67
if not success :
55
- return KunitResult (KunitStatus .CONFIG_FAILURE , 'could not configure kernel' )
68
+ return KunitResult (KunitStatus .CONFIG_FAILURE ,
69
+ 'could not configure kernel' ,
70
+ config_end - config_start )
71
+ return KunitResult (KunitStatus .SUCCESS ,
72
+ 'configured kernel successfully' ,
73
+ config_end - config_start )
56
74
75
+ def build_tests (linux : kunit_kernel .LinuxSourceTree ,
76
+ request : KunitBuildRequest ) -> KunitResult :
57
77
kunit_parser .print_with_timestamp ('Building KUnit Kernel ...' )
58
78
59
79
build_start = time .time ()
@@ -64,88 +84,174 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
64
84
build_end = time .time ()
65
85
if not success :
66
86
return KunitResult (KunitStatus .BUILD_FAILURE , 'could not build kernel' )
87
+ if not success :
88
+ return KunitResult (KunitStatus .BUILD_FAILURE ,
89
+ 'could not build kernel' ,
90
+ build_end - build_start )
91
+ return KunitResult (KunitStatus .SUCCESS ,
92
+ 'built kernel successfully' ,
93
+ build_end - build_start )
67
94
95
+ def exec_tests (linux : kunit_kernel .LinuxSourceTree ,
96
+ request : KunitExecRequest ) -> KunitResult :
68
97
kunit_parser .print_with_timestamp ('Starting KUnit Kernel ...' )
69
98
test_start = time .time ()
70
- kunit_output = linux .run_kernel (
99
+ result = linux .run_kernel (
71
100
timeout = None if request .alltests else request .timeout ,
72
101
build_dir = request .build_dir )
102
+
103
+ test_end = time .time ()
104
+
105
+ return KunitResult (KunitStatus .SUCCESS ,
106
+ result ,
107
+ test_end - test_start )
108
+
109
+ def parse_tests (request : KunitParseRequest ) -> KunitResult :
110
+ parse_start = time .time ()
111
+
112
+ test_result = kunit_parser .TestResult (kunit_parser .TestStatus .SUCCESS ,
113
+ [],
114
+ 'Tests not Parsed.' )
73
115
if request .raw_output :
74
- raw_output = kunit_parser .raw_output (kunit_output )
75
- isolated = list (kunit_parser .isolate_kunit_output (raw_output ))
76
- test_result = kunit_parser .parse_test_result (isolated )
116
+ kunit_parser .raw_output (request .input_data )
77
117
else :
78
- test_result = kunit_parser .parse_run_tests (kunit_output )
79
- test_end = time .time ()
118
+ test_result = kunit_parser .parse_run_tests (request .input_data )
119
+ parse_end = time .time ()
120
+
121
+ if test_result .status != kunit_parser .TestStatus .SUCCESS :
122
+ return KunitResult (KunitStatus .TEST_FAILURE , test_result ,
123
+ parse_end - parse_start )
124
+
125
+ return KunitResult (KunitStatus .SUCCESS , test_result ,
126
+ parse_end - parse_start )
127
+
128
+
129
+ def run_tests (linux : kunit_kernel .LinuxSourceTree ,
130
+ request : KunitRequest ) -> KunitResult :
131
+ run_start = time .time ()
132
+
133
+ config_request = KunitConfigRequest (request .build_dir ,
134
+ request .defconfig ,
135
+ request .make_options )
136
+ config_result = config_tests (linux , config_request )
137
+ if config_result .status != KunitStatus .SUCCESS :
138
+ return config_result
139
+
140
+ build_request = KunitBuildRequest (request .jobs , request .build_dir ,
141
+ request .alltests ,
142
+ request .make_options )
143
+ build_result = build_tests (linux , build_request )
144
+ if build_result .status != KunitStatus .SUCCESS :
145
+ return build_result
146
+
147
+ exec_request = KunitExecRequest (request .timeout , request .build_dir ,
148
+ request .alltests )
149
+ exec_result = exec_tests (linux , exec_request )
150
+ if exec_result .status != KunitStatus .SUCCESS :
151
+ return exec_result
152
+
153
+ parse_request = KunitParseRequest (request .raw_output ,
154
+ exec_result .result )
155
+ parse_result = parse_tests (parse_request )
156
+
157
+ run_end = time .time ()
80
158
81
159
kunit_parser .print_with_timestamp ((
82
160
'Elapsed time: %.3fs total, %.3fs configuring, %.3fs ' +
83
161
'building, %.3fs running\n ' ) % (
84
- test_end - config_start ,
85
- config_end - config_start ,
86
- build_end - build_start ,
87
- test_end - test_start ))
162
+ run_end - run_start ,
163
+ config_result .elapsed_time ,
164
+ build_result .elapsed_time ,
165
+ exec_result .elapsed_time ))
166
+ return parse_result
167
+
168
+ def add_common_opts (parser ):
169
+ parser .add_argument ('--build_dir' ,
170
+ help = 'As in the make command, it specifies the build '
171
+ 'directory.' ,
172
+ type = str , default = '' , metavar = 'build_dir' )
173
+ parser .add_argument ('--make_options' ,
174
+ help = 'X=Y make option, can be repeated.' ,
175
+ action = 'append' )
176
+ parser .add_argument ('--alltests' ,
177
+ help = 'Run all KUnit tests through allyesconfig' ,
178
+ action = 'store_true' )
179
+
180
+ def add_config_opts (parser ):
181
+ parser .add_argument ('--defconfig' ,
182
+ help = 'Uses a default .kunitconfig.' ,
183
+ action = 'store_true' )
184
+
185
+ def add_build_opts (parser ):
186
+ parser .add_argument ('--jobs' ,
187
+ help = 'As in the make command, "Specifies the number of '
188
+ 'jobs (commands) to run simultaneously."' ,
189
+ type = int , default = 8 , metavar = 'jobs' )
190
+
191
+ def add_exec_opts (parser ):
192
+ parser .add_argument ('--timeout' ,
193
+ help = 'maximum number of seconds to allow for all tests '
194
+ 'to run. This does not include time taken to build the '
195
+ 'tests.' ,
196
+ type = int ,
197
+ default = 300 ,
198
+ metavar = 'timeout' )
199
+
200
+ def add_parse_opts (parser ):
201
+ parser .add_argument ('--raw_output' , help = 'don\' t format output from kernel' ,
202
+ action = 'store_true' )
88
203
89
- if test_result .status != kunit_parser .TestStatus .SUCCESS :
90
- return KunitResult (KunitStatus .TEST_FAILURE , test_result )
91
- else :
92
- return KunitResult (KunitStatus .SUCCESS , test_result )
93
204
94
205
def main (argv , linux = None ):
95
206
parser = argparse .ArgumentParser (
96
207
description = 'Helps writing and running KUnit tests.' )
97
208
subparser = parser .add_subparsers (dest = 'subcommand' )
98
209
210
+ # The 'run' command will config, build, exec, and parse in one go.
99
211
run_parser = subparser .add_parser ('run' , help = 'Runs KUnit tests.' )
100
- run_parser . add_argument ( '--raw_output' , help = 'don \' t format output from kernel' ,
101
- action = 'store_true' )
102
-
103
- run_parser . add_argument ( '--timeout' ,
104
- help = 'maximum number of seconds to allow for all tests '
105
- 'to run. This does not include time taken to build the '
106
- 'tests. ' ,
107
- type = int ,
108
- default = 300 ,
109
- metavar = 'timeout' )
110
-
111
- run_parser . add_argument ( '--jobs' ,
112
- help = 'As in the make command, "Specifies the number of '
113
- 'jobs (commands) to run simultaneously."' ,
114
- type = int , default = 8 , metavar = 'jobs' )
115
-
116
- run_parser . add_argument ( '--build_dir' ,
117
- help = 'As in the make command, it specifies the build '
118
- 'directory.' ,
119
- type = str , default = '' , metavar = 'build_dir' )
120
-
121
- run_parser . add_argument ( '--defconfig' ,
122
- help = 'Uses a default .kunitconfig.' ,
123
- action = 'store_true' )
124
-
125
- run_parser . add_argument ( '--alltests ' ,
126
- help = 'Run all KUnit tests through allyesconfig' ,
127
- action = 'store_true ' )
128
-
129
- run_parser .add_argument ('--make_options ' ,
130
- help = 'X=Y make option, can be repeated .' ,
131
- action = 'append ' )
212
+ add_common_opts ( run_parser )
213
+ add_config_opts ( run_parser )
214
+ add_build_opts ( run_parser )
215
+ add_exec_opts ( run_parser )
216
+ add_parse_opts ( run_parser )
217
+
218
+ config_parser = subparser . add_parser ( 'config ' ,
219
+ help = 'Ensures that .config contains all of '
220
+ 'the options in .kunitconfig' )
221
+ add_common_opts ( config_parser )
222
+ add_config_opts ( config_parser )
223
+
224
+ build_parser = subparser . add_parser ( 'build' , help = 'Builds a kernel with KUnit tests' )
225
+ add_common_opts ( build_parser )
226
+ add_build_opts ( build_parser )
227
+
228
+ exec_parser = subparser . add_parser ( 'exec' , help = 'Run a kernel with KUnit tests' )
229
+ add_common_opts ( exec_parser )
230
+ add_exec_opts ( exec_parser )
231
+ add_parse_opts ( exec_parser )
232
+
233
+ # The 'parse' option is special, as it doesn't need the kernel source
234
+ # (therefore there is no need for a build_dir, hence no add_common_opts)
235
+ # and the '--file' argument is not relevant to 'run', so isn't in
236
+ # add_parse_opts()
237
+ parse_parser = subparser . add_parser ( 'parse ' ,
238
+ help = 'Parses KUnit results from a file, '
239
+ 'and parses formatted results. ' )
240
+ add_parse_opts ( parse_parser )
241
+ parse_parser .add_argument ('file ' ,
242
+ help = 'Specifies the file to read results from .' ,
243
+ type = str , nargs = '?' , metavar = 'input_file ' )
132
244
133
245
cli_args = parser .parse_args (argv )
134
246
135
247
if cli_args .subcommand == 'run' :
136
- if get_kernel_root_path ():
137
- os .chdir (get_kernel_root_path ())
138
-
139
248
if cli_args .build_dir :
140
249
if not os .path .exists (cli_args .build_dir ):
141
250
os .mkdir (cli_args .build_dir )
142
251
kunit_kernel .kunitconfig_path = os .path .join (
143
252
cli_args .build_dir ,
144
253
kunit_kernel .kunitconfig_path )
145
254
146
- if cli_args .defconfig :
147
- create_default_kunitconfig ()
148
-
149
255
if not linux :
150
256
linux = kunit_kernel .LinuxSourceTree ()
151
257
@@ -159,6 +265,81 @@ def main(argv, linux=None):
159
265
result = run_tests (linux , request )
160
266
if result .status != KunitStatus .SUCCESS :
161
267
sys .exit (1 )
268
+ elif cli_args .subcommand == 'config' :
269
+ if cli_args .build_dir :
270
+ if not os .path .exists (cli_args .build_dir ):
271
+ os .mkdir (cli_args .build_dir )
272
+ kunit_kernel .kunitconfig_path = os .path .join (
273
+ cli_args .build_dir ,
274
+ kunit_kernel .kunitconfig_path )
275
+
276
+ if not linux :
277
+ linux = kunit_kernel .LinuxSourceTree ()
278
+
279
+ request = KunitConfigRequest (cli_args .build_dir ,
280
+ cli_args .defconfig ,
281
+ cli_args .make_options )
282
+ result = config_tests (linux , request )
283
+ kunit_parser .print_with_timestamp ((
284
+ 'Elapsed time: %.3fs\n ' ) % (
285
+ result .elapsed_time ))
286
+ if result .status != KunitStatus .SUCCESS :
287
+ sys .exit (1 )
288
+ elif cli_args .subcommand == 'build' :
289
+ if cli_args .build_dir :
290
+ if not os .path .exists (cli_args .build_dir ):
291
+ os .mkdir (cli_args .build_dir )
292
+ kunit_kernel .kunitconfig_path = os .path .join (
293
+ cli_args .build_dir ,
294
+ kunit_kernel .kunitconfig_path )
295
+
296
+ if not linux :
297
+ linux = kunit_kernel .LinuxSourceTree ()
298
+
299
+ request = KunitBuildRequest (cli_args .jobs ,
300
+ cli_args .build_dir ,
301
+ cli_args .alltests ,
302
+ cli_args .make_options )
303
+ result = build_tests (linux , request )
304
+ kunit_parser .print_with_timestamp ((
305
+ 'Elapsed time: %.3fs\n ' ) % (
306
+ result .elapsed_time ))
307
+ if result .status != KunitStatus .SUCCESS :
308
+ sys .exit (1 )
309
+ elif cli_args .subcommand == 'exec' :
310
+ if cli_args .build_dir :
311
+ if not os .path .exists (cli_args .build_dir ):
312
+ os .mkdir (cli_args .build_dir )
313
+ kunit_kernel .kunitconfig_path = os .path .join (
314
+ cli_args .build_dir ,
315
+ kunit_kernel .kunitconfig_path )
316
+
317
+ if not linux :
318
+ linux = kunit_kernel .LinuxSourceTree ()
319
+
320
+ exec_request = KunitExecRequest (cli_args .timeout ,
321
+ cli_args .build_dir ,
322
+ cli_args .alltests )
323
+ exec_result = exec_tests (linux , exec_request )
324
+ parse_request = KunitParseRequest (cli_args .raw_output ,
325
+ exec_result .result )
326
+ result = parse_tests (parse_request )
327
+ kunit_parser .print_with_timestamp ((
328
+ 'Elapsed time: %.3fs\n ' ) % (
329
+ exec_result .elapsed_time ))
330
+ if result .status != KunitStatus .SUCCESS :
331
+ sys .exit (1 )
332
+ elif cli_args .subcommand == 'parse' :
333
+ if cli_args .file == None :
334
+ kunit_output = sys .stdin
335
+ else :
336
+ with open (cli_args .file , 'r' ) as f :
337
+ kunit_output = f .read ().splitlines ()
338
+ request = KunitParseRequest (cli_args .raw_output ,
339
+ kunit_output )
340
+ result = parse_tests (request )
341
+ if result .status != KunitStatus .SUCCESS :
342
+ sys .exit (1 )
162
343
else :
163
344
parser .print_help ()
164
345
0 commit comments