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

Side by Side Diff: swarm_client/tests/isolate_test.py

Issue 69143004: Delete swarm_client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 7 years, 1 month 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
OLDNEW
(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 cStringIO
7 import hashlib
8 import json
9 import logging
10 import os
11 import sys
12 import tempfile
13 import unittest
14
15 import auto_stub
16
17 ROOT_DIR = unicode(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
18 sys.path.insert(0, ROOT_DIR)
19
20 import isolate
21 from utils import file_path
22 # Create shortcuts.
23 from isolate import KEY_TOUCHED, KEY_TRACKED, KEY_UNTRACKED
24
25
26 ALGO = hashlib.sha1
27
28
29 def _size(*args):
30 return os.stat(os.path.join(ROOT_DIR, *args)).st_size
31
32
33 def hash_file(*args):
34 return isolate.isolateserver.hash_file(os.path.join(ROOT_DIR, *args), ALGO)
35
36
37 class IsolateBase(auto_stub.TestCase):
38 def setUp(self):
39 super(IsolateBase, self).setUp()
40 self.old_cwd = os.getcwd()
41 self.cwd = tempfile.mkdtemp(prefix='isolate_')
42 # Everything should work even from another directory.
43 os.chdir(self.cwd)
44
45 def tearDown(self):
46 try:
47 os.chdir(self.old_cwd)
48 isolate.run_isolated.rmtree(self.cwd)
49 finally:
50 super(IsolateBase, self).tearDown()
51
52
53 class IsolateTest(IsolateBase):
54 def test_savedstate_load_minimal(self):
55 # The file referenced by 'isolate_file' must exist even if its content is
56 # not read.
57 open(os.path.join(self.cwd, 'fake.isolate'), 'wb').close()
58 values = {
59 'isolate_file': 'fake.isolate',
60 }
61 expected = {
62 'algo': 'sha-1',
63 'child_isolated_files': [],
64 'command': [],
65 'files': {},
66 'isolate_file': 'fake.isolate',
67 'variables': {
68 'OS': isolate.get_flavor(),
69 },
70 'version': '1.0',
71 }
72 saved_state = isolate.SavedState.load(values, self.cwd)
73 self.assertEqual(expected, saved_state.flatten())
74
75 def test_savedstate_load(self):
76 # The file referenced by 'isolate_file' must exist even if its content is
77 # not read.
78 open(os.path.join(self.cwd, 'fake.isolate'), 'wb').close()
79 values = {
80 'isolate_file': 'fake.isolate',
81 'variables': {
82 'foo': 42,
83 'OS': isolate.get_flavor(),
84 },
85 }
86 expected = {
87 'algo': 'sha-1',
88 'child_isolated_files': [],
89 'command': [],
90 'files': {},
91 'isolate_file': 'fake.isolate',
92 'variables': {
93 'foo': 42,
94 'OS': isolate.get_flavor(),
95 },
96 'version': '1.0',
97 }
98 saved_state = isolate.SavedState.load(values, self.cwd)
99 self.assertEqual(expected, saved_state.flatten())
100
101 def test_unknown_key(self):
102 try:
103 isolate.verify_variables({'foo': [],})
104 self.fail()
105 except AssertionError:
106 pass
107
108 def test_unknown_var(self):
109 try:
110 isolate.verify_condition({'variables': {'foo': [],}}, {})
111 self.fail()
112 except AssertionError:
113 pass
114
115 def test_union(self):
116 value1 = {
117 'a': set(['A']),
118 'b': ['B', 'C'],
119 'c': 'C',
120 }
121 value2 = {
122 'a': set(['B', 'C']),
123 'b': [],
124 'd': set(),
125 }
126 expected = {
127 'a': set(['A', 'B', 'C']),
128 'b': ['B', 'C'],
129 'c': 'C',
130 'd': set(),
131 }
132 self.assertEqual(expected, isolate.union(value1, value2))
133
134 def test_eval_content(self):
135 try:
136 # Intrinsics are not available.
137 isolate.eval_content('map(str, [1, 2])')
138 self.fail()
139 except NameError:
140 pass
141
142 def test_load_isolate_as_config_empty(self):
143 self.assertEqual({}, isolate.load_isolate_as_config(
144 self.cwd, {}, None).flatten())
145
146 def test_load_isolate_as_config(self):
147 value = {
148 'conditions': [
149 ['OS=="amiga" or OS=="atari" or OS=="coleco" or OS=="dendy"', {
150 'variables': {
151 KEY_TRACKED: ['a'],
152 KEY_UNTRACKED: ['b'],
153 KEY_TOUCHED: ['touched'],
154 },
155 }],
156 ['OS=="atari"', {
157 'variables': {
158 KEY_TRACKED: ['c', 'x'],
159 KEY_UNTRACKED: ['d'],
160 KEY_TOUCHED: ['touched_a'],
161 'command': ['echo', 'Hello World'],
162 'read_only': True,
163 },
164 }],
165 ['OS=="amiga" or OS=="coleco" or OS=="dendy"', {
166 'variables': {
167 KEY_TRACKED: ['e', 'x'],
168 KEY_UNTRACKED: ['f'],
169 KEY_TOUCHED: ['touched_e'],
170 'command': ['echo', 'You should get an Atari'],
171 },
172 }],
173 ['OS=="amiga"', {
174 'variables': {
175 KEY_TRACKED: ['g'],
176 'read_only': False,
177 },
178 }],
179 ['OS=="amiga" or OS=="atari" or OS=="dendy"', {
180 'variables': {
181 KEY_UNTRACKED: ['h'],
182 },
183 }],
184 ],
185 }
186 expected = {
187 ('amiga',): {
188 'command': ['echo', 'You should get an Atari'],
189 KEY_TOUCHED: ['touched', 'touched_e'],
190 KEY_TRACKED: ['a', 'e', 'g', 'x'],
191 KEY_UNTRACKED: ['b', 'f', 'h'],
192 'read_only': False,
193 },
194 ('atari',): {
195 'command': ['echo', 'Hello World'],
196 KEY_TOUCHED: ['touched', 'touched_a'],
197 KEY_TRACKED: ['a', 'c', 'x'],
198 KEY_UNTRACKED: ['b', 'd', 'h'],
199 'read_only': True,
200 },
201 ('coleco',): {
202 'command': ['echo', 'You should get an Atari'],
203 KEY_TOUCHED: ['touched', 'touched_e'],
204 KEY_TRACKED: ['a', 'e', 'x'],
205 KEY_UNTRACKED: ['b', 'f'],
206 },
207 ('dendy',): {
208 'command': ['echo', 'You should get an Atari'],
209 KEY_TOUCHED: ['touched', 'touched_e'],
210 KEY_TRACKED: ['a', 'e', 'x'],
211 KEY_UNTRACKED: ['b', 'f', 'h'],
212 },
213 }
214 self.assertEqual(
215 expected, isolate.load_isolate_as_config(
216 self.cwd, value, None).flatten())
217
218 def test_load_isolate_as_config_duplicate_command(self):
219 value = {
220 'variables': {
221 'command': ['rm', '-rf', '/'],
222 },
223 'conditions': [
224 ['OS=="atari"', {
225 'variables': {
226 'command': ['echo', 'Hello World'],
227 },
228 }],
229 ],
230 }
231 try:
232 isolate.load_isolate_as_config(self.cwd, value, None)
233 self.fail()
234 except AssertionError:
235 pass
236
237 def test_invert_map(self):
238 value = {
239 ('amiga',): {
240 'command': ['echo', 'You should get an Atari'],
241 KEY_TOUCHED: ['touched', 'touched_e'],
242 KEY_TRACKED: ['a', 'e', 'g', 'x'],
243 KEY_UNTRACKED: ['b', 'f', 'h'],
244 'read_only': False,
245 },
246 ('atari',): {
247 'command': ['echo', 'Hello World'],
248 KEY_TOUCHED: ['touched', 'touched_a'],
249 KEY_TRACKED: ['a', 'c', 'x'],
250 KEY_UNTRACKED: ['b', 'd', 'h'],
251 'read_only': True,
252 },
253 ('coleco',): {
254 'command': ['echo', 'You should get an Atari'],
255 KEY_TOUCHED: ['touched', 'touched_e'],
256 KEY_TRACKED: ['a', 'e', 'x'],
257 KEY_UNTRACKED: ['b', 'f'],
258 },
259 ('dendy',): {
260 'command': ['echo', 'You should get an Atari'],
261 KEY_TOUCHED: ['touched', 'touched_e'],
262 KEY_TRACKED: ['a', 'e', 'x'],
263 KEY_UNTRACKED: ['b', 'f', 'h'],
264 },
265 }
266 amiga, atari, coleco, dendy = (
267 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy'))
268 expected_values = {
269 'command': {
270 ('echo', 'Hello World'): atari,
271 ('echo', 'You should get an Atari'): amiga | coleco | dendy,
272 },
273 KEY_TRACKED: {
274 'a': amiga | atari | coleco | dendy,
275 'c': atari,
276 'e': amiga | coleco | dendy,
277 'g': amiga,
278 'x': amiga | atari | coleco | dendy,
279 },
280 KEY_UNTRACKED: {
281 'b': amiga | atari | coleco | dendy,
282 'd': atari,
283 'f': amiga | coleco | dendy,
284 'h': amiga | atari | dendy,
285 },
286 KEY_TOUCHED: {
287 'touched': amiga | atari | coleco | dendy,
288 'touched_a': atari,
289 'touched_e': amiga | coleco | dendy,
290 },
291 'read_only': {
292 False: amiga,
293 True: atari,
294 },
295 }
296 actual_values = isolate.invert_map(value)
297 self.assertEqual(expected_values, actual_values)
298
299 def test_reduce_inputs(self):
300 amiga, atari, coleco, dendy = (
301 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy'))
302 values = {
303 'command': {
304 ('echo', 'Hello World'): atari,
305 ('echo', 'You should get an Atari'): amiga | coleco | dendy,
306 },
307 KEY_TRACKED: {
308 'a': amiga | atari | coleco | dendy,
309 'c': atari,
310 'e': amiga | coleco | dendy,
311 'g': amiga,
312 'x': amiga | atari | coleco | dendy,
313 },
314 KEY_UNTRACKED: {
315 'b': amiga | atari | coleco | dendy,
316 'd': atari,
317 'f': amiga | coleco | dendy,
318 'h': amiga | atari | dendy,
319 },
320 KEY_TOUCHED: {
321 'touched': amiga | atari | coleco | dendy,
322 'touched_a': atari,
323 'touched_e': amiga | coleco | dendy,
324 },
325 'read_only': {
326 False: amiga,
327 True: atari,
328 },
329 }
330 expected_values = {
331 'command': {
332 ('echo', 'Hello World'): atari,
333 ('echo', 'You should get an Atari'): amiga | coleco | dendy,
334 },
335 KEY_TRACKED: {
336 'a': amiga | atari | coleco | dendy,
337 'c': atari,
338 'e': amiga | coleco | dendy,
339 'g': amiga,
340 'x': amiga | atari | coleco | dendy,
341 },
342 KEY_UNTRACKED: {
343 'b': amiga | atari | coleco | dendy,
344 'd': atari,
345 'f': amiga | coleco | dendy,
346 'h': amiga | atari | dendy,
347 },
348 KEY_TOUCHED: {
349 'touched': amiga | atari | coleco | dendy,
350 'touched_a': atari,
351 'touched_e': amiga | coleco | dendy,
352 },
353 'read_only': {
354 False: amiga,
355 True: atari,
356 },
357 }
358 actual_values = isolate.reduce_inputs(values)
359 self.assertEqual(expected_values, actual_values)
360
361 def test_reduce_inputs_merge_subfolders_and_files(self):
362 linux, mac, win = (set([(os,)]) for os in ('linux', 'mac', 'win'))
363 values = {
364 KEY_TRACKED: {
365 'folder/tracked_file': win,
366 'folder_helper/tracked_file': win,
367 },
368 KEY_UNTRACKED: {
369 'folder/': linux | mac | win,
370 'folder/subfolder/': win,
371 'folder/untracked_file': linux | mac | win,
372 'folder_helper/': linux,
373 },
374 KEY_TOUCHED: {
375 'folder/touched_file': win,
376 'folder/helper_folder/deep_file': win,
377 'folder_helper/touched_file1': mac | win,
378 'folder_helper/touched_file2': linux,
379 },
380 }
381 expected_values = {
382 'command': {},
383 KEY_TRACKED: {
384 'folder_helper/tracked_file': win,
385 },
386 KEY_UNTRACKED: {
387 'folder/': linux | mac | win,
388 'folder_helper/': linux,
389 },
390 KEY_TOUCHED: {
391 'folder_helper/touched_file1': mac | win,
392 },
393 'read_only': {},
394 }
395 actual_values = isolate.reduce_inputs(values)
396 self.assertEqual(expected_values, actual_values)
397
398 def test_reduce_inputs_take_strongest_dependency(self):
399 amiga, atari, coleco, dendy = (
400 set([(os,)]) for os in ('amiga', 'atari', 'coleco', 'dendy'))
401 values = {
402 'command': {
403 ('echo', 'Hello World'): atari,
404 ('echo', 'You should get an Atari'): amiga | coleco | dendy,
405 },
406 KEY_TRACKED: {
407 'a': amiga | atari | coleco | dendy,
408 'b': amiga | atari | coleco,
409 },
410 KEY_UNTRACKED: {
411 'c': amiga | atari | coleco | dendy,
412 'd': amiga | coleco | dendy,
413 },
414 KEY_TOUCHED: {
415 'a': amiga | atari | coleco | dendy,
416 'b': atari | coleco | dendy,
417 'c': amiga | atari | coleco | dendy,
418 'd': atari | coleco | dendy,
419 },
420 }
421 expected_values = {
422 'command': {
423 ('echo', 'Hello World'): atari,
424 ('echo', 'You should get an Atari'): amiga | coleco | dendy,
425 },
426 KEY_TRACKED: {
427 'a': amiga | atari | coleco | dendy,
428 'b': amiga | atari | coleco,
429 },
430 KEY_UNTRACKED: {
431 'c': amiga | atari | coleco | dendy,
432 'd': amiga | coleco | dendy,
433 },
434 KEY_TOUCHED: {
435 'b': dendy,
436 'd': atari,
437 },
438 'read_only': {},
439 }
440 actual_values = isolate.reduce_inputs(values)
441 self.assertEqual(expected_values, actual_values)
442
443 def test_convert_map_to_isolate_dict(self):
444 amiga = ('amiga',)
445 atari = ('atari',)
446 coleco = ('coleco',)
447 dendy = ('dendy',)
448 values = {
449 'command': {
450 ('echo', 'Hello World'): (atari,),
451 ('echo', 'You should get an Atari'): (amiga, coleco, dendy),
452 },
453 KEY_TRACKED: {
454 'a': (amiga, atari, coleco, dendy),
455 'c': (atari,),
456 'e': (amiga, coleco, dendy),
457 'g': (amiga,),
458 'x': (amiga, atari, coleco, dendy),
459 },
460 KEY_UNTRACKED: {
461 'b': (amiga, atari, coleco, dendy),
462 'd': (atari,),
463 'f': (amiga, coleco, dendy),
464 'h': (amiga, atari, dendy),
465 },
466 KEY_TOUCHED: {
467 'touched': (amiga, atari, coleco, dendy),
468 'touched_a': (atari,),
469 'touched_e': (amiga, coleco, dendy),
470 },
471 'read_only': {
472 False: (amiga,),
473 True: (atari,),
474 },
475 }
476 expected_conditions = [
477 ['OS=="amiga"', {
478 'variables': {
479 KEY_TRACKED: ['g'],
480 'read_only': False,
481 },
482 }],
483 ['OS=="amiga" or OS=="atari" or OS=="coleco" or OS=="dendy"', {
484 'variables': {
485 KEY_TRACKED: ['a', 'x'],
486 KEY_UNTRACKED: ['b'],
487 KEY_TOUCHED: ['touched'],
488 },
489 }],
490 ['OS=="amiga" or OS=="atari" or OS=="dendy"', {
491 'variables': {
492 KEY_UNTRACKED: ['h'],
493 },
494 }],
495 ['OS=="amiga" or OS=="coleco" or OS=="dendy"', {
496 'variables': {
497 'command': ['echo', 'You should get an Atari'],
498 KEY_TRACKED: ['e'],
499 KEY_UNTRACKED: ['f'],
500 KEY_TOUCHED: ['touched_e'],
501 },
502 }],
503 ['OS=="atari"', {
504 'variables': {
505 'command': ['echo', 'Hello World'],
506 KEY_TRACKED: ['c'],
507 KEY_UNTRACKED: ['d'],
508 KEY_TOUCHED: ['touched_a'],
509 'read_only': True,
510 },
511 }],
512 ]
513 actual = isolate.convert_map_to_isolate_dict(values, ('OS',))
514 self.assertEqual(expected_conditions, sorted(actual.pop('conditions')))
515 self.assertFalse(actual)
516
517 def test_merge_two_empty(self):
518 # Flat stay flat. Pylint is confused about union() return type.
519 # pylint: disable=E1103
520 actual = isolate.union(
521 isolate.union(
522 isolate.Configs(None),
523 isolate.load_isolate_as_config(self.cwd, {}, None)),
524 isolate.load_isolate_as_config(self.cwd, {}, None)).flatten()
525 self.assertEqual({}, actual)
526
527 def test_merge_empty(self):
528 actual = isolate.convert_map_to_isolate_dict(
529 isolate.reduce_inputs(isolate.invert_map({})), ('dummy1', 'dummy2'))
530 self.assertEqual({'conditions': []}, actual)
531
532 def test_load_two_conditions(self):
533 linux = {
534 'conditions': [
535 ['OS=="linux"', {
536 'variables': {
537 'isolate_dependency_tracked': [
538 'file_linux',
539 'file_common',
540 ],
541 },
542 }],
543 ],
544 }
545 mac = {
546 'conditions': [
547 ['OS=="mac"', {
548 'variables': {
549 'isolate_dependency_tracked': [
550 'file_mac',
551 'file_common',
552 ],
553 },
554 }],
555 ],
556 }
557 expected = {
558 ('linux',): {
559 'isolate_dependency_tracked': ['file_common', 'file_linux'],
560 },
561 ('mac',): {
562 'isolate_dependency_tracked': ['file_common', 'file_mac'],
563 },
564 }
565 # Pylint is confused about union() return type.
566 # pylint: disable=E1103
567 configs = isolate.union(
568 isolate.union(
569 isolate.Configs(None),
570 isolate.load_isolate_as_config(self.cwd, linux, None)),
571 isolate.load_isolate_as_config(self.cwd, mac, None)).flatten()
572 self.assertEqual(expected, configs)
573
574 def test_load_three_conditions(self):
575 linux = {
576 'conditions': [
577 ['OS=="linux" and chromeos==1', {
578 'variables': {
579 'isolate_dependency_tracked': [
580 'file_linux',
581 'file_common',
582 ],
583 },
584 }],
585 ],
586 }
587 mac = {
588 'conditions': [
589 ['OS=="mac" and chromeos==0', {
590 'variables': {
591 'isolate_dependency_tracked': [
592 'file_mac',
593 'file_common',
594 ],
595 },
596 }],
597 ],
598 }
599 win = {
600 'conditions': [
601 ['OS=="win" and chromeos==0', {
602 'variables': {
603 'isolate_dependency_tracked': [
604 'file_win',
605 'file_common',
606 ],
607 },
608 }],
609 ],
610 }
611 expected = {
612 ('linux', 1): {
613 'isolate_dependency_tracked': ['file_common', 'file_linux'],
614 },
615 ('mac', 0): {
616 'isolate_dependency_tracked': ['file_common', 'file_mac'],
617 },
618 ('win', 0): {
619 'isolate_dependency_tracked': ['file_common', 'file_win'],
620 },
621 }
622 # Pylint is confused about union() return type.
623 # pylint: disable=E1103
624 configs = isolate.union(
625 isolate.union(
626 isolate.union(
627 isolate.Configs(None),
628 isolate.load_isolate_as_config(self.cwd, linux, None)),
629 isolate.load_isolate_as_config(self.cwd, mac, None)),
630 isolate.load_isolate_as_config(self.cwd, win, None)).flatten()
631 self.assertEqual(expected, configs)
632
633 def test_merge_three_conditions(self):
634 values = {
635 ('linux',): {
636 'isolate_dependency_tracked': ['file_common', 'file_linux'],
637 },
638 ('mac',): {
639 'isolate_dependency_tracked': ['file_common', 'file_mac'],
640 },
641 ('win',): {
642 'isolate_dependency_tracked': ['file_common', 'file_win'],
643 },
644 }
645 expected = {
646 'conditions': [
647 ['OS=="linux"', {
648 'variables': {
649 'isolate_dependency_tracked': [
650 'file_linux',
651 ],
652 },
653 }],
654 ['OS=="linux" or OS=="mac" or OS=="win"', {
655 'variables': {
656 'isolate_dependency_tracked': [
657 'file_common',
658 ],
659 },
660 }],
661 ['OS=="mac"', {
662 'variables': {
663 'isolate_dependency_tracked': [
664 'file_mac',
665 ],
666 },
667 }],
668 ['OS=="win"', {
669 'variables': {
670 'isolate_dependency_tracked': [
671 'file_win',
672 ],
673 },
674 }],
675 ],
676 }
677 actual = isolate.convert_map_to_isolate_dict(
678 isolate.reduce_inputs(isolate.invert_map(values)), ('OS',))
679 self.assertEqual(expected, actual)
680
681 def test_configs_comment(self):
682 # Pylint is confused with isolate.union() return type.
683 # pylint: disable=E1103
684 configs = isolate.union(
685 isolate.load_isolate_as_config(
686 self.cwd, {}, '# Yo dawg!\n# Chill out.\n'),
687 isolate.load_isolate_as_config(self.cwd, {}, None))
688 self.assertEqual('# Yo dawg!\n# Chill out.\n', configs.file_comment)
689
690 configs = isolate.union(
691 isolate.load_isolate_as_config(self.cwd, {}, None),
692 isolate.load_isolate_as_config(
693 self.cwd, {}, '# Yo dawg!\n# Chill out.\n'))
694 self.assertEqual('# Yo dawg!\n# Chill out.\n', configs.file_comment)
695
696 # Only keep the first one.
697 configs = isolate.union(
698 isolate.load_isolate_as_config(self.cwd, {}, '# Yo dawg!\n'),
699 isolate.load_isolate_as_config(self.cwd, {}, '# Chill out.\n'))
700 self.assertEqual('# Yo dawg!\n', configs.file_comment)
701
702 def test_load_with_includes(self):
703 included_isolate = {
704 'variables': {
705 'isolate_dependency_tracked': [
706 'file_common',
707 ],
708 },
709 'conditions': [
710 ['OS=="linux"', {
711 'variables': {
712 'isolate_dependency_tracked': [
713 'file_linux',
714 ],
715 },
716 }, {
717 'variables': {
718 'isolate_dependency_tracked': [
719 'file_non_linux',
720 ],
721 },
722 }],
723 ],
724 }
725 isolate.trace_inputs.write_json(
726 os.path.join(self.cwd, 'included.isolate'), included_isolate, True)
727 values = {
728 'includes': ['included.isolate'],
729 'variables': {
730 'isolate_dependency_tracked': [
731 'file_less_common',
732 ],
733 },
734 'conditions': [
735 ['OS=="mac"', {
736 'variables': {
737 'isolate_dependency_tracked': [
738 'file_mac',
739 ],
740 },
741 }],
742 ],
743 }
744 actual = isolate.load_isolate_as_config(self.cwd, values, None)
745
746 expected = {
747 ('linux',): {
748 'isolate_dependency_tracked': [
749 'file_common',
750 'file_less_common',
751 'file_linux',
752 ],
753 },
754 ('mac',): {
755 'isolate_dependency_tracked': [
756 'file_common',
757 'file_less_common',
758 'file_mac',
759 'file_non_linux',
760 ],
761 },
762 ('win',): {
763 'isolate_dependency_tracked': [
764 'file_common',
765 'file_less_common',
766 'file_non_linux',
767 ],
768 },
769 }
770 self.assertEqual(expected, actual.flatten())
771
772 def test_extract_comment(self):
773 self.assertEqual(
774 '# Foo\n# Bar\n', isolate.extract_comment('# Foo\n# Bar\n{}'))
775 self.assertEqual('', isolate.extract_comment('{}'))
776
777 def _test_pretty_print_impl(self, value, expected):
778 actual = cStringIO.StringIO()
779 isolate.pretty_print(value, actual)
780 self.assertEqual(expected, actual.getvalue())
781
782 def test_pretty_print_empty(self):
783 self._test_pretty_print_impl({}, '{\n}\n')
784
785 def test_pretty_print_mid_size(self):
786 value = {
787 'variables': {
788 'bar': [
789 'file1',
790 'file2',
791 ],
792 },
793 'conditions': [
794 ['OS=\"foo\"', {
795 'variables': {
796 isolate.KEY_UNTRACKED: [
797 'dir1',
798 'dir2',
799 ],
800 isolate.KEY_TRACKED: [
801 'file4',
802 'file3',
803 ],
804 'command': ['python', '-c', 'print "H\\i\'"'],
805 'read_only': True,
806 'relative_cwd': 'isol\'at\\e',
807 },
808 }],
809 ['OS=\"bar\"', {
810 'variables': {},
811 }, {
812 'variables': {},
813 }],
814 ],
815 }
816 expected = (
817 "{\n"
818 " 'variables': {\n"
819 " 'bar': [\n"
820 " 'file1',\n"
821 " 'file2',\n"
822 " ],\n"
823 " },\n"
824 " 'conditions': [\n"
825 " ['OS=\"foo\"', {\n"
826 " 'variables': {\n"
827 " 'command': [\n"
828 " 'python',\n"
829 " '-c',\n"
830 " 'print \"H\\i\'\"',\n"
831 " ],\n"
832 " 'relative_cwd': 'isol\\'at\\\\e',\n"
833 " 'read_only': True\n"
834 " 'isolate_dependency_tracked': [\n"
835 " 'file4',\n"
836 " 'file3',\n"
837 " ],\n"
838 " 'isolate_dependency_untracked': [\n"
839 " 'dir1',\n"
840 " 'dir2',\n"
841 " ],\n"
842 " },\n"
843 " }],\n"
844 " ['OS=\"bar\"', {\n"
845 " 'variables': {\n"
846 " },\n"
847 " }, {\n"
848 " 'variables': {\n"
849 " },\n"
850 " }],\n"
851 " ],\n"
852 "}\n")
853 self._test_pretty_print_impl(value, expected)
854
855 def test_convert_old_to_new_bypass(self):
856 isolate_not_needing_conversion = {
857 'conditions': [
858 ['OS=="mac"', {'variables': {'foo': 'bar'}}],
859 ['condition shouldn\'t matter', {'variables': {'x': 'y'}}],
860 ],
861 }
862 self.assertEqual(
863 isolate_not_needing_conversion,
864 isolate.convert_old_to_new_format(isolate_not_needing_conversion))
865
866 def test_convert_old_to_new_else(self):
867 isolate_with_else_clauses = {
868 'conditions': [
869 ['OS=="mac"', {
870 'variables': {'foo': 'bar'},
871 }, {
872 'variables': {'x': 'y'},
873 }],
874 ['OS=="foo"', {
875 }, {
876 'variables': {'p': 'q'},
877 }],
878 ],
879 }
880 expected_output = {
881 'conditions': [
882 ['OS=="foo" or OS=="linux" or OS=="win"', {
883 'variables': {'x': 'y'},
884 }],
885 ['OS=="linux" or OS=="mac" or OS=="win"', {
886 'variables': {'p': 'q'},
887 }],
888 ['OS=="mac"', {
889 'variables': {'foo': 'bar'},
890 }],
891 ],
892 }
893 self.assertEqual(
894 expected_output,
895 isolate.convert_old_to_new_format(isolate_with_else_clauses))
896
897 def test_convert_old_to_new_default_variables(self):
898 isolate_with_default_variables = {
899 'conditions': [
900 ['OS=="abc"', {
901 'variables': {'foo': 'bar'},
902 }],
903 ],
904 'variables': {'p': 'q'},
905 }
906 expected_output = {
907 'conditions': [
908 ['OS=="abc"', {
909 'variables': {'foo': 'bar'},
910 }],
911 ['OS=="abc" or OS=="linux" or OS=="mac" or OS=="win"', {
912 'variables': {'p': 'q'},
913 }],
914 ],
915 }
916 self.assertEqual(
917 expected_output,
918 isolate.convert_old_to_new_format(isolate_with_default_variables))
919
920 def test_variable_arg(self):
921 parser = isolate.OptionParserIsolate()
922 parser.require_isolated = False
923 expected = {
924 'Baz': 'sub=string',
925 'EXECUTABLE_SUFFIX': '.exe' if isolate.get_flavor() == 'win' else '',
926 'Foo': 'bar',
927 'OS': isolate.get_flavor(),
928 }
929
930 options, args = parser.parse_args(
931 ['-V', 'Foo', 'bar', '-V', 'Baz=sub=string'])
932 self.assertEqual(expected, options.variables)
933 self.assertEqual([], args)
934
935 def test_variable_arg_fail(self):
936 parser = isolate.OptionParserIsolate()
937 self.mock(sys, 'stderr', cStringIO.StringIO())
938 self.assertRaises(SystemExit, parser.parse_args, ['-V', 'Foo'])
939
940 def test_blacklist(self):
941 ok = [
942 '.git2',
943 '.pyc',
944 '.swp',
945 'allo.git',
946 'foo',
947 ]
948 blocked = [
949 '.git',
950 os.path.join('foo', '.git'),
951 'foo.pyc',
952 'bar.swp',
953 ]
954 blacklist = isolate.trace_inputs.gen_blacklist(isolate.DEFAULT_BLACKLIST)
955 for i in ok:
956 self.assertFalse(blacklist(i), i)
957 for i in blocked:
958 self.assertTrue(blacklist(i), i)
959
960 def test_blacklist_chromium(self):
961 ok = [
962 '.run_test_cases',
963 'testserver.log2',
964 ]
965 blocked = [
966 'foo.run_test_cases',
967 'testserver.log',
968 os.path.join('foo', 'testserver.log'),
969 ]
970 blacklist = isolate.trace_inputs.gen_blacklist(isolate.DEFAULT_BLACKLIST)
971 for i in ok:
972 self.assertFalse(blacklist(i), i)
973 for i in blocked:
974 self.assertTrue(blacklist(i), i)
975
976 if sys.platform == 'darwin':
977 def test_expand_symlinks_path_case(self):
978 # Ensures that the resulting path case is fixed on case insensitive file
979 # system.
980 os.symlink('dest', os.path.join(self.cwd, 'link'))
981 os.mkdir(os.path.join(self.cwd, 'Dest'))
982 open(os.path.join(self.cwd, 'Dest', 'file.txt'), 'w').close()
983
984 result = isolate.expand_symlinks(unicode(self.cwd), 'link')
985 self.assertEqual((u'Dest', [u'link']), result)
986 result = isolate.expand_symlinks(unicode(self.cwd), 'link/File.txt')
987 self.assertEqual((u'Dest/file.txt', [u'link']), result)
988
989 def test_expand_directories_and_symlinks_path_case(self):
990 # Ensures that the resulting path case is fixed on case insensitive file
991 # system. A superset of test_expand_symlinks_path_case.
992 # Create *all* the paths with the wrong path case.
993 basedir = os.path.join(self.cwd, 'baseDir')
994 os.mkdir(basedir.lower())
995 subdir = os.path.join(basedir, 'subDir')
996 os.mkdir(subdir.lower())
997 open(os.path.join(subdir, 'Foo.txt'), 'w').close()
998 os.symlink('subDir', os.path.join(basedir, 'linkdir'))
999 actual = isolate.expand_directories_and_symlinks(
1000 unicode(self.cwd), [u'baseDir/'], lambda _: None, True, False)
1001 expected = [
1002 u'basedir/linkdir',
1003 u'basedir/subdir/Foo.txt',
1004 u'basedir/subdir/Foo.txt',
1005 ]
1006 self.assertEqual(expected, actual)
1007
1008 def test_process_input_path_case_simple(self):
1009 # Ensure the symlink dest is saved in the right path case.
1010 subdir = os.path.join(self.cwd, 'subdir')
1011 os.mkdir(subdir)
1012 linkdir = os.path.join(self.cwd, 'linkdir')
1013 os.symlink('subDir', linkdir)
1014 actual = isolate.process_input(
1015 unicode(linkdir.upper()), {}, True, 'mac', ALGO)
1016 expected = {'l': u'subdir', 'm': 360, 't': int(os.stat(linkdir).st_mtime)}
1017 self.assertEqual(expected, actual)
1018
1019 def test_process_input_path_case_complex(self):
1020 # Ensure the symlink dest is saved in the right path case. This includes 2
1021 # layers of symlinks.
1022 basedir = os.path.join(self.cwd, 'basebir')
1023 os.mkdir(basedir)
1024
1025 linkeddir2 = os.path.join(self.cwd, 'linkeddir2')
1026 os.mkdir(linkeddir2)
1027
1028 linkeddir1 = os.path.join(basedir, 'linkeddir1')
1029 os.symlink('../linkedDir2', linkeddir1)
1030
1031 subsymlinkdir = os.path.join(basedir, 'symlinkdir')
1032 os.symlink('linkedDir1', subsymlinkdir)
1033
1034 actual = isolate.process_input(
1035 unicode(subsymlinkdir.upper()), {}, True, 'mac', ALGO)
1036 expected = {
1037 'l': u'linkeddir1', 'm': 360, 't': int(os.stat(subsymlinkdir).st_mtime),
1038 }
1039 self.assertEqual(expected, actual)
1040
1041 actual = isolate.process_input(
1042 unicode(linkeddir1.upper()), {}, True, 'mac', ALGO)
1043 expected = {
1044 'l': u'../linkeddir2', 'm': 360, 't': int(os.stat(linkeddir1).st_mtime),
1045 }
1046 self.assertEqual(expected, actual)
1047
1048 if sys.platform != 'win32':
1049 def test_symlink_input_absolute_path(self):
1050 # A symlink is outside of the checkout, it should be treated as a normal
1051 # directory.
1052 # .../src
1053 # .../src/out -> .../tmp/foo
1054 # .../tmp
1055 # .../tmp/foo
1056 src = os.path.join(self.cwd, u'src')
1057 src_out = os.path.join(src, 'out')
1058 tmp = os.path.join(self.cwd, 'tmp')
1059 tmp_foo = os.path.join(tmp, 'foo')
1060 os.mkdir(src)
1061 os.mkdir(tmp)
1062 os.mkdir(tmp_foo)
1063 # The problem was that it's an absolute path, so it must be considered a
1064 # normal directory.
1065 os.symlink(tmp, src_out)
1066 open(os.path.join(tmp_foo, 'bar.txt'), 'w').close()
1067 actual = isolate.expand_symlinks(src, u'out/foo/bar.txt')
1068 self.assertEqual((u'out/foo/bar.txt', []), actual)
1069
1070
1071 class IsolateLoad(IsolateBase):
1072 def setUp(self):
1073 super(IsolateLoad, self).setUp()
1074 self.directory = tempfile.mkdtemp(prefix='isolate_')
1075
1076 def tearDown(self):
1077 try:
1078 isolate.run_isolated.rmtree(self.directory)
1079 finally:
1080 super(IsolateLoad, self).tearDown()
1081
1082 def _get_option(self, isolate_file):
1083 OS = isolate.get_flavor()
1084 chromeos_value = int(OS == 'linux')
1085 class Options(object):
1086 isolated = os.path.join(self.directory, 'foo.isolated')
1087 outdir = os.path.join(self.directory, 'outdir')
1088 isolate = isolate_file
1089 variables = {'foo': 'bar', 'OS': OS, 'chromeos': chromeos_value}
1090 ignore_broken_items = False
1091 return Options()
1092
1093 def _cleanup_isolated(self, expected_isolated):
1094 """Modifies isolated to remove the non-deterministic parts."""
1095 if sys.platform == 'win32':
1096 # 'm' are not saved in windows.
1097 for values in expected_isolated['files'].itervalues():
1098 self.assertTrue(values.pop('m'))
1099
1100 def _cleanup_saved_state(self, actual_saved_state):
1101 for item in actual_saved_state['files'].itervalues():
1102 self.assertTrue(item.pop('t'))
1103
1104 def test_load_stale_isolated(self):
1105 isolate_file = os.path.join(
1106 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
1107
1108 # Data to be loaded in the .isolated file. Do not create a .state file.
1109 input_data = {
1110 'command': ['python'],
1111 'files': {
1112 'foo': {
1113 "m": 416,
1114 "h": "invalid",
1115 "s": 538,
1116 "t": 1335146921,
1117 },
1118 os.path.join('tests', 'isolate', 'touch_root.py'): {
1119 "m": 488,
1120 "h": "invalid",
1121 "s": 538,
1122 "t": 1335146921,
1123 },
1124 },
1125 }
1126 options = self._get_option(isolate_file)
1127 isolate.trace_inputs.write_json(options.isolated, input_data, False)
1128
1129 # A CompleteState object contains two parts:
1130 # - Result instance stored in complete_state.isolated, corresponding to the
1131 # .isolated file, is what is read by run_test_from_archive.py.
1132 # - SavedState instance stored in compelte_state.saved_state,
1133 # corresponding to the .state file, which is simply to aid the developer
1134 # when re-running the same command multiple times and contain
1135 # discardable information.
1136 complete_state = isolate.load_complete_state(options, self.cwd, None, False)
1137 actual_isolated = complete_state.saved_state.to_isolated()
1138 actual_saved_state = complete_state.saved_state.flatten()
1139
1140 expected_isolated = {
1141 'algo': 'sha-1',
1142 'command': ['python', 'touch_root.py'],
1143 'files': {
1144 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1145 'm': 488,
1146 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1147 's': _size('tests', 'isolate', 'touch_root.py'),
1148 },
1149 u'isolate.py': {
1150 'm': 488,
1151 'h': hash_file('isolate.py'),
1152 's': _size('isolate.py'),
1153 },
1154 },
1155 'os': isolate.get_flavor(),
1156 'relative_cwd': os.path.join(u'tests', 'isolate'),
1157 'version': '1.0',
1158 }
1159 self._cleanup_isolated(expected_isolated)
1160 self.assertEqual(expected_isolated, actual_isolated)
1161
1162 expected_saved_state = {
1163 'algo': 'sha-1',
1164 'child_isolated_files': [],
1165 'command': ['python', 'touch_root.py'],
1166 'files': {
1167 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1168 'm': 488,
1169 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1170 's': _size('tests', 'isolate', 'touch_root.py'),
1171 },
1172 u'isolate.py': {
1173 'm': 488,
1174 'h': hash_file('isolate.py'),
1175 's': _size('isolate.py'),
1176 },
1177 },
1178 'isolate_file': isolate.safe_relpath(
1179 file_path.get_native_path_case(isolate_file),
1180 os.path.dirname(options.isolated)),
1181 'relative_cwd': os.path.join(u'tests', 'isolate'),
1182 'variables': {
1183 'foo': 'bar',
1184 'OS': isolate.get_flavor(),
1185 'chromeos': options.variables['chromeos'],
1186 },
1187 'version': '1.0',
1188 }
1189 self._cleanup_isolated(expected_saved_state)
1190 self._cleanup_saved_state(actual_saved_state)
1191 self.assertEqual(expected_saved_state, actual_saved_state)
1192
1193 def test_subdir(self):
1194 # The resulting .isolated file will be missing ../../isolate.py. It is
1195 # because this file is outside the --subdir parameter.
1196 isolate_file = os.path.join(
1197 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
1198 options = self._get_option(isolate_file)
1199 chromeos_value = int(isolate.get_flavor() == 'linux')
1200 options.variables['chromeos'] = chromeos_value
1201 complete_state = isolate.load_complete_state(
1202 options, self.cwd, os.path.join('tests', 'isolate'), False)
1203 actual_isolated = complete_state.saved_state.to_isolated()
1204 actual_saved_state = complete_state.saved_state.flatten()
1205
1206 expected_isolated = {
1207 'algo': 'sha-1',
1208 'command': ['python', 'touch_root.py'],
1209 'files': {
1210 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1211 'm': 488,
1212 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1213 's': _size('tests', 'isolate', 'touch_root.py'),
1214 },
1215 },
1216 'os': isolate.get_flavor(),
1217 'relative_cwd': os.path.join(u'tests', 'isolate'),
1218 'version': '1.0',
1219 }
1220 self._cleanup_isolated(expected_isolated)
1221 self.assertEqual(expected_isolated, actual_isolated)
1222
1223 expected_saved_state = {
1224 'algo': 'sha-1',
1225 'child_isolated_files': [],
1226 'command': ['python', 'touch_root.py'],
1227 'files': {
1228 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1229 'm': 488,
1230 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1231 's': _size('tests', 'isolate', 'touch_root.py'),
1232 },
1233 },
1234 'isolate_file': isolate.safe_relpath(
1235 file_path.get_native_path_case(isolate_file),
1236 os.path.dirname(options.isolated)),
1237 'relative_cwd': os.path.join(u'tests', 'isolate'),
1238 'variables': {
1239 'foo': 'bar',
1240 'OS': isolate.get_flavor(),
1241 'chromeos': chromeos_value,
1242 },
1243 'version': '1.0',
1244 }
1245 self._cleanup_isolated(expected_saved_state)
1246 self._cleanup_saved_state(actual_saved_state)
1247 self.assertEqual(expected_saved_state, actual_saved_state)
1248
1249 def test_subdir_variable(self):
1250 # the resulting .isolated file will be missing ../../isolate.py. it is
1251 # because this file is outside the --subdir parameter.
1252 isolate_file = os.path.join(
1253 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
1254 options = self._get_option(isolate_file)
1255 chromeos_value = int(isolate.get_flavor() == 'linux')
1256 options.variables['chromeos'] = chromeos_value
1257 options.variables['BAZ'] = os.path.join('tests', 'isolate')
1258 complete_state = isolate.load_complete_state(
1259 options, self.cwd, '<(BAZ)', False)
1260 actual_isolated = complete_state.saved_state.to_isolated()
1261 actual_saved_state = complete_state.saved_state.flatten()
1262
1263 expected_isolated = {
1264 'algo': 'sha-1',
1265 'command': ['python', 'touch_root.py'],
1266 'files': {
1267 os.path.join('tests', 'isolate', 'touch_root.py'): {
1268 'm': 488,
1269 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1270 's': _size('tests', 'isolate', 'touch_root.py'),
1271 },
1272 },
1273 'os': isolate.get_flavor(),
1274 'relative_cwd': os.path.join(u'tests', 'isolate'),
1275 'version': '1.0',
1276 }
1277 self._cleanup_isolated(expected_isolated)
1278 self.assertEqual(expected_isolated, actual_isolated)
1279
1280 expected_saved_state = {
1281 'algo': 'sha-1',
1282 'child_isolated_files': [],
1283 'command': ['python', 'touch_root.py'],
1284 'files': {
1285 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1286 'm': 488,
1287 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1288 's': _size('tests', 'isolate', 'touch_root.py'),
1289 },
1290 },
1291 'isolate_file': isolate.safe_relpath(
1292 file_path.get_native_path_case(isolate_file),
1293 os.path.dirname(options.isolated)),
1294 'relative_cwd': os.path.join(u'tests', 'isolate'),
1295 'variables': {
1296 'foo': 'bar',
1297 'BAZ': os.path.join('tests', 'isolate'),
1298 'OS': isolate.get_flavor(),
1299 'chromeos': chromeos_value,
1300 },
1301 'version': '1.0',
1302 }
1303 self._cleanup_isolated(expected_saved_state)
1304 self._cleanup_saved_state(actual_saved_state)
1305 self.assertEqual(expected_saved_state, actual_saved_state)
1306
1307 def test_variable_not_exist(self):
1308 isolate_file = os.path.join(
1309 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
1310 options = self._get_option(isolate_file)
1311 options.variables['PRODUCT_DIR'] = os.path.join(u'tests', u'isolate')
1312 native_cwd = file_path.get_native_path_case(unicode(self.cwd))
1313 try:
1314 isolate.load_complete_state(options, self.cwd, None, False)
1315 self.fail()
1316 except isolate.ExecutionError, e:
1317 self.assertEqual(
1318 'PRODUCT_DIR=%s is not a directory' %
1319 os.path.join(native_cwd, 'tests', 'isolate'),
1320 e.args[0])
1321
1322 def test_variable(self):
1323 isolate_file = os.path.join(
1324 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
1325 options = self._get_option(isolate_file)
1326 chromeos_value = int(isolate.get_flavor() == 'linux')
1327 options.variables['chromeos'] = chromeos_value
1328 options.variables['PRODUCT_DIR'] = os.path.join('tests', 'isolate')
1329 complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
1330 actual_isolated = complete_state.saved_state.to_isolated()
1331 actual_saved_state = complete_state.saved_state.flatten()
1332
1333 expected_isolated = {
1334 'algo': 'sha-1',
1335 'command': ['python', 'touch_root.py'],
1336 'files': {
1337 u'isolate.py': {
1338 'm': 488,
1339 'h': hash_file('isolate.py'),
1340 's': _size('isolate.py'),
1341 },
1342 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1343 'm': 488,
1344 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1345 's': _size('tests', 'isolate', 'touch_root.py'),
1346 },
1347 },
1348 'os': isolate.get_flavor(),
1349 'relative_cwd': os.path.join(u'tests', 'isolate'),
1350 'version': '1.0',
1351 }
1352 self._cleanup_isolated(expected_isolated)
1353 self.assertEqual(expected_isolated, actual_isolated)
1354
1355 expected_saved_state = {
1356 'algo': 'sha-1',
1357 'child_isolated_files': [],
1358 'command': ['python', 'touch_root.py'],
1359 'files': {
1360 u'isolate.py': {
1361 'm': 488,
1362 'h': hash_file('isolate.py'),
1363 's': _size('isolate.py'),
1364 },
1365 os.path.join(u'tests', 'isolate', 'touch_root.py'): {
1366 'm': 488,
1367 'h': hash_file('tests', 'isolate', 'touch_root.py'),
1368 's': _size('tests', 'isolate', 'touch_root.py'),
1369 },
1370 },
1371 'isolate_file': isolate.safe_relpath(
1372 file_path.get_native_path_case(isolate_file),
1373 os.path.dirname(options.isolated)),
1374 'relative_cwd': os.path.join(u'tests', 'isolate'),
1375 'variables': {
1376 'foo': 'bar',
1377 'PRODUCT_DIR': '.',
1378 'OS': isolate.get_flavor(),
1379 'chromeos': chromeos_value,
1380 },
1381 'version': '1.0',
1382 }
1383 self._cleanup_isolated(expected_saved_state)
1384 self._cleanup_saved_state(actual_saved_state)
1385 self.assertEqual(expected_saved_state, actual_saved_state)
1386 self.assertEqual([], os.listdir(self.directory))
1387
1388 def test_root_dir_because_of_variable(self):
1389 # Ensures that load_isolate() works even when path variables have deep root
1390 # dirs. The end result is similar to touch_root.isolate, except that
1391 # no_run.isolate doesn't reference '..' at all.
1392 #
1393 # A real world example would be PRODUCT_DIR=../../out/Release but nothing in
1394 # this directory is mapped.
1395 #
1396 # Imagine base/base_unittests.isolate would not map anything in
1397 # PRODUCT_DIR. In that case, the automatically determined root dir is
1398 # src/base, since nothing outside this directory is mapped.
1399 isolate_file = os.path.join(
1400 ROOT_DIR, 'tests', 'isolate', 'no_run.isolate')
1401 options = self._get_option(isolate_file)
1402 chromeos_value = int(isolate.get_flavor() == 'linux')
1403 # Any directory outside ROOT_DIR/tests/isolate.
1404 options.variables['PRODUCT_DIR'] = os.path.join('third_party')
1405 complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
1406 actual_isolated = complete_state.saved_state.to_isolated()
1407 actual_saved_state = complete_state.saved_state.flatten()
1408
1409 expected_isolated = {
1410 'algo': 'sha-1',
1411 'files': {
1412 os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
1413 'm': 416,
1414 'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1415 's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1416 },
1417 os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
1418 'm': 416,
1419 'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
1420 's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
1421 },
1422 os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
1423 'm': 416,
1424 'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
1425 's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
1426 },
1427 os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
1428 'm': 416,
1429 'h': hash_file('tests', 'isolate', 'no_run.isolate'),
1430 's': _size('tests', 'isolate', 'no_run.isolate'),
1431 },
1432 },
1433 'os': isolate.get_flavor(),
1434 'relative_cwd': os.path.join(u'tests', 'isolate'),
1435 'version': '1.0',
1436 }
1437 self._cleanup_isolated(expected_isolated)
1438 self.assertEqual(expected_isolated, actual_isolated)
1439
1440 expected_saved_state = {
1441 'algo': 'sha-1',
1442 'child_isolated_files': [],
1443 'command': [],
1444 'files': {
1445 os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
1446 'm': 416,
1447 'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1448 's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1449 },
1450 os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
1451 'm': 416,
1452 'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
1453 's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
1454 },
1455 os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
1456 'm': 416,
1457 'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
1458 's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
1459 },
1460 os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
1461 'm': 416,
1462 'h': hash_file('tests', 'isolate', 'no_run.isolate'),
1463 's': _size('tests', 'isolate', 'no_run.isolate'),
1464 },
1465 },
1466 'isolate_file': isolate.safe_relpath(
1467 file_path.get_native_path_case(isolate_file),
1468 os.path.dirname(options.isolated)),
1469 'relative_cwd': os.path.join(u'tests', 'isolate'),
1470 'variables': {
1471 'foo': 'bar',
1472 'PRODUCT_DIR': os.path.join(u'..', '..', 'third_party'),
1473 'OS': isolate.get_flavor(),
1474 'chromeos': chromeos_value,
1475 },
1476 'version': '1.0',
1477 }
1478 self._cleanup_isolated(expected_saved_state)
1479 self._cleanup_saved_state(actual_saved_state)
1480 self.assertEqual(expected_saved_state, actual_saved_state)
1481 self.assertEqual([], os.listdir(self.directory))
1482
1483 def test_chromium_split(self):
1484 # Create an .isolate file and a tree of random stuff.
1485 isolate_file = os.path.join(
1486 ROOT_DIR, 'tests', 'isolate', 'split.isolate')
1487 options = self._get_option(isolate_file)
1488 options.variables = {
1489 'OS': isolate.get_flavor(),
1490 'DEPTH': '.',
1491 'PRODUCT_DIR': os.path.join('files1'),
1492 }
1493 complete_state = isolate.load_complete_state(
1494 options, os.path.join(ROOT_DIR, 'tests', 'isolate'), None, False)
1495 # By saving the files, it forces splitting the data up.
1496 complete_state.save_files()
1497
1498 actual_isolated_master = isolate.trace_inputs.read_json(
1499 os.path.join(self.directory, 'foo.isolated'))
1500 expected_isolated_master = {
1501 u'algo': u'sha-1',
1502 u'command': [u'python', u'split.py'],
1503 u'files': {
1504 u'split.py': {
1505 u'm': 488,
1506 u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
1507 u's': _size('tests', 'isolate', 'split.py'),
1508 },
1509 },
1510 u'includes': [
1511 unicode(hash_file(os.path.join(self.directory, 'foo.0.isolated'))),
1512 unicode(hash_file(os.path.join(self.directory, 'foo.1.isolated'))),
1513 ],
1514 u'os': unicode(isolate.get_flavor()),
1515 u'relative_cwd': u'.',
1516 u'version': u'1.0',
1517 }
1518 self._cleanup_isolated(expected_isolated_master)
1519 self.assertEqual(expected_isolated_master, actual_isolated_master)
1520
1521 actual_isolated_0 = isolate.trace_inputs.read_json(
1522 os.path.join(self.directory, 'foo.0.isolated'))
1523 expected_isolated_0 = {
1524 u'algo': u'sha-1',
1525 u'files': {
1526 os.path.join(u'test', 'data', 'foo.txt'): {
1527 u'm': 416,
1528 u'h': unicode(
1529 hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
1530 u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
1531 },
1532 },
1533 u'os': unicode(isolate.get_flavor()),
1534 u'version': u'1.0',
1535 }
1536 self._cleanup_isolated(expected_isolated_0)
1537 self.assertEqual(expected_isolated_0, actual_isolated_0)
1538
1539 actual_isolated_1 = isolate.trace_inputs.read_json(
1540 os.path.join(self.directory, 'foo.1.isolated'))
1541 expected_isolated_1 = {
1542 u'algo': u'sha-1',
1543 u'files': {
1544 os.path.join(u'files1', 'subdir', '42.txt'): {
1545 u'm': 416,
1546 u'h': unicode(
1547 hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
1548 u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1549 },
1550 },
1551 u'os': unicode(isolate.get_flavor()),
1552 u'version': u'1.0',
1553 }
1554 self._cleanup_isolated(expected_isolated_1)
1555 self.assertEqual(expected_isolated_1, actual_isolated_1)
1556
1557 actual_saved_state = isolate.trace_inputs.read_json(
1558 isolate.isolatedfile_to_state(options.isolated))
1559 isolated_base = unicode(os.path.basename(options.isolated))
1560 expected_saved_state = {
1561 u'algo': u'sha-1',
1562 u'child_isolated_files': [
1563 isolated_base[:-len('.isolated')] + '.0.isolated',
1564 isolated_base[:-len('.isolated')] + '.1.isolated',
1565 ],
1566 u'command': [u'python', u'split.py'],
1567 u'files': {
1568 os.path.join(u'files1', 'subdir', '42.txt'): {
1569 u'm': 416,
1570 u'h': unicode(
1571 hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
1572 u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
1573 },
1574 u'split.py': {
1575 u'm': 488,
1576 u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
1577 u's': _size('tests', 'isolate', 'split.py'),
1578 },
1579 os.path.join(u'test', 'data', 'foo.txt'): {
1580 u'm': 416,
1581 u'h': unicode(
1582 hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
1583 u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
1584 },
1585 },
1586 u'isolate_file': isolate.safe_relpath(
1587 file_path.get_native_path_case(isolate_file),
1588 unicode(os.path.dirname(options.isolated))),
1589 u'relative_cwd': u'.',
1590 u'variables': {
1591 u'OS': unicode(isolate.get_flavor()),
1592 u'DEPTH': u'.',
1593 u'PRODUCT_DIR': u'files1',
1594 },
1595 u'version': u'1.0',
1596 }
1597 self._cleanup_isolated(expected_saved_state)
1598 self._cleanup_saved_state(actual_saved_state)
1599 self.assertEqual(expected_saved_state, actual_saved_state)
1600 self.assertEqual(
1601 [
1602 'foo.0.isolated', 'foo.1.isolated',
1603 'foo.isolated', 'foo.isolated.state',
1604 ],
1605 sorted(os.listdir(self.directory)))
1606
1607
1608 class IsolateCommand(IsolateBase):
1609 def load_complete_state(self, *_):
1610 """Creates a minimalist CompleteState instance without an .isolated
1611 reference.
1612 """
1613 out = isolate.CompleteState(None, isolate.SavedState(self.cwd))
1614 out.saved_state.isolate_file = u'blah.isolate'
1615 out.saved_state.relative_cwd = u''
1616 return out
1617
1618 def test_CMDrewrite(self):
1619 isolate_file = os.path.join(self.cwd, 'x.isolate')
1620 data = (
1621 '# Foo',
1622 '{',
1623 '}',
1624 )
1625 with open(isolate_file, 'wb') as f:
1626 f.write('\n'.join(data))
1627
1628 self.mock(sys, 'stdout', cStringIO.StringIO())
1629 cmd = ['-i', isolate_file]
1630 self.assertEqual(0, isolate.CMDrewrite(isolate.OptionParserIsolate(), cmd))
1631 with open(isolate_file, 'rb') as f:
1632 actual = f.read()
1633
1634 expected = "# Foo\n{\n 'conditions': [\n ],\n}\n"
1635 self.assertEqual(expected, actual)
1636
1637 if sys.platform != 'win32':
1638 def test_CMDcheck_no_mode_on_windows(self):
1639 # Store for Windows, make sure file mode are not included. Hopefully, run
1640 # this test on another OS.
1641 isolate_file = os.path.join(
1642 ROOT_DIR, 'tests', 'isolate', 'symlink_full.isolate')
1643 isolated_file = os.path.join(self.cwd, 'foo.isolated')
1644 cmd = [
1645 '-i', isolate_file,
1646 '-V', 'OS', 'win',
1647 '-V', 'chromeos', '0',
1648 '-s', isolated_file,
1649 ]
1650 self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
1651 with open(isolated_file, 'rb') as f:
1652 actual = json.load(f)
1653 mapped = [
1654 os.path.join(u'files2', 'subdir', '42.txt'),
1655 os.path.join(u'files2', 'test_file1.txt'),
1656 os.path.join(u'files2', 'test_file2.txt'),
1657 os.path.join(u'symlink_full.py'),
1658 ]
1659 files = dict(
1660 (
1661 f,
1662 {
1663 u'h': unicode(hash_file('tests', 'isolate', f)),
1664 u's': _size('tests', 'isolate', f),
1665 }
1666 )
1667 for f in mapped)
1668 expected = {
1669 u'algo': u'sha-1',
1670 u'command': [u'python', u'symlink_full.py'],
1671 u'files': files,
1672 u'os': u'win',
1673 u'relative_cwd': u'.',
1674 u'version': u'1.0',
1675 }
1676 self.assertEqual(expected, actual)
1677
1678 def test_CMDrun_extra_args(self):
1679 cmd = [
1680 'run',
1681 '--isolate', 'blah.isolate',
1682 '--outdir', os.path.join(self.cwd, 'jumbo'),
1683 '--', 'extra_args',
1684 ]
1685 self.mock(isolate, 'load_complete_state', self.load_complete_state)
1686 self.mock(isolate.subprocess, 'call', lambda *_, **_kwargs: 0)
1687 self.assertEqual(0, isolate.CMDrun(isolate.OptionParserIsolate(), cmd))
1688
1689
1690 if __name__ == '__main__':
1691 logging.basicConfig(
1692 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR,
1693 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
1694 if '-v' in sys.argv:
1695 unittest.TestCase.maxDiff = None
1696 unittest.main()
OLDNEW
« no previous file with comments | « swarm_client/tests/isolate_smoke_test.py ('k') | swarm_client/tests/isolateserver/small_file.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698