| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright 2008-2009 Google Inc. All Rights Reserved. | 3 # Copyright 2008-2009 Google Inc. All Rights Reserved. |
| 4 # | 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
| 8 # | 8 # |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 # | 10 # |
| 11 # Unless required by applicable law or agreed to in writing, software | 11 # Unless required by applicable law or agreed to in writing, software |
| 12 # distributed under the License is distributed on an "AS IS" BASIS, | 12 # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 # See the License for the specific language governing permissions and | 14 # See the License for the specific language governing permissions and |
| 15 # limitations under the License. | 15 # limitations under the License. |
| 16 | 16 |
| 17 """Unit tests for gclient.py.""" | 17 """Unit tests for gclient.py.""" |
| 18 | 18 |
| 19 __author__ = 'stephen5.ng@gmail.com (Stephen Ng)' | 19 __author__ = 'stephen5.ng@gmail.com (Stephen Ng)' |
| 20 | 20 |
| 21 import __builtin__ | 21 import __builtin__ |
| 22 import copy | |
| 23 import os | 22 import os |
| 24 import random | |
| 25 import string | |
| 26 import StringIO | 23 import StringIO |
| 27 import subprocess | |
| 28 import sys | |
| 29 import unittest | 24 import unittest |
| 30 | 25 |
| 31 import __init__ | |
| 32 import gclient | 26 import gclient |
| 33 mox = __init__.mox | 27 import super_mox |
| 28 from super_mox import mox |
| 34 | 29 |
| 35 | 30 |
| 36 ## Some utilities for generating arbitrary arguments. | 31 class BaseTestCase(super_mox.SuperMoxTestBase): |
| 32 def setUp(self): |
| 33 super_mox.SuperMoxTestBase.setUp(self) |
| 34 self.mox.StubOutWithMock(gclient.os.path, 'exists') |
| 35 self.mox.StubOutWithMock(gclient.os.path, 'isdir') |
| 36 self.mox.StubOutWithMock(gclient.sys, 'stdout') |
| 37 self.mox.StubOutWithMock(gclient, 'subprocess') |
| 38 # These are not tested. |
| 39 self.mox.StubOutWithMock(gclient, 'FileRead') |
| 40 self.mox.StubOutWithMock(gclient, 'FileWrite') |
| 41 self.mox.StubOutWithMock(gclient, 'SubprocessCall') |
| 42 self.mox.StubOutWithMock(gclient, 'RemoveDirectory') |
| 37 | 43 |
| 38 | |
| 39 def String(max_length): | |
| 40 return ''.join([random.choice(string.letters) | |
| 41 for x in xrange(random.randint(1, max_length))]) | |
| 42 | |
| 43 | |
| 44 def Strings(max_arg_count, max_arg_length): | |
| 45 return [String(max_arg_length) for x in xrange(max_arg_count)] | |
| 46 | |
| 47 | |
| 48 def Args(max_arg_count=8, max_arg_length=16): | |
| 49 return Strings(max_arg_count, random.randint(1, max_arg_length)) | |
| 50 | |
| 51 | |
| 52 def _DirElts(max_elt_count=4, max_elt_length=8): | |
| 53 return os.sep.join(Strings(max_elt_count, max_elt_length)) | |
| 54 | |
| 55 | |
| 56 def Dir(max_elt_count=4, max_elt_length=8): | |
| 57 return random.choice((os.sep, '')) + _DirElts(max_elt_count, max_elt_length) | |
| 58 | |
| 59 def Url(max_elt_count=4, max_elt_length=8): | |
| 60 return ('svn://random_host:port/a' + | |
| 61 _DirElts(max_elt_count, max_elt_length).replace(os.sep, '/')) | |
| 62 | |
| 63 def RootDir(max_elt_count=4, max_elt_length=8): | |
| 64 return os.sep + _DirElts(max_elt_count, max_elt_length) | |
| 65 | |
| 66 | |
| 67 class BaseTestCase(mox.MoxTestBase): | |
| 68 # Like unittest's assertRaises, but checks for Gclient.Error. | 44 # Like unittest's assertRaises, but checks for Gclient.Error. |
| 69 def assertRaisesError(self, msg, fn, *args, **kwargs): | 45 def assertRaisesError(self, msg, fn, *args, **kwargs): |
| 70 try: | 46 try: |
| 71 fn(*args, **kwargs) | 47 fn(*args, **kwargs) |
| 72 except gclient.Error, e: | 48 except gclient.Error, e: |
| 73 self.assertEquals(e.args[0], msg) | 49 self.assertEquals(e.args[0], msg) |
| 74 else: | 50 else: |
| 75 self.fail('%s not raised' % msg) | 51 self.fail('%s not raised' % msg) |
| 76 | 52 |
| 77 def compareMembers(self, object, members): | |
| 78 """If you add a member, be sure to add the relevant test!""" | |
| 79 # Skip over members starting with '_' since they are usually not meant to | |
| 80 # be for public use. | |
| 81 actual_members = [x for x in sorted(dir(object)) | |
| 82 if not x.startswith('_')] | |
| 83 expected_members = sorted(members) | |
| 84 if actual_members != expected_members: | |
| 85 diff = ([i for i in actual_members if i not in expected_members] + | |
| 86 [i for i in expected_members if i not in actual_members]) | |
| 87 print diff | |
| 88 self.assertEqual(actual_members, expected_members) | |
| 89 | |
| 90 | 53 |
| 91 class GClientBaseTestCase(BaseTestCase): | 54 class GClientBaseTestCase(BaseTestCase): |
| 92 def Options(self, *args, **kwargs): | 55 def Options(self, *args, **kwargs): |
| 93 return self.OptionsObject(self, *args, **kwargs) | 56 return self.OptionsObject(self, *args, **kwargs) |
| 94 | 57 |
| 95 def setUp(self): | 58 def setUp(self): |
| 96 BaseTestCase.setUp(self) | 59 BaseTestCase.setUp(self) |
| 97 # Mock them to be sure nothing bad happens. | 60 # Mock them to be sure nothing bad happens. |
| 98 self._CaptureSVN = gclient.CaptureSVN | 61 self.mox.StubOutWithMock(gclient, 'CaptureSVN') |
| 99 gclient.CaptureSVN = self.mox.CreateMockAnything() | |
| 100 self._CaptureSVNInfo = gclient.CaptureSVNInfo | 62 self._CaptureSVNInfo = gclient.CaptureSVNInfo |
| 101 gclient.CaptureSVNInfo = self.mox.CreateMockAnything() | 63 self.mox.StubOutWithMock(gclient, 'CaptureSVNInfo') |
| 102 self._CaptureSVNStatus = gclient.CaptureSVNStatus | 64 self.mox.StubOutWithMock(gclient, 'CaptureSVNStatus') |
| 103 gclient.CaptureSVNStatus = self.mox.CreateMockAnything() | 65 self.mox.StubOutWithMock(gclient, 'RunSVN') |
| 104 self._FileRead = gclient.FileRead | 66 self.mox.StubOutWithMock(gclient, 'RunSVNAndGetFileList') |
| 105 gclient.FileRead = self.mox.CreateMockAnything() | |
| 106 self._FileWrite = gclient.FileWrite | |
| 107 gclient.FileWrite = self.mox.CreateMockAnything() | |
| 108 self._RemoveDirectory = gclient.RemoveDirectory | |
| 109 gclient.RemoveDirectory = self.mox.CreateMockAnything() | |
| 110 self._RunSVN = gclient.RunSVN | |
| 111 gclient.RunSVN = self.mox.CreateMockAnything() | |
| 112 self._RunSVNAndGetFileList = gclient.RunSVNAndGetFileList | |
| 113 gclient.RunSVNAndGetFileList = self.mox.CreateMockAnything() | |
| 114 self._sys_stdout = gclient.sys.stdout | |
| 115 gclient.sys.stdout = self.mox.CreateMock(self._sys_stdout) | |
| 116 self._subprocess = gclient.subprocess | |
| 117 gclient.subprocess = self.mox.CreateMock(self._subprocess) | |
| 118 self._os_path_exists = gclient.os.path.exists | |
| 119 gclient.os.path.exists = self.mox.CreateMockAnything() | |
| 120 self._gclient_gclient = gclient.GClient | 67 self._gclient_gclient = gclient.GClient |
| 121 gclient.GClient = self.mox.CreateMockAnything() | 68 gclient.GClient = self.mox.CreateMockAnything() |
| 122 self._scm_wrapper = gclient.SCMWrapper | 69 self._scm_wrapper = gclient.SCMWrapper |
| 123 gclient.SCMWrapper = self.mox.CreateMockAnything() | 70 gclient.SCMWrapper = self.mox.CreateMockAnything() |
| 124 | 71 |
| 125 def tearDown(self): | 72 def tearDown(self): |
| 126 gclient.CaptureSVN = self._CaptureSVN | |
| 127 gclient.CaptureSVNInfo = self._CaptureSVNInfo | |
| 128 gclient.CaptureSVNStatus = self._CaptureSVNStatus | |
| 129 gclient.FileRead = self._FileRead | |
| 130 gclient.FileWrite = self._FileWrite | |
| 131 gclient.RemoveDirectory = self._RemoveDirectory | |
| 132 gclient.RunSVN = self._RunSVN | |
| 133 gclient.RunSVNAndGetFileList = self._RunSVNAndGetFileList | |
| 134 gclient.sys.stdout = self._sys_stdout | |
| 135 gclient.subprocess = self._subprocess | |
| 136 gclient.os.path.exists = self._os_path_exists | |
| 137 gclient.GClient = self._gclient_gclient | 73 gclient.GClient = self._gclient_gclient |
| 138 gclient.SCMWrapper = self._scm_wrapper | 74 gclient.SCMWrapper = self._scm_wrapper |
| 139 BaseTestCase.tearDown(self) | 75 BaseTestCase.tearDown(self) |
| 140 | 76 |
| 141 | 77 |
| 142 class GclientTestCase(GClientBaseTestCase): | 78 class GclientTestCase(GClientBaseTestCase): |
| 143 class OptionsObject(object): | 79 class OptionsObject(object): |
| 144 def __init__(self, test_case, verbose=False, spec=None, | 80 def __init__(self, test_case, verbose=False, spec=None, |
| 145 config_filename='a_file_name', | 81 config_filename='a_file_name', |
| 146 entries_filename='a_entry_file_name', | 82 entries_filename='a_entry_file_name', |
| 147 deps_file='a_deps_file_name', force=False): | 83 deps_file='a_deps_file_name', force=False): |
| 148 self.verbose = verbose | 84 self.verbose = verbose |
| 149 self.spec = spec | 85 self.spec = spec |
| 150 self.config_filename = config_filename | 86 self.config_filename = config_filename |
| 151 self.entries_filename = entries_filename | 87 self.entries_filename = entries_filename |
| 152 self.deps_file = deps_file | 88 self.deps_file = deps_file |
| 153 self.force = force | 89 self.force = force |
| 154 self.revisions = [] | 90 self.revisions = [] |
| 155 self.manually_grab_svn_rev = True | 91 self.manually_grab_svn_rev = True |
| 156 self.deps_os = None | 92 self.deps_os = None |
| 157 self.head = False | 93 self.head = False |
| 158 | 94 |
| 159 # Mox | 95 # Mox |
| 160 self.platform = test_case.platform | 96 self.platform = test_case.platform |
| 161 | 97 |
| 162 def setUp(self): | 98 def setUp(self): |
| 163 GClientBaseTestCase.setUp(self) | 99 GClientBaseTestCase.setUp(self) |
| 164 self.platform = 'darwin' | 100 self.platform = 'darwin' |
| 165 | 101 |
| 166 self.args = Args() | 102 self.args = self.Args() |
| 167 self.root_dir = Dir() | 103 self.root_dir = self.Dir() |
| 168 self.url = Url() | 104 self.url = self.Url() |
| 169 | 105 |
| 170 | 106 |
| 171 class GClientCommandsTestCase(GClientBaseTestCase): | 107 class GClientCommandsTestCase(GClientBaseTestCase): |
| 172 def testCommands(self): | 108 def testCommands(self): |
| 173 known_commands = [gclient.DoCleanup, gclient.DoConfig, gclient.DoDiff, | 109 known_commands = [gclient.DoCleanup, gclient.DoConfig, gclient.DoDiff, |
| 174 gclient.DoHelp, gclient.DoStatus, gclient.DoUpdate, | 110 gclient.DoHelp, gclient.DoStatus, gclient.DoUpdate, |
| 175 gclient.DoRevert, gclient.DoRunHooks, gclient.DoRevInfo] | 111 gclient.DoRevert, gclient.DoRunHooks, gclient.DoRevInfo] |
| 176 for (k,v) in gclient.gclient_command_map.iteritems(): | 112 for (k,v) in gclient.gclient_command_map.iteritems(): |
| 177 # If it fails, you need to add a test case for the new command. | 113 # If it fails, you need to add a test case for the new command. |
| 178 self.assert_(v in known_commands) | 114 self.assert_(v in known_commands) |
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 class OptionsObject(object): | 990 class OptionsObject(object): |
| 1055 def __init__(self, test_case, verbose=False, revision=None): | 991 def __init__(self, test_case, verbose=False, revision=None): |
| 1056 self.verbose = verbose | 992 self.verbose = verbose |
| 1057 self.revision = revision | 993 self.revision = revision |
| 1058 self.manually_grab_svn_rev = True | 994 self.manually_grab_svn_rev = True |
| 1059 self.deps_os = None | 995 self.deps_os = None |
| 1060 self.force = False | 996 self.force = False |
| 1061 | 997 |
| 1062 def setUp(self): | 998 def setUp(self): |
| 1063 GClientBaseTestCase.setUp(self) | 999 GClientBaseTestCase.setUp(self) |
| 1064 self.root_dir = Dir() | 1000 self.root_dir = self.Dir() |
| 1065 self.args = Args() | 1001 self.args = self.Args() |
| 1066 self.url = Url() | 1002 self.url = self.Url() |
| 1067 self.relpath = 'asf' | 1003 self.relpath = 'asf' |
| 1068 self._os_path_isdir = gclient.os.path.isdir | |
| 1069 gclient.os.path.isdir = self.mox.CreateMockAnything() | |
| 1070 | |
| 1071 def tearDown(self): | |
| 1072 gclient.os.path.isdir = self._os_path_isdir | |
| 1073 GClientBaseTestCase.tearDown(self) | |
| 1074 | 1004 |
| 1075 def testDir(self): | 1005 def testDir(self): |
| 1076 members = [ | 1006 members = [ |
| 1077 'FullUrlForRelativeUrl', 'RunCommand', 'cleanup', 'diff', 'relpath', | 1007 'FullUrlForRelativeUrl', 'RunCommand', 'cleanup', 'diff', 'relpath', |
| 1078 'revert', 'scm_name', 'status', 'update', 'url', | 1008 'revert', 'scm_name', 'status', 'update', 'url', |
| 1079 ] | 1009 ] |
| 1080 | 1010 |
| 1081 # If you add a member, be sure to add the relevant test! | 1011 # If you add a member, be sure to add the relevant test! |
| 1082 self.compareMembers(self._scm_wrapper(), members) | 1012 self.compareMembers(self._scm_wrapper(), members) |
| 1083 | 1013 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 'Schedule': 'normal', | 1230 'Schedule': 'normal', |
| 1301 'Copied From URL': None, | 1231 'Copied From URL': None, |
| 1302 'Copied From Rev': None, | 1232 'Copied From Rev': None, |
| 1303 'Path': '.', | 1233 'Path': '.', |
| 1304 'Node Kind': 'dir', | 1234 'Node Kind': 'dir', |
| 1305 } | 1235 } |
| 1306 self.assertEqual(file_info, expected) | 1236 self.assertEqual(file_info, expected) |
| 1307 | 1237 |
| 1308 | 1238 |
| 1309 class RunSVNTestCase(BaseTestCase): | 1239 class RunSVNTestCase(BaseTestCase): |
| 1310 def setUp(self): | |
| 1311 BaseTestCase.setUp(self) | |
| 1312 self._OldSubprocessCall = gclient.SubprocessCall | |
| 1313 gclient.SubprocessCall = self.mox.CreateMockAnything() | |
| 1314 | |
| 1315 def tearDown(self): | |
| 1316 gclient.SubprocessCall = self._OldSubprocessCall | |
| 1317 BaseTestCase.tearDown(self) | |
| 1318 | |
| 1319 def testRunSVN(self): | 1240 def testRunSVN(self): |
| 1320 param2 = 'bleh' | 1241 param2 = 'bleh' |
| 1321 gclient.SubprocessCall(['svn', 'foo', 'bar'], param2).AndReturn(None) | 1242 gclient.SubprocessCall(['svn', 'foo', 'bar'], param2).AndReturn(None) |
| 1322 self.mox.ReplayAll() | 1243 self.mox.ReplayAll() |
| 1323 gclient.RunSVN(['foo', 'bar'], param2) | 1244 gclient.RunSVN(['foo', 'bar'], param2) |
| 1324 | 1245 |
| 1325 | 1246 |
| 1326 class SubprocessCallAndCaptureTestCase(BaseTestCase): | 1247 class SubprocessCallAndCaptureTestCase(BaseTestCase): |
| 1327 def setUp(self): | 1248 def setUp(self): |
| 1328 BaseTestCase.setUp(self) | 1249 BaseTestCase.setUp(self) |
| 1329 self._sys_stdout = gclient.sys.stdout | 1250 self.mox.StubOutWithMock(gclient, 'CaptureSVN') |
| 1330 gclient.sys.stdout = self.mox.CreateMock(self._sys_stdout) | |
| 1331 self._subprocess_Popen = gclient.subprocess.Popen | |
| 1332 gclient.subprocess.Popen = self.mox.CreateMockAnything() | |
| 1333 self._CaptureSVN = gclient.CaptureSVN | |
| 1334 gclient.CaptureSVN = self.mox.CreateMockAnything() | |
| 1335 | |
| 1336 def tearDown(self): | |
| 1337 gclient.sys.stdout = self._sys_stdout | |
| 1338 gclient.subprocess.Popen = self._subprocess_Popen | |
| 1339 gclient.CaptureSVN = self._CaptureSVN | |
| 1340 BaseTestCase.tearDown(self) | |
| 1341 | 1251 |
| 1342 def testSubprocessCallAndCapture(self): | 1252 def testSubprocessCallAndCapture(self): |
| 1343 command = ['boo', 'foo', 'bar'] | 1253 command = ['boo', 'foo', 'bar'] |
| 1344 in_directory = 'bleh' | 1254 in_directory = 'bleh' |
| 1345 fail_status = None | 1255 fail_status = None |
| 1346 pattern = 'a(.*)b' | 1256 pattern = 'a(.*)b' |
| 1347 test_string = 'ahah\naccb\nallo\naddb\n' | 1257 test_string = 'ahah\naccb\nallo\naddb\n' |
| 1348 class Mock(object): | 1258 class Mock(object): |
| 1349 stdout = StringIO.StringIO(test_string) | 1259 stdout = StringIO.StringIO(test_string) |
| 1350 def wait(self): | 1260 def wait(self): |
| 1351 pass | 1261 pass |
| 1352 kid = Mock() | 1262 kid = Mock() |
| 1353 print("\n________ running 'boo foo bar' in 'bleh'") | 1263 print("\n________ running 'boo foo bar' in 'bleh'") |
| 1354 for i in test_string: | 1264 for i in test_string: |
| 1355 gclient.sys.stdout.write(i) | 1265 gclient.sys.stdout.write(i) |
| 1356 gclient.subprocess.Popen(command, bufsize=0, cwd=in_directory, | 1266 gclient.subprocess.Popen(command, bufsize=0, cwd=in_directory, |
| 1357 shell=(sys.platform == 'win32'), | 1267 shell=(gclient.sys.platform == 'win32'), |
| 1358 stdout=gclient.subprocess.PIPE).AndReturn(kid) | 1268 stdout=gclient.subprocess.PIPE).AndReturn(kid) |
| 1359 self.mox.ReplayAll() | 1269 self.mox.ReplayAll() |
| 1360 capture_list = [] | 1270 capture_list = [] |
| 1361 gclient.SubprocessCallAndCapture(command, in_directory, fail_status, | 1271 gclient.SubprocessCallAndCapture(command, in_directory, fail_status, |
| 1362 pattern, capture_list) | 1272 pattern, capture_list) |
| 1363 self.assertEquals(capture_list, ['cc', 'dd']) | 1273 self.assertEquals(capture_list, ['cc', 'dd']) |
| 1364 | 1274 |
| 1365 def testCaptureSVNStatus(self): | 1275 def testCaptureSVNStatus(self): |
| 1366 x = self | 1276 x = self |
| 1367 def CaptureSVNMock(command, in_directory=None, print_error=True): | 1277 def CaptureSVNMock(command, in_directory=None, print_error=True): |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 """ | 1340 """ |
| 1431 gclient.CaptureSVN = CaptureSVNMock | 1341 gclient.CaptureSVN = CaptureSVNMock |
| 1432 info = gclient.CaptureSVNStatus(None) | 1342 info = gclient.CaptureSVNStatus(None) |
| 1433 self.assertEquals(info, []) | 1343 self.assertEquals(info, []) |
| 1434 | 1344 |
| 1435 | 1345 |
| 1436 if __name__ == '__main__': | 1346 if __name__ == '__main__': |
| 1437 unittest.main() | 1347 unittest.main() |
| 1438 | 1348 |
| 1439 # vim: ts=2:sw=2:tw=80:et: | 1349 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |