Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: tools/sharding_supervisor/sharding_supervisor_unittest.py

Issue 10749018: Make merging of shard test results handle test suites that are split across shards better. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/sharding_supervisor/sharding_supervisor.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Verify basic usage of sharding_supervisor.""" 6 """Verify basic usage of sharding_supervisor."""
7 7
8 import difflib
8 import os 9 import os
9 import subprocess 10 import subprocess
10 import sys 11 import sys
11 import unittest 12 import unittest
12 13
14 from xml.dom import minidom
15
13 import sharding_supervisor 16 import sharding_supervisor
14 17
15 SHARDING_SUPERVISOR = os.path.join(os.path.dirname(sys.argv[0]), 18 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
16 'sharding_supervisor.py') 19 SHARDING_SUPERVISOR = os.path.join(ROOT_DIR, 'sharding_supervisor.py')
17 DUMMY_TEST = os.path.join(os.path.dirname(sys.argv[0]), 'dummy_test.py') 20 DUMMY_TEST = os.path.join(ROOT_DIR, 'dummy_test.py')
18 NUM_CORES = sharding_supervisor.DetectNumCores() 21 NUM_CORES = sharding_supervisor.DetectNumCores()
19 SHARDS_PER_CORE = sharding_supervisor.SS_DEFAULT_SHARDS_PER_CORE 22 SHARDS_PER_CORE = sharding_supervisor.SS_DEFAULT_SHARDS_PER_CORE
20 23
21 24
22 def generate_expected_output(start, end, num_shards): 25 def generate_expected_output(start, end, num_shards):
23 """Generate the expected stdout and stderr for the dummy test.""" 26 """Generate the expected stdout and stderr for the dummy test."""
24 stdout = '' 27 stdout = ''
25 stderr = '' 28 stderr = ''
26 for i in range(start, end): 29 for i in range(start, end):
27 stdout += 'Running shard %d of %d\n' % (i, num_shards) 30 stdout += 'Running shard %d of %d\n' % (i, num_shards)
28 stdout += '\nALL SHARDS PASSED!\nALL TESTS PASSED!\n' 31 stdout += '\nALL SHARDS PASSED!\nALL TESTS PASSED!\n'
29 32
30 return (stdout, stderr) 33 return (stdout, stderr)
31 34
32 35
33 class ShardingSupervisorUnittest(unittest.TestCase): 36 class ShardingSupervisorUnittest(unittest.TestCase):
34 def test_basic_run(self): 37 def test_basic_run(self):
35 # Default test. 38 # Default test.
36 expected_shards = NUM_CORES * SHARDS_PER_CORE 39 expected_shards = NUM_CORES * SHARDS_PER_CORE
37 (expected_out, expected_err) = \ 40 (expected_out, expected_err) = generate_expected_output(
38 generate_expected_output(0, expected_shards, expected_shards) 41 0, expected_shards, expected_shards)
39 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color', DUMMY_TEST], 42 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color', DUMMY_TEST],
40 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 43 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
41 44
42 (out, err) = p.communicate() 45 (out, err) = p.communicate()
43 self.assertEqual(expected_out, out) 46 self.assertEqual(expected_out, out)
44 self.assertEqual(expected_err, err) 47 self.assertEqual(expected_err, err)
45 self.assertEqual(0, p.returncode) 48 self.assertEqual(0, p.returncode)
46 49
47 def test_shard_per_core(self): 50 def test_shard_per_core(self):
48 """Test the --shards_per_core parameter.""" 51 """Test the --shards_per_core parameter."""
49 expected_shards = NUM_CORES * 25 52 expected_shards = NUM_CORES * 25
50 (expected_out, expected_err) = \ 53 (expected_out, expected_err) = generate_expected_output(
51 generate_expected_output(0, expected_shards, expected_shards) 54 0, expected_shards, expected_shards)
52 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color', 55 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color',
53 '--shards_per_core', '25', DUMMY_TEST], 56 '--shards_per_core', '25', DUMMY_TEST],
54 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 57 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55 58
56 (out, err) = p.communicate() 59 (out, err) = p.communicate()
57 self.assertEqual(expected_out, out) 60 self.assertEqual(expected_out, out)
58 self.assertEqual(expected_err, err) 61 self.assertEqual(expected_err, err)
59 self.assertEqual(0, p.returncode) 62 self.assertEqual(0, p.returncode)
60 63
61 def test_slave_sharding(self): 64 def test_slave_sharding(self):
62 """Test the --total-slaves and --slave-index parameters.""" 65 """Test the --total-slaves and --slave-index parameters."""
63 total_shards = 6 66 total_shards = 6
64 expected_shards = NUM_CORES * SHARDS_PER_CORE * total_shards 67 expected_shards = NUM_CORES * SHARDS_PER_CORE * total_shards
65 68
66 # Test every single index to make sure they run correctly. 69 # Test every single index to make sure they run correctly.
67 for index in range(total_shards): 70 for index in range(total_shards):
68 begin = NUM_CORES * SHARDS_PER_CORE * index 71 begin = NUM_CORES * SHARDS_PER_CORE * index
69 end = begin + NUM_CORES * SHARDS_PER_CORE 72 end = begin + NUM_CORES * SHARDS_PER_CORE
70 (expected_out, expected_err) = \ 73 (expected_out, expected_err) = generate_expected_output(
71 generate_expected_output(begin, end, expected_shards) 74 begin, end, expected_shards)
72 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color', 75 p = subprocess.Popen([SHARDING_SUPERVISOR, '--no-color',
73 '--total-slaves', str(total_shards), 76 '--total-slaves', str(total_shards),
74 '--slave-index', str(index), 77 '--slave-index', str(index),
75 DUMMY_TEST], 78 DUMMY_TEST],
76 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 79 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
77 80
78 (out, err) = p.communicate() 81 (out, err) = p.communicate()
79 self.assertEqual(expected_out, out) 82 self.assertEqual(expected_out, out)
80 self.assertEqual(expected_err, err) 83 self.assertEqual(expected_err, err)
81 self.assertEqual(0, p.returncode) 84 self.assertEqual(0, p.returncode)
82 85
86 def test_append_to_xml(self):
87 shard_xml_path = os.path.join(ROOT_DIR, 'data', 'gtest_results.xml')
88 expected_xml_path = os.path.join(
89 ROOT_DIR, 'data', 'gtest_results_expected.xml')
90 merged_xml = sharding_supervisor.AppendToXML(None, shard_xml_path, 0)
91 merged_xml = sharding_supervisor.AppendToXML(merged_xml, shard_xml_path, 1)
92
93 with open(expected_xml_path) as expected_xml_file:
94 expected_xml = minidom.parse(expected_xml_file)
95
96 # Serialize XML to a list of strings that is consistently formatted
97 # (ignoring whitespace between elements) so that it may be compared.
98 def _serialize_xml(xml):
99 def _remove_whitespace_and_comments(xml):
100 children_to_remove = []
101 for child in xml.childNodes:
102 if (child.nodeType == minidom.Node.TEXT_NODE and
103 not child.data.strip()):
104 children_to_remove.append(child)
105 elif child.nodeType == minidom.Node.COMMENT_NODE:
106 children_to_remove.append(child)
107 elif child.nodeType == minidom.Node.ELEMENT_NODE:
108 _remove_whitespace_and_comments(child)
109
110 for child in children_to_remove:
111 xml.removeChild(child)
112
113 _remove_whitespace_and_comments(xml)
114 return xml.toprettyxml(indent=' ').splitlines()
115
116 diff = list(difflib.unified_diff(
117 _serialize_xml(expected_xml),
118 _serialize_xml(merged_xml),
119 fromfile='gtest_results_expected.xml',
120 tofile='gtest_results_actual.xml'))
121 if diff:
122 self.fail('Did not merge results XML correctly:\n' + '\n'.join(diff))
123
83 124
84 if __name__ == '__main__': 125 if __name__ == '__main__':
85 unittest.main() 126 unittest.main()
OLDNEW
« no previous file with comments | « tools/sharding_supervisor/sharding_supervisor.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698