Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / tools / swarming_client / googletest / tests / isolate_test_cases_smoke_test.py
1 #!/usr/bin/env python
2 # Copyright 2013 The Swarming Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 that
4 # can be found in the LICENSE file.
5
6 import hashlib
7 import json
8 import logging
9 import os
10 import re
11 import shutil
12 import subprocess
13 import sys
14 import tempfile
15 import unittest
16
17 GOOGLETEST_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 ROOT_DIR = os.path.dirname(GOOGLETEST_DIR)
19
20 sys.path.insert(0, ROOT_DIR)
21 sys.path.insert(0, os.path.join(GOOGLETEST_DIR, '..', 'tests'))
22
23 import isolate
24 import trace_test_util
25 from googletest import trace_test_cases
26 from utils import file_path
27
28
29 class IsolateTestCases(unittest.TestCase):
30   def setUp(self):
31     self.tempdir = None
32
33     self.initial_cwd = ROOT_DIR
34     if sys.platform == 'win32':
35       # Windows has no kernel mode concept of current working directory.
36       self.initial_cwd = None
37
38     # There's 2 kinds of references to python, self.executable,
39     # self.real_executable. It depends how python was started and on which OS.
40     self.executable = unicode(sys.executable)
41     if sys.platform == 'darwin':
42       # /usr/bin/python is a thunk executable that decides which version of
43       # python gets executed.
44       suffix = '.'.join(map(str, sys.version_info[0:2]))
45       if os.access(self.executable + suffix, os.X_OK):
46         # So it'll look like /usr/bin/python2.7
47         self.executable += suffix
48
49     self.real_executable = file_path.get_native_path_case(
50         self.executable)
51     # Make sure there's no environment variable that could cause side effects.
52     os.environ.pop('GTEST_SHARD_INDEX', '')
53     os.environ.pop('GTEST_TOTAL_SHARDS', '')
54
55   def tearDown(self):
56     if self.tempdir:
57       if VERBOSE:
58         # If -v is used, this means the user wants to do further analisys on
59         # the data.
60         print('Leaking %s' % self.tempdir)
61       else:
62         shutil.rmtree(self.tempdir)
63
64   def _copy(self, root, *relpath):
65     relpath = os.path.join(*relpath)
66     shutil.copy(
67         os.path.join(root, relpath),
68         os.path.join(self.tempdir, relpath))
69
70   @trace_test_util.check_can_trace
71   def test_simple(self):
72     # Create a directory and re-use tests/gtest_fake/gtest_fake_pass.isolate.
73     # Warning: we need to copy the files around, since the original .isolate
74     # file is modified.
75     gtest_fake_base_py = os.path.join(
76         'tests', 'gtest_fake', 'gtest_fake_base.py')
77     gtest_fake_pass_py = os.path.join(
78         'tests', 'gtest_fake', 'gtest_fake_pass.py')
79     gtest_fake_pass_isolate = os.path.join(
80         'tests', 'isolate_test_cases', 'gtest_fake_pass.isolate')
81
82     self.tempdir = tempfile.mkdtemp(prefix='isolate_test_cases_test')
83     os.mkdir(os.path.join(self.tempdir, 'isolated'))
84     os.mkdir(os.path.join(self.tempdir, 'tests'))
85     os.mkdir(os.path.join(self.tempdir, 'tests', 'gtest_fake'))
86     os.mkdir(os.path.join(self.tempdir, 'tests', 'isolate_test_cases'))
87     self._copy(ROOT_DIR, 'isolate.py')
88     self._copy(GOOGLETEST_DIR, gtest_fake_base_py)
89     self._copy(GOOGLETEST_DIR, gtest_fake_pass_isolate)
90     self._copy(GOOGLETEST_DIR, gtest_fake_pass_py)
91
92     basename = os.path.join(self.tempdir, 'isolated', 'gtest_fake_pass')
93     isolated = basename + '.isolated'
94
95     # Create a proper .isolated file.
96     cmd = [
97       sys.executable, 'isolate.py',
98       'check',
99       '--config-variable', 'OS', 'amiga',
100       '--extra-variable', 'FLAG', 'run',
101       '--isolate', os.path.join(self.tempdir, gtest_fake_pass_isolate),
102       '--isolated', isolated,
103     ]
104     if VERBOSE:
105       cmd.extend(['-v'] * 3)
106     subprocess.check_call(cmd, cwd=ROOT_DIR)
107
108     # Assert the content of the .isolated file.
109     with open(isolated) as f:
110       actual_isolated = json.load(f)
111     root_dir_gtest_fake_pass_py = os.path.join(
112         GOOGLETEST_DIR, gtest_fake_pass_py)
113     rel_gtest_fake_pass_py = os.path.join(u'gtest_fake', 'gtest_fake_pass.py')
114     expected_isolated = {
115       u'algo': u'sha-1',
116       u'command': [u'../gtest_fake/gtest_fake_pass.py'],
117       u'files': {
118         rel_gtest_fake_pass_py: {
119           u'm': 488,
120           u'h': unicode(hashlib.sha1(
121               open(root_dir_gtest_fake_pass_py, 'rb').read()).hexdigest()),
122           u's': os.stat(root_dir_gtest_fake_pass_py).st_size,
123         },
124       },
125       u'relative_cwd': u'isolate_test_cases',
126       u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
127     }
128     if sys.platform == 'win32':
129       expected_isolated['files'][rel_gtest_fake_pass_py].pop('m')
130     self.assertEqual(expected_isolated, actual_isolated)
131
132     cmd = [
133         sys.executable,
134         os.path.join(GOOGLETEST_DIR, 'isolate_test_cases.py'),
135         # Forces 4 parallel jobs.
136         '--jobs', '4',
137         '--isolated', isolated,
138     ]
139     if VERBOSE:
140       cmd.extend(['-v'] * 3)
141     logging.debug(' '.join(cmd))
142     proc = subprocess.Popen(
143         cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
144     out, err = proc.communicate() or ('', '')  # pylint is confused.
145     logging.info(err)
146     self.assertEqual(0, proc.returncode, (out, err))
147     lines = out.splitlines()
148     expected_out_re = [
149       r'\[0/3\]   \d\.\d\ds ',
150       r'\[1/3\]   \d+\.\d\ds .+',
151       r'\[2/3\]   \d+\.\d\ds .+',
152       r'\[3/3\]   \d+\.\d\ds .+',
153     ]
154     self.assertEqual(len(expected_out_re), len(lines), (out, err))
155     for index in range(len(expected_out_re)):
156       self.assertTrue(
157           re.match('^%s$' % expected_out_re[index], lines[index]),
158           '%d\n%r\n%r\n%r' % (
159             index, expected_out_re[index], lines[index], out))
160     # Junk is printed on win32.
161     if sys.platform != 'win32' and not VERBOSE:
162       self.assertEqual('', err)
163
164     test_cases = (
165       'Foo.Bar1',
166       'Foo.Bar2',
167       'Foo.Bar/3',
168     )
169     expected = {
170       'conditions': [
171         ['OS=="amiga"', {
172           'variables': {
173             'isolate_dependency_untracked': [
174               '../gtest_fake/',
175             ],
176           },
177         }],
178       ],
179     }
180     for test_case in test_cases:
181       tracename = trace_test_cases.sanitize_test_case_name(test_case)
182       with open(basename + '.' + tracename + '.isolate', 'r') as f:
183         result = eval(f.read(), {'__builtins__': None}, None)
184         self.assertEqual(expected, result)
185
186     # Now verify the .isolate file was updated! (That's the magical part where
187     # you say wow!)
188     with open(os.path.join(self.tempdir, gtest_fake_pass_isolate)) as f:
189       actual = eval(f.read(), {'__builtins__': None}, None)
190     expected = {
191       'conditions': [
192         ['OS=="amiga"', {
193           'variables': {
194             'isolate_dependency_untracked': [
195               '../gtest_fake/',
196             ],
197           },
198         }],
199       ],
200       'variables': {
201         'command': ['../gtest_fake/gtest_fake_pass.py'],
202         'isolate_dependency_tracked': [
203           '../gtest_fake/gtest_fake_pass.py',
204         ],
205       },
206     }
207     self.assertEqual(expected, actual)
208
209
210 if __name__ == '__main__':
211   VERBOSE = '-v' in sys.argv
212   logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
213   if VERBOSE:
214     unittest.TestCase.maxDiff = None
215   unittest.main()