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 """Unit tests for gclient_scm.py.""" | 6 """Unit tests for gclient_scm.py.""" |
7 | 7 |
8 # pylint: disable=E1103 | 8 # pylint: disable=E1103 |
9 | 9 |
10 # Import before super_mox to keep valid references. | 10 # Import before super_mox to keep valid references. |
11 from shutil import rmtree | 11 from shutil import rmtree |
12 from subprocess import Popen, PIPE, STDOUT | 12 from subprocess import Popen, PIPE, STDOUT |
13 | 13 |
14 import logging | 14 import logging |
15 import os | 15 import os |
16 import re | 16 import re |
17 import sys | 17 import sys |
18 import tempfile | 18 import tempfile |
| 19 import threading |
19 import unittest | 20 import unittest |
20 | 21 |
21 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | 22 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
22 | 23 |
23 from testing_support.super_mox import mox, StdoutCheck, SuperMoxTestBase | 24 from testing_support.super_mox import mox, StdoutCheck, SuperMoxTestBase |
24 from testing_support.super_mox import TestCaseUtils | 25 from testing_support.super_mox import TestCaseUtils |
25 | 26 |
26 import gclient_scm | 27 import gclient_scm |
27 import git_cache | 28 import git_cache |
28 import subprocess2 | 29 import subprocess2 |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 relpath=self.relpath) | 963 relpath=self.relpath) |
963 file_list = [] | 964 file_list = [] |
964 options.revision = 'unmanaged' | 965 options.revision = 'unmanaged' |
965 scm.update(options, (), file_list) | 966 scm.update(options, (), file_list) |
966 self.assertEquals(file_list, expected_file_list) | 967 self.assertEquals(file_list, expected_file_list) |
967 self.assertEquals(scm.revinfo(options, (), None), | 968 self.assertEquals(scm.revinfo(options, (), None), |
968 '069c602044c5388d2d15c3f875b057c852003458') | 969 '069c602044c5388d2d15c3f875b057c852003458') |
969 self.checkstdout('________ unmanaged solution; skipping .\n') | 970 self.checkstdout('________ unmanaged solution; skipping .\n') |
970 | 971 |
971 | 972 |
| 973 class GitHungTest(BaseGitWrapperTestCase): |
| 974 def setUp(self): |
| 975 super(GitHungTest, self).setUp() |
| 976 self.old = gclient_scm.gclient_utils.CheckCallAndFilter |
| 977 self.old2 = gclient_scm.gclient_utils.subprocess2.Popen |
| 978 self.options = self.Options() |
| 979 self.options.verbose = False |
| 980 self.scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, |
| 981 relpath=self.relpath) |
| 982 os.environ['GCLIENT_KILL_GIT_FETCH_AFTER'] = '1.0' |
| 983 |
| 984 def tearDown(self): |
| 985 os.environ.pop('GCLIENT_KILL_GIT_FETCH_AFTER') |
| 986 gclient_scm.gclient_utils.CheckCallAndFilter = self.old |
| 987 gclient_scm.gclient_utils.subprocess2.Popen = self.old2 |
| 988 super(GitHungTest, self).tearDown() |
| 989 |
| 990 def testGitFetchOk(self): |
| 991 def subprocess_git_fetch_run(_, filter_fn, kill_timeout, **__): |
| 992 self.assertEqual(kill_timeout, 1.0) |
| 993 filter_fn('remote: something') |
| 994 gclient_scm.gclient_utils.CheckCallAndFilter = subprocess_git_fetch_run |
| 995 self.scm._Fetch(self.options) |
| 996 self.checkstdout('remote: something\n') |
| 997 |
| 998 def testGitFetchHungAndRetry(self): |
| 999 class Process(object): |
| 1000 # First process will hang, second process will exit with 0 quickly. |
| 1001 cv = threading.Condition() |
| 1002 count = -1 |
| 1003 killed = [] |
| 1004 def __init__(self): |
| 1005 self.count += 1 |
| 1006 self.stdout = self |
| 1007 self.data = list('retry' if self.count > 0 else 'hung') |
| 1008 self.data.reverse() |
| 1009 self.this_killed = False |
| 1010 def read(self, _): |
| 1011 if self.data: |
| 1012 return self.data.pop() |
| 1013 if self.count == 0: |
| 1014 # Simulate hung process. |
| 1015 with self.cv: |
| 1016 self.cv.wait(timeout=0) |
| 1017 return '' |
| 1018 def kill(self): |
| 1019 self.this_killed = True |
| 1020 self.killed.append(self.count) |
| 1021 with self.cv: |
| 1022 self.cv.notify() |
| 1023 def wait(self): |
| 1024 if self.this_killed: |
| 1025 return 1 |
| 1026 return 0 |
| 1027 |
| 1028 gclient_scm.gclient_utils.subprocess2.Popen = lambda *_, **__: Process() |
| 1029 self.scm._Capture = lambda *_, **__: None |
| 1030 self.scm._Fetch(self.options) |
| 1031 self.checkstdout('hung\n') |
| 1032 |
| 1033 |
972 if __name__ == '__main__': | 1034 if __name__ == '__main__': |
973 level = logging.DEBUG if '-v' in sys.argv else logging.FATAL | 1035 level = logging.DEBUG if '-v' in sys.argv else logging.FATAL |
974 logging.basicConfig( | 1036 logging.basicConfig( |
975 level=level, | 1037 level=level, |
976 format='%(asctime).19s %(levelname)s %(filename)s:' | 1038 format='%(asctime).19s %(levelname)s %(filename)s:' |
977 '%(lineno)s %(message)s') | 1039 '%(lineno)s %(message)s') |
978 unittest.main() | 1040 unittest.main() |
979 | 1041 |
980 # vim: ts=2:sw=2:tw=80:et: | 1042 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |