1 # Copyright (C) 2010 Google Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 from jsonresults import *
33 print "ERROR: Add the TestResultServer, google_appengine and yaml/lib directories to your PYTHONPATH"
40 FULL_RESULT_EXAMPLE = """ADD_RESULTS({
41 "seconds_since_epoch": 1368146629,
45 "encrypted-media-v2-events.html": {
46 "bugs": ["crbug.com/1234"],
47 "expected": "TIMEOUT",
51 "encrypted-media-v2-syntax.html": {
52 "expected": "TIMEOUT",
56 "progress-events-generated-correctly.html": {
57 "expected": "PASS FAIL IMAGE TIMEOUT CRASH MISSING",
64 "src_removal_does_not_trigger_loadstart.html": {
73 "src_removal_does_not_trigger_loadstart.html": {
86 "unexpected-skip.html": {
90 "unexpected-fail.html": {
94 "flaky-failed.html": {
95 "expected": "PASS FAIL",
98 "media-document-audio-repaint.html": {
103 "unexpected-leak.html": {
110 "num_regressions": 0,
112 "interrupted": false,
113 "layout_tests_dir": "\/tmp\/cr\/src\/third_party\/WebKit\/LayoutTests",
115 "builder_name": "Webkit",
117 "pixel_tests_enabled": true,
118 "blink_revision": "1234",
119 "has_pretty_patch": true,
122 "num_failures_by_type": {
136 "chromium_revision": "5678"
139 JSON_RESULTS_OLD_TEMPLATE = (
140 '{"[BUILDER_NAME]":{'
141 '"allFixableCount":[[TESTDATA_COUNT]],'
142 '"blinkRevision":[[TESTDATA_WEBKITREVISION]],'
143 '"buildNumbers":[[TESTDATA_BUILDNUMBERS]],'
144 '"chromeRevision":[[TESTDATA_CHROMEREVISION]],'
146 '"fixableCount":[[TESTDATA_COUNT]],'
147 '"fixableCounts":[[TESTDATA_COUNTS]],'
148 '"secondsSinceEpoch":[[TESTDATA_TIMES]],'
149 '"tests":{[TESTDATA_TESTS]}'
151 '"version":[VERSION]'
152 '}') % json.dumps(CHAR_TO_FAILURE)
154 JSON_RESULTS_COUNTS = '{"' + '":[[TESTDATA_COUNT]],"'.join([char for char in CHAR_TO_FAILURE.values()]) + '":[[TESTDATA_COUNT]]}'
156 JSON_RESULTS_TEMPLATE = (
157 '{"[BUILDER_NAME]":{'
158 '"blinkRevision":[[TESTDATA_WEBKITREVISION]],'
159 '"buildNumbers":[[TESTDATA_BUILDNUMBERS]],'
160 '"chromeRevision":[[TESTDATA_CHROMEREVISION]],'
162 '"num_failures_by_type":%s,'
163 '"secondsSinceEpoch":[[TESTDATA_TIMES]],'
164 '"tests":{[TESTDATA_TESTS]}'
166 '"version":[VERSION]'
167 '}') % (json.dumps(CHAR_TO_FAILURE), JSON_RESULTS_COUNTS)
169 JSON_RESULTS_COUNTS_TEMPLATE = '{"' + '":[TESTDATA],"'.join([char for char in CHAR_TO_FAILURE]) + '":[TESTDATA]}'
171 JSON_RESULTS_TEST_LIST_TEMPLATE = '{"Webkit":{"tests":{[TESTDATA_TESTS]}}}'
174 class MockFile(object):
175 def __init__(self, name='results.json', data=''):
176 self.master = 'MockMasterName'
177 self.builder = 'MockBuilderName'
178 self.test_type = 'MockTestType'
182 def save(self, data):
187 class JsonResultsTest(unittest.TestCase):
189 self._builder = "Webkit"
190 self.old_log_level = logging.root.level
191 logging.root.setLevel(logging.ERROR)
194 logging.root.setLevel(self.old_log_level)
196 # Use this to get better error messages than just string compare gives.
197 def assert_json_equal(self, a, b):
199 a = json.loads(a) if isinstance(a, str) else a
200 b = json.loads(b) if isinstance(b, str) else b
201 self.assertEqual(a, b)
203 def test_strip_prefix_suffix(self):
204 json = "['contents']"
205 self.assertEqual(JsonResults._strip_prefix_suffix("ADD_RESULTS(" + json + ");"), json)
206 self.assertEqual(JsonResults._strip_prefix_suffix(json), json)
208 def _make_test_json(self, test_data, json_string=JSON_RESULTS_TEMPLATE, builder_name="Webkit"):
212 builds = test_data["builds"]
213 tests = test_data["tests"]
214 if not builds or not tests:
223 counts.append(JSON_RESULTS_COUNTS_TEMPLATE.replace("[TESTDATA]", build))
224 build_numbers.append("1000%s" % build)
225 webkit_revision.append("2000%s" % build)
226 chrome_revision.append("3000%s" % build)
227 times.append("100000%s000" % build)
229 json_string = json_string.replace("[BUILDER_NAME]", builder_name)
230 json_string = json_string.replace("[TESTDATA_COUNTS]", ",".join(counts))
231 json_string = json_string.replace("[TESTDATA_COUNT]", ",".join(builds))
232 json_string = json_string.replace("[TESTDATA_BUILDNUMBERS]", ",".join(build_numbers))
233 json_string = json_string.replace("[TESTDATA_WEBKITREVISION]", ",".join(webkit_revision))
234 json_string = json_string.replace("[TESTDATA_CHROMEREVISION]", ",".join(chrome_revision))
235 json_string = json_string.replace("[TESTDATA_TIMES]", ",".join(times))
237 version = str(test_data["version"]) if "version" in test_data else "4"
238 json_string = json_string.replace("[VERSION]", version)
239 json_string = json_string.replace("{[TESTDATA_TESTS]}", json.dumps(tests, separators=(',', ':'), sort_keys=True))
242 def _test_merge(self, aggregated_data, incremental_data, expected_data, max_builds=jsonresults.JSON_RESULTS_MAX_BUILDS):
243 aggregated_results = self._make_test_json(aggregated_data, builder_name=self._builder)
244 incremental_json, _ = JsonResults._get_incremental_json(self._builder, self._make_test_json(incremental_data, builder_name=self._builder), is_full_results_format=False)
245 merged_results, status_code = JsonResults.merge(self._builder, aggregated_results, incremental_json, num_runs=max_builds, sort_keys=True)
248 expected_results = self._make_test_json(expected_data, builder_name=self._builder)
249 self.assert_json_equal(merged_results, expected_results)
250 self.assertEqual(status_code, 200)
252 self.assertTrue(status_code != 200)
254 def _test_get_test_list(self, input_data, expected_data):
255 input_results = self._make_test_json(input_data)
256 expected_results = JSON_RESULTS_TEST_LIST_TEMPLATE.replace("{[TESTDATA_TESTS]}", json.dumps(expected_data, separators=(',', ':')))
257 actual_results = JsonResults.get_test_list(self._builder, input_results)
258 self.assert_json_equal(actual_results, expected_results)
260 def test_update_files_empty_aggregate_data(self):
261 small_file = MockFile(name='results-small.json')
262 large_file = MockFile(name='results.json')
265 "builds": ["2", "1"],
268 "results": [[200, TEXT]],
273 incremental_string = self._make_test_json(incremental_data, builder_name=small_file.builder)
275 self.assertTrue(JsonResults.update_files(small_file.builder, incremental_string, small_file, large_file, is_full_results_format=False))
276 self.assert_json_equal(small_file.data, incremental_string)
277 self.assert_json_equal(large_file.data, incremental_string)
279 def test_update_files_null_incremental_data(self):
280 small_file = MockFile(name='results-small.json')
281 large_file = MockFile(name='results.json')
284 "builds": ["2", "1"],
287 "results": [[200, TEXT]],
292 aggregated_string = self._make_test_json(aggregated_data, builder_name=small_file.builder)
294 small_file.data = large_file.data = aggregated_string
296 incremental_string = ""
298 self.assertEqual(JsonResults.update_files(small_file.builder, incremental_string, small_file, large_file, is_full_results_format=False),
299 ('No incremental JSON data to merge.', 403))
300 self.assert_json_equal(small_file.data, aggregated_string)
301 self.assert_json_equal(large_file.data, aggregated_string)
303 def test_update_files_empty_incremental_data(self):
304 small_file = MockFile(name='results-small.json')
305 large_file = MockFile(name='results.json')
308 "builds": ["2", "1"],
311 "results": [[200, TEXT]],
316 aggregated_string = self._make_test_json(aggregated_data, builder_name=small_file.builder)
318 small_file.data = large_file.data = aggregated_string
324 incremental_string = self._make_test_json(incremental_data, builder_name=small_file.builder)
326 self.assertEqual(JsonResults.update_files(small_file.builder, incremental_string, small_file, large_file, is_full_results_format=False),
327 ('No incremental JSON data to merge.', 403))
328 self.assert_json_equal(small_file.data, aggregated_string)
329 self.assert_json_equal(large_file.data, aggregated_string)
331 def test_merge_with_empty_aggregated_results(self):
333 "builds": ["2", "1"],
336 "results": [[200, TEXT]],
341 incremental_results, _ = JsonResults._get_incremental_json(self._builder, self._make_test_json(incremental_data), is_full_results_format=False)
342 aggregated_results = ""
343 merged_results, _ = JsonResults.merge(self._builder, aggregated_results, incremental_results, num_runs=jsonresults.JSON_RESULTS_MAX_BUILDS, sort_keys=True)
344 self.assert_json_equal(merged_results, incremental_results)
346 def test_failures_by_type_added(self):
347 aggregated_results = self._make_test_json({
348 "builds": ["2", "1"],
351 "results": [[100, TEXT], [100, FAIL]],
355 }, json_string=JSON_RESULTS_OLD_TEMPLATE)
356 incremental_results = self._make_test_json({
360 "results": [[1, TEXT]],
364 }, json_string=JSON_RESULTS_OLD_TEMPLATE)
365 incremental_json, _ = JsonResults._get_incremental_json(self._builder, incremental_results, is_full_results_format=False)
366 merged_results, _ = JsonResults.merge(self._builder, aggregated_results, incremental_json, num_runs=201, sort_keys=True)
367 self.assert_json_equal(merged_results, self._make_test_json({
368 "builds": ["3", "2", "1"],
371 "results": [[101, TEXT], [100, FAIL]],
377 def test_merge_full_results_format(self):
378 expected_incremental_results = {
380 "blinkRevision": ["1234"],
381 "buildNumbers": ["3"],
382 "chromeRevision": ["5678"],
383 "failure_map": CHAR_TO_FAILURE,
384 "num_failures_by_type": {"AUDIO": [0], "CRASH": [3], "FAIL": [2], "IMAGE": [1], "IMAGE+TEXT": [0], "MISSING": [0], "PASS": [10], "SKIP": [2], "TEXT": [3], "TIMEOUT": [16], "LEAK": [1]},
385 "secondsSinceEpoch": [1368146629],
391 "src_removal_does_not_trigger_loadstart.html": {
392 "results": [[1, PASS]],
399 "encrypted-media-v2-events.html": {
400 "bugs": ["crbug.com/1234"],
401 "expected": "TIMEOUT",
402 "results": [[1, TIMEOUT]],
405 "encrypted-media-v2-syntax.html": {
406 "expected": "TIMEOUT",
407 "results": [[1, TIMEOUT]],
411 "media-document-audio-repaint.html": {
413 "results": [[1, IMAGE]],
416 "progress-events-generated-correctly.html": {
417 "expected": "PASS FAIL IMAGE TIMEOUT CRASH MISSING",
418 "results": [[1, TIMEOUT]],
421 "flaky-failed.html": {
422 "expected": "PASS FAIL",
423 "results": [[1, FAIL]],
426 "unexpected-fail.html": {
427 "results": [[1, FAIL]],
430 "unexpected-leak.html": {
431 "results": [[1, LEAK]],
440 aggregated_results = ""
441 incremental_json, _ = JsonResults._get_incremental_json(self._builder, FULL_RESULT_EXAMPLE, is_full_results_format=True)
442 merged_results, _ = JsonResults.merge("Webkit", aggregated_results, incremental_json, num_runs=jsonresults.JSON_RESULTS_MAX_BUILDS, sort_keys=True)
443 self.assert_json_equal(merged_results, expected_incremental_results)
445 def test_merge_empty_aggregated_results(self):
446 # No existing aggregated results.
447 # Merged results == new incremental results.
451 # Incremental results
452 {"builds": ["2", "1"],
453 "tests": {"001.html": {
454 "results": [[200, TEXT]],
455 "times": [[200, 0]]}}},
457 {"builds": ["2", "1"],
458 "tests": {"001.html": {
459 "results": [[200, TEXT]],
460 "times": [[200, 0]]}}})
462 def test_merge_duplicate_build_number(self):
465 {"builds": ["2", "1"],
466 "tests": {"001.html": {
467 "results": [[100, TEXT]],
468 "times": [[100, 0]]}}},
469 # Incremental results
471 "tests": {"001.html": {
472 "results": [[1, TEXT]],
473 "times": [[1, 0]]}}},
477 def test_merge_incremental_single_test_single_run_same_result(self):
478 # Incremental results has the latest build and same test results for
480 # Insert the incremental results at the first place and sum number
481 # of runs for TEXT (200 + 1) to get merged results.
484 {"builds": ["2", "1"],
485 "tests": {"001.html": {
486 "results": [[200, TEXT]],
487 "times": [[200, 0]]}}},
488 # Incremental results
490 "tests": {"001.html": {
491 "results": [[1, TEXT]],
492 "times": [[1, 0]]}}},
494 {"builds": ["3", "2", "1"],
495 "tests": {"001.html": {
496 "results": [[201, TEXT]],
497 "times": [[201, 0]]}}})
499 def test_merge_single_test_single_run_different_result(self):
500 # Incremental results has the latest build but different test results
502 # Insert the incremental results at the first place.
505 {"builds": ["2", "1"],
506 "tests": {"001.html": {
507 "results": [[200, TEXT]],
508 "times": [[200, 0]]}}},
509 # Incremental results
511 "tests": {"001.html": {
512 "results": [[1, IMAGE]],
513 "times": [[1, 1]]}}},
515 {"builds": ["3", "2", "1"],
516 "tests": {"001.html": {
517 "results": [[1, IMAGE], [200, TEXT]],
518 "times": [[1, 1], [200, 0]]}}})
520 def test_merge_single_test_single_run_result_changed(self):
521 # Incremental results has the latest build but results which differ from
522 # the latest result (but are the same as an older result).
525 {"builds": ["2", "1"],
526 "tests": {"001.html": {
527 "results": [[200, TEXT], [10, IMAGE]],
528 "times": [[200, 0], [10, 1]]}}},
529 # Incremental results
531 "tests": {"001.html": {
532 "results": [[1, IMAGE]],
533 "times": [[1, 1]]}}},
535 {"builds": ["3", "2", "1"],
536 "tests": {"001.html": {
537 "results": [[1, IMAGE], [200, TEXT], [10, IMAGE]],
538 "times": [[1, 1], [200, 0], [10, 1]]}}})
540 def test_merge_multiple_tests_single_run(self):
541 # All tests have incremental updates.
544 {"builds": ["2", "1"],
545 "tests": {"001.html": {
546 "results": [[200, TEXT]],
547 "times": [[200, 0]]},
549 "results": [[100, IMAGE]],
550 "times": [[100, 1]]}}},
551 # Incremental results
553 "tests": {"001.html": {
554 "results": [[1, TEXT]],
557 "results": [[1, IMAGE]],
558 "times": [[1, 1]]}}},
560 {"builds": ["3", "2", "1"],
561 "tests": {"001.html": {
562 "results": [[201, TEXT]],
563 "times": [[201, 0]]},
565 "results": [[101, IMAGE]],
566 "times": [[101, 1]]}}})
568 def test_merge_multiple_tests_single_run_one_no_result(self):
571 {"builds": ["2", "1"],
572 "tests": {"001.html": {
573 "results": [[200, TEXT]],
574 "times": [[200, 0]]},
576 "results": [[100, IMAGE]],
577 "times": [[100, 1]]}}},
578 # Incremental results
580 "tests": {"002.html": {
581 "results": [[1, IMAGE]],
582 "times": [[1, 1]]}}},
584 {"builds": ["3", "2", "1"],
585 "tests": {"001.html": {
586 "results": [[1, NO_DATA], [200, TEXT]],
587 "times": [[201, 0]]},
589 "results": [[101, IMAGE]],
590 "times": [[101, 1]]}}})
592 def test_merge_single_test_multiple_runs(self):
595 {"builds": ["2", "1"],
596 "tests": {"001.html": {
597 "results": [[200, TEXT]],
598 "times": [[200, 0]]}}},
599 # Incremental results
600 {"builds": ["4", "3"],
601 "tests": {"001.html": {
602 "results": [[2, IMAGE], [1, FAIL]],
603 "times": [[3, 2]]}}},
605 {"builds": ["4", "3", "2", "1"],
606 "tests": {"001.html": {
607 "results": [[1, FAIL], [2, IMAGE], [200, TEXT]],
608 "times": [[3, 2], [200, 0]]}}})
610 def test_merge_multiple_tests_multiple_runs(self):
613 {"builds": ["2", "1"],
614 "tests": {"001.html": {
615 "results": [[200, TEXT]],
616 "times": [[200, 0]]},
618 "results": [[10, IMAGE_PLUS_TEXT]],
619 "times": [[10, 0]]}}},
620 # Incremental results
621 {"builds": ["4", "3"],
622 "tests": {"001.html": {
623 "results": [[2, IMAGE]],
626 "results": [[1, CRASH]],
627 "times": [[1, 1]]}}},
629 {"builds": ["4", "3", "2", "1"],
630 "tests": {"001.html": {
631 "results": [[2, IMAGE], [200, TEXT]],
632 "times": [[2, 2], [200, 0]]},
634 "results": [[1, CRASH], [10, IMAGE_PLUS_TEXT]],
635 "times": [[1, 1], [10, 0]]}}})
637 def test_merge_incremental_result_older_build(self):
638 # Test the build in incremental results is older than the most recent
639 # build in aggregated results.
642 {"builds": ["3", "1"],
643 "tests": {"001.html": {
644 "results": [[5, TEXT]],
645 "times": [[5, 0]]}}},
646 # Incremental results
648 "tests": {"001.html": {
649 "results": [[1, TEXT]],
650 "times": [[1, 0]]}}},
651 # Expected no merge happens.
652 {"builds": ["2", "3", "1"],
653 "tests": {"001.html": {
654 "results": [[6, TEXT]],
655 "times": [[6, 0]]}}})
657 def test_merge_incremental_result_same_build(self):
658 # Test the build in incremental results is same as the build in
659 # aggregated results.
662 {"builds": ["2", "1"],
663 "tests": {"001.html": {
664 "results": [[5, TEXT]],
665 "times": [[5, 0]]}}},
666 # Incremental results
667 {"builds": ["3", "2"],
668 "tests": {"001.html": {
669 "results": [[2, TEXT]],
670 "times": [[2, 0]]}}},
671 # Expected no merge happens.
672 {"builds": ["3", "2", "2", "1"],
673 "tests": {"001.html": {
674 "results": [[7, TEXT]],
675 "times": [[7, 0]]}}})
677 def test_merge_remove_new_test(self):
680 {"builds": ["2", "1"],
681 "tests": {"001.html": {
682 "results": [[199, TEXT]],
683 "times": [[199, 0]]},
685 # Incremental results
687 "tests": {"001.html": {
688 "results": [[1, TEXT]],
691 "results": [[1, PASS]],
694 "results": [[1, NOTRUN]],
697 "results": [[1, NO_DATA]],
701 {"builds": ["3", "2", "1"],
702 "tests": {"001.html": {
703 "results": [[200, TEXT]],
704 "times": [[200, 0]]},
708 def test_merge_remove_test(self):
712 "builds": ["2", "1"],
717 "results": [[200, PASS]],
723 "results": [[10, TEXT]],
727 "results": [[190, PASS], [9, NO_DATA], [1, TEXT]],
732 # Incremental results
739 "results": [[1, PASS]],
745 "results": [[1, PASS]],
749 "results": [[1, PASS]],
756 "builds": ["3", "2", "1"],
759 "results": [[1, PASS], [10, TEXT]],
766 def test_merge_updates_expected(self):
770 "builds": ["2", "1"],
776 "results": [[200, PASS]],
782 "bugs": ["crbug.com/1234"],
784 "results": [[10, TEXT]],
789 "results": [[190, PASS], [9, NO_DATA], [1, TEXT]],
793 "results": [[199, PASS], [1, TEXT]],
798 # Incremental results
804 "results": [[1, PASS]],
808 "expected": "TIMEOUT",
809 "results": [[1, PASS]],
813 "bugs": ["crbug.com/1234"],
814 "results": [[1, PASS]],
821 "builds": ["3", "2", "1"],
824 "results": [[1, PASS], [10, TEXT]],
828 "expected": "TIMEOUT",
829 "results": [[191, PASS], [9, NO_DATA]],
833 "bugs": ["crbug.com/1234"],
834 "results": [[200, PASS]],
842 def test_merge_keep_test_with_all_pass_but_slow_time(self):
845 {"builds": ["2", "1"],
846 "tests": {"001.html": {
847 "results": [[200, PASS]],
848 "times": [[200, jsonresults.JSON_RESULTS_MIN_TIME]]},
850 "results": [[10, TEXT]],
851 "times": [[10, 0]]}}},
852 # Incremental results
854 "tests": {"001.html": {
855 "results": [[1, PASS]],
858 "results": [[1, PASS]],
859 "times": [[1, 0]]}}},
861 {"builds": ["3", "2", "1"],
862 "tests": {"001.html": {
863 "results": [[201, PASS]],
864 "times": [[1, 1], [200, jsonresults.JSON_RESULTS_MIN_TIME]]},
866 "results": [[1, PASS], [10, TEXT]],
867 "times": [[11, 0]]}}})
869 def test_merge_pruning_slow_tests_for_debug_builders(self):
870 self._builder = "MockBuilder(dbg)"
873 {"builds": ["2", "1"],
874 "tests": {"001.html": {
875 "results": [[200, PASS]],
876 "times": [[200, 3 * jsonresults.JSON_RESULTS_MIN_TIME]]},
878 "results": [[10, TEXT]],
879 "times": [[10, 0]]}}},
880 # Incremental results
882 "tests": {"001.html": {
883 "results": [[1, PASS]],
886 "results": [[1, PASS]],
889 "results": [[1, PASS]],
890 "times": [[1, jsonresults.JSON_RESULTS_MIN_TIME]]}}},
892 {"builds": ["3", "2", "1"],
893 "tests": {"001.html": {
894 "results": [[201, PASS]],
895 "times": [[1, 1], [200, 3 * jsonresults.JSON_RESULTS_MIN_TIME]]},
897 "results": [[1, PASS], [10, TEXT]],
898 "times": [[11, 0]]}}})
900 def test_merge_prune_extra_results(self):
901 # Remove items from test results and times that exceed the max number
902 # of builds to track.
903 max_builds = jsonresults.JSON_RESULTS_MAX_BUILDS
906 {"builds": ["2", "1"],
907 "tests": {"001.html": {
908 "results": [[max_builds, TEXT], [1, IMAGE]],
909 "times": [[max_builds, 0], [1, 1]]}}},
910 # Incremental results
912 "tests": {"001.html": {
913 "results": [[1, TIMEOUT]],
914 "times": [[1, 1]]}}},
916 {"builds": ["3", "2", "1"],
917 "tests": {"001.html": {
918 "results": [[1, TIMEOUT], [max_builds, TEXT]],
919 "times": [[1, 1], [max_builds, 0]]}}})
921 def test_merge_prune_extra_results_small(self):
922 # Remove items from test results and times that exceed the max number
923 # of builds to track, using smaller threshold.
924 max_builds = jsonresults.JSON_RESULTS_MAX_BUILDS_SMALL
927 {"builds": ["2", "1"],
928 "tests": {"001.html": {
929 "results": [[max_builds, TEXT], [1, IMAGE]],
930 "times": [[max_builds, 0], [1, 1]]}}},
931 # Incremental results
933 "tests": {"001.html": {
934 "results": [[1, TIMEOUT]],
935 "times": [[1, 1]]}}},
937 {"builds": ["3", "2", "1"],
938 "tests": {"001.html": {
939 "results": [[1, TIMEOUT], [max_builds, TEXT]],
940 "times": [[1, 1], [max_builds, 0]]}}},
943 def test_merge_prune_extra_results_with_new_result_of_same_type(self):
944 # Test that merging in a new result of the same type as the last result
945 # causes old results to fall off.
946 max_builds = jsonresults.JSON_RESULTS_MAX_BUILDS_SMALL
949 {"builds": ["2", "1"],
950 "tests": {"001.html": {
951 "results": [[max_builds, TEXT], [1, NO_DATA]],
952 "times": [[max_builds, 0], [1, 1]]}}},
953 # Incremental results
955 "tests": {"001.html": {
956 "results": [[1, TEXT]],
957 "times": [[1, 0]]}}},
959 {"builds": ["3", "2", "1"],
960 "tests": {"001.html": {
961 "results": [[max_builds, TEXT]],
962 "times": [[max_builds, 0]]}}},
965 def test_merge_build_directory_hierarchy(self):
968 {"builds": ["2", "1"],
969 "tests": {"bar": {"baz": {
971 "results": [[25, TEXT]],
972 "times": [[25, 0]]}}},
975 "results": [[50, TEXT]],
978 "results": [[100, IMAGE]],
979 "times": [[100, 0]]}}},
981 # Incremental results
985 "results": [[1, IMAGE]],
989 "results": [[1, TEXT]],
992 "results": [[1, IMAGE]],
993 "times": [[1, 0]]}}},
996 {"builds": ["3", "2", "1"],
997 "tests": {"bar": {"baz": {
999 "results": [[1, NO_DATA], [25, TEXT]],
1000 "times": [[26, 0]]}}},
1003 "results": [[1, IMAGE]],
1004 "times": [[1, 0]]}},
1007 "results": [[51, TEXT]],
1008 "times": [[51, 0]]},
1010 "results": [[101, IMAGE]],
1011 "times": [[101, 0]]}}},
1014 # FIXME(aboxhall): Add some tests for xhtml/svg test results.
1016 def test_get_test_name_list(self):
1017 # Get test name list only. Don't include non-test-list data and
1018 # of test result details.
1019 # FIXME: This also tests a temporary bug in the data where directory-level
1020 # results have a results and times values. Once that bug is fixed,
1021 # remove this test-case and assert we don't ever hit it.
1022 self._test_get_test_list(
1024 {"builds": ["3", "2", "1"],
1027 "results": [[200, PASS]],
1028 "times": [[200, 0]]},
1029 "results": [[1, NO_DATA]],
1032 "results": [[10, TEXT]],
1033 "times": [[10, 0]]}}},
1035 {"foo": {"001.html": {}}, "002.html": {}})
1037 def test_gtest(self):
1039 # Aggregated results
1040 {"builds": ["2", "1"],
1041 "tests": {"foo.bar": {
1042 "results": [[50, TEXT]],
1043 "times": [[50, 0]]},
1045 "results": [[100, IMAGE]],
1046 "times": [[100, 0]]},
1048 "results": [[5, FAIL]],
1052 # Incremental results
1054 "tests": {"foo.bar2": {
1055 "results": [[1, IMAGE]],
1058 "results": [[1, TEXT]],
1061 "results": [[5, FAIL]],
1066 {"builds": ["3", "2", "1"],
1067 "tests": {"foo.bar": {
1068 "results": [[1, NO_DATA], [50, TEXT]],
1069 "times": [[51, 0]]},
1071 "results": [[101, IMAGE]],
1072 "times": [[101, 0]]},
1074 "results": [[1, TEXT]],
1077 "results": [[10, FAIL]],
1078 "times": [[10, 0]]},
1082 if __name__ == '__main__':