297 lines
7.8 KiB
Python
Executable File
297 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env vpython3
|
|
# Copyright 2016 The Chromium Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import copy
|
|
import os
|
|
import six
|
|
import sys
|
|
import unittest
|
|
|
|
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
# For results_merger.
|
|
sys.path.insert(0, os.path.join(THIS_DIR, '..', 'resources'))
|
|
import results_merger
|
|
|
|
|
|
GOOD_JSON_TEST_RESULT_0 = {
|
|
'tests': {
|
|
'car': {
|
|
'honda': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
},
|
|
'toyota': {
|
|
'expected': 'FAIL',
|
|
'actual': 'FAIL'
|
|
}
|
|
},
|
|
'computer': {
|
|
'dell': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
}
|
|
},
|
|
},
|
|
'interrupted': False,
|
|
'version': 3,
|
|
'seconds_since_epoch': 1406662289.76,
|
|
'num_failures_by_type': {
|
|
'FAIL': 0,
|
|
'PASS': 2
|
|
},
|
|
'layout_tests_dir': 'abc'
|
|
}
|
|
|
|
GOOD_JSON_TEST_RESULT_1 = {
|
|
'tests': {
|
|
'car': {
|
|
'tesla': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
},
|
|
},
|
|
'burger': {
|
|
'mcdonald': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
}
|
|
},
|
|
},
|
|
'interrupted': False,
|
|
'version': 3,
|
|
'seconds_since_epoch': 1406662283.11,
|
|
'num_failures_by_type': {
|
|
'FAIL': 0,
|
|
'PASS': 2
|
|
},
|
|
'layout_tests_dir': '123'
|
|
}
|
|
|
|
GOOD_JSON_TEST_RESULT_2 = {
|
|
'tests': {
|
|
'car': {
|
|
'mercedes': {
|
|
'expected': 'PASS',
|
|
'actual': 'FAIL'
|
|
},
|
|
},
|
|
'burger': {
|
|
'in n out': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
}
|
|
},
|
|
},
|
|
'interrupted': True,
|
|
'version': 3,
|
|
'seconds_since_epoch': 1406662200.01,
|
|
'num_failures_by_type': {
|
|
'FAIL': 1,
|
|
'PASS': 1
|
|
}
|
|
}
|
|
|
|
GOOD_JSON_TEST_RESULT_MERGED = {
|
|
'tests': {
|
|
'car': {
|
|
'tesla': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
},
|
|
'mercedes': {
|
|
'expected': 'PASS',
|
|
'actual': 'FAIL'
|
|
},
|
|
'honda': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
},
|
|
'toyota': {
|
|
'expected': 'FAIL',
|
|
'actual': 'FAIL'
|
|
}
|
|
},
|
|
'computer': {
|
|
'dell': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
}
|
|
},
|
|
'burger': {
|
|
'mcdonald': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
},
|
|
'in n out': {
|
|
'expected': 'PASS',
|
|
'actual': 'PASS'
|
|
}
|
|
}
|
|
},
|
|
'interrupted': True,
|
|
'version': 3,
|
|
'seconds_since_epoch': 1406662200.01,
|
|
'num_failures_by_type': {
|
|
'FAIL': 1,
|
|
'PASS': 5
|
|
},
|
|
'layout_tests_dir': '123'
|
|
}
|
|
|
|
|
|
def extend(initial, add):
|
|
out = copy.deepcopy(initial)
|
|
out.update(add)
|
|
return out
|
|
|
|
|
|
def remove(initial, keys):
|
|
out = copy.deepcopy(initial)
|
|
for k in keys:
|
|
del out[k]
|
|
return out
|
|
|
|
|
|
|
|
# These unittests are run in PRESUBMIT, but not by recipe_simulation_test, hence
|
|
# to avoid false alert on missing coverage by recipe_simulation_test, we mark
|
|
# these code as no cover.
|
|
class MergingTest(unittest.TestCase): # pragma: no cover
|
|
maxDiff = None # Show full diff if assertion fail
|
|
|
|
def test_merge_tries(self):
|
|
self.assertEqual(
|
|
{'a': 'A', 'b': {'c': 'C'}},
|
|
results_merger.merge_tries(
|
|
{'a': 'A', 'b': {}}, {'b': {'c': 'C'}}))
|
|
|
|
def test_merge_tries_unmergable(self):
|
|
with six.assertRaisesRegex(self, results_merger.MergeException, "a:b"):
|
|
results_merger.merge_tries(
|
|
{'a': {'b': 'A'}}, {'a': {'b': 'C'}})
|
|
|
|
def test_merge_metadata(self):
|
|
metadata1 = {'metadata': {'tags': ['foo', 'bar']}}
|
|
metadata2 = {'metadata': {'tags': ['foo', 'bat']}}
|
|
merged_results = results_merger.merge_test_results(
|
|
[extend(GOOD_JSON_TEST_RESULT_0, metadata1),
|
|
extend(GOOD_JSON_TEST_RESULT_1, metadata2)])
|
|
self.assertEqual(
|
|
merged_results['metadata']['tags'], ['foo', 'bat'])
|
|
|
|
def test_merge_json_test_results_nop(self):
|
|
good_json_results = (
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
GOOD_JSON_TEST_RESULT_1,
|
|
GOOD_JSON_TEST_RESULT_2,
|
|
GOOD_JSON_TEST_RESULT_MERGED)
|
|
for j in good_json_results:
|
|
# Clone so we can check the input dictionaries are not modified
|
|
a = copy.deepcopy(j)
|
|
self.assertEqual(results_merger.merge_test_results([a]), j)
|
|
self.assertEqual(a, j)
|
|
|
|
def test_merge_json_test_results_invalid_version(self):
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
extend(GOOD_JSON_TEST_RESULT_0, {'version': 5}),
|
|
])
|
|
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
extend(GOOD_JSON_TEST_RESULT_1, {'version': 5}),
|
|
])
|
|
|
|
def test_merge_json_test_results_missing_version(self):
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
remove(GOOD_JSON_TEST_RESULT_0, ['version']),
|
|
])
|
|
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
remove(GOOD_JSON_TEST_RESULT_1, ['version']),
|
|
])
|
|
|
|
def test_merge_json_test_results_invalid_extra(self):
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
extend(GOOD_JSON_TEST_RESULT_0, {'extra': True}),
|
|
])
|
|
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
extend(GOOD_JSON_TEST_RESULT_1, {'extra': True}),
|
|
])
|
|
|
|
def test_merge_json_test_results_missing_required(self):
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
remove(GOOD_JSON_TEST_RESULT_0, ['interrupted']),
|
|
])
|
|
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
remove(GOOD_JSON_TEST_RESULT_1, ['interrupted']),
|
|
])
|
|
|
|
def test_merge_json_test_results_multiple(self):
|
|
self.assertEqual(
|
|
results_merger.merge_test_results([
|
|
GOOD_JSON_TEST_RESULT_0,
|
|
GOOD_JSON_TEST_RESULT_1,
|
|
GOOD_JSON_TEST_RESULT_2,
|
|
]),
|
|
GOOD_JSON_TEST_RESULT_MERGED)
|
|
|
|
def test_merge_json_test_results_optional_matches(self):
|
|
self.assertEqual(
|
|
results_merger.merge_test_results([
|
|
extend(GOOD_JSON_TEST_RESULT_0, {'path_delimiter': '.'}),
|
|
extend(GOOD_JSON_TEST_RESULT_1, {'path_delimiter': '.'}),
|
|
extend(GOOD_JSON_TEST_RESULT_2, {'path_delimiter': '.'}),
|
|
]),
|
|
extend(GOOD_JSON_TEST_RESULT_MERGED, {'path_delimiter': '.'}))
|
|
|
|
def test_merge_json_test_results_optional_differs(self):
|
|
with self.assertRaises(results_merger.MergeException):
|
|
results_merger.merge_test_results([
|
|
extend(GOOD_JSON_TEST_RESULT_0, {'path_delimiter': '.'}),
|
|
extend(GOOD_JSON_TEST_RESULT_1, {'path_delimiter': '.'}),
|
|
extend(GOOD_JSON_TEST_RESULT_2, {'path_delimiter': '/'}),
|
|
])
|
|
|
|
def test_merge_json_test_results_optional_count(self):
|
|
self.assertEqual(
|
|
results_merger.merge_test_results([
|
|
extend(GOOD_JSON_TEST_RESULT_0, {'fixable': 1}),
|
|
extend(GOOD_JSON_TEST_RESULT_1, {'fixable': 2}),
|
|
extend(GOOD_JSON_TEST_RESULT_2, {'fixable': 3}),
|
|
]),
|
|
extend(GOOD_JSON_TEST_RESULT_MERGED, {'fixable': 6}))
|
|
|
|
def test_merge_nothing(self):
|
|
self.assertEqual(
|
|
results_merger.merge_test_results([]),
|
|
{})
|
|
|
|
# TODO(tansell): Make this test fail properly, currently fails with an
|
|
# AttributeError.
|
|
# def test_merge_test_name_conflict(self):
|
|
# self.maxDiff = None # Show full diff if assertion fail
|
|
# with self.assertRaises(results_merger.MergeException):
|
|
# results_merger.merge_test_results(
|
|
# [GOOD_JSON_TEST_RESULT_0, GOOD_JSON_TEST_RESULT_0])
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main() # pragma: no cover
|