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 cStringIO | |
7 import logging | |
8 import os | |
9 import sys | |
10 import tempfile | |
11 import unittest | |
12 | |
13 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
14 sys.path.insert(0, ROOT_DIR) | |
15 | |
16 import isolate | |
17 # Create shortcuts. | |
18 from isolate import KEY_TOUCHED, KEY_TRACKED, KEY_UNTRACKED | |
19 | |
20 | |
21 class Isolate(unittest.TestCase): | |
22 def setUp(self): | |
23 # Everything should work even from another directory. | |
24 os.chdir(os.path.dirname(ROOT_DIR)) | |
25 | |
26 def test_load_isolate_for_flavor_empty(self): | |
27 content = "{}" | |
28 command, infiles, touched, read_only = isolate.load_isolate_for_flavor( | |
29 content, isolate.get_flavor()) | |
30 self.assertEquals([], command) | |
31 self.assertEquals([], infiles) | |
32 self.assertEquals([], touched) | |
33 self.assertEquals(None, read_only) | |
34 | |
35 def test_result_load_empty(self): | |
36 values = { | |
37 } | |
38 expected = { | |
39 'command': [], | |
40 'files': {}, | |
41 'os': isolate.get_flavor(), | |
42 } | |
43 self.assertEquals(expected, isolate.Result.load(values).flatten()) | |
44 | |
45 def test_result_load(self): | |
46 values = { | |
47 'command': 'maybe', | |
48 'files': {'foo': 42}, | |
49 'read_only': 2, | |
50 } | |
51 expected = { | |
52 'command': 'maybe', | |
53 'files': {'foo': 42}, | |
54 'os': isolate.get_flavor(), | |
55 'read_only': 2, | |
56 } | |
57 self.assertEquals(expected, isolate.Result.load(values).flatten()) | |
58 | |
59 def test_result_load_unexpected(self): | |
60 values = { | |
61 'foo': 'bar', | |
62 } | |
63 expected = ( | |
64 ("Found unexpected entry {'foo': 'bar'} while constructing an " | |
65 "object Result"), | |
66 {'foo': 'bar'}, | |
67 'Result') | |
68 try: | |
69 isolate.Result.load(values) | |
70 self.fail() | |
71 except ValueError, e: | |
72 self.assertEquals(expected, e.args) | |
73 | |
74 def test_savedstate_load_empty(self): | |
75 values = { | |
76 } | |
77 expected = { | |
78 'variables': {}, | |
79 } | |
80 self.assertEquals(expected, isolate.SavedState.load(values).flatten()) | |
81 | |
82 def test_savedstate_load(self): | |
83 values = { | |
84 'isolate_file': os.path.join(ROOT_DIR, 'maybe'), | |
85 'variables': {'foo': 42}, | |
86 } | |
87 expected = { | |
88 'isolate_file': os.path.join(ROOT_DIR, 'maybe'), | |
89 'variables': {'foo': 42}, | |
90 } | |
91 self.assertEquals(expected, isolate.SavedState.load(values).flatten()) | |
92 | |
93 def test_load_stale_result(self): | |
94 directory = tempfile.mkdtemp(prefix='isolate_') | |
95 try: | |
96 isolate_file = os.path.join( | |
97 ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate') | |
98 class Options(object): | |
99 result = os.path.join(directory, 'result') | |
100 outdir = os.path.join(directory, '0utdir') | |
101 isolate = isolate_file | |
102 variables = {'foo': 'bar'} | |
103 | |
104 # Data to be loaded in the .result file. Do not create a .state file. | |
105 input_data = { | |
106 'command': ['python'], | |
107 'files': { | |
108 'foo': { | |
109 "mode": 416, | |
110 "sha-1": "invalid", | |
111 "size": 538, | |
112 "timestamp": 1335146921, | |
113 }, | |
114 os.path.join('tests', 'isolate', 'touch_root.py'): { | |
115 "mode": 488, | |
116 "sha-1": "invalid", | |
117 "size": 538, | |
118 "timestamp": 1335146921, | |
119 }, | |
120 }, | |
121 } | |
122 isolate.trace_inputs.write_json(Options.result, input_data, False) | |
123 | |
124 # A CompleteState object contains two parts: | |
125 # - Result instance stored in complete_state.result, corresponding to the | |
126 # .result file, is what is read by run_test_from_archive.py. | |
127 # - SavedState instance stored in compelte_state.saved_state, | |
128 # corresponding to the .state file, which is simply to aid the developer | |
129 # when re-running the same command multiple times and contain | |
130 # discardable information. | |
131 complete_state = isolate.load_complete_state(Options, isolate.STATS_ONLY) | |
132 actual_result = complete_state.result.flatten() | |
133 actual_saved_state = complete_state.saved_state.flatten() | |
134 | |
135 expected_result = { | |
136 'command': ['python', 'touch_root.py'], | |
137 'files': { | |
138 os.path.join(u'tests', 'isolate', 'touch_root.py'): { | |
139 'mode': 488, | |
140 'size': self._size('tests', 'isolate', 'touch_root.py'), | |
141 }, | |
142 'isolate.py': { | |
143 'mode': 488, | |
144 'size': self._size('isolate.py'), | |
145 }, | |
146 }, | |
147 'os': isolate.get_flavor(), | |
148 'relative_cwd': os.path.join('tests', 'isolate'), | |
149 } | |
150 if sys.platform == 'win32': | |
151 # 'mode' are not saved in windows. | |
152 for values in expected_result['files'].itervalues(): | |
153 del values['mode'] | |
154 for item in actual_result['files'].itervalues(): | |
155 self.assertTrue(item.pop('timestamp')) | |
156 self.assertEquals(expected_result, actual_result) | |
157 | |
158 expected_saved_state = { | |
159 'isolate_file': isolate_file, | |
160 'variables': {'foo': 'bar'}, | |
161 } | |
162 self.assertEquals(expected_saved_state, actual_saved_state) | |
163 finally: | |
164 isolate.run_test_from_archive.rmtree(directory) | |
165 | |
166 @staticmethod | |
167 def _size(*args): | |
168 return os.stat(os.path.join(ROOT_DIR, *args)).st_size | |
169 | |
170 def test_unknown_key(self): | |
171 try: | |
172 isolate.verify_variables({'foo': [],}) | |
173 self.fail() | |
174 except AssertionError: | |
175 pass | |
176 | |
177 def test_unknown_var(self): | |
178 try: | |
179 isolate.verify_condition({'variables': {'foo': [],}}) | |
180 self.fail() | |
181 except AssertionError: | |
182 pass | |
183 | |
184 def test_union(self): | |
185 value1 = { | |
186 'a': set(['A']), | |
187 'b': ['B', 'C'], | |
188 'c': 'C', | |
189 } | |
190 value2 = { | |
191 'a': set(['B', 'C']), | |
192 'b': [], | |
193 'd': set(), | |
194 } | |
195 expected = { | |
196 'a': set(['A', 'B', 'C']), | |
197 'b': ['B', 'C'], | |
198 'c': 'C', | |
199 'd': set(), | |
200 } | |
201 self.assertEquals(expected, isolate.union(value1, value2)) | |
202 | |
203 def test_eval_content(self): | |
204 try: | |
205 # Intrinsics are not available. | |
206 isolate.eval_content('map(str, [1, 2])') | |
207 self.fail() | |
208 except NameError: | |
209 pass | |
210 | |
211 def test_load_isolate_as_config_empty(self): | |
212 self.assertEquals({}, isolate.load_isolate_as_config( | |
213 {}, None, []).flatten()) | |
214 | |
215 def test_load_isolate_as_config(self): | |
216 value = { | |
217 'variables': { | |
218 KEY_TRACKED: ['a'], | |
219 KEY_UNTRACKED: ['b'], | |
220 KEY_TOUCHED: ['touched'], | |
221 }, | |
222 'conditions': [ | |
223 ['OS=="atari"', { | |
224 'variables': { | |
225 KEY_TRACKED: ['c', 'x'], | |
226 KEY_UNTRACKED: ['d'], | |
227 KEY_TOUCHED: ['touched_a'], | |
228 'command': ['echo', 'Hello World'], | |
229 'read_only': True, | |
230 }, | |
231 }, { # else | |
232 'variables': { | |
233 KEY_TRACKED: ['e', 'x'], | |
234 KEY_UNTRACKED: ['f'], | |
235 KEY_TOUCHED: ['touched_e'], | |
236 'command': ['echo', 'You should get an Atari'], | |
237 }, | |
238 }], | |
239 ['OS=="amiga"', { | |
240 'variables': { | |
241 KEY_TRACKED: ['g'], | |
242 'read_only': False, | |
243 }, | |
244 }], | |
245 ['OS=="dendy"', { | |
246 }], | |
247 ['OS=="coleco"', { | |
248 }, { # else | |
249 'variables': { | |
250 KEY_UNTRACKED: ['h'], | |
251 'read_only': None, | |
252 }, | |
253 }], | |
254 ], | |
255 } | |
256 expected = { | |
257 'amiga': { | |
258 'command': ['echo', 'You should get an Atari'], | |
259 KEY_TOUCHED: ['touched', 'touched_e'], | |
260 KEY_TRACKED: ['a', 'e', 'g', 'x'], | |
261 KEY_UNTRACKED: ['b', 'f', 'h'], | |
262 'read_only': False, | |
263 }, | |
264 'atari': { | |
265 'command': ['echo', 'Hello World'], | |
266 KEY_TOUCHED: ['touched', 'touched_a'], | |
267 KEY_TRACKED: ['a', 'c', 'x'], | |
268 KEY_UNTRACKED: ['b', 'd', 'h'], | |
269 'read_only': True, | |
270 }, | |
271 'coleco': { | |
272 'command': ['echo', 'You should get an Atari'], | |
273 KEY_TOUCHED: ['touched', 'touched_e'], | |
274 KEY_TRACKED: ['a', 'e', 'x'], | |
275 KEY_UNTRACKED: ['b', 'f'], | |
276 }, | |
277 'dendy': { | |
278 'command': ['echo', 'You should get an Atari'], | |
279 KEY_TOUCHED: ['touched', 'touched_e'], | |
280 KEY_TRACKED: ['a', 'e', 'x'], | |
281 KEY_UNTRACKED: ['b', 'f', 'h'], | |
282 }, | |
283 } | |
284 self.assertEquals( | |
285 expected, isolate.load_isolate_as_config(value, None, []).flatten()) | |
286 | |
287 def test_load_isolate_as_config_duplicate_command(self): | |
288 value = { | |
289 'variables': { | |
290 'command': ['rm', '-rf', '/'], | |
291 }, | |
292 'conditions': [ | |
293 ['OS=="atari"', { | |
294 'variables': { | |
295 'command': ['echo', 'Hello World'], | |
296 }, | |
297 }], | |
298 ], | |
299 } | |
300 try: | |
301 isolate.load_isolate_as_config(value, None, []) | |
302 self.fail() | |
303 except AssertionError: | |
304 pass | |
305 | |
306 def test_load_isolate_as_config_no_condition(self): | |
307 value = { | |
308 'variables': { | |
309 KEY_TRACKED: ['a'], | |
310 KEY_UNTRACKED: ['b'], | |
311 }, | |
312 } | |
313 expected = { | |
314 KEY_TRACKED: ['a'], | |
315 KEY_UNTRACKED: ['b'], | |
316 } | |
317 actual = isolate.load_isolate_as_config(value, None, []) | |
318 # Flattening the whole config will discard 'None'. | |
319 self.assertEquals({}, actual.flatten()) | |
320 self.assertEquals([None], actual.per_os.keys()) | |
321 # But the 'None' value is still available as a backup. | |
322 self.assertEquals(expected, actual.per_os[None].flatten()) | |
323 | |
324 def test_invert_map(self): | |
325 value = { | |
326 'amiga': { | |
327 'command': ['echo', 'You should get an Atari'], | |
328 KEY_TOUCHED: ['touched', 'touched_e'], | |
329 KEY_TRACKED: ['a', 'e', 'g', 'x'], | |
330 KEY_UNTRACKED: ['b', 'f', 'h'], | |
331 'read_only': False, | |
332 }, | |
333 'atari': { | |
334 'command': ['echo', 'Hello World'], | |
335 KEY_TOUCHED: ['touched', 'touched_a'], | |
336 KEY_TRACKED: ['a', 'c', 'x'], | |
337 KEY_UNTRACKED: ['b', 'd', 'h'], | |
338 'read_only': True, | |
339 }, | |
340 'coleco': { | |
341 'command': ['echo', 'You should get an Atari'], | |
342 KEY_TOUCHED: ['touched', 'touched_e'], | |
343 KEY_TRACKED: ['a', 'e', 'x'], | |
344 KEY_UNTRACKED: ['b', 'f'], | |
345 }, | |
346 'dendy': { | |
347 'command': ['echo', 'You should get an Atari'], | |
348 KEY_TOUCHED: ['touched', 'touched_e'], | |
349 KEY_TRACKED: ['a', 'e', 'x'], | |
350 KEY_UNTRACKED: ['b', 'f', 'h'], | |
351 }, | |
352 } | |
353 expected_values = { | |
354 'command': { | |
355 ('echo', 'Hello World'): set(['atari']), | |
356 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), | |
357 }, | |
358 KEY_TRACKED: { | |
359 'a': set(['amiga', 'atari', 'coleco', 'dendy']), | |
360 'c': set(['atari']), | |
361 'e': set(['amiga', 'coleco', 'dendy']), | |
362 'g': set(['amiga']), | |
363 'x': set(['amiga', 'atari', 'coleco', 'dendy']), | |
364 }, | |
365 KEY_UNTRACKED: { | |
366 'b': set(['amiga', 'atari', 'coleco', 'dendy']), | |
367 'd': set(['atari']), | |
368 'f': set(['amiga', 'coleco', 'dendy']), | |
369 'h': set(['amiga', 'atari', 'dendy']), | |
370 }, | |
371 KEY_TOUCHED: { | |
372 'touched': set(['amiga', 'atari', 'coleco', 'dendy']), | |
373 'touched_a': set(['atari']), | |
374 'touched_e': set(['amiga', 'coleco', 'dendy']), | |
375 }, | |
376 'read_only': { | |
377 None: set(['coleco', 'dendy']), | |
378 False: set(['amiga']), | |
379 True: set(['atari']), | |
380 }, | |
381 } | |
382 expected_oses = set(['amiga', 'atari', 'coleco', 'dendy']) | |
383 actual_values, actual_oses = isolate.invert_map(value) | |
384 self.assertEquals(expected_values, actual_values) | |
385 self.assertEquals(expected_oses, actual_oses) | |
386 | |
387 def test_reduce_inputs(self): | |
388 values = { | |
389 'command': { | |
390 ('echo', 'Hello World'): set(['atari']), | |
391 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), | |
392 }, | |
393 KEY_TRACKED: { | |
394 'a': set(['amiga', 'atari', 'coleco', 'dendy']), | |
395 'c': set(['atari']), | |
396 'e': set(['amiga', 'coleco', 'dendy']), | |
397 'g': set(['amiga']), | |
398 'x': set(['amiga', 'atari', 'coleco', 'dendy']), | |
399 }, | |
400 KEY_UNTRACKED: { | |
401 'b': set(['amiga', 'atari', 'coleco', 'dendy']), | |
402 'd': set(['atari']), | |
403 'f': set(['amiga', 'coleco', 'dendy']), | |
404 'h': set(['amiga', 'atari', 'dendy']), | |
405 }, | |
406 KEY_TOUCHED: { | |
407 'touched': set(['amiga', 'atari', 'coleco', 'dendy']), | |
408 'touched_a': set(['atari']), | |
409 'touched_e': set(['amiga', 'coleco', 'dendy']), | |
410 }, | |
411 'read_only': { | |
412 None: set(['coleco', 'dendy']), | |
413 False: set(['amiga']), | |
414 True: set(['atari']), | |
415 }, | |
416 } | |
417 oses = set(['amiga', 'atari', 'coleco', 'dendy']) | |
418 expected_values = { | |
419 'command': { | |
420 ('echo', 'Hello World'): set(['atari']), | |
421 ('echo', 'You should get an Atari'): set(['!atari']), | |
422 }, | |
423 KEY_TRACKED: { | |
424 'a': set([None]), | |
425 'c': set(['atari']), | |
426 'e': set(['!atari']), | |
427 'g': set(['amiga']), | |
428 'x': set([None]), | |
429 }, | |
430 KEY_UNTRACKED: { | |
431 'b': set([None]), | |
432 'd': set(['atari']), | |
433 'f': set(['!atari']), | |
434 'h': set(['!coleco']), | |
435 }, | |
436 KEY_TOUCHED: { | |
437 'touched': set([None]), | |
438 'touched_a': set(['atari']), | |
439 'touched_e': set(['!atari']), | |
440 }, | |
441 'read_only': { | |
442 None: set(['coleco', 'dendy']), | |
443 False: set(['amiga']), | |
444 True: set(['atari']), | |
445 }, | |
446 } | |
447 actual_values, actual_oses = isolate.reduce_inputs(values, oses) | |
448 self.assertEquals(expected_values, actual_values) | |
449 self.assertEquals(oses, actual_oses) | |
450 | |
451 def test_reduce_inputs_take_strongest_dependency(self): | |
452 values = { | |
453 'command': { | |
454 ('echo', 'Hello World'): set(['atari']), | |
455 ('echo', 'You should get an Atari'): set(['amiga', 'coleco', 'dendy']), | |
456 }, | |
457 KEY_TRACKED: { | |
458 'a': set(['amiga', 'atari', 'coleco', 'dendy']), | |
459 'b': set(['amiga', 'atari', 'coleco']), | |
460 }, | |
461 KEY_UNTRACKED: { | |
462 'c': set(['amiga', 'atari', 'coleco', 'dendy']), | |
463 'd': set(['amiga', 'coleco', 'dendy']), | |
464 }, | |
465 KEY_TOUCHED: { | |
466 'a': set(['amiga', 'atari', 'coleco', 'dendy']), | |
467 'b': set(['atari', 'coleco', 'dendy']), | |
468 'c': set(['amiga', 'atari', 'coleco', 'dendy']), | |
469 'd': set(['atari', 'coleco', 'dendy']), | |
470 }, | |
471 } | |
472 oses = set(['amiga', 'atari', 'coleco', 'dendy']) | |
473 expected_values = { | |
474 'command': { | |
475 ('echo', 'Hello World'): set(['atari']), | |
476 ('echo', 'You should get an Atari'): set(['!atari']), | |
477 }, | |
478 KEY_TRACKED: { | |
479 'a': set([None]), | |
480 'b': set(['!dendy']), | |
481 }, | |
482 KEY_UNTRACKED: { | |
483 'c': set([None]), | |
484 'd': set(['!atari']), | |
485 }, | |
486 KEY_TOUCHED: { | |
487 'b': set(['dendy']), | |
488 'd': set(['atari']), | |
489 }, | |
490 'read_only': {}, | |
491 } | |
492 actual_values, actual_oses = isolate.reduce_inputs(values, oses) | |
493 self.assertEquals(expected_values, actual_values) | |
494 self.assertEquals(oses, actual_oses) | |
495 | |
496 def test_convert_map_to_isolate_dict(self): | |
497 values = { | |
498 'command': { | |
499 ('echo', 'Hello World'): set(['atari']), | |
500 ('echo', 'You should get an Atari'): set(['!atari']), | |
501 }, | |
502 KEY_TRACKED: { | |
503 'a': set([None]), | |
504 'c': set(['atari']), | |
505 'e': set(['!atari']), | |
506 'g': set(['amiga']), | |
507 'x': set([None]), | |
508 }, | |
509 KEY_UNTRACKED: { | |
510 'b': set([None]), | |
511 'd': set(['atari']), | |
512 'f': set(['!atari']), | |
513 'h': set(['!coleco']), | |
514 }, | |
515 KEY_TOUCHED: { | |
516 'touched': set([None]), | |
517 'touched_a': set(['atari']), | |
518 'touched_e': set(['!atari']), | |
519 }, | |
520 'read_only': { | |
521 None: set(['coleco', 'dendy']), | |
522 False: set(['amiga']), | |
523 True: set(['atari']), | |
524 }, | |
525 } | |
526 oses = set(['amiga', 'atari', 'coleco', 'dendy']) | |
527 expected = { | |
528 'variables': { | |
529 KEY_TRACKED: ['a', 'x'], | |
530 KEY_UNTRACKED: ['b'], | |
531 KEY_TOUCHED: ['touched'], | |
532 }, | |
533 'conditions': [ | |
534 ['OS=="amiga"', { | |
535 'variables': { | |
536 KEY_TRACKED: ['g'], | |
537 'read_only': False, | |
538 }, | |
539 }], | |
540 ['OS=="atari"', { | |
541 'variables': { | |
542 'command': ['echo', 'Hello World'], | |
543 KEY_TRACKED: ['c'], | |
544 KEY_UNTRACKED: ['d'], | |
545 KEY_TOUCHED: ['touched_a'], | |
546 'read_only': True, | |
547 }, | |
548 }, { | |
549 'variables': { | |
550 'command': ['echo', 'You should get an Atari'], | |
551 KEY_TRACKED: ['e'], | |
552 KEY_UNTRACKED: ['f'], | |
553 KEY_TOUCHED: ['touched_e'], | |
554 }, | |
555 }], | |
556 ['OS=="coleco"', { | |
557 }, { | |
558 'variables': { | |
559 KEY_UNTRACKED: ['h'], | |
560 }, | |
561 }], | |
562 ], | |
563 } | |
564 self.assertEquals( | |
565 expected, isolate.convert_map_to_isolate_dict(values, oses)) | |
566 | |
567 def test_merge_two_empty(self): | |
568 # Flat stay flat. Pylint is confused about union() return type. | |
569 # pylint: disable=E1103 | |
570 actual = isolate.union( | |
571 isolate.union( | |
572 isolate.Configs([], None), | |
573 isolate.load_isolate_as_config({}, None, [])), | |
574 isolate.load_isolate_as_config({}, None, [])).flatten() | |
575 self.assertEquals({}, actual) | |
576 | |
577 def test_merge_empty(self): | |
578 actual = isolate.convert_map_to_isolate_dict( | |
579 *isolate.reduce_inputs(*isolate.invert_map({}))) | |
580 self.assertEquals({}, actual) | |
581 | |
582 def test_load_two_conditions(self): | |
583 linux = { | |
584 'conditions': [ | |
585 ['OS=="linux"', { | |
586 'variables': { | |
587 'isolate_dependency_tracked': [ | |
588 'file_linux', | |
589 'file_common', | |
590 ], | |
591 }, | |
592 }], | |
593 ], | |
594 } | |
595 mac = { | |
596 'conditions': [ | |
597 ['OS=="mac"', { | |
598 'variables': { | |
599 'isolate_dependency_tracked': [ | |
600 'file_mac', | |
601 'file_common', | |
602 ], | |
603 }, | |
604 }], | |
605 ], | |
606 } | |
607 expected = { | |
608 'linux': { | |
609 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
610 }, | |
611 'mac': { | |
612 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
613 }, | |
614 } | |
615 # Pylint is confused about union() return type. | |
616 # pylint: disable=E1103 | |
617 configs = isolate.union( | |
618 isolate.union( | |
619 isolate.Configs([], None), | |
620 isolate.load_isolate_as_config(linux, None, [])), | |
621 isolate.load_isolate_as_config(mac, None, [])).flatten() | |
622 self.assertEquals(expected, configs) | |
623 | |
624 def test_load_three_conditions(self): | |
625 linux = { | |
626 'conditions': [ | |
627 ['OS=="linux"', { | |
628 'variables': { | |
629 'isolate_dependency_tracked': [ | |
630 'file_linux', | |
631 'file_common', | |
632 ], | |
633 }, | |
634 }], | |
635 ], | |
636 } | |
637 mac = { | |
638 'conditions': [ | |
639 ['OS=="mac"', { | |
640 'variables': { | |
641 'isolate_dependency_tracked': [ | |
642 'file_mac', | |
643 'file_common', | |
644 ], | |
645 }, | |
646 }], | |
647 ], | |
648 } | |
649 win = { | |
650 'conditions': [ | |
651 ['OS=="win"', { | |
652 'variables': { | |
653 'isolate_dependency_tracked': [ | |
654 'file_win', | |
655 'file_common', | |
656 ], | |
657 }, | |
658 }], | |
659 ], | |
660 } | |
661 expected = { | |
662 'linux': { | |
663 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
664 }, | |
665 'mac': { | |
666 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
667 }, | |
668 'win': { | |
669 'isolate_dependency_tracked': ['file_common', 'file_win'], | |
670 }, | |
671 } | |
672 # Pylint is confused about union() return type. | |
673 # pylint: disable=E1103 | |
674 configs = isolate.union( | |
675 isolate.union( | |
676 isolate.union( | |
677 isolate.Configs([], None), | |
678 isolate.load_isolate_as_config(linux, None, [])), | |
679 isolate.load_isolate_as_config(mac, None, [])), | |
680 isolate.load_isolate_as_config(win, None, [])).flatten() | |
681 self.assertEquals(expected, configs) | |
682 | |
683 def test_merge_three_conditions(self): | |
684 values = { | |
685 'linux': { | |
686 'isolate_dependency_tracked': ['file_common', 'file_linux'], | |
687 }, | |
688 'mac': { | |
689 'isolate_dependency_tracked': ['file_common', 'file_mac'], | |
690 }, | |
691 'win': { | |
692 'isolate_dependency_tracked': ['file_common', 'file_win'], | |
693 }, | |
694 } | |
695 expected = { | |
696 'variables': { | |
697 'isolate_dependency_tracked': [ | |
698 'file_common', | |
699 ], | |
700 }, | |
701 'conditions': [ | |
702 ['OS=="linux"', { | |
703 'variables': { | |
704 'isolate_dependency_tracked': [ | |
705 'file_linux', | |
706 ], | |
707 }, | |
708 }], | |
709 ['OS=="mac"', { | |
710 'variables': { | |
711 'isolate_dependency_tracked': [ | |
712 'file_mac', | |
713 ], | |
714 }, | |
715 }], | |
716 ['OS=="win"', { | |
717 'variables': { | |
718 'isolate_dependency_tracked': [ | |
719 'file_win', | |
720 ], | |
721 }, | |
722 }], | |
723 ], | |
724 } | |
725 actual = isolate.convert_map_to_isolate_dict( | |
726 *isolate.reduce_inputs(*isolate.invert_map(values))) | |
727 self.assertEquals(expected, actual) | |
728 | |
729 def test_configs_comment(self): | |
730 # Pylint is confused with isolate.union() return type. | |
731 # pylint: disable=E1103 | |
732 configs = isolate.union( | |
733 isolate.load_isolate_as_config({}, '# Yo dawg!\n# Chill out.\n', []), | |
734 isolate.load_isolate_as_config({}, None, [])) | |
735 self.assertEquals('# Yo dawg!\n# Chill out.\n', configs.file_comment) | |
736 | |
737 configs = isolate.union( | |
738 isolate.load_isolate_as_config({}, None, []), | |
739 isolate.load_isolate_as_config({}, '# Yo dawg!\n# Chill out.\n', [])) | |
740 self.assertEquals('# Yo dawg!\n# Chill out.\n', configs.file_comment) | |
741 | |
742 # Only keep the first one. | |
743 configs = isolate.union( | |
744 isolate.load_isolate_as_config({}, '# Yo dawg!\n', []), | |
745 isolate.load_isolate_as_config({}, '# Chill out.\n', [])) | |
746 self.assertEquals('# Yo dawg!\n', configs.file_comment) | |
747 | |
748 def test_extract_comment(self): | |
749 self.assertEquals( | |
750 '# Foo\n# Bar\n', isolate.extract_comment('# Foo\n# Bar\n{}')) | |
751 self.assertEquals('', isolate.extract_comment('{}')) | |
752 | |
753 def _test_pretty_print_impl(self, value, expected): | |
754 actual = cStringIO.StringIO() | |
755 isolate.pretty_print(value, actual) | |
756 self.assertEquals(expected, actual.getvalue()) | |
757 | |
758 def test_pretty_print_empty(self): | |
759 self._test_pretty_print_impl({}, '{\n}\n') | |
760 | |
761 def test_pretty_print_mid_size(self): | |
762 value = { | |
763 'variables': { | |
764 'bar': [ | |
765 'file1', | |
766 'file2', | |
767 ], | |
768 }, | |
769 'conditions': [ | |
770 ['OS=\"foo\"', { | |
771 'variables': { | |
772 isolate.KEY_UNTRACKED: [ | |
773 'dir1', | |
774 'dir2', | |
775 ], | |
776 isolate.KEY_TRACKED: [ | |
777 'file4', | |
778 'file3', | |
779 ], | |
780 'command': ['python', '-c', 'print "H\\i\'"'], | |
781 'read_only': True, | |
782 'relative_cwd': 'isol\'at\\e', | |
783 }, | |
784 }], | |
785 ['OS=\"bar\"', { | |
786 'variables': {}, | |
787 }, { | |
788 'variables': {}, | |
789 }], | |
790 ], | |
791 } | |
792 expected = ( | |
793 "{\n" | |
794 " 'variables': {\n" | |
795 " 'bar': [\n" | |
796 " 'file1',\n" | |
797 " 'file2',\n" | |
798 " ],\n" | |
799 " },\n" | |
800 " 'conditions': [\n" | |
801 " ['OS=\"foo\"', {\n" | |
802 " 'variables': {\n" | |
803 " 'command': [\n" | |
804 " 'python',\n" | |
805 " '-c',\n" | |
806 " 'print \"H\\i\'\"',\n" | |
807 " ],\n" | |
808 " 'relative_cwd': 'isol\\'at\\\\e',\n" | |
809 " 'read_only': True\n" | |
810 " 'isolate_dependency_tracked': [\n" | |
811 " 'file4',\n" | |
812 " 'file3',\n" | |
813 " ],\n" | |
814 " 'isolate_dependency_untracked': [\n" | |
815 " 'dir1',\n" | |
816 " 'dir2',\n" | |
817 " ],\n" | |
818 " },\n" | |
819 " }],\n" | |
820 " ['OS=\"bar\"', {\n" | |
821 " 'variables': {\n" | |
822 " },\n" | |
823 " }, {\n" | |
824 " 'variables': {\n" | |
825 " },\n" | |
826 " }],\n" | |
827 " ],\n" | |
828 "}\n") | |
829 self._test_pretty_print_impl(value, expected) | |
830 | |
831 | |
832 if __name__ == '__main__': | |
833 logging.basicConfig( | |
834 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, | |
835 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | |
836 unittest.main() | |
OLD | NEW |