summaryrefslogtreecommitdiffstats
path: root/Tools/Scripts/webkitpy/common/net/testoutputset.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/common/net/testoutputset.py')
-rw-r--r--Tools/Scripts/webkitpy/common/net/testoutputset.py130
1 files changed, 130 insertions, 0 deletions
diff --git a/Tools/Scripts/webkitpy/common/net/testoutputset.py b/Tools/Scripts/webkitpy/common/net/testoutputset.py
new file mode 100644
index 0000000..4074686
--- /dev/null
+++ b/Tools/Scripts/webkitpy/common/net/testoutputset.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from webkitpy.common.system.directoryfileset import DirectoryFileSet
+from webkitpy.common.system.zipfileset import ZipFileSet
+import re
+import testoutput
+import urllib
+
+
+class TestOutputSet(object):
+ def __init__(self, name, platform, zip_file, **kwargs):
+ self._name = name
+ self._platform = platform
+ self._zip_file = zip_file
+ self._include_expected = kwargs.get('include_expected', True)
+
+ @classmethod
+ def from_zip_url(cls, platform, zip_path):
+ return TestOutputSet('local zip %s builder' % platform, platform, ZipFileSet(zip_path))
+
+ @classmethod
+ def from_zip(cls, platform, zip):
+ return TestOutputSet('local zip %s builder' % platform, platform, zip)
+
+ @classmethod
+ def from_zip_map(cls, zip_map):
+ output_sets = []
+ for k, v in zip_map.items():
+ output_sets.append(TestOutputSet.from_zip(k, v))
+ return AggregateTestOutputSet(output_sets)
+
+ @classmethod
+ def from_path(self, path, platform=None):
+ return TestOutputSet('local %s builder' % platform, platform, DirectoryFileSet(path))
+
+ def name(self):
+ return self._name
+
+ def set_platform(self, platform):
+ self._platform = platform
+
+ def files(self):
+ return [self._zip_file.open(filename) for filename in self._zip_file.namelist()]
+
+ def _extract_output_files(self, name, exact_match):
+ name_matcher = re.compile(name)
+ actual_matcher = re.compile(r'-actual\.')
+ expected_matcher = re.compile(r'-expected\.')
+
+ checksum_files = []
+ text_files = []
+ image_files = []
+ for output_file in self.files():
+ name_match = name_matcher.search(output_file.name())
+ actual_match = actual_matcher.search(output_file.name())
+ expected_match = expected_matcher.search(output_file.name())
+ if not (name_match and (actual_match or (self._include_expected and expected_match))):
+ continue
+ if output_file.name().endswith('.checksum'):
+ checksum_files.append(output_file)
+ elif output_file.name().endswith('.txt'):
+ text_files.append(output_file)
+ elif output_file.name().endswith('.png'):
+ image_files.append(output_file)
+
+ return (checksum_files, text_files, image_files)
+
+ def _extract_file_with_name(self, name, files):
+ for file in files:
+ if file.name() == name:
+ return file
+ return None
+
+ def _make_output_from_image(self, image_file, checksum_files):
+ checksum_file_name = re.sub('\.png', '.checksum', image_file.name())
+ checksum_file = self._extract_file_with_name(checksum_file_name, checksum_files)
+ return testoutput.ImageTestOutput(self._platform, image_file, checksum_file)
+
+ def outputs_for(self, name, **kwargs):
+ target_type = kwargs.get('target_type', None)
+ exact_match = kwargs.get('exact_match', False)
+ if re.search(r'\.x?html', name):
+ name = name[:name.rindex('.')]
+
+ (checksum_files, text_files, image_files) = self._extract_output_files(name, exact_match)
+
+ outputs = [self._make_output_from_image(image_file, checksum_files) for image_file in image_files]
+
+ outputs += [testoutput.TextTestOutput(self._platform, text_file) for text_file in text_files]
+
+ if exact_match:
+ outputs = filter(lambda output: output.name() == name, outputs)
+
+ outputs = filter(lambda r: target_type in [None, r.type()], outputs)
+
+ return outputs
+
+
+class AggregateTestOutputSet(object):
+ """Set of test outputs from a list of builders"""
+ def __init__(self, builders):
+ self._builders = builders
+
+ def outputs_for(self, name, **kwargs):
+ return sum([builder.outputs_for(name, **kwargs) for builder in self._builders], [])
+
+ def builders(self):
+ return self._builders