summaryrefslogtreecommitdiffstats
path: root/WebKitTools/Scripts/webkitpy/layout_tests/layout_package
diff options
context:
space:
mode:
authorLeon Clarke <leonclarke@google.com>2010-07-15 12:03:35 +0100
committerLeon Clarke <leonclarke@google.com>2010-07-20 16:57:23 +0100
commite458d70a0d18538346f41b503114c9ebe6b2ce12 (patch)
tree86f1637deca2c524432a822e5fcedd4bef221091 /WebKitTools/Scripts/webkitpy/layout_tests/layout_package
parentf43eabc081f7ce6af24b9df4953498a3cd6ca24d (diff)
downloadexternal_webkit-e458d70a0d18538346f41b503114c9ebe6b2ce12.zip
external_webkit-e458d70a0d18538346f41b503114c9ebe6b2ce12.tar.gz
external_webkit-e458d70a0d18538346f41b503114c9ebe6b2ce12.tar.bz2
Merge WebKit at r63173 : Initial merge by git.
Change-Id: Ife5af0c7c6261fbbc8ae6bc08c390efa9ef10b44
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/layout_tests/layout_package')
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py3
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py52
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py282
-rw-r--r--WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator_unittest.py126
4 files changed, 346 insertions, 117 deletions
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
index a2e2091..6364511 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/dump_render_tree_thread.py
@@ -429,7 +429,8 @@ class TestShellThread(threading.Thread):
# previous run will be copied into the baseline.)
image_hash = test_info.image_hash()
if (image_hash and
- (self._test_args.new_baseline or self._test_args.reset_results)):
+ (self._test_args.new_baseline or self._test_args.reset_results or
+ not self._options.pixel_tests)):
image_hash = ""
start = time.time()
crash, timeout, actual_checksum, output, error = \
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
index bb214f7..c0525ea 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_layout_results_generator.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -35,7 +34,8 @@ from webkitpy.layout_tests.layout_package import test_expectations
from webkitpy.layout_tests.layout_package import test_failures
import webkitpy.thirdparty.simplejson as simplejson
-class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
+
+class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGeneratorBase):
"""A JSON results generator for layout tests."""
LAYOUT_TESTS_PATH = "LayoutTests"
@@ -44,6 +44,16 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
WONTFIX = "wontfixCounts"
DEFERRED = "deferredCounts"
+ # Note that we omit test_expectations.FAIL from this list because
+ # it should never show up (it's a legacy input expectation, never
+ # an output expectation).
+ FAILURE_TO_CHAR = {test_expectations.CRASH: "C",
+ test_expectations.TIMEOUT: "T",
+ test_expectations.IMAGE: "I",
+ test_expectations.TEXT: "F",
+ test_expectations.MISSING: "O",
+ test_expectations.IMAGE_PLUS_TEXT: "Z"}
+
def __init__(self, port, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
test_timings, expectations, result_summary, all_tests):
@@ -53,20 +63,14 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
Args:
result_summary: ResultsSummary object storing the summary of the test
results.
- (see the comment of JSONResultsGenerator.__init__ for other Args)
"""
+ super(JSONLayoutResultsGenerator, self).__init__(
+ builder_name, build_name, build_number, results_file_base_path,
+ builder_base_url, {}, port.test_repository_paths())
+
self._port = port
- self._builder_name = builder_name
- self._build_name = build_name
- self._build_number = build_number
- self._builder_base_url = builder_base_url
- self._results_file_path = os.path.join(results_file_base_path,
- self.RESULTS_FILENAME)
self._expectations = expectations
- # We don't use self._skipped_tests and self._passed_tests as we
- # override _InsertFailureSummaries.
-
# We want relative paths to LayoutTest root for JSON output.
path_to_name = self._get_path_relative_to_layout_test_root
self._result_summary = result_summary
@@ -77,9 +81,8 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
self._test_timings = dict(
(path_to_name(test_tuple.filename), test_tuple.test_run_time)
for test_tuple in test_timings)
- self._svn_repositories = port.test_repository_paths()
- self._generate_json_output()
+ self.generate_json_output()
def _get_path_relative_to_layout_test_root(self, test):
"""Returns the path of the test relative to the layout test root.
@@ -102,6 +105,27 @@ class JSONLayoutResultsGenerator(json_results_generator.JSONResultsGenerator):
return relativePath.replace('\\', '/')
# override
+ def _get_test_timing(self, test_name):
+ if test_name in self._test_timings:
+ # Floor for now to get time in seconds.
+ return int(self._test_timings[test_name])
+ return 0
+
+ # override
+ def _get_failed_test_names(self):
+ return set(self._failures.keys())
+
+ # override
+ def _get_result_type_char(self, test_name):
+ if test_name not in self._all_tests:
+ return self.NO_DATA_RESULT
+
+ if test_name in self._failures:
+ return self.FAILURE_TO_CHAR[self._failures[test_name]]
+
+ return self.PASS_RESULT
+
+ # override
def _convert_json_to_current_version(self, results_json):
archive_version = None
if self.VERSION_KEY in results_json:
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
index 1cf1b95..595fc2b 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -38,16 +37,27 @@ import time
import urllib2
import xml.dom.minidom
-from webkitpy.common.checkout import scm
-from webkitpy.common.system.executive import ScriptError
-from webkitpy.layout_tests.layout_package import test_expectations
import webkitpy.thirdparty.simplejson as simplejson
-_log = logging.getLogger("webkitpy.layout_tests.layout_package."
- "json_results_generator")
+# A JSON results generator for generic tests.
+# FIXME: move this code out of the layout_package directory.
+_log = logging.getLogger("webkitpy.layout_tests.layout_package.json_results_generator")
-class JSONResultsGenerator(object):
+
+class TestResult(object):
+ """A simple class that represents a single test result."""
+ def __init__(self, name, failed=False, skipped=False, elapsed_time=0):
+ self.name = name
+ self.failed = failed
+ self.skipped = skipped
+ self.time = elapsed_time
+
+ def fixable(self):
+ return self.failed or self.skipped
+
+
+class JSONResultsGeneratorBase(object):
"""A JSON results generator for generic tests."""
MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG = 750
@@ -57,6 +67,7 @@ class JSONResultsGenerator(object):
JSON_SUFFIX = ");"
PASS_RESULT = "P"
SKIP_RESULT = "X"
+ FAIL_RESULT = "F"
NO_DATA_RESULT = "N"
VERSION = 3
VERSION_KEY = "version"
@@ -70,22 +81,11 @@ class JSONResultsGenerator(object):
FIXABLE = "fixableCounts"
ALL_FIXABLE_COUNT = "allFixableCount"
- # Note that we omit test_expectations.FAIL from this list because
- # it should never show up (it's a legacy input expectation, never
- # an output expectation).
- FAILURE_TO_CHAR = {test_expectations.CRASH: "C",
- test_expectations.TIMEOUT: "T",
- test_expectations.IMAGE: "I",
- test_expectations.TEXT: "F",
- test_expectations.MISSING: "O",
- test_expectations.IMAGE_PLUS_TEXT: "Z"}
- FAILURE_CHARS = FAILURE_TO_CHAR.values()
-
RESULTS_FILENAME = "results.json"
- def __init__(self, port, builder_name, build_name, build_number,
+ def __init__(self, builder_name, build_name, build_number,
results_file_base_path, builder_base_url,
- test_timings, failures, passed_tests, skipped_tests, all_tests):
+ test_results_map, svn_repositories=None):
"""Modifies the results.json file. Grabs it off the archive directory
if it is not found locally.
@@ -96,12 +96,11 @@ class JSONResultsGenerator(object):
results_file_base_path: Absolute path to the directory containing the
results json file.
builder_base_url: the URL where we have the archived test results.
- test_timings: Map of test name to a test_run-time.
- failures: Map of test name to a failure type (of test_expectations).
- passed_tests: A set containing all the passed tests.
- skipped_tests: A set containing all the skipped tests.
- all_tests: List of all the tests that were run. This should not
- include skipped tests.
+ If this is None no archived results will be retrieved.
+ test_results_map: A dictionary that maps test_name to TestResult.
+ svn_repositories: A (json_field_name, svn_path) pair for SVN
+ repositories that tests rely on. The SVN revision will be
+ included in the JSON with the given json_field_name.
"""
self._builder_name = builder_name
self._build_name = build_name
@@ -109,31 +108,106 @@ class JSONResultsGenerator(object):
self._builder_base_url = builder_base_url
self._results_file_path = os.path.join(results_file_base_path,
self.RESULTS_FILENAME)
- self._test_timings = test_timings
- self._failures = failures
- self._passed_tests = passed_tests
- self._skipped_tests = skipped_tests
- self._all_tests = all_tests
- self._svn_repositories = port.test_repository_paths()
- self._generate_json_output()
+ self._test_results_map = test_results_map
+ self._test_results = test_results_map.values()
+
+ self._svn_repositories = svn_repositories
+ if not self._svn_repositories:
+ self._svn_repositories = {}
+
+ self._json = None
- def _generate_json_output(self):
+ def generate_json_output(self):
"""Generates the JSON output file."""
- json = self._get_json()
- if json:
+ if not self._json:
+ self._json = self.get_json()
+ if self._json:
+ # Specify separators in order to get compact encoding.
+ json_data = simplejson.dumps(self._json, separators=(',', ':'))
+ json_string = self.JSON_PREFIX + json_data + self.JSON_SUFFIX
+
results_file = codecs.open(self._results_file_path, "w", "utf-8")
- results_file.write(json)
+ results_file.write(json_string)
results_file.close()
+ def get_json(self):
+ """Gets the results for the results.json file."""
+ if self._json:
+ return self._json
+
+ results_json, error = self._get_archived_json_results()
+ if error:
+ # If there was an error don't write a results.json
+ # file at all as it would lose all the information on the bot.
+ _log.error("Archive directory is inaccessible. Not modifying "
+ "or clobbering the results.json file: " + str(error))
+ return None
+
+ builder_name = self._builder_name
+ if results_json and builder_name not in results_json:
+ _log.debug("Builder name (%s) is not in the results.json file."
+ % builder_name)
+
+ self._convert_json_to_current_version(results_json)
+
+ if builder_name not in results_json:
+ results_json[builder_name] = (
+ self._create_results_for_builder_json())
+
+ results_for_builder = results_json[builder_name]
+
+ self._insert_generic_metadata(results_for_builder)
+
+ self._insert_failure_summaries(results_for_builder)
+
+ # Update the all failing tests with result type and time.
+ tests = results_for_builder[self.TESTS]
+ all_failing_tests = self._get_failed_test_names()
+ all_failing_tests.update(tests.iterkeys())
+ for test in all_failing_tests:
+ self._insert_test_time_and_result(test, tests)
+
+ self._json = results_json
+ return self._json
+
+ def _get_test_timing(self, test_name):
+ """Returns test timing data (elapsed time) in second
+ for the given test_name."""
+ if test_name in self._test_results_map:
+ # Floor for now to get time in seconds.
+ return int(self._test_results_map[test_name].time)
+ return 0
+
+ def _get_failed_test_names(self):
+ """Returns a set of failed test names."""
+ return set([r.name for r in self._test_results if r.failed])
+
+ def _get_result_type_char(self, test_name):
+ """Returns a single char (e.g. SKIP_RESULT, FAIL_RESULT,
+ PASS_RESULT, NO_DATA_RESULT, etc) that indicates the test result
+ for the given test_name.
+ """
+ if test_name not in self._test_results_map:
+ return JSONResultsGenerator.NO_DATA_RESULT
+
+ test_result = self._test_results_map[test_name]
+ if test_result.skipped:
+ return JSONResultsGenerator.SKIP_RESULT
+ if test_result.failed:
+ return JSONResultsGenerator.FAIL_RESULT
+
+ return JSONResultsGenerator.PASS_RESULT
+
# FIXME: Callers should use scm.py instead.
+ # FIXME: Identify and fix the run-time errors that were observed on Windows
+ # chromium buildbot when we had updated this code to use scm.py once before.
def _get_svn_revision(self, in_directory):
"""Returns the svn revision for the given directory.
Args:
in_directory: The directory where svn is to be run.
"""
-
if os.path.exists(os.path.join(in_directory, '.svn')):
# Note: Not thread safe: http://bugs.python.org/issue2320
output = subprocess.Popen(["svn", "info", "--xml"],
@@ -196,76 +270,34 @@ class JSONResultsGenerator(object):
return results_json, error
- def _get_json(self):
- """Gets the results for the results.json file."""
- results_json, error = self._get_archived_json_results()
- if error:
- # If there was an error don't write a results.json
- # file at all as it would lose all the information on the bot.
- _log.error("Archive directory is inaccessible. Not modifying "
- "or clobbering the results.json file: " + str(error))
- return None
-
- builder_name = self._builder_name
- if results_json and builder_name not in results_json:
- _log.debug("Builder name (%s) is not in the results.json file."
- % builder_name)
-
- self._convert_json_to_current_version(results_json)
-
- if builder_name not in results_json:
- results_json[builder_name] = (
- self._create_results_for_builder_json())
-
- results_for_builder = results_json[builder_name]
-
- self._insert_generic_metadata(results_for_builder)
-
- self._insert_failure_summaries(results_for_builder)
-
- # Update the all failing tests with result type and time.
- tests = results_for_builder[self.TESTS]
- all_failing_tests = set(self._failures.iterkeys())
- all_failing_tests.update(tests.iterkeys())
- for test in all_failing_tests:
- self._insert_test_time_and_result(test, tests)
-
- # Specify separators in order to get compact encoding.
- results_str = simplejson.dumps(results_json, separators=(',', ':'))
- return self.JSON_PREFIX + results_str + self.JSON_SUFFIX
-
def _insert_failure_summaries(self, results_for_builder):
"""Inserts aggregate pass/failure statistics into the JSON.
- This method reads self._skipped_tests, self._passed_tests and
- self._failures and inserts FIXABLE, FIXABLE_COUNT and ALL_FIXABLE_COUNT
- entries.
+ This method reads self._test_results and generates
+ FIXABLE, FIXABLE_COUNT and ALL_FIXABLE_COUNT entries.
Args:
results_for_builder: Dictionary containing the test results for a
single builder.
"""
- # Insert the number of tests that failed.
+ # Insert the number of tests that failed or skipped.
+ fixable_count = len([r for r in self._test_results if r.fixable()])
self._insert_item_into_raw_list(results_for_builder,
- len(set(self._failures.keys()) | self._skipped_tests),
- self.FIXABLE_COUNT)
+ fixable_count, self.FIXABLE_COUNT)
# Create a pass/skip/failure summary dictionary.
entry = {}
- entry[self.SKIP_RESULT] = len(self._skipped_tests)
- entry[self.PASS_RESULT] = len(self._passed_tests)
- get = entry.get
- for failure_type in self._failures.values():
- failure_char = self.FAILURE_TO_CHAR[failure_type]
- entry[failure_char] = get(failure_char, 0) + 1
+ for test_name in self._test_results_map.iterkeys():
+ result_char = self._get_result_type_char(test_name)
+ entry[result_char] = entry.get(result_char, 0) + 1
# Insert the pass/skip/failure summary dictionary.
self._insert_item_into_raw_list(results_for_builder, entry,
self.FIXABLE)
# Insert the number of all the tests that are supposed to pass.
+ all_test_count = len(self._test_results)
self._insert_item_into_raw_list(results_for_builder,
- len(self._skipped_tests | self._all_tests),
- self.ALL_FIXABLE_COUNT)
+ all_test_count, self.ALL_FIXABLE_COUNT)
def _insert_item_into_raw_list(self, results_for_builder, item, key):
"""Inserts the item into the list with the given key in the results for
@@ -331,18 +363,8 @@ class JSONResultsGenerator(object):
tests: Dictionary containing test result entries.
"""
- result = JSONResultsGenerator.PASS_RESULT
- time = 0
-
- if test_name not in self._all_tests:
- result = JSONResultsGenerator.NO_DATA_RESULT
-
- if test_name in self._failures:
- result = self.FAILURE_TO_CHAR[self._failures[test_name]]
-
- if test_name in self._test_timings:
- # Floor for now to get time in seconds.
- time = int(self._test_timings[test_name])
+ result = self._get_result_type_char(test_name)
+ time = self._get_test_timing(test_name)
if test_name not in tests:
tests[test_name] = self._create_results_and_times_json()
@@ -420,3 +442,59 @@ class JSONResultsGenerator(object):
"""Returns whether all the results are of the given type
(e.g. all passes)."""
return len(results) == 1 and results[0][1] == type
+
+
+# A wrapper class for JSONResultsGeneratorBase.
+# Note: There's a script outside the WebKit codebase calling this script.
+# FIXME: Please keep the interface until the other script is cleaned up.
+# (http://src.chromium.org/viewvc/chrome/trunk/src/webkit/tools/layout_tests/webkitpy/layout_tests/test_output_xml_to_json.py?view=markup)
+class JSONResultsGenerator(JSONResultsGeneratorBase):
+ # The flag is for backward compatibility.
+ output_json_in_init = True
+
+ def __init__(self, port, builder_name, build_name, build_number,
+ results_file_base_path, builder_base_url,
+ test_timings, failures, passed_tests, skipped_tests, all_tests):
+ """Generates a JSON results file.
+
+ Args
+ builder_name: the builder name (e.g. Webkit).
+ build_name: the build name (e.g. webkit-rel).
+ build_number: the build number.
+ results_file_base_path: Absolute path to the directory containing the
+ results json file.
+ builder_base_url: the URL where we have the archived test results.
+ test_timings: Map of test name to a test_run-time.
+ failures: Map of test name to a failure type (of test_expectations).
+ passed_tests: A set containing all the passed tests.
+ skipped_tests: A set containing all the skipped tests.
+ all_tests: List of all the tests that were run. This should not
+ include skipped tests.
+ """
+
+ # Create a map of (name, TestResult).
+ test_results_map = dict()
+ get = test_results_map.get
+ for (test, time) in test_timings.iteritems():
+ test_results_map[test] = TestResult(test, elapsed_time=time)
+ for test in failures.iterkeys():
+ test_results_map[test] = test_result = get(test, TestResult(test))
+ test_result.failed = True
+ for test in skipped_tests:
+ test_results_map[test] = test_result = get(test, TestResult(test))
+ test_result.skipped = True
+ for test in passed_tests:
+ test_results_map[test] = test_result = get(test, TestResult(test))
+ test_result.failed = False
+ test_result.skipped = False
+ for test in all_tests:
+ if test not in test_results_map:
+ test_results_map[test] = TestResult(test)
+
+ super(JSONResultsGenerator, self).__init__(
+ builder_name, build_name, build_number,
+ results_file_base_path, builder_base_url, test_results_map,
+ svn_repositories=port.test_repository_paths())
+
+ if self.__class__.output_json_in_init:
+ self.generate_json_output()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator_unittest.py b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator_unittest.py
new file mode 100644
index 0000000..0a60cc7
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator_unittest.py
@@ -0,0 +1,126 @@
+# 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:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * 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.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+# OWNER OR 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.
+
+"""Unit tests for json_results_generator.py."""
+
+import unittest
+import optparse
+import random
+import shutil
+import tempfile
+
+from webkitpy.layout_tests.layout_package import json_results_generator
+from webkitpy.layout_tests.layout_package import test_expectations
+from webkitpy.layout_tests import port
+
+
+class JSONGeneratorTest(unittest.TestCase):
+ def setUp(self):
+ json_results_generator.JSONResultsGenerator.output_json_in_init = False
+ self.builder_name = 'DUMMY_BUILDER_NAME'
+ self.build_name = 'DUMMY_BUILD_NAME'
+ self.build_number = 'DUMMY_BUILDER_NUMBER'
+
+ def _test_json_generation(self, passed_tests, failed_tests, skipped_tests):
+ # Make sure we have sets (rather than lists).
+ passed_tests = set(passed_tests)
+ skipped_tests = set(skipped_tests)
+ tests_list = passed_tests | set(failed_tests.keys())
+ test_timings = {}
+ for test in tests_list:
+ test_timings[test] = float(random.randint(1, 10))
+
+ port_obj = port.get(None)
+
+ # Generate a JSON file.
+ generator = json_results_generator.JSONResultsGenerator(port_obj,
+ self.builder_name, self.build_name, self.build_number,
+ '',
+ None, # don't fetch past json results archive
+ test_timings,
+ failed_tests,
+ passed_tests,
+ skipped_tests,
+ tests_list)
+
+ json = generator.get_json()
+
+ # Aliasing to a short name for better access to its constants.
+ JRG = json_results_generator.JSONResultsGenerator
+
+ self.assertTrue(JRG.VERSION_KEY in json)
+ self.assertTrue(self.builder_name in json)
+
+ buildinfo = json[self.builder_name]
+ self.assertTrue(JRG.FIXABLE in buildinfo)
+ self.assertTrue(JRG.TESTS in buildinfo)
+ self.assertTrue(len(buildinfo[JRG.BUILD_NUMBERS]) == 1)
+ self.assertTrue(buildinfo[JRG.BUILD_NUMBERS][0] == self.build_number)
+
+ if tests_list or skipped_tests:
+ fixable = buildinfo[JRG.FIXABLE][0]
+ if passed_tests:
+ self.assertTrue(fixable[JRG.PASS_RESULT] == len(passed_tests))
+ else:
+ self.assertTrue(JRG.PASS_RESULT not in fixable or
+ fixable[JRG.PASS_RESULT] == 0)
+ if skipped_tests:
+ self.assertTrue(fixable[JRG.SKIP_RESULT] == len(skipped_tests))
+ else:
+ self.assertTrue(JRG.SKIP_RESULT not in fixable or
+ fixable[JRG.SKIP_RESULT] == 0)
+
+ if failed_tests:
+ tests = buildinfo[JRG.TESTS]
+ for test_name, failure in failed_tests.iteritems():
+ self.assertTrue(test_name in tests)
+ test = tests[test_name]
+ self.assertTrue(test[JRG.RESULTS][0][0] == 1)
+ self.assertTrue(test[JRG.RESULTS][0][1] == JRG.FAIL_RESULT)
+ self.assertTrue(test[JRG.TIMES][0][0] == 1)
+ self.assertTrue(test[JRG.TIMES][0][1] ==
+ int(test_timings[test_name]))
+
+ fixable_count = len(skipped_tests) + len(failed_tests.keys())
+ if skipped_tests or failed_tests:
+ self.assertTrue(buildinfo[JRG.FIXABLE_COUNT][0] == fixable_count)
+
+ def test_json_generation(self):
+ reason = test_expectations.TEXT
+
+ self._test_json_generation([], {}, [])
+ self._test_json_generation(['A', 'B'], {}, [])
+ self._test_json_generation([], {'A': reason, 'B': reason}, [])
+ self._test_json_generation([], {}, ['A', 'B'])
+ self._test_json_generation(['A'], {'B': reason, 'C': reason}, [])
+ self._test_json_generation([], {'A': reason, 'B': reason}, ['C', 'D'])
+ self._test_json_generation(['A', 'B', 'C'], {'D': reason}, ['E', 'F'])
+
+
+if __name__ == '__main__':
+ unittest.main()