OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
2 # | |
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 import errno | |
8 import os | |
9 import shutil | |
10 import subprocess | |
11 import tempfile | |
12 import unittest | |
13 import cros_build_lib | |
14 import mox | |
15 | |
16 | |
17 class TestRunCommand(unittest.TestCase): | |
18 | |
19 def setUp(self): | |
20 self.mox = mox.Mox() | |
21 self.mox.StubOutWithMock(subprocess, 'Popen', use_mock_anything=True) | |
22 self.proc_mock = self.mox.CreateMockAnything() | |
23 self.cmd = 'test cmd' | |
24 self.error = 'test error' | |
25 self.output = 'test output' | |
26 | |
27 def tearDown(self): | |
28 self.mox.UnsetStubs() | |
29 self.mox.VerifyAll() | |
30 | |
31 def _AssertCrEqual(self, expected, actual): | |
32 """Helper method to compare two CommandResult objects. | |
33 | |
34 This is needed since assertEqual does not know how to compare two | |
35 CommandResult objects. | |
36 | |
37 Args: | |
38 expected: a CommandResult object, expected result. | |
39 actual: a CommandResult object, actual result. | |
40 """ | |
41 self.assertEqual(expected.cmd, actual.cmd) | |
42 self.assertEqual(expected.error, actual.error) | |
43 self.assertEqual(expected.output, actual.output) | |
44 self.assertEqual(expected.returncode, actual.returncode) | |
45 | |
46 def _TestCmd(self, cmd, sp_kv=dict(), rc_kv=dict()): | |
47 """Factor out common setup logic for testing --cmd. | |
48 | |
49 Args: | |
50 cmd: a string or an array of strings. | |
51 sp_kv: key-value pairs passed to subprocess.Popen(). | |
52 rc_kv: key-value pairs passed to RunCommand(). | |
53 """ | |
54 expected_result = cros_build_lib.CommandResult() | |
55 expected_result.cmd = self.cmd | |
56 expected_result.error = self.error | |
57 expected_result.output = self.output | |
58 if 'exit_code' in rc_kv: | |
59 expected_result.returncode = self.proc_mock.returncode | |
60 | |
61 arg_dict = dict() | |
62 for attr in 'cwd stdin stdout stderr shell'.split(): | |
63 if attr in sp_kv: | |
64 arg_dict[attr] = sp_kv[attr] | |
65 else: | |
66 if attr == 'shell': | |
67 arg_dict[attr] = False | |
68 else: | |
69 arg_dict[attr] = None | |
70 | |
71 subprocess.Popen(self.cmd, **arg_dict).AndReturn(self.proc_mock) | |
72 self.proc_mock.communicate(None).AndReturn((self.output, self.error)) | |
73 self.mox.ReplayAll() | |
74 actual_result = cros_build_lib.RunCommand(cmd, **rc_kv) | |
75 self._AssertCrEqual(expected_result, actual_result) | |
76 | |
77 def testReturnCodeZeroWithArrayCmd(self): | |
78 """--enter_chroot=False and --cmd is an array of strings.""" | |
79 self.proc_mock.returncode = 0 | |
80 cmd_list = ['foo', 'bar', 'roger'] | |
81 self.cmd = 'foo bar roger' | |
82 self._TestCmd(cmd_list, rc_kv=dict(exit_code=True)) | |
83 | |
84 def testReturnCodeZeroWithArrayCmdEnterChroot(self): | |
85 """--enter_chroot=True and --cmd is an array of strings.""" | |
86 self.proc_mock.returncode = 0 | |
87 cmd_list = ['foo', 'bar', 'roger'] | |
88 self.cmd = './enter_chroot.sh -- %s' % ' '.join(cmd_list) | |
89 self._TestCmd(cmd_list, rc_kv=dict(enter_chroot=True)) | |
90 | |
91 def testReturnCodeNotZeroErrorOkNotRaisesError(self): | |
92 """Raise error when proc.communicate() returns non-zero.""" | |
93 self.proc_mock.returncode = 1 | |
94 self._TestCmd(self.cmd, rc_kv=dict(error_ok=True)) | |
95 | |
96 def testSubprocessCommunicateExceptionRaisesError(self): | |
97 """Verify error raised by communicate() is caught.""" | |
98 subprocess.Popen(self.cmd, cwd=None, stdin=None, stdout=None, stderr=None, | |
99 shell=False).AndReturn(self.proc_mock) | |
100 self.proc_mock.communicate(None).AndRaise(ValueError) | |
101 self.mox.ReplayAll() | |
102 self.assertRaises(ValueError, cros_build_lib.RunCommand, self.cmd) | |
103 | |
104 def testSubprocessCommunicateExceptionNotRaisesError(self): | |
105 """Don't re-raise error from communicate() when --error_ok=True.""" | |
106 expected_result = cros_build_lib.CommandResult() | |
107 cmd_str = './enter_chroot.sh -- %s' % self.cmd | |
108 expected_result.cmd = cmd_str | |
109 | |
110 subprocess.Popen(cmd_str, cwd=None, stdin=None, stdout=None, stderr=None, | |
111 shell=False).AndReturn(self.proc_mock) | |
112 self.proc_mock.communicate(None).AndRaise(ValueError) | |
113 self.mox.ReplayAll() | |
114 actual_result = cros_build_lib.RunCommand(self.cmd, error_ok=True, | |
115 enter_chroot=True) | |
116 self._AssertCrEqual(expected_result, actual_result) | |
117 | |
118 | |
119 class TestListFiles(unittest.TestCase): | |
120 | |
121 def setUp(self): | |
122 self.root_dir = tempfile.mkdtemp(prefix='listfiles_unittest') | |
123 | |
124 def tearDown(self): | |
125 shutil.rmtree(self.root_dir) | |
126 | |
127 def _CreateNestedDir(self, dir_structure): | |
128 for entry in dir_structure: | |
129 full_path = os.path.join(os.path.join(self.root_dir, entry)) | |
130 # ensure dirs are created | |
131 try: | |
132 os.makedirs(os.path.dirname(full_path)) | |
133 if full_path.endswith('/'): | |
134 # we only want to create directories | |
135 return | |
136 except OSError, err: | |
137 if err.errno == errno.EEXIST: | |
138 # we don't care if the dir already exists | |
139 pass | |
140 else: | |
141 raise | |
142 # create dummy files | |
143 tmp = open(full_path, 'w') | |
144 tmp.close() | |
145 | |
146 def testTraverse(self): | |
147 """Test that we are traversing the directory properly.""" | |
148 dir_structure = ['one/two/test.txt', 'one/blah.py', | |
149 'three/extra.conf'] | |
150 self._CreateNestedDir(dir_structure) | |
151 | |
152 files = cros_build_lib.ListFiles(self.root_dir) | |
153 for f in files: | |
154 f = f.replace(self.root_dir, '').lstrip('/') | |
155 if f not in dir_structure: | |
156 self.fail('%s was not found in %s' % (f, dir_structure)) | |
157 | |
158 def testEmptyFilePath(self): | |
159 """Test that we return nothing when directories are empty.""" | |
160 dir_structure = ['one/', 'two/', 'one/a/'] | |
161 self._CreateNestedDir(dir_structure) | |
162 files = cros_build_lib.ListFiles(self.root_dir) | |
163 self.assertEqual(files, []) | |
164 | |
165 def testNoSuchDir(self): | |
166 try: | |
167 cros_build_lib.ListFiles('/me/no/existe') | |
168 except OSError, err: | |
169 self.assertEqual(err.errno, errno.ENOENT) | |
170 | |
171 | |
172 class HelperMethodMoxTests(unittest.TestCase): | |
173 """Tests for various helper methods using mox.""" | |
174 | |
175 def setUp(self): | |
176 self.mox = mox.Mox() | |
177 self.mox.StubOutWithMock(os.path, 'abspath') | |
178 | |
179 def tearDown(self): | |
180 self.mox.UnsetStubs() | |
181 self.mox.VerifyAll() | |
182 | |
183 def testGetSrcRoot(self): | |
184 test_path = '/tmp/foo/src/scripts/bar/more' | |
185 expected = '/tmp/foo/src/scripts' | |
186 os.path.abspath('.').AndReturn(test_path) | |
187 self.mox.ReplayAll() | |
188 actual = cros_build_lib.GetSrcRoot() | |
189 self.assertEqual(expected, actual) | |
190 | |
191 def testGetOutputImageDir(self): | |
192 expected = '/tmp/foo/src/build/images/x86-generic/0.0.1-a1' | |
193 self.mox.StubOutWithMock(cros_build_lib, 'GetSrcRoot') | |
194 cros_build_lib.GetSrcRoot().AndReturn('/tmp/foo/src/scripts') | |
195 self.mox.ReplayAll() | |
196 actual = cros_build_lib.GetOutputImageDir('x86-generic', '0.0.1') | |
197 self.assertEqual(expected, actual) | |
198 | |
199 | |
200 class HelperMethodSimpleTests(unittest.TestCase): | |
201 """Tests for various helper methods without using mox.""" | |
202 | |
203 def _TestChromeosVersion(self, test_str, expected=None): | |
204 actual = cros_build_lib.GetChromeosVersion(test_str) | |
205 self.assertEqual(expected, actual) | |
206 | |
207 def testGetChromeosVersionWithValidVersionReturnsValue(self): | |
208 expected = '0.8.71.2010_09_10_1530' | |
209 test_str = ' CHROMEOS_VERSION_STRING=0.8.71.2010_09_10_1530 ' | |
210 self._TestChromeosVersion(test_str, expected) | |
211 | |
212 def testGetChromeosVersionWithMultipleVersionReturnsFirstMatch(self): | |
213 expected = '0.8.71.2010_09_10_1530' | |
214 test_str = (' CHROMEOS_VERSION_STRING=0.8.71.2010_09_10_1530 ' | |
215 ' CHROMEOS_VERSION_STRING=10_1530 ') | |
216 self._TestChromeosVersion(test_str, expected) | |
217 | |
218 def testGetChromeosVersionWithInvalidVersionReturnsDefault(self): | |
219 test_str = ' CHROMEOS_VERSION_STRING=invalid_version_string ' | |
220 self._TestChromeosVersion(test_str) | |
221 | |
222 def testGetChromeosVersionWithEmptyInputReturnsDefault(self): | |
223 self._TestChromeosVersion('') | |
224 | |
225 def testGetChromeosVersionWithNoneInputReturnsDefault(self): | |
226 self._TestChromeosVersion(None) | |
227 | |
228 | |
229 if __name__ == '__main__': | |
230 unittest.main() | |
OLD | NEW |