Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: tests/fake_repos.py

Issue 2446001: Fix smoke tests on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/gclient_smoketest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 """Generate fake repositories for testing.""" 6 """Generate fake repositories for testing."""
7 7
8 import atexit 8 import atexit
9 import errno
9 import logging 10 import logging
10 import os 11 import os
11 import pprint 12 import pprint
12 import re 13 import re
13 import shutil 14 import stat
14 import subprocess 15 import subprocess
15 import sys 16 import sys
17 import time
16 import unittest 18 import unittest
17 19
18 20
19 ## Utility functions 21 ## Utility functions
20 22
21 23
22 def addKill(): 24 def addKill():
23 """Add kill() method to subprocess.Popen for python <2.6""" 25 """Add kill() method to subprocess.Popen for python <2.6"""
24 if getattr(subprocess.Popen, 'kill', None): 26 if getattr(subprocess.Popen, 'kill', None):
25 return 27 return
26 if sys.platform.startswith('win'): 28 if sys.platform.startswith('win'):
27 def kill_win(process): 29 def kill_win(process):
28 import win32process 30 import win32process
29 return win32process.TerminateProcess(process._handle, -1) 31 return win32process.TerminateProcess(process._handle, -1)
30 subprocess.kill = kill_win 32 subprocess.kill = kill_win
31 else: 33 else:
32 def kill_nix(process): 34 def kill_nix(process):
33 import signal 35 import signal
34 return os.kill(process.pid, signal.SIGKILL) 36 return os.kill(process.pid, signal.SIGKILL)
35 subprocess.kill = kill_nix 37 subprocess.kill = kill_nix
36 38
37 39
38 def rmtree(path): 40 def rmtree(*path):
39 """Delete a directory.""" 41 """Recursively removes a directory, even if it's marked read-only.
40 if os.path.exists(path): 42
41 shutil.rmtree(path) 43 Remove the directory located at *path, if it exists.
44
45 shutil.rmtree() doesn't work on Windows if any of the files or directories
46 are read-only, which svn repositories and some .svn files are. We need to
47 be able to force the files to be writable (i.e., deletable) as we traverse
48 the tree.
49
50 Even with all this, Windows still sometimes fails to delete a file, citing
51 a permission error (maybe something to do with antivirus scans or disk
52 indexing). The best suggestion any of the user forums had was to wait a
53 bit and try again, so we do that too. It's hand-waving, but sometimes it
54 works. :/
55 """
56 file_path = os.path.join(*path)
57 if not os.path.exists(file_path):
58 return
59
60 def RemoveWithRetry_win(rmfunc, path):
61 os.chmod(path, stat.S_IWRITE)
62 if win32_api_avail:
63 win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL)
64 try:
65 return rmfunc(path)
66 except EnvironmentError, e:
67 if e.errno != errno.EACCES:
68 raise
69 print 'Failed to delete %s: trying again' % repr(path)
70 time.sleep(0.1)
71 return rmfunc(path)
72
73 def RemoveWithRetry_non_win(rmfunc, path):
74 if os.path.islink(path):
75 return os.remove(path)
76 else:
77 return rmfunc(path)
78
79 win32_api_avail = False
80 remove_with_retry = None
81 if sys.platform.startswith('win'):
bradn 2010/06/01 01:12:04 Pretty sure this is always win32, but anyways. Did
M-A Ruel 2010/06/01 01:26:27 You are right, it's just a copy-paste from scripts
82 # Some people don't have the APIs installed. In that case we'll do without.
83 try:
84 win32api = __import__('win32api')
85 win32con = __import__('win32con')
86 win32_api_avail = True
87 except ImportError:
88 pass
89 remove_with_retry = RemoveWithRetry_win
90 else:
91 remove_with_retry = RemoveWithRetry_non_win
92
93 for root, dirs, files in os.walk(file_path, topdown=False):
94 # For POSIX: making the directory writable guarantees removability.
95 # Windows will ignore the non-read-only bits in the chmod value.
96 os.chmod(root, 0770)
97 for name in files:
98 remove_with_retry(os.remove, os.path.join(root, name))
99 for name in dirs:
100 remove_with_retry(os.rmdir, os.path.join(root, name))
101
102 remove_with_retry(os.rmdir, file_path)
42 103
43 104
44 def write(path, content): 105 def write(path, content):
45 f = open(path, 'wb') 106 f = open(path, 'wb')
46 f.write(content) 107 f.write(content)
47 f.close() 108 f.close()
48 109
49 110
50 join = os.path.join 111 join = os.path.join
51 112
(...skipping 10 matching lines...) Expand all
62 return subprocess.Popen(*args, **kwargs) 123 return subprocess.Popen(*args, **kwargs)
63 124
64 125
65 def read_tree(tree_root): 126 def read_tree(tree_root):
66 """Returns a dict of all the files in a tree. Defaults to self.root_dir.""" 127 """Returns a dict of all the files in a tree. Defaults to self.root_dir."""
67 tree = {} 128 tree = {}
68 for root, dirs, files in os.walk(tree_root): 129 for root, dirs, files in os.walk(tree_root):
69 for d in filter(lambda x: x.startswith('.'), dirs): 130 for d in filter(lambda x: x.startswith('.'), dirs):
70 dirs.remove(d) 131 dirs.remove(d)
71 for f in [join(root, f) for f in files if not f.startswith('.')]: 132 for f in [join(root, f) for f in files if not f.startswith('.')]:
72 tree[f[len(tree_root) + 1:]] = open(join(root, f), 'rb').read() 133 filepath = f[len(tree_root) + 1:].replace(os.sep, '/')
134 assert len(filepath), f
135 tree[filepath] = open(join(root, f), 'rU').read()
73 return tree 136 return tree
74 137
75 138
76 def dict_diff(dict1, dict2): 139 def dict_diff(dict1, dict2):
77 diff = {} 140 diff = {}
78 for k, v in dict1.iteritems(): 141 for k, v in dict1.iteritems():
79 if k not in dict2: 142 if k not in dict2:
80 diff[k] = v 143 diff[k] = v
81 elif v != dict2[k]: 144 elif v != dict2[k]:
82 diff[k] = (v, dict2[k]) 145 diff[k] = (v, dict2[k])
83 for k, v in dict2.iteritems(): 146 for k, v in dict2.iteritems():
84 if k not in dict1: 147 if k not in dict1:
85 diff[k] = v 148 diff[k] = v
86 return diff 149 return diff
87 150
88 151
89 def mangle_svn_tree(*args): 152 def mangle_svn_tree(*args):
90 result = {} 153 result = {}
91 for old_root, new_root, tree in args: 154 for old_root, new_root, tree in args:
92 for k, v in tree.iteritems(): 155 for k, v in tree.iteritems():
93 if not k.startswith(old_root): 156 if not k.startswith(old_root):
94 continue 157 continue
95 result[join(new_root, k[len(old_root) + 1:])] = v 158 result[join(new_root, k[len(old_root) + 1:]).replace(os.sep, '/')] = v
96 return result 159 return result
97 160
98 161
99 def mangle_git_tree(*args): 162 def mangle_git_tree(*args):
100 result = {} 163 result = {}
101 for new_root, tree in args: 164 for new_root, tree in args:
102 for k, v in tree.iteritems(): 165 for k, v in tree.iteritems():
103 result[join(new_root, k)] = v 166 result[join(new_root, k)] = v
104 return result 167 return result
105 168
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 'pattern': 'nonexistent', 386 'pattern': 'nonexistent',
324 'action': ['python', '-c', 387 'action': ['python', '-c',
325 'open(\\'src/svn_hooked2\\', \\'w\\').write(\\'svn_hooked2\\')'], 388 'open(\\'src/svn_hooked2\\', \\'w\\').write(\\'svn_hooked2\\')'],
326 }, 389 },
327 ] 390 ]
328 """ % { 'host': self.HOST })) 391 """ % { 'host': self.HOST }))
329 392
330 def setUpGIT(self): 393 def setUpGIT(self):
331 """Creates git repositories and start the servers.""" 394 """Creates git repositories and start the servers."""
332 if self.gitdaemon: 395 if self.gitdaemon:
333 return 396 return True
334 self.setUp() 397 self.setUp()
398 if sys.platform == 'win32':
399 return False
335 for repo in ['repo_%d' % r for r in range(1, 5)]: 400 for repo in ['repo_%d' % r for r in range(1, 5)]:
336 check_call(['git', 'init', '-q', join(self.git_root, repo)]) 401 check_call(['git', 'init', '-q', join(self.git_root, repo)])
337 self.git_hashes[repo] = [] 402 self.git_hashes[repo] = []
338 403
339 # Testing: 404 # Testing:
340 # - dependency disapear 405 # - dependency disapear
341 # - dependency renamed 406 # - dependency renamed
342 # - versioned and unversioned reference 407 # - versioned and unversioned reference
343 # - relative and full reference 408 # - relative and full reference
344 # - deps_os 409 # - deps_os
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 }, 482 },
418 'origin': "git/repo_1@2\n" 483 'origin': "git/repo_1@2\n"
419 }) 484 })
420 485
421 # Start the daemon. 486 # Start the daemon.
422 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir] 487 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir]
423 if self.HOST == '127.0.0.1': 488 if self.HOST == '127.0.0.1':
424 cmd.append('--listen=127.0.0.1') 489 cmd.append('--listen=127.0.0.1')
425 logging.debug(cmd) 490 logging.debug(cmd)
426 self.gitdaemon = Popen(cmd, cwd=self.repos_dir) 491 self.gitdaemon = Popen(cmd, cwd=self.repos_dir)
492 return True
427 493
428 def _commit_svn(self, tree): 494 def _commit_svn(self, tree):
429 self._genTree(self.svn_root, tree) 495 self._genTree(self.svn_root, tree)
430 commit_svn(self.svn_root) 496 commit_svn(self.svn_root)
431 if self.svn_revs and self.svn_revs[-1]: 497 if self.svn_revs and self.svn_revs[-1]:
432 new_tree = self.svn_revs[-1].copy() 498 new_tree = self.svn_revs[-1].copy()
433 new_tree.update(tree) 499 new_tree.update(tree)
434 else: 500 else:
435 new_tree = tree.copy() 501 new_tree = tree.copy()
436 self.svn_revs.append(new_tree) 502 self.svn_revs.append(new_tree)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 fake.setUp() 577 fake.setUp()
512 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') 578 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.')
513 sys.stdin.readline() 579 sys.stdin.readline()
514 except KeyboardInterrupt: 580 except KeyboardInterrupt:
515 fake.SHOULD_LEAK = True 581 fake.SHOULD_LEAK = True
516 return 0 582 return 0
517 583
518 584
519 if __name__ == '__main__': 585 if __name__ == '__main__':
520 sys.exit(main(sys.argv)) 586 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | tests/gclient_smoketest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698