2 # Permission is hereby granted, free of charge, to any person
3 # obtaining a copy of this software and associated documentation
4 # files (the "Software"), to deal in the Software without
5 # restriction, including without limitation the rights to use,
6 # copy, modify, merge, publish, distribute, sublicense, and/or
7 # sell copies of the Software, and to permit persons to whom the
8 # Software is furnished to do so, subject to the following
11 # This permission notice shall be included in all copies or
12 # substantial portions of the Software.
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
15 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
16 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR(S) BE
18 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 # OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 # DEALINGS IN THE SOFTWARE.
26 import os
.path
as path
30 from framework
import summary
, status
, core
, backends
, exceptions
42 DEFAULT_FMT_STR
="{name} ::: {time} ::: {returncode} ::: {result}"
46 # Make a copy of the status text list and add all. This is used as the
47 # argument list for -e/--exclude
48 statuses
= set(str(s
) for s
in status
.ALL
)
51 """Combine files in a tests/ directory into a single results file."""
52 unparsed
= parsers
.parse_config(input_
)[1]
54 # Adding the parent is necissary to get the help options
55 parser
= argparse
.ArgumentParser(parents
=[parsers
.CONFIG
])
56 parser
.add_argument("-o", "--overwrite",
58 help="Overwrite existing directories")
59 parser
.add_argument("-l", "--list",
61 help="Load a newline separated list of results. These "
62 "results will be prepended to any Results "
63 "specified on the command line")
64 parser
.add_argument("-e", "--exclude-details",
68 help="Optionally exclude the generation of HTML pages "
69 "for individual test pages with the status(es) "
70 "given as arguments. This speeds up HTML "
71 "generation, but reduces the info in the HTML "
72 "pages. May be used multiple times")
73 parser
.add_argument("summaryDir",
74 metavar
="<Summary Directory>",
75 help="Directory to put HTML files in")
76 parser
.add_argument("resultsFiles",
77 metavar
="<Results Files>",
79 help="Results files to include in HTML")
80 args
= parser
.parse_args(unparsed
)
82 # If args.list and args.resultsFiles are empty, then raise an error
83 if not args
.list and not args
.resultsFiles
:
84 raise parser
.error("Missing required option -l or <resultsFiles>")
86 # Convert the exclude_details list to status objects, without this using
87 # the -e option will except
88 if args
.exclude_details
:
89 # If exclude-results has all, then change it to be all
90 if 'all' in args
.exclude_details
:
91 args
.exclude_details
= status
.ALL
93 args
.exclude_details
= frozenset(
94 status
.status_lookup(i
) for i
in args
.exclude_details
)
97 # if overwrite is requested delete the output directory
98 if path
.exists(args
.summaryDir
) and args
.overwrite
:
99 shutil
.rmtree(args
.summaryDir
)
101 # If the requested directory doesn't exist, create it or throw an error
103 core
.check_dir(args
.summaryDir
, not args
.overwrite
)
104 except exceptions
.PiglitException
:
105 raise exceptions
.PiglitFatalError(
106 '{} already exists.\n'
107 'use -o/--overwrite if you want to overwrite it.'.format(
110 # Merge args.list and args.resultsFiles
112 args
.resultsFiles
.extend(core
.parse_listfile(args
.list))
114 # Create the HTML output
115 summary
.html(args
.resultsFiles
, args
.summaryDir
, args
.exclude_details
)
120 """Combine files in a tests/ directory into a single results file."""
121 unparsed
= parsers
.parse_config(input_
)[1]
123 # Adding the parent is necessary to get the help options
124 parser
= argparse
.ArgumentParser(parents
=[parsers
.CONFIG
])
126 # Set the -d and -s options as exclusive, since it's silly to call for diff
127 # and then call for only summary
128 excGroup1
= parser
.add_mutually_exclusive_group()
129 excGroup1
.add_argument("-d", "--diff",
130 action
="store_const",
133 help="Only display the differences between multiple "
135 excGroup1
.add_argument("-s", "--summary",
136 action
="store_const",
139 help="Only display the summary, not the individual "
141 excGroup1
.add_argument("-g", "--fixes",
142 action
="store_const",
145 help="Only display tests that have been fixed.")
146 excGroup1
.add_argument("-i", "--incomplete",
147 action
="store_const",
150 help="Only display tests that are incomplete.")
151 excGroup1
.add_argument("-p", "--problems",
152 action
="store_const",
155 help="Only display tests that had problems.")
156 excGroup1
.add_argument("-r", "--regressions",
157 action
="store_const",
160 help="Only display tests that regressed.")
161 parser
.add_argument("-l", "--list",
163 help="Use test results from a list file")
164 parser
.add_argument("results",
165 metavar
="<Results Path(s)>",
167 help="Space separated paths to at least one results "
169 args
= parser
.parse_args(unparsed
)
171 # Throw an error if -d/--diff is called, but only one results file is
173 if args
.mode
== 'diff' and len(args
.results
) < 2:
174 parser
.error('-d/--diff cannot be specified unless two or more '
175 'results files are specified')
177 # make list of results
179 args
.results
.extend(core
.parse_listfile(args
.list))
181 # Generate the output
182 summary
.console(args
.results
, args
.mode
or 'all')
187 format_string
="{name},{time},{returncode},{result}"
188 return formatted(input_
, default_format_string
=format_string
)
191 def formatted(input_
, default_format_string
=DEFAULT_FMT_STR
):
192 # Make a copy of the status text list and add all. This is used as the
193 # argument list for -e/--exclude
194 statuses
= set(str(s
) for s
in status
.ALL
)
196 unparsed
= parsers
.parse_config(input_
)[1]
198 # Adding the parent is necissary to get the help options
199 parser
= argparse
.ArgumentParser(parents
=[parsers
.CONFIG
])
200 parser
.add_argument("--format",
201 dest
="format_string",
202 metavar
="<format string>",
203 default
=default_format_string
,
205 help="A template string that defines the format. "
206 "Replacement tokens are {name}, {time}, "
207 "{returncode} and {result}")
208 parser
.add_argument("-e", "--exclude-details",
212 help="Optionally exclude the listing of tests with "
213 "the status(es) given as arguments. "
214 "May be used multiple times")
215 parser
.add_argument("-o", "--output",
216 metavar
="<Output File>",
220 help="Output filename")
221 parser
.add_argument("test_results",
222 metavar
="<Input Files>",
223 help="JSON results file to be converted")
224 args
= parser
.parse_args(unparsed
)
226 testrun
= backends
.load(args
.test_results
)
228 def write_results(output
):
229 for name
, result
in testrun
.tests
.items():
230 if result
.result
in args
.exclude_details
:
232 output
.write((args
.format_string
+ "\n").format(
234 time
=result
.time
.total
,
235 returncode
=result
.returncode
,
236 result
=result
.result
))
238 if args
.output
!= "stdout":
239 with
open(args
.output
, 'w') as output
:
240 write_results(output
)
242 write_results(sys
.stdout
)
246 def aggregate(input_
):
247 """Combine files in a tests/ directory into a single results file."""
248 unparsed
= parsers
.parse_config(input_
)[1]
250 # Adding the parent is necissary to get the help options
251 parser
= argparse
.ArgumentParser(parents
=[parsers
.CONFIG
])
252 parser
.add_argument('results_folder',
254 metavar
="<results path>",
255 help="Path to a results directory "
256 "(which contains a tests directory)")
257 parser
.add_argument('-o', '--output',
258 default
="results.json",
259 help="name of output file. Default: results.json")
260 args
= parser
.parse_args(unparsed
)
262 assert os
.path
.isdir(args
.results_folder
)
264 # args.results_folder must be a path with a 'tests' directory in it, not
265 # the tests directory itself.
266 outfile
= os
.path
.join(args
.results_folder
, args
.output
)
268 results
= backends
.load(args
.results_folder
)
269 except backends
.BackendError
:
270 raise exceptions
.PiglitFatalError(
271 'Cannot find a tests directory to aggregate in {}.\n'
272 'Are you you sure that you pointed to '
273 'a results directory (not results/tests)?'.format(args
.results_folder
))
276 use_compression
= backends
.write(results
, outfile
)
278 if e
.errno
== errno
.EPERM
:
279 raise exceptions
.PiglitFatalError(
280 "Unable to write aggregated file, permission denied.")
283 mode
= backends
.compression
.get_mode() if use_compression
else 'none'
284 comp_ext
= '.{}'.format(mode
) if mode
!= 'none' else ''
285 print("Aggregated file written to: {}{}".format(outfile
, comp_ext
))
290 parser
= argparse
.ArgumentParser()
291 parser
.add_argument("-o", "--overwrite",
293 help="Overwrite existing directories")
294 parser
.add_argument("featureFile",
295 metavar
="<Feature json file>",
296 help="Json file containing the features description")
297 parser
.add_argument("summaryDir",
298 metavar
="<Summary Directory>",
299 help="Directory to put HTML files in")
300 parser
.add_argument("resultsFiles",
301 metavar
="<Results Files>",
303 help="Results files to include in HTML")
304 args
= parser
.parse_args(input_
)
306 # If args.list and args.resultsFiles are empty, then raise an error
307 if not args
.featureFile
and not args
.resultsFiles
:
308 raise parser
.error("Missing required option -l or <resultsFiles>")
310 # If args.list and args.resultsFiles are empty, then raise an error
311 if not args
.resultsFiles
or not path
.exists(args
.featureFile
):
312 raise parser
.error("Missing json file")
314 # if overwrite is requested delete the output directory
315 if path
.exists(args
.summaryDir
) and args
.overwrite
:
316 shutil
.rmtree(args
.summaryDir
)
318 # If the requested directory doesn't exist, create it or throw an error
320 core
.check_dir(args
.summaryDir
, not args
.overwrite
)
321 except exceptions
.PiglitException
:
322 raise exceptions
.PiglitFatalError(
323 '{} already exists.\n'
324 'use -o/--overwrite if you want to overwrite it.'.format(
327 summary
.feat(args
.resultsFiles
, args
.summaryDir
, args
.featureFile
)