| 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 import json | |
| 7 import os | |
| 8 import StringIO | |
| 9 import sys | |
| 10 import unittest | |
| 11 | |
| 12 import auto_stub | |
| 13 | |
| 14 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| 15 sys.path.insert(0, ROOT_DIR) | |
| 16 import swarm_trigger_step | |
| 17 | |
| 18 FILE_NAME = u'test.isolated' | |
| 19 FILE_HASH = u'brodoyouevenhash' | |
| 20 TEST_NAME = u'unit_tests' | |
| 21 STDOUT_FOR_TRIGGER_LEN = 188 | |
| 22 | |
| 23 | |
| 24 def chromium_tasks(retrieval_url): | |
| 25 return [ | |
| 26 { | |
| 27 u'action': [ | |
| 28 u'python', u'run_isolated.py', | |
| 29 u'--hash', FILE_HASH, | |
| 30 u'--remote', retrieval_url + u'default-gzip/', | |
| 31 ], | |
| 32 u'decorate_output': False, | |
| 33 u'test_name': u'Run Test', | |
| 34 u'time_out': 600, | |
| 35 }, | |
| 36 { | |
| 37 u'action' : [ | |
| 38 u'python', u'swarm_cleanup.py', | |
| 39 ], | |
| 40 u'decorate_output': False, | |
| 41 u'test_name': u'Clean Up', | |
| 42 u'time_out': 600, | |
| 43 } | |
| 44 ] | |
| 45 | |
| 46 | |
| 47 def generate_expected_json( | |
| 48 shards, | |
| 49 os_image, | |
| 50 working_dir, | |
| 51 data_server, | |
| 52 profile): | |
| 53 retrieval_url = data_server + '/content/retrieve/' | |
| 54 os_value = unicode(swarm_trigger_step.PLATFORM_MAPPING[os_image]) | |
| 55 expected = { | |
| 56 u'cleanup': u'root', | |
| 57 u'configurations': [ | |
| 58 { | |
| 59 u'config_name': os_value, | |
| 60 u'dimensions': { | |
| 61 u'os': os_value, | |
| 62 }, | |
| 63 u'min_instances': shards, | |
| 64 }, | |
| 65 ], | |
| 66 u'data': [[retrieval_url + u'default/', u'swarm_data.zip']], | |
| 67 u'env_vars': {}, | |
| 68 u'restart_on_failure': True, | |
| 69 u'test_case_name': TEST_NAME, | |
| 70 u'tests': chromium_tasks(retrieval_url), | |
| 71 u'working_dir': unicode(working_dir), | |
| 72 u'priority': 101, | |
| 73 } | |
| 74 if shards > 1: | |
| 75 expected[u'env_vars'][u'GTEST_SHARD_INDEX'] = u'%(instance_index)s' | |
| 76 expected[u'env_vars'][u'GTEST_TOTAL_SHARDS'] = u'%(num_instances)s' | |
| 77 if profile: | |
| 78 expected[u'tests'][0][u'action'].append(u'--verbose') | |
| 79 return expected | |
| 80 | |
| 81 | |
| 82 class MockZipFile(object): | |
| 83 def __init__(self, filename, mode): | |
| 84 pass | |
| 85 | |
| 86 def write(self, source, dest=None): | |
| 87 pass | |
| 88 | |
| 89 def close(self): | |
| 90 pass | |
| 91 | |
| 92 | |
| 93 def MockUrlOpen(url, _data, has_return_value): | |
| 94 if '/content/contains' in url: | |
| 95 return StringIO.StringIO(has_return_value) | |
| 96 return StringIO.StringIO('{}') | |
| 97 | |
| 98 | |
| 99 def MockUrlOpenHasZip(url, data=None, content_type=None): | |
| 100 assert content_type in (None, 'application/json', 'application/octet-stream') | |
| 101 return MockUrlOpen(url, data, has_return_value=chr(1)) | |
| 102 | |
| 103 | |
| 104 def MockUrlOpenNoZip(url, data=None, content_type=None): | |
| 105 assert content_type in (None, 'application/json', 'application/octet-stream') | |
| 106 return MockUrlOpen(url, data, has_return_value=chr(0)) | |
| 107 | |
| 108 | |
| 109 class ManifestTest(auto_stub.TestCase): | |
| 110 def setUp(self): | |
| 111 self.mock(swarm_trigger_step.time, 'sleep', lambda x: None) | |
| 112 self.mock(swarm_trigger_step.zipfile, 'ZipFile', MockZipFile) | |
| 113 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 114 self.mock(sys, 'stderr', StringIO.StringIO()) | |
| 115 | |
| 116 def tearDown(self): | |
| 117 if not self.has_failed(): | |
| 118 self._check_output('', '') | |
| 119 super(ManifestTest, self).tearDown() | |
| 120 | |
| 121 def _check_output(self, out, err): | |
| 122 self.assertEqual(out, sys.stdout.getvalue()) | |
| 123 self.assertEqual(err, sys.stderr.getvalue()) | |
| 124 | |
| 125 # Flush their content by mocking them again. | |
| 126 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 127 self.mock(sys, 'stderr', StringIO.StringIO()) | |
| 128 | |
| 129 def test_basic_manifest(self): | |
| 130 manifest = swarm_trigger_step.Manifest( | |
| 131 manifest_hash=FILE_HASH, | |
| 132 test_name=TEST_NAME, | |
| 133 shards=2, | |
| 134 test_filter='*', | |
| 135 os_image='win32', | |
| 136 working_dir='swarm_tests', | |
| 137 data_server='http://localhost:8081', | |
| 138 verbose=False, | |
| 139 profile=False, | |
| 140 priority=101) | |
| 141 | |
| 142 swarm_trigger_step.chromium_setup(manifest) | |
| 143 manifest_json = json.loads(manifest.to_json()) | |
| 144 | |
| 145 expected = generate_expected_json( | |
| 146 shards=2, | |
| 147 os_image='win32', | |
| 148 working_dir='swarm_tests', | |
| 149 data_server='http://localhost:8081', | |
| 150 profile=False) | |
| 151 self.assertEqual(expected, manifest_json) | |
| 152 | |
| 153 def test_basic_linux(self): | |
| 154 """A basic linux manifest test to ensure that windows specific values | |
| 155 aren't used. | |
| 156 """ | |
| 157 manifest = swarm_trigger_step.Manifest( | |
| 158 manifest_hash=FILE_HASH, | |
| 159 test_name=TEST_NAME, | |
| 160 shards=1, | |
| 161 test_filter='*', | |
| 162 os_image='linux2', | |
| 163 working_dir='swarm_tests', | |
| 164 data_server='http://localhost:8081', | |
| 165 verbose=False, | |
| 166 profile=False, | |
| 167 priority=101) | |
| 168 | |
| 169 swarm_trigger_step.chromium_setup(manifest) | |
| 170 manifest_json = json.loads(manifest.to_json()) | |
| 171 | |
| 172 expected = generate_expected_json( | |
| 173 shards=1, | |
| 174 os_image='linux2', | |
| 175 working_dir='swarm_tests', | |
| 176 data_server='http://localhost:8081', | |
| 177 profile=False) | |
| 178 self.assertEqual(expected, manifest_json) | |
| 179 | |
| 180 def test_basic_linux_profile(self): | |
| 181 manifest = swarm_trigger_step.Manifest( | |
| 182 manifest_hash=FILE_HASH, | |
| 183 test_name=TEST_NAME, | |
| 184 shards=1, | |
| 185 test_filter='*', | |
| 186 os_image='linux2', | |
| 187 working_dir='swarm_tests', | |
| 188 data_server='http://localhost:8081', | |
| 189 verbose=False, | |
| 190 profile=True, | |
| 191 priority=101) | |
| 192 | |
| 193 swarm_trigger_step.chromium_setup(manifest) | |
| 194 manifest_json = json.loads(manifest.to_json()) | |
| 195 | |
| 196 expected = generate_expected_json( | |
| 197 shards=1, | |
| 198 os_image='linux2', | |
| 199 working_dir='swarm_tests', | |
| 200 data_server='http://localhost:8081', | |
| 201 profile=True) | |
| 202 self.assertEqual(expected, manifest_json) | |
| 203 | |
| 204 def test_process_manifest_success(self): | |
| 205 self.mock(swarm_trigger_step.run_isolated, 'url_open', MockUrlOpenNoZip) | |
| 206 | |
| 207 result = swarm_trigger_step.process_manifest( | |
| 208 file_sha1=FILE_HASH, | |
| 209 test_name=TEST_NAME, | |
| 210 shards=1, | |
| 211 test_filter='*', | |
| 212 os_image='linux2', | |
| 213 working_dir='swarm_tests', | |
| 214 data_server='http://localhost:8081', | |
| 215 swarm_url='http://localhost:8082', | |
| 216 verbose=False, | |
| 217 profile=False, | |
| 218 priority=101) | |
| 219 self.assertEqual(0, result) | |
| 220 | |
| 221 # Just assert it printed enough, since it contains variable output. | |
| 222 out = sys.stdout.getvalue() | |
| 223 self.assertTrue(len(out) > STDOUT_FOR_TRIGGER_LEN) | |
| 224 self.assertTrue('Zip file not on server, starting uploading.' in out) | |
| 225 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 226 | |
| 227 def test_process_manifest_success_zip_already_uploaded(self): | |
| 228 self.mock(swarm_trigger_step.run_isolated, 'url_open', MockUrlOpenHasZip) | |
| 229 | |
| 230 result = swarm_trigger_step.process_manifest( | |
| 231 file_sha1=FILE_HASH, | |
| 232 test_name=TEST_NAME, | |
| 233 shards=1, | |
| 234 test_filter='*', | |
| 235 os_image='linux2', | |
| 236 working_dir='swarm_tests', | |
| 237 data_server='http://localhost:8081', | |
| 238 swarm_url='http://localhost:8082', | |
| 239 verbose=False, | |
| 240 profile=False, | |
| 241 priority=101) | |
| 242 self.assertEqual(0, result) | |
| 243 | |
| 244 # Just assert it printed enough, since it contains variable output. | |
| 245 out = sys.stdout.getvalue() | |
| 246 self.assertTrue(len(out) > STDOUT_FOR_TRIGGER_LEN) | |
| 247 self.assertTrue('Zip file already on server, no need to reupload.' in out) | |
| 248 self.mock(sys, 'stdout', StringIO.StringIO()) | |
| 249 | |
| 250 def test_no_dir(self): | |
| 251 try: | |
| 252 swarm_trigger_step.main([]) | |
| 253 self.fail() | |
| 254 except SystemExit as e: | |
| 255 self.assertEqual(2, e.code) | |
| 256 self._check_output( | |
| 257 '', | |
| 258 'Usage: swarm_trigger_step_test.py [options]\n\n' | |
| 259 'swarm_trigger_step_test.py: error: Must specify the data ' | |
| 260 'directory\n') | |
| 261 | |
| 262 def test_no_request(self): | |
| 263 try: | |
| 264 swarm_trigger_step.main(['-d', '.']) | |
| 265 self.fail() | |
| 266 except SystemExit as e: | |
| 267 self.assertEqual(2, e.code) | |
| 268 self._check_output( | |
| 269 '', | |
| 270 'Usage: swarm_trigger_step_test.py [options]\n\n' | |
| 271 'swarm_trigger_step_test.py: error: At least one --run_from_hash is ' | |
| 272 'required.\n') | |
| 273 | |
| 274 | |
| 275 if __name__ == '__main__': | |
| 276 if '-v' in sys.argv: | |
| 277 unittest.TestCase.maxDiff = None | |
| 278 unittest.main() | |
| OLD | NEW |