1 # Copyright 2013-2016 Intel Corporation
2 # Copyright 2013, 2014 Advanced Micro Devices
3 # Copyright 2014 VMWare
5 # Permission is hereby granted, free of charge, to any person obtaining a copy
6 # of this software and associated documentation files (the "Software"), to deal
7 # in the Software without restriction, including without limitation the rights
8 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 # copies of the Software, and to permit persons to whom the Software is
10 # furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included in
13 # all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 """Genrate html summaries."""
25 from __future__
import (
26 absolute_import
, division
, print_function
, unicode_literals
36 from mako
.lookup
import TemplateLookup
39 # a local variable status exists, prevent accidental overloading by renaming
41 from framework
import backends
, exceptions
, core
43 from .common
import Results
, escape_filename
, escape_pathname
44 from .feature
import FeatResults
51 _TEMP_DIR
= os
.path
.join(
52 tempfile
.gettempdir(),
54 'python-{}'.format(sys
.version
.split()[0]),
55 'mako-{}'.format(mako
.__version
__),
59 _TEMPLATE_DIR
= os
.path
.join(os
.path
.dirname(__file__
), '../..', 'templates')
61 # To ease the bytes/str/uincode between python 2 and python 3 the
62 # output_encoding keyword is set below. This means that in both python 2 and 3
63 # bytes are returned. This means that the files need to be opened in bytes mode
65 _TEMPLATES
= TemplateLookup(
67 output_encoding
='utf-8',
68 module_directory
=os
.path
.join(_TEMP_DIR
, "html-summary"))
71 def _copy_static_files(destination
):
72 """Copy static files into the results directory."""
73 shutil
.copy(os
.path
.join(_TEMPLATE_DIR
, "index.css"),
74 os
.path
.join(destination
, "index.css"))
75 shutil
.copy(os
.path
.join(_TEMPLATE_DIR
, "result.css"),
76 os
.path
.join(destination
, "result.css"))
79 def _make_testrun_info(results
, destination
, exclude
=None):
80 """Create the pages for each results file."""
81 exclude
= exclude
or {}
82 result_css
= os
.path
.join(destination
, "result.css")
83 index
= os
.path
.join(destination
, "index.html")
85 for each
in results
.results
:
86 name
= escape_pathname(each
.name
)
88 core
.check_dir(os
.path
.join(destination
, name
), True)
89 except exceptions
.PiglitException
:
90 raise exceptions
.PiglitFatalError(
91 'Two or more of your results have the same "name" '
92 'attribute. Try changing one or more of the "name" '
93 'values in your json files.\n'
94 'Duplicate value: {}'.format(name
))
96 with
open(os
.path
.join(destination
, name
, "index.html"), 'wb') as out
:
97 out
.write(_TEMPLATES
.get_template('testrun_info.mako').render(
99 totals
=each
.totals
['root'],
100 time
=each
.time_elapsed
.delta
,
101 options
=each
.options
,
103 glxinfo
=each
.glxinfo
,
107 # Then build the individual test results
108 for key
, value
in six
.iteritems(each
.tests
):
109 html_path
= os
.path
.join(destination
, name
,
110 escape_filename(key
+ ".html"))
111 temp_path
= os
.path
.dirname(html_path
)
113 if value
.result
not in exclude
:
114 core
.check_dir(temp_path
)
116 with
open(html_path
, 'wb') as out
:
117 out
.write(_TEMPLATES
.get_template(
118 'test_result.mako').render(
121 css
=os
.path
.relpath(result_css
, temp_path
),
122 index
=os
.path
.relpath(index
, temp_path
)))
125 def _make_comparison_pages(results
, destination
, exclude
):
126 """Create the pages of comparisons."""
127 pages
= frozenset(['changes', 'problems', 'skips', 'fixes',
128 'regressions', 'enabled', 'disabled'])
130 # Index.html is a bit of a special case since there is index, all, and
131 # alltests, where the other pages all use the same name. ie,
132 # changes.html, changes, and page=changes.
133 with
open(os
.path
.join(destination
, "index.html"), 'wb') as out
:
134 out
.write(_TEMPLATES
.get_template('index.mako').render(
140 # Generate the rest of the pages
142 with
open(os
.path
.join(destination
, page
+ '.html'), 'wb') as out
:
143 # If there is information to display display it
144 if sum(getattr(results
.counts
, page
)) > 0:
145 out
.write(_TEMPLATES
.get_template('index.mako').render(
150 # otherwise provide an empty page
153 _TEMPLATES
.get_template('empty_status.mako').render(
154 page
=page
, pages
=pages
))
157 def _make_feature_info(results
, destination
):
158 """Create the feature readiness page."""
160 with
open(os
.path
.join(destination
, "feature.html"), 'wb') as out
:
161 out
.write(_TEMPLATES
.get_template('feature.mako').render(
165 def html(results
, destination
, exclude
):
167 Produce HTML summaries.
169 Basically all this does is takes the information provided by the
170 constructor, and passes it to mako templates to generate HTML files.
171 The beauty of this approach is that mako is leveraged to do the
172 heavy lifting, this method just passes it a bunch of dicts and lists
173 of dicts, which mako turns into pretty HTML.
175 results
= Results([backends
.load(i
) for i
in results
])
177 _copy_static_files(destination
)
178 _make_testrun_info(results
, destination
, exclude
)
179 _make_comparison_pages(results
, destination
, exclude
)
182 def feat(results
, destination
, feat_desc
):
183 """Produce HTML feature readiness summary."""
185 feat_res
= FeatResults([backends
.load(i
) for i
in results
], feat_desc
)
187 _copy_static_files(destination
)
188 _make_testrun_info(feat_res
, destination
)
189 _make_feature_info(feat_res
, destination
)