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

Side by Side Diff: client/tests/run_isolated_test.py

Issue 2037253002: run_isolated.py: install CIPD packages (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: fix client fetching Created 4 years, 6 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
« no previous file with comments | « client/tests/isolateserver_mock.py ('k') | client/tests/subprocess42_test.py » ('j') | 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 2013 The LUCI Authors. All rights reserved. 2 # Copyright 2013 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 # pylint: disable=R0201 6 # pylint: disable=R0201
7 7
8 import StringIO 8 import StringIO
9 import base64 9 import base64
10 import functools 10 import functools
11 import json 11 import json
12 import logging 12 import logging
13 import os 13 import os
14 import sys 14 import sys
15 import tempfile 15 import tempfile
16 import unittest 16 import unittest
17 17
18 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 18 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19 sys.path.insert(0, ROOT_DIR) 19 sys.path.insert(0, ROOT_DIR)
20 sys.path.insert(0, os.path.join(ROOT_DIR, 'third_party')) 20 sys.path.insert(0, os.path.join(ROOT_DIR, 'third_party'))
21 21
22 import cipd
22 import isolated_format 23 import isolated_format
23 import isolateserver 24 import isolateserver
24 import run_isolated 25 import run_isolated
25 from depot_tools import auto_stub 26 from depot_tools import auto_stub
26 from depot_tools import fix_encoding 27 from depot_tools import fix_encoding
27 from utils import file_path 28 from utils import file_path
29 from utils import fs
28 from utils import large 30 from utils import large
29 from utils import logging_utils 31 from utils import logging_utils
30 from utils import on_error 32 from utils import on_error
31 from utils import subprocess42 33 from utils import subprocess42
32 from utils import tools 34 from utils import tools
33 35
34 import isolateserver_mock 36 import isolateserver_mock
37 import cipdserver_mock
35 38
36 39
37 def write_content(filepath, content): 40 def write_content(filepath, content):
38 with open(filepath, 'wb') as f: 41 with open(filepath, 'wb') as f:
39 f.write(content) 42 f.write(content)
40 43
41 44
42 def json_dumps(data): 45 def json_dumps(data):
43 return json.dumps(data, sort_keys=True, separators=(',', ':')) 46 return json.dumps(data, sort_keys=True, separators=(',', ':'))
44 47
(...skipping 27 matching lines...) Expand all
72 def setUp(self): 75 def setUp(self):
73 super(RunIsolatedTestBase, self).setUp() 76 super(RunIsolatedTestBase, self).setUp()
74 self.tempdir = tempfile.mkdtemp(prefix=u'run_isolated_test') 77 self.tempdir = tempfile.mkdtemp(prefix=u'run_isolated_test')
75 logging.debug(self.tempdir) 78 logging.debug(self.tempdir)
76 self.mock(run_isolated, 'make_temp_dir', self.fake_make_temp_dir) 79 self.mock(run_isolated, 'make_temp_dir', self.fake_make_temp_dir)
77 self.mock(run_isolated.auth, 'ensure_logged_in', lambda _: None) 80 self.mock(run_isolated.auth, 'ensure_logged_in', lambda _: None)
78 self.mock( 81 self.mock(
79 logging_utils.OptionParserWithLogging, 'logger_root', 82 logging_utils.OptionParserWithLogging, 'logger_root',
80 logging.Logger('unittest')) 83 logging.Logger('unittest'))
81 84
85 self.cipd_server = cipdserver_mock.MockCipdServer()
86
82 def tearDown(self): 87 def tearDown(self):
83 for dirpath, dirnames, filenames in os.walk(self.tempdir, topdown=True): 88 for dirpath, dirnames, filenames in os.walk(self.tempdir, topdown=True):
84 for filename in filenames: 89 for filename in filenames:
85 file_path.set_read_only(os.path.join(dirpath, filename), False) 90 file_path.set_read_only(os.path.join(dirpath, filename), False)
86 for dirname in dirnames: 91 for dirname in dirnames:
87 file_path.set_read_only(os.path.join(dirpath, dirname), False) 92 file_path.set_read_only(os.path.join(dirpath, dirname), False)
88 file_path.rmtree(self.tempdir) 93 file_path.rmtree(self.tempdir)
94 self.cipd_server.close()
89 super(RunIsolatedTestBase, self).tearDown() 95 super(RunIsolatedTestBase, self).tearDown()
90 96
91 @property 97 @property
92 def run_test_temp_dir(self): 98 def run_test_temp_dir(self):
93 """Where to map all files in run_isolated.run_tha_test.""" 99 """Where to map all files in run_isolated.run_tha_test."""
94 return os.path.join(self.tempdir, 'isolated_run') 100 return os.path.join(self.tempdir, 'isolated_run')
95 101
96 def fake_make_temp_dir(self, prefix, _root_dir=None): 102 def fake_make_temp_dir(self, prefix, _root_dir=None):
97 """Predictably returns directory for run_tha_test (one per test case).""" 103 """Predictably returns directory for run_tha_test (one per test case)."""
98 self.assertIn(prefix, ('isolated_out', 'isolated_run', 'isolated_tmp')) 104 self.assertIn(
105 prefix,
106 ('isolated_out', 'isolated_run', 'isolated_tmp', 'cipd_site_root'))
99 temp_dir = os.path.join(self.tempdir, prefix) 107 temp_dir = os.path.join(self.tempdir, prefix)
100 self.assertFalse(os.path.isdir(temp_dir)) 108 self.assertFalse(os.path.isdir(temp_dir))
101 os.makedirs(temp_dir) 109 os.makedirs(temp_dir)
102 return temp_dir 110 return temp_dir
103 111
104 def temp_join(self, *args): 112 def temp_join(self, *args):
105 """Shortcut for joining path with self.run_test_temp_dir.""" 113 """Shortcut for joining path with self.run_test_temp_dir."""
106 return os.path.join(self.run_test_temp_dir, *args) 114 return os.path.join(self.run_test_temp_dir, *args)
107 115
108 116
109 class RunIsolatedTest(RunIsolatedTestBase): 117 class RunIsolatedTest(RunIsolatedTestBase):
110 def setUp(self): 118 def setUp(self):
111 super(RunIsolatedTest, self).setUp() 119 super(RunIsolatedTest, self).setUp()
112 self.popen_calls = [] 120 self.popen_calls = []
113 # pylint: disable=no-self-argument 121 # pylint: disable=no-self-argument
114 class Popen(object): 122 class Popen(object):
115 def __init__(self2, args, **kwargs): 123 def __init__(self2, args, **kwargs):
116 kwargs.pop('cwd', None) 124 kwargs.pop('cwd', None)
117 kwargs.pop('env', None) 125 kwargs.pop('env', None)
118 self.popen_calls.append((args, kwargs)) 126 self.popen_calls.append((args, kwargs))
119 self2.returncode = None 127 self2.returncode = None
120 128
129 def yield_any_line(self, timeout=None): # pylint: disable=unused-argument
130 return ()
131
121 def wait(self, timeout=None): # pylint: disable=unused-argument 132 def wait(self, timeout=None): # pylint: disable=unused-argument
122 self.returncode = 0 133 self.returncode = 0
123 return self.returncode 134 return self.returncode
124 135
125 def kill(self): 136 def kill(self):
126 pass 137 pass
127 138
128 self.mock(subprocess42, 'Popen', Popen) 139 self.mock(subprocess42, 'Popen', Popen)
129 140
130 def test_main(self): 141 def test_main(self):
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 ret = run_isolated.run_tha_test( 199 ret = run_isolated.run_tha_test(
189 command, 200 command,
190 isolated_hash, 201 isolated_hash,
191 StorageFake(files), 202 StorageFake(files),
192 isolateserver.MemoryCache(), 203 isolateserver.MemoryCache(),
193 False, 204 False,
194 None, 205 None,
195 None, 206 None,
196 None, 207 None,
197 None, 208 None,
209 None,
210 None,
198 None) 211 None)
199 self.assertEqual(0, ret) 212 self.assertEqual(0, ret)
200 return make_tree_call 213 return make_tree_call
201 214
202 def test_run_tha_test_naked(self): 215 def test_run_tha_test_naked(self):
203 isolated = json_dumps({'command': ['invalid', 'command']}) 216 isolated = json_dumps({'command': ['invalid', 'command']})
204 isolated_hash = isolateserver_mock.hash_content(isolated) 217 isolated_hash = isolateserver_mock.hash_content(isolated)
205 files = {isolated_hash:isolated} 218 files = {isolated_hash:isolated}
206 make_tree_call = self._run_tha_test(isolated_hash, files) 219 make_tree_call = self._run_tha_test(isolated_hash, files)
207 self.assertEqual( 220 self.assertEqual(
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 'hello', 326 'hello',
314 'world', 327 'world',
315 ] 328 ]
316 ret = run_isolated.main(cmd) 329 ret = run_isolated.main(cmd)
317 self.assertEqual(1, ret) 330 self.assertEqual(1, ret)
318 self.assertEqual(1, len(self.popen_calls)) 331 self.assertEqual(1, len(self.popen_calls))
319 self.assertEqual( 332 self.assertEqual(
320 [([u'/bin/echo', u'hello', u'world'], {'detached': True})], 333 [([u'/bin/echo', u'hello', u'world'], {'detached': True})],
321 self.popen_calls) 334 self.popen_calls)
322 335
336 def test_main_naked_with_packages(self):
337 cmd = [
338 '--no-log',
339 '--cipd-package', 'infra/tools/echo/${platform}:latest',
340 '--cipd-server', self.cipd_server.url,
341 '${CIPD_PATH}/echo',
342 'hello',
343 'world',
344 ]
345 ret = run_isolated.main(cmd)
346 self.assertEqual(0, ret)
347
348 self.assertEqual(2, len(self.popen_calls))
349
350 # Test cipd-ensure command.
351 cipd_ensure_cmd, _ = self.popen_calls[0]
352 self.assertEqual(cipd_ensure_cmd[:2], [
353 os.path.abspath('cipd_cache/cipd' + cipd.EXECUTABLE_SUFFIX),
354 'ensure',
355 ])
356 cache_dir_index = cipd_ensure_cmd.index('-cache-dir')
357 self.assertEqual(
358 cipd_ensure_cmd[cache_dir_index+1],
359 os.path.abspath('cipd_cache/cipd_internal'))
360
361 # Test cipd cache.
362 version_file = unicode(os.path.abspath(
363 'cipd_cache/versions/1481d0a0ceb16ea4672fed76a0710306eb9f3a33'))
364 self.assertTrue(fs.isfile(version_file))
365 with open(version_file) as f:
366 self.assertEqual(f.read(), 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
367
368 client_binary_file = unicode(os.path.abspath(
369 'cipd_cache/clients/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))
370 self.assertTrue(fs.isfile(client_binary_file))
371
372 # Test echo call.
373 echo_cmd, _ = self.popen_calls[1]
374 self.assertTrue(echo_cmd[0].endswith('cipd_site_root/echo'))
375 self.assertEqual(echo_cmd[1:], ['hello', 'world'])
376
323 def test_modified_cwd(self): 377 def test_modified_cwd(self):
324 isolated = json_dumps({ 378 isolated = json_dumps({
325 'command': ['../out/some.exe', 'arg'], 379 'command': ['../out/some.exe', 'arg'],
326 'relative_cwd': 'some', 380 'relative_cwd': 'some',
327 }) 381 })
328 isolated_hash = isolateserver_mock.hash_content(isolated) 382 isolated_hash = isolateserver_mock.hash_content(isolated)
329 files = {isolated_hash:isolated} 383 files = {isolated_hash:isolated}
330 _ = self._run_tha_test(isolated_hash, files) 384 _ = self._run_tha_test(isolated_hash, files)
331 self.assertEqual(1, len(self.popen_calls)) 385 self.assertEqual(1, len(self.popen_calls))
332 self.assertEqual( 386 self.assertEqual(
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 ret = run_isolated.run_tha_test( 445 ret = run_isolated.run_tha_test(
392 None, 446 None,
393 isolated_hash, 447 isolated_hash,
394 store, 448 store,
395 isolateserver.MemoryCache(), 449 isolateserver.MemoryCache(),
396 False, 450 False,
397 None, 451 None,
398 None, 452 None,
399 None, 453 None,
400 None, 454 None,
401 []) 455 [],
456 None,
457 None)
402 self.assertEqual(0, ret) 458 self.assertEqual(0, ret)
403 459
404 # It uploaded back. Assert the store has a new item containing foo. 460 # It uploaded back. Assert the store has a new item containing foo.
405 hashes = {isolated_hash, script_hash} 461 hashes = {isolated_hash, script_hash}
406 output_hash = isolateserver_mock.hash_content('bar') 462 output_hash = isolateserver_mock.hash_content('bar')
407 hashes.add(output_hash) 463 hashes.add(output_hash)
408 isolated = { 464 isolated = {
409 'algo': 'sha-1', 465 'algo': 'sha-1',
410 'files': { 466 'files': {
411 'foo': { 467 'foo': {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 u'initial_size': 0, 578 u'initial_size': 0,
523 u'items_cold': [len(isolated_in_json)], 579 u'items_cold': [len(isolated_in_json)],
524 u'items_hot': [], 580 u'items_hot': [],
525 }, 581 },
526 u'upload': { 582 u'upload': {
527 u'items_cold': [len(isolated_out_json)], 583 u'items_cold': [len(isolated_out_json)],
528 u'items_hot': [15], 584 u'items_hot': [15],
529 }, 585 },
530 }, 586 },
531 }, 587 },
532 u'version': 4, 588 u'version': 5,
533 } 589 }
534 actual = tools.read_json(out) 590 actual = tools.read_json(out)
535 # duration can be exactly 0 due to low timer resolution, especially but not 591 # duration can be exactly 0 due to low timer resolution, especially but not
536 # exclusively on Windows. 592 # exclusively on Windows.
537 self.assertLessEqual(0, actual.pop(u'duration')) 593 self.assertLessEqual(0, actual.pop(u'duration'))
538 actual_isolated_stats = actual[u'stats'][u'isolated'] 594 actual_isolated_stats = actual[u'stats'][u'isolated']
539 self.assertLessEqual(0, actual_isolated_stats[u'download'].pop(u'duration')) 595 self.assertLessEqual(0, actual_isolated_stats[u'download'].pop(u'duration'))
540 self.assertLessEqual(0, actual_isolated_stats[u'upload'].pop(u'duration')) 596 self.assertLessEqual(0, actual_isolated_stats[u'upload'].pop(u'duration'))
541 for i in (u'download', u'upload'): 597 for i in (u'download', u'upload'):
542 for j in (u'items_cold', u'items_hot'): 598 for j in (u'items_cold', u'items_hot'):
543 actual_isolated_stats[i][j] = large.unpack( 599 actual_isolated_stats[i][j] = large.unpack(
544 base64.b64decode(actual_isolated_stats[i][j])) 600 base64.b64decode(actual_isolated_stats[i][j]))
545 self.assertEqual(expected, actual) 601 self.assertEqual(expected, actual)
546 602
547 603
548 if __name__ == '__main__': 604 if __name__ == '__main__':
549 fix_encoding.fix_encoding() 605 fix_encoding.fix_encoding()
550 if '-v' in sys.argv: 606 if '-v' in sys.argv:
551 unittest.TestCase.maxDiff = None 607 unittest.TestCase.maxDiff = None
552 logging.basicConfig( 608 logging.basicConfig(
553 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR) 609 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR)
554 unittest.main() 610 unittest.main()
OLDNEW
« no previous file with comments | « client/tests/isolateserver_mock.py ('k') | client/tests/subprocess42_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698