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

Unified 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, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/gclient_smoketest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/fake_repos.py
===================================================================
--- tests/fake_repos.py (revision 48611)
+++ tests/fake_repos.py (working copy)
@@ -6,13 +6,15 @@
"""Generate fake repositories for testing."""
import atexit
+import errno
import logging
import os
import pprint
import re
-import shutil
+import stat
import subprocess
import sys
+import time
import unittest
@@ -35,12 +37,71 @@
subprocess.kill = kill_nix
-def rmtree(path):
- """Delete a directory."""
- if os.path.exists(path):
- shutil.rmtree(path)
+def rmtree(*path):
+ """Recursively removes a directory, even if it's marked read-only.
+ Remove the directory located at *path, if it exists.
+ shutil.rmtree() doesn't work on Windows if any of the files or directories
+ are read-only, which svn repositories and some .svn files are. We need to
+ be able to force the files to be writable (i.e., deletable) as we traverse
+ the tree.
+
+ Even with all this, Windows still sometimes fails to delete a file, citing
+ a permission error (maybe something to do with antivirus scans or disk
+ indexing). The best suggestion any of the user forums had was to wait a
+ bit and try again, so we do that too. It's hand-waving, but sometimes it
+ works. :/
+ """
+ file_path = os.path.join(*path)
+ if not os.path.exists(file_path):
+ return
+
+ def RemoveWithRetry_win(rmfunc, path):
+ os.chmod(path, stat.S_IWRITE)
+ if win32_api_avail:
+ win32api.SetFileAttributes(path, win32con.FILE_ATTRIBUTE_NORMAL)
+ try:
+ return rmfunc(path)
+ except EnvironmentError, e:
+ if e.errno != errno.EACCES:
+ raise
+ print 'Failed to delete %s: trying again' % repr(path)
+ time.sleep(0.1)
+ return rmfunc(path)
+
+ def RemoveWithRetry_non_win(rmfunc, path):
+ if os.path.islink(path):
+ return os.remove(path)
+ else:
+ return rmfunc(path)
+
+ win32_api_avail = False
+ remove_with_retry = None
+ 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
+ # Some people don't have the APIs installed. In that case we'll do without.
+ try:
+ win32api = __import__('win32api')
+ win32con = __import__('win32con')
+ win32_api_avail = True
+ except ImportError:
+ pass
+ remove_with_retry = RemoveWithRetry_win
+ else:
+ remove_with_retry = RemoveWithRetry_non_win
+
+ for root, dirs, files in os.walk(file_path, topdown=False):
+ # For POSIX: making the directory writable guarantees removability.
+ # Windows will ignore the non-read-only bits in the chmod value.
+ os.chmod(root, 0770)
+ for name in files:
+ remove_with_retry(os.remove, os.path.join(root, name))
+ for name in dirs:
+ remove_with_retry(os.rmdir, os.path.join(root, name))
+
+ remove_with_retry(os.rmdir, file_path)
+
+
def write(path, content):
f = open(path, 'wb')
f.write(content)
@@ -69,7 +130,9 @@
for d in filter(lambda x: x.startswith('.'), dirs):
dirs.remove(d)
for f in [join(root, f) for f in files if not f.startswith('.')]:
- tree[f[len(tree_root) + 1:]] = open(join(root, f), 'rb').read()
+ filepath = f[len(tree_root) + 1:].replace(os.sep, '/')
+ assert len(filepath), f
+ tree[filepath] = open(join(root, f), 'rU').read()
return tree
@@ -92,7 +155,7 @@
for k, v in tree.iteritems():
if not k.startswith(old_root):
continue
- result[join(new_root, k[len(old_root) + 1:])] = v
+ result[join(new_root, k[len(old_root) + 1:]).replace(os.sep, '/')] = v
return result
@@ -330,8 +393,10 @@
def setUpGIT(self):
"""Creates git repositories and start the servers."""
if self.gitdaemon:
- return
+ return True
self.setUp()
+ if sys.platform == 'win32':
+ return False
for repo in ['repo_%d' % r for r in range(1, 5)]:
check_call(['git', 'init', '-q', join(self.git_root, repo)])
self.git_hashes[repo] = []
@@ -424,6 +489,7 @@
cmd.append('--listen=127.0.0.1')
logging.debug(cmd)
self.gitdaemon = Popen(cmd, cwd=self.repos_dir)
+ return True
def _commit_svn(self, tree):
self._genTree(self.svn_root, tree)
« 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