OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import logging | 6 import logging |
7 import os | 7 import os |
8 import shutil | 8 import shutil |
9 import subprocess | 9 import subprocess |
10 import sys | 10 import sys |
11 import tempfile | 11 import tempfile |
12 import unittest | 12 import unittest |
13 | 13 |
14 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | 14 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) |
15 | 15 |
16 VERBOSE = False | 16 VERBOSE = False |
17 | 17 |
18 | 18 |
19 class CalledProcessError(subprocess.CalledProcessError): | 19 class CalledProcessError(subprocess.CalledProcessError): |
20 """Makes 2.6 version act like 2.7""" | 20 """Makes 2.6 version act like 2.7""" |
21 def __init__(self, returncode, cmd, output): | 21 def __init__(self, returncode, cmd, output, cwd): |
22 super(CalledProcessError, self).__init__(returncode, cmd) | 22 super(CalledProcessError, self).__init__(returncode, cmd) |
23 self.output = output | 23 self.output = output |
| 24 self.cwd = cwd |
| 25 |
| 26 def __str__(self): |
| 27 return super(CalledProcessError, self).__str__() + ( |
| 28 '\n' |
| 29 'cwd=%s\n%s') % (self.cwd, self.output) |
24 | 30 |
25 | 31 |
26 class TraceInputs(unittest.TestCase): | 32 class TraceInputs(unittest.TestCase): |
27 def setUp(self): | 33 def setUp(self): |
28 self.tempdir = tempfile.mkdtemp() | 34 self.tempdir = tempfile.mkdtemp() |
29 self.log = os.path.join(self.tempdir, 'log') | 35 self.log = os.path.join(self.tempdir, 'log') |
30 | 36 |
31 def tearDown(self): | 37 def tearDown(self): |
32 shutil.rmtree(self.tempdir) | 38 shutil.rmtree(self.tempdir) |
33 | 39 |
34 def _execute(self, args): | 40 def _execute(self, args): |
35 cmd = [ | 41 cmd = [ |
36 sys.executable, os.path.join(ROOT_DIR, 'trace_inputs.py'), | 42 sys.executable, os.path.join(ROOT_DIR, 'trace_inputs.py'), |
37 '--log', self.log, | 43 '--log', self.log, |
38 '--gyp', os.path.join('data', 'trace_inputs'), | 44 '--root-dir', ROOT_DIR, |
39 '--product', '.', # Not tested. | |
40 '--root-dir', ROOT_DIR, | |
41 ] + args | 45 ] + args |
42 p = subprocess.Popen( | 46 p = subprocess.Popen( |
43 cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=ROOT_DIR) | 47 cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=ROOT_DIR) |
44 out = p.communicate()[0] | 48 out = p.communicate()[0] |
45 if p.returncode: | 49 if p.returncode: |
46 raise CalledProcessError(p.returncode, cmd, out) | 50 raise CalledProcessError(p.returncode, cmd, out, ROOT_DIR) |
47 return out | 51 return out |
48 | 52 |
| 53 @staticmethod |
| 54 def _gyp(): |
| 55 return [ |
| 56 '--gyp', os.path.join('data', 'trace_inputs'), |
| 57 '--product', '.', # Not tested. |
| 58 ] |
| 59 |
49 def test_trace(self): | 60 def test_trace(self): |
50 if sys.platform == 'linux2': | 61 if sys.platform == 'linux2': |
51 return self._test_trace_linux() | 62 return self._test_trace_linux() |
52 if sys.platform == 'darwin': | 63 if sys.platform == 'darwin': |
53 return self._test_trace_mac() | 64 return self._test_trace_mac() |
54 print 'Unsupported: %s' % sys.platform | 65 print 'Unsupported: %s' % sys.platform |
55 | 66 |
| 67 def test_trace_gyp(self): |
| 68 if sys.platform == 'linux2': |
| 69 return self._test_trace_gyp_linux() |
| 70 if sys.platform == 'darwin': |
| 71 return self._test_trace_gyp_mac() |
| 72 print 'Unsupported: %s' % sys.platform |
| 73 |
56 def _test_trace_linux(self): | 74 def _test_trace_linux(self): |
57 # TODO(maruel): BUG: Note that child.py is missing. | 75 expected_end = [ |
| 76 "Interesting: 4 reduced to 3", |
| 77 " data/trace_inputs/", |
| 78 " trace_inputs.py", |
| 79 " trace_inputs_test.py", |
| 80 ] |
| 81 actual = self._execute(['trace_inputs_test.py', '--child1']).splitlines() |
| 82 self.assertTrue(actual[0].startswith('Tracing... [')) |
| 83 self.assertTrue(actual[1].startswith('Loading traces... ')) |
| 84 self.assertTrue(actual[2].startswith('Total: ')) |
| 85 self.assertEquals("Non existent: 0", actual[3]) |
| 86 # Ignore any Unexpected part. |
| 87 # TODO(maruel): Make sure there is no Unexpected part, even in the case of |
| 88 # virtualenv usage. |
| 89 self.assertEquals(expected_end, actual[-len(expected_end):]) |
| 90 |
| 91 def _test_trace_gyp_linux(self): |
58 expected = ( | 92 expected = ( |
59 "{\n" | 93 "{\n" |
60 " 'variables': {\n" | 94 " 'variables': {\n" |
61 " 'isolate_files': [\n" | 95 " 'isolate_files': [\n" |
62 " '<(DEPTH)/trace_inputs.py',\n" | 96 " '<(DEPTH)/trace_inputs.py',\n" |
63 " '<(DEPTH)/trace_inputs_test.py',\n" | 97 " '<(DEPTH)/trace_inputs_test.py',\n" |
64 " ],\n" | 98 " ],\n" |
65 " 'isolate_dirs': [\n" | 99 " 'isolate_dirs': [\n" |
| 100 " './',\n" |
66 " ],\n" | 101 " ],\n" |
67 " },\n" | 102 " },\n" |
68 "},\n") | 103 "},\n") |
69 gyp = self._execute(['trace_inputs_test.py', '--child1']) | 104 actual = self._execute(self._gyp() + ['trace_inputs_test.py', '--child1']) |
70 self.assertEquals(expected, gyp) | 105 self.assertEquals(expected, actual) |
71 | 106 |
72 def _test_trace_mac(self): | 107 def _test_trace_mac(self): |
73 # It is annoying in the case of dtrace because it requires root access. | 108 # It is annoying in the case of dtrace because it requires root access. |
74 # TODO(maruel): BUG: Note that child.py is missing. | 109 # TODO(maruel): BUG: Note that child.py is missing. |
75 expected = ( | 110 expected = ( |
| 111 "Total: 2\n" |
| 112 "Non existent: 0\n" |
| 113 "Interesting: 2 reduced to 2\n" |
| 114 " trace_inputs.py\n" |
| 115 " trace_inputs_test.py\n") |
| 116 actual = self._execute( |
| 117 ['trace_inputs_test.py', '--child1']).splitlines(True) |
| 118 self.assertTrue(actual[0].startswith('Tracing... [')) |
| 119 self.assertTrue(actual[1].startswith('Loading traces... ')) |
| 120 self.assertEquals(expected, ''.join(actual[2:])) |
| 121 |
| 122 def _test_trace_gyp_mac(self): |
| 123 # It is annoying in the case of dtrace because it requires root access. |
| 124 # TODO(maruel): BUG: Note that child.py is missing. |
| 125 expected = ( |
76 "{\n" | 126 "{\n" |
77 " 'variables': {\n" | 127 " 'variables': {\n" |
78 " 'isolate_files': [\n" | 128 " 'isolate_files': [\n" |
79 " '<(DEPTH)/trace_inputs.py',\n" | 129 " '<(DEPTH)/trace_inputs.py',\n" |
80 " '<(DEPTH)/trace_inputs_test.py',\n" | 130 " '<(DEPTH)/trace_inputs_test.py',\n" |
81 " ],\n" | 131 " ],\n" |
82 " 'isolate_dirs': [\n" | 132 " 'isolate_dirs': [\n" |
83 " ],\n" | 133 " ],\n" |
84 " },\n" | 134 " },\n" |
85 "},\n") | 135 "},\n") |
86 gyp = self._execute(['trace_inputs_test.py', '--child1']) | 136 actual = self._execute(self._gyp() + ['trace_inputs_test.py', '--child1']) |
87 self.assertEquals(expected, gyp) | 137 self.assertEquals(expected, actual) |
88 | 138 |
89 | 139 |
90 def child1(): | 140 def child1(): |
91 print 'child1' | 141 print 'child1' |
92 # Implicitly force file opening. | 142 # Implicitly force file opening. |
93 import trace_inputs # pylint: disable=W0612 | 143 import trace_inputs # pylint: disable=W0612 |
94 # Do not wait for the child to exit. | 144 # Do not wait for the child to exit. |
95 # Use relative directory. | 145 # Use relative directory. |
96 subprocess.Popen( | 146 subprocess.Popen( |
97 ['python', 'child2.py'], cwd=os.path.join('data', 'trace_inputs')) | 147 ['python', 'child2.py'], cwd=os.path.join('data', 'trace_inputs')) |
98 return 0 | 148 return 0 |
99 | 149 |
100 | 150 |
101 def main(): | 151 def main(): |
102 global VERBOSE | 152 global VERBOSE |
103 VERBOSE = '-v' in sys.argv | 153 VERBOSE = '-v' in sys.argv |
104 level = logging.DEBUG if VERBOSE else logging.ERROR | 154 level = logging.DEBUG if VERBOSE else logging.ERROR |
105 logging.basicConfig(level=level) | 155 logging.basicConfig(level=level) |
106 if len(sys.argv) == 1: | 156 if len(sys.argv) == 1: |
107 unittest.main() | 157 unittest.main() |
108 | 158 |
109 if sys.argv[1] == '--child1': | 159 if sys.argv[1] == '--child1': |
110 return child1() | 160 return child1() |
111 | 161 |
112 unittest.main() | 162 unittest.main() |
113 | 163 |
114 | 164 |
115 if __name__ == '__main__': | 165 if __name__ == '__main__': |
116 sys.exit(main()) | 166 sys.exit(main()) |
OLD | NEW |