OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
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 | |
4 # found in the LICENSE file. | |
5 | |
6 """Verify basic usage of sharding_supervisor.""" | |
7 | |
8 import difflib | |
9 import os | |
10 import subprocess | |
11 import sys | |
12 import unittest | |
13 | |
14 from xml.dom import minidom | |
15 | |
16 import sharding_supervisor_old as sharding_supervisor | |
17 | |
18 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
19 SHARDING_SUPERVISOR = os.path.join(ROOT_DIR, 'sharding_supervisor.py') | |
20 DUMMY_TEST = os.path.join(ROOT_DIR, 'dummy_test.py') | |
21 NUM_CORES = sharding_supervisor.DetectNumCores() | |
22 SHARDS_PER_CORE = sharding_supervisor.SS_DEFAULT_SHARDS_PER_CORE | |
23 | |
24 | |
25 def generate_expected_output(start, end, num_shards): | |
26 """Generate the expected stdout and stderr for the dummy test.""" | |
27 stdout = '' | |
28 stderr = '' | |
29 for i in range(start, end): | |
30 stdout += 'Running shard %d of %d%s' % (i, num_shards, os.linesep) | |
31 stdout += '%sALL SHARDS PASSED!%sALL TESTS PASSED!%s' % (os.linesep, | |
32 os.linesep, | |
33 os.linesep) | |
34 | |
35 return (stdout, stderr) | |
36 | |
37 | |
38 class ShardingSupervisorUnittest(unittest.TestCase): | |
39 def test_basic_run(self): | |
40 # Default test. | |
41 expected_shards = NUM_CORES * SHARDS_PER_CORE | |
42 (expected_out, expected_err) = generate_expected_output( | |
43 0, expected_shards, expected_shards) | |
44 p = subprocess.Popen([sys.executable, SHARDING_SUPERVISOR, '--no-color', | |
45 DUMMY_TEST], stdout=subprocess.PIPE, | |
46 stderr=subprocess.PIPE) | |
47 | |
48 (out, err) = p.communicate() | |
49 self.assertEqual(expected_out, out) | |
50 self.assertEqual(expected_err, err) | |
51 self.assertEqual(0, p.returncode) | |
52 | |
53 def test_shard_per_core(self): | |
54 """Test the --shards_per_core parameter.""" | |
55 expected_shards = NUM_CORES * 25 | |
56 (expected_out, expected_err) = generate_expected_output( | |
57 0, expected_shards, expected_shards) | |
58 p = subprocess.Popen([sys.executable, SHARDING_SUPERVISOR, '--no-color', | |
59 '--shards_per_core', '25', DUMMY_TEST], | |
60 stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
61 | |
62 (out, err) = p.communicate() | |
63 self.assertEqual(expected_out, out) | |
64 self.assertEqual(expected_err, err) | |
65 self.assertEqual(0, p.returncode) | |
66 | |
67 def test_slave_sharding(self): | |
68 """Test the --total-slaves and --slave-index parameters.""" | |
69 total_shards = 6 | |
70 expected_shards = NUM_CORES * SHARDS_PER_CORE * total_shards | |
71 | |
72 # Test every single index to make sure they run correctly. | |
73 for index in range(total_shards): | |
74 begin = NUM_CORES * SHARDS_PER_CORE * index | |
75 end = begin + NUM_CORES * SHARDS_PER_CORE | |
76 (expected_out, expected_err) = generate_expected_output( | |
77 begin, end, expected_shards) | |
78 p = subprocess.Popen([sys.executable, SHARDING_SUPERVISOR, '--no-color', | |
79 '--total-slaves', str(total_shards), | |
80 '--slave-index', str(index), | |
81 DUMMY_TEST], | |
82 stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
83 | |
84 (out, err) = p.communicate() | |
85 self.assertEqual(expected_out, out) | |
86 self.assertEqual(expected_err, err) | |
87 self.assertEqual(0, p.returncode) | |
88 | |
89 def test_append_to_xml(self): | |
90 shard_xml_path = os.path.join(ROOT_DIR, 'data', 'gtest_results.xml') | |
91 expected_xml_path = os.path.join( | |
92 ROOT_DIR, 'data', 'gtest_results_expected.xml') | |
93 merged_xml = sharding_supervisor.AppendToXML(None, shard_xml_path, 0) | |
94 merged_xml = sharding_supervisor.AppendToXML(merged_xml, shard_xml_path, 1) | |
95 | |
96 with open(expected_xml_path) as expected_xml_file: | |
97 expected_xml = minidom.parse(expected_xml_file) | |
98 | |
99 # Serialize XML to a list of strings that is consistently formatted | |
100 # (ignoring whitespace between elements) so that it may be compared. | |
101 def _serialize_xml(xml): | |
102 def _remove_whitespace_and_comments(xml): | |
103 children_to_remove = [] | |
104 for child in xml.childNodes: | |
105 if (child.nodeType == minidom.Node.TEXT_NODE and | |
106 not child.data.strip()): | |
107 children_to_remove.append(child) | |
108 elif child.nodeType == minidom.Node.COMMENT_NODE: | |
109 children_to_remove.append(child) | |
110 elif child.nodeType == minidom.Node.ELEMENT_NODE: | |
111 _remove_whitespace_and_comments(child) | |
112 | |
113 for child in children_to_remove: | |
114 xml.removeChild(child) | |
115 | |
116 _remove_whitespace_and_comments(xml) | |
117 return xml.toprettyxml(indent=' ').splitlines() | |
118 | |
119 diff = list(difflib.unified_diff( | |
120 _serialize_xml(expected_xml), | |
121 _serialize_xml(merged_xml), | |
122 fromfile='gtest_results_expected.xml', | |
123 tofile='gtest_results_actual.xml')) | |
124 if diff: | |
125 self.fail('Did not merge results XML correctly:\n' + '\n'.join(diff)) | |
126 | |
127 | |
128 if __name__ == '__main__': | |
129 unittest.main() | |
OLD | NEW |