<div dir="ltr">From my reading of the current summary code it doesn't handle cases of malicious tests using shell expansion. <div><br></div><div>On the other hand I'm certain that my code does not do *any* expansion, so you would end up with folders named '/home/foo/tests/~shaders/$HOME/blah/blah/blah.html', since python doesn't expand *anything* implicitly, and I have not used os.path.expandvars() or os.path.expanduser()</div>
<div><br></div><div style>Otherwise I'll make the changes.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, May 25, 2013 at 3:00 AM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 05/17/2013 09:31 AM, Dylan Baker wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
With 10,000+ tests all living in the same folder it can be hard to<br>
identify a single file, especially when trying to work with the HTML<br>
generation itself. This patch changes the behavior so that each test<br>
has a directory tree for the group results with tests under it (ie<br>
spec/GLSL 1.0/foo/bar/test.html)<br>
<br>
A side effect of this is that the group names of tests don't have to be<br>
altered to create a valid name (since the slashes in the group names<br>
just become the slashes in the folder structure) and this was the single<br>
most expensive operation of HTML generation (about 1/3 of the total<br>
time). This is a tidy little speedup.<br>
</blockquote>
<br></div>
I'm nervous about skipping sanitizing of output filenames entirely. It seems kind of dangerous. For example, I could (accidentally or maliciously) create a file named tests/shaders/~.shader_test or tests/shaders/$HOME.frag and it'll automatically create tests of similar names. I suppose since '/' can't be part of a filename, it might work out fine, but I'd rather not have to think about it...<br>
<br>
Regarding the speed, as I mentioned earlier, I think your implementation of sanitizePath could be a lot more efficient. tr/translate would be much faster, for example.<br>
<br>
You could probably also just sanitize it once (instead of twice) and pass the path name around. Dunno.<br>
<br>
I'm not opposed to putting things in subdirectories.<div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Signed-off-by: Dylan Baker <<a href="mailto:baker.dylan.c@gmail.com" target="_blank">baker.dylan.c@gmail.com</a>><br>
---<br>
framework/summary.py | 76 ++++++++++++++++--------------<u></u>----------------<br>
templates/test_result.mako | 6 ++--<br>
2 files changed, 30 insertions(+), 52 deletions(-)<br>
<br>
diff --git a/framework/summary.py b/framework/summary.py<br>
index 867dbad..9f2a924 100644<br>
--- a/framework/summary.py<br>
+++ b/framework/summary.py<br>
@@ -472,8 +472,7 @@ class BuildHTMLIndex(list):<br>
"""<br>
self.append({'type': 'testResult',<br>
'class': text,<br>
- 'href': path.join(self._sanitizePath(<u></u>group),<br>
- self._sanitizePath(href + ".html")),<br>
+ 'href': path.join(group, href + ".html"),<br>
'text': text})<br>
<br>
def _subtestResult(self, group, text):<br>
@@ -489,29 +488,6 @@ class BuildHTMLIndex(list):<br>
'class': text,<br>
'text': text})<br>
<br>
- # This will be removed from here in a later patch<br>
- def _sanitizePath(self, path):<br>
- """<br>
- Private: convert the testname to only contain valid characters for<br>
- a path<br>
-<br>
- This attempts to faithfully reconstruct the output of<br>
- pigli-summary-html.<u></u>testPathToHtmlFilename, but without the use of<br>
- lambda. The advantage to not using lambda is readability, and the<br>
- desire to make future changes to the way that sub-tests are written<br>
- """<br>
- valid_chars = frozenset("_-.%s%s" % (string.ascii_letters,<br>
- string.digits))<br>
- out = []<br>
- for c in path:<br>
- if c in valid_chars:<br>
- out.append(c)<br>
- elif c == "/":<br>
- out.append("__")<br>
- else:<br>
- out.append("_")<br>
- return ''.join(out)<br>
-<br>
<br>
class NewSummary:<br>
"""<br>
@@ -635,10 +611,17 @@ class NewSummary:<br>
output_encoding = "utf-8",<br>
module_directory = ".makotmp")<br>
<br>
+ # Although these are only referenced once, that refernce is in a loop<br>
+ # and they are less expensive to find once and store than find<br>
+ # 10,000+ times<br>
</blockquote>
<br></div></div>
This is kind of a "You don't say" moment - not doing things in a loop is of course faster. I don't think you need to explain it. If you'd like to keep the comment, there's a typo: "reference"<div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ resultCss = path.join(destination, "result.css")<br>
+ index = path.join(destination, "index.html")<br>
+<br>
# Iterate across the tests creating the various test specific files<br>
for each in self.results:<br>
os.mkdir(path.join(<u></u>destination, <a href="http://each.name" target="_blank">each.name</a>))<br>
<br>
+ # Create an index file for each test run<br>
file = open(path.join(destination, <a href="http://each.name" target="_blank">each.name</a>, "index.html"), 'w')<br>
file.write(testindex.render(<u></u>name = <a href="http://each.name" target="_blank">each.name</a>,<br>
time = each.time,<br>
@@ -649,15 +632,32 @@ class NewSummary:<br>
<br>
# Then build the individual test results<br>
for key, value in each.tests.iteritems():<br>
+<br>
+ # This is also improves performance, by cutting the number of<br>
+ # times path.join and path.dirname is by 3, that's 20,000+<br>
+ # times!<br>
</blockquote>
<br></div>
This English is very broken. I'm not sure it needs explaining either.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ tPath = path.join(destination, <a href="http://each.name" target="_blank">each.name</a>, path.dirname(key))<br>
+<br>
+ # os.makedirs is very annoying, it throws an OSError if the<br>
+ # path requested already exists, so do this check to esnure<br>
+ # that it doesn't<br>
+ if not path.exists(tPath):<br>
+ os.makedirs(tPath)<br>
</blockquote>
<br></div>
If you want, you could use checkDir. But this is also fine.<br>
"ensure" (typo)<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
file = open(path.join(destination,<br>
<a href="http://each.name" target="_blank">each.name</a>,<br>
- self._sanitizePath(key + ".html")), 'w')<br>
+ key + ".html"),<br>
+ 'w')<br>
file.write(testfile.render(<u></u>testname = key,<br>
status = value['result'],<br>
returncode = value['returncode'],<br>
time = value['time'],<br>
info = value['info'],<br>
- command = value['command']))<br>
+ command = value['command'],<br>
+ css = path.relpath(resultCss,<br>
+ tPath),<br>
+ index = index))<br>
+<br>
file.close()<br>
</blockquote>
<br></div>
I'd probably use "with open(...) as file:" syntax here, but that's just me...it's your call.<div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
# Finally build the root html files: index, regressions, etc<br>
@@ -811,25 +811,3 @@ class NewSummary:<br>
assert(len(currentStatus) == 1)<br>
<br>
return counts, status<br>
-<br>
- def _sanitizePath(self, path):<br>
- """<br>
- Private: convert the testname to only contain valid characters for<br>
- a path<br>
-<br>
- This attempts to faithfully reconstruct the output of<br>
- pigli-summary-html.<u></u>testPathToHtmlFilename, but without the use of<br>
- lambda. The advantage to not using lambda is readability, and the<br>
- desire to make future changes to the way that sub-tests are written<br>
- """<br>
- valid_chars = frozenset("_-.%s%s" % (string.ascii_letters,<br>
- string.digits))<br>
- out = []<br>
- for c in path:<br>
- if c in valid_chars:<br>
- out.append(c)<br>
- elif c == "/":<br>
- out.append("__")<br>
- else:<br>
- out.append("_")<br>
- return ''.join(out)<br>
diff --git a/templates/test_result.mako b/templates/test_result.mako<br>
index 1f944cb..7de0af7 100644<br>
--- a/templates/test_result.mako<br>
+++ b/templates/test_result.mako<br>
@@ -5,7 +5,7 @@<br>
<head><br>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><br>
<title>${testname} - Details</title><br>
- <link rel="stylesheet" href="../result.css" type="text/css" /><br>
+ <link rel="stylesheet" href="${css}" type="text/css" /><br>
</head><br>
<body><br>
<h1>Results for ${testname}</h1><br>
@@ -14,7 +14,7 @@<br>
<p><b>Status:</b> ${status}</p><br>
<p><b>Result:</b> ${status}</p><br>
</div><br>
- <p><a href="../index.html">Back to summary</a></p><br>
+ <p><a href="${index}">Back to summary</a></p><br>
<h2>Details</h2><br>
<table><br>
<tr><br>
@@ -42,6 +42,6 @@<br>
</td><br>
</tr><br>
</table><br>
- <p><a href="../index.html">Back to summary</a></p><br>
+ <p><a href="${index}">Back to summary</a></p><br>
</body><br>
</html><br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div>