Rev 4800: (jam) Lots of win32 test-suite fixes. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Nov 16 22:42:56 GMT 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 4800 [merge]
revision-id: pqm at pqm.ubuntu.com-20091116224254-fgspnq9xz29z662j
parent: pqm at pqm.ubuntu.com-20091116215927-rula71sotgtosnc4
parent: john at arbash-meinel.com-20091116213652-74njzf1y3hvp9ojb
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2009-11-16 22:42:54 +0000
message:
(jam) Lots of win32 test-suite fixes.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_add.py test_add.py-20060518072250-857e4f86f54a30b2
bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
bzrlib/tests/blackbox/test_init.py test_init.py-20060309032856-a292116204d86eb7
bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
bzrlib/tests/http_server.py httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
bzrlib/tests/per_branch/test_parent.py test_parent.py-20050830052751-5e62766623c32222
bzrlib/tests/per_bzrdir/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
bzrlib/tests/per_tree/test_path_content_summary.py test_path_content_su-20070904100855-3vrwedz6akn34kl5-1
bzrlib/tests/per_workingtree/test_smart_add.py test_smart_add.py-20070215175752-9s5mxoz8aqpd80fm-1
bzrlib/tests/per_workingtree/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
bzrlib/tests/script.py script.py-20090901081155-yk3tiy1nunxg16ne-1
bzrlib/tests/test_directory_service.py test_directory_servi-20080305221044-vr2mkvlsk8jypa2y-2
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
bzrlib/tests/test_script.py test_script.py-20090901081156-y90z4w2t62fv7e7b-1
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/tests/test_win32utils.py test_win32utils.py-20070713181630-8xsrjymd3e8mgw23-108
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
=== modified file 'NEWS'
--- a/NEWS 2009-11-16 19:45:47 +0000
+++ b/NEWS 2009-11-16 20:50:41 +0000
@@ -8,7 +8,7 @@
bzr 2.1.0b4 (not released yet)
##############################
-:Codename: san franscisco airport
+:Codename: san francisco airport
:2.1.0b4: ???
Compatibility Breaks
@@ -19,6 +19,13 @@
Bug Fixes
*********
+* After renaming a file, the dirstate could accidentally reference
+ ``source\\path`` rather than ``source/path`` on Windows. This might be a
+ source of some dirstate-related failures. (John Arbash Meinel)
+
+* Lots of bugfixes for the test suite on Windows. We should once again
+ have a test suite with no failures on Windows. (Once all the patches
+ have landed, remove this line.) (John Arbash Meinel)
Improvements
************
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2009-10-02 05:43:41 +0000
+++ b/bzrlib/dirstate.py 2009-11-08 19:29:02 +0000
@@ -1339,14 +1339,14 @@
minikind = child[1][0][0]
fingerprint = child[1][0][4]
executable = child[1][0][3]
- old_child_path = osutils.pathjoin(child[0][0],
- child[0][1])
+ old_child_path = osutils.pathjoin(child_dirname,
+ child_basename)
removals[child[0][2]] = old_child_path
child_suffix = child_dirname[len(old_path):]
new_child_dirname = (new_path + child_suffix)
key = (new_child_dirname, child_basename, child[0][2])
- new_child_path = os.path.join(new_child_dirname,
- child_basename)
+ new_child_path = osutils.pathjoin(new_child_dirname,
+ child_basename)
insertions[child[0][2]] = (key, minikind, executable,
fingerprint, new_child_path)
self._check_delta_ids_absent(new_ids, delta, 0)
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2009-10-23 16:31:03 +0000
+++ b/bzrlib/osutils.py 2009-11-10 07:01:56 +0000
@@ -224,6 +224,7 @@
else:
file_existed = True
+ failure_exc = None
success = False
try:
try:
@@ -235,8 +236,12 @@
# source and target may be aliases of each other (e.g. on a
# case-insensitive filesystem), so we may have accidentally renamed
# source by when we tried to rename target
- if not (file_existed and e.errno in (None, errno.ENOENT)):
- raise
+ failure_exc = sys.exc_info()
+ if (file_existed and e.errno in (None, errno.ENOENT)
+ and old.lower() == new.lower()):
+ # source and target are the same file on a case-insensitive
+ # filesystem, so we don't generate an exception
+ failure_exc = None
finally:
if file_existed:
# If the file used to exist, rename it back into place
@@ -245,6 +250,8 @@
unlink_func(tmp_name)
else:
rename_func(tmp_name, new)
+ if failure_exc is not None:
+ raise failure_exc[0], failure_exc[1], failure_exc[2]
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2009-11-04 11:59:35 +0000
+++ b/bzrlib/tests/__init__.py 2009-11-16 19:56:24 +0000
@@ -4321,7 +4321,9 @@
# Windows doesn't have os.kill, and we catch the SIGBREAK signal.
# We trigger SIGBREAK via a Console api so we need ctypes to
# access the function
- if not have_ctypes:
+ try:
+ import ctypes
+ except OSError:
return False
return True
=== modified file 'bzrlib/tests/blackbox/test_add.py'
--- a/bzrlib/tests/blackbox/test_add.py 2009-08-10 08:25:05 +0000
+++ b/bzrlib/tests/blackbox/test_add.py 2009-11-08 00:05:26 +0000
@@ -27,7 +27,6 @@
SymlinkFeature
)
from bzrlib.tests.blackbox import ExternalBase
-from bzrlib.tests.test_win32utils import NeedsGlobExpansionFeature
def load_tests(standard_tests, module, loader):
@@ -211,20 +210,6 @@
err = self.run_bzr('add .bzr/crescent', retcode=3)[1]
self.assertContainsRe(err, r'ERROR:.*\.bzr.*control file')
- def test_add_with_wildcards(self):
- self.requireFeature(NeedsGlobExpansionFeature)
- self.make_branch_and_tree('.')
- self.build_tree(['a1', 'a2', 'b', 'c33'])
- self.run_bzr(['add', 'a?', 'c*'])
- self.assertEquals(self.run_bzr('unknowns')[0], 'b\n')
-
- def test_add_with_wildcards_unicode(self):
- self.requireFeature(NeedsGlobExpansionFeature)
- self.make_branch_and_tree('.')
- self.build_tree([u'\u1234A', u'\u1235A', u'\u1235AA', 'cc'])
- self.run_bzr(['add', u'\u1234?', u'\u1235*'])
- self.assertEquals(self.run_bzr('unknowns')[0], 'cc\n')
-
def test_add_via_symlink(self):
self.requireFeature(SymlinkFeature)
self.make_branch_and_tree('source')
=== modified file 'bzrlib/tests/blackbox/test_commit.py'
--- a/bzrlib/tests/blackbox/test_commit.py 2009-11-03 20:24:25 +0000
+++ b/bzrlib/tests/blackbox/test_commit.py 2009-11-08 01:09:14 +0000
@@ -25,6 +25,7 @@
ignores,
msgeditor,
osutils,
+ tests,
)
from bzrlib.bzrdir import BzrDir
from bzrlib.tests import (
@@ -263,6 +264,9 @@
self.run_bzr('commit -m ""', retcode=3)
def test_unsupported_encoding_commit_message(self):
+ if sys.platform == 'win32':
+ raise tests.TestNotApplicable('Win32 parses arguments directly'
+ ' as Unicode, so we can\'t pass invalid non-ascii')
tree = self.make_branch_and_tree('.')
self.build_tree_contents([('foo.c', 'int main() {}')])
tree.add('foo.c')
@@ -273,10 +277,6 @@
if char is None:
raise TestSkipped('Cannot find suitable non-ascii character'
'for user_encoding (%s)' % osutils.get_user_encoding())
- # TODO: jam 2009-07-23 This test seems to fail on Windows now. My best
- # guess is that the change to use Unicode command lines means
- # that we no longer pay any attention to LANG=C when decoding the
- # commandline arguments.
out,err = self.run_bzr_subprocess('commit -m "%s"' % char,
retcode=1,
env_changes={'LANG': 'C'})
=== modified file 'bzrlib/tests/blackbox/test_init.py'
--- a/bzrlib/tests/blackbox/test_init.py 2009-08-12 22:16:29 +0000
+++ b/bzrlib/tests/blackbox/test_init.py 2009-11-08 02:23:13 +0000
@@ -22,6 +22,7 @@
from bzrlib import (
branch as _mod_branch,
+ osutils,
urlutils,
)
from bzrlib.bzrdir import BzrDirMetaFormat1
@@ -74,8 +75,8 @@
Using shared repository: %s
""" % (self._default_label, urlutils.local_path_from_url(
repo.bzrdir.root_transport.external_url())), out)
- self.assertEndsWith(out, "bzrlib.tests.blackbox.test_init.TestInit."
- "test_init_at_repository_root/work/repo/\n")
+ cwd = osutils.getcwd()
+ self.assertEndsWith(out, cwd + '/repo/\n')
self.assertEqual('', err)
newdir.open_branch()
newdir.open_workingtree()
=== modified file 'bzrlib/tests/blackbox/test_serve.py'
--- a/bzrlib/tests/blackbox/test_serve.py 2009-09-22 04:25:05 +0000
+++ b/bzrlib/tests/blackbox/test_serve.py 2009-11-16 21:36:52 +0000
@@ -30,6 +30,7 @@
errors,
osutils,
revision as _mod_revision,
+ urlutils,
)
from bzrlib.branch import Branch
from bzrlib.bzrdir import BzrDir
@@ -278,23 +279,26 @@
(optionally decorated with 'readonly+'). BzrServerFactory can
determine the original --directory from that transport.
"""
+ # URLs always include the trailing slash, and get_base_path returns it
+ base_dir = osutils.abspath('/a/b/c') + '/'
+ base_url = urlutils.local_path_to_url(base_dir) + '/'
# Define a fake 'protocol' to capture the transport that cmd_serve
# passes to serve_bzr.
def capture_transport(transport, host, port, inet):
self.bzr_serve_transport = transport
cmd = builtins.cmd_serve()
# Read-only
- cmd.run(directory='/a/b/c', protocol=capture_transport)
+ cmd.run(directory=base_dir, protocol=capture_transport)
server_maker = BzrServerFactory()
self.assertEqual(
- 'readonly+file:///a/b/c/', self.bzr_serve_transport.base)
+ 'readonly+%s' % base_url, self.bzr_serve_transport.base)
self.assertEqual(
- u'/a/b/c/', server_maker.get_base_path(self.bzr_serve_transport))
+ base_dir, server_maker.get_base_path(self.bzr_serve_transport))
# Read-write
- cmd.run(directory='/a/b/c', protocol=capture_transport,
+ cmd.run(directory=base_dir, protocol=capture_transport,
allow_writes=True)
server_maker = BzrServerFactory()
- self.assertEqual('file:///a/b/c/', self.bzr_serve_transport.base)
- self.assertEqual(
- u'/a/b/c/', server_maker.get_base_path(self.bzr_serve_transport))
+ self.assertEqual(base_url, self.bzr_serve_transport.base)
+ self.assertEqual(base_dir,
+ server_maker.get_base_path(self.bzr_serve_transport))
=== modified file 'bzrlib/tests/http_server.py'
--- a/bzrlib/tests/http_server.py 2009-07-08 15:24:31 +0000
+++ b/bzrlib/tests/http_server.py 2009-11-11 07:23:59 +0000
@@ -462,7 +462,7 @@
raise httplib.UnknownProtocol(proto_vers)
else:
self._httpd = self.create_httpd(serv_cls, rhandler)
- host, self.port = self._httpd.socket.getsockname()
+ self.host, self.port = self._httpd.socket.getsockname()
return self._httpd
def _http_start(self):
=== modified file 'bzrlib/tests/per_branch/test_parent.py'
--- a/bzrlib/tests/per_branch/test_parent.py 2009-04-15 03:45:24 +0000
+++ b/bzrlib/tests/per_branch/test_parent.py 2009-11-08 03:00:33 +0000
@@ -96,11 +96,11 @@
if sys.platform != 'win32':
raise TestSkipped('windows-specific test')
b = self.make_branch('.')
- base_url = b.abspath('.')
+ base_url = b.bzrdir.transport.abspath('.')
if not base_url.startswith('file:///'):
raise TestNotApplicable('this test should be run with local base')
base = urlutils.local_path_from_url(base_url)
- other = 'file:///B:/path'
+ other = 'file:///D:/path'
if base[0] != 'C':
other = 'file:///C:/path'
b.set_parent(other)
=== modified file 'bzrlib/tests/per_bzrdir/test_bzrdir.py'
--- a/bzrlib/tests/per_bzrdir/test_bzrdir.py 2009-09-18 17:19:15 +0000
+++ b/bzrlib/tests/per_bzrdir/test_bzrdir.py 2009-11-16 20:05:44 +0000
@@ -778,13 +778,16 @@
'./.bzr/repository/inventory.knit',
])
try:
+ local_inventory = dir.transport.local_abspath('inventory')
+ except errors.NotLocalUrl:
+ return
+ try:
# If we happen to have a tree, we'll guarantee everything
# except for the tree root is the same.
- inventory_f = file(dir.transport.base+'inventory', 'rb')
+ inventory_f = file(local_inventory, 'rb')
+ self.addCleanup(inventory_f.close)
self.assertContainsRe(inventory_f.read(),
- '<inventory file_id="TREE_ROOT[^"]*"'
- ' format="5">\n</inventory>\n')
- inventory_f.close()
+ '<inventory format="5">\n</inventory>\n')
except IOError, e:
if e.errno != errno.ENOENT:
raise
=== modified file 'bzrlib/tests/per_tree/test_path_content_summary.py'
--- a/bzrlib/tests/per_tree/test_path_content_summary.py 2009-08-26 05:34:10 +0000
+++ b/bzrlib/tests/per_tree/test_path_content_summary.py 2009-11-10 19:38:37 +0000
@@ -21,6 +21,7 @@
from bzrlib import (
osutils,
tests,
+ transform,
)
from bzrlib.tests import per_tree
@@ -78,13 +79,13 @@
self.assertEqual(('missing', None, None, None), summary)
def test_file_content_summary_executable(self):
- if not osutils.supports_executable():
- raise tests.TestNotApplicable()
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/path'])
tree.add(['path'])
- current_mode = os.stat('tree/path').st_mode
- os.chmod('tree/path', current_mode | 0100)
+ tt = transform.TreeTransform(tree)
+ self.addCleanup(tt.finalize)
+ tt.set_executability(True, tt.trans_id_tree_path('path'))
+ tt.apply()
summary = self._convert_tree(tree).path_content_summary('path')
self.assertEqual(4, len(summary))
self.assertEqual('file', summary[0])
@@ -95,6 +96,28 @@
self.assertSubset((summary[3],),
(None, '0c352290ae1c26ca7f97d5b2906c4624784abd60'))
+ def test_file_content_summary_not_versioned(self):
+ tree = self.make_branch_and_tree('tree')
+ self.build_tree(['tree/path'])
+ tree = self._convert_tree(tree)
+ summary = tree.path_content_summary('path')
+ self.assertEqual(4, len(summary))
+ if isinstance(tree, (per_tree.DirStateRevisionTree,
+ per_tree.RevisionTree)):
+ self.assertEqual('missing', summary[0])
+ self.assertIs(None, summary[2])
+ self.assertIs(None, summary[3])
+ elif isinstance(tree, transform._PreviewTree):
+ self.expectFailure('PreviewTree returns "missing" for unversioned'
+ 'files', self.assertEqual, 'file', summary[0])
+ self.assertEqual('file', summary[0])
+ else:
+ self.assertEqual('file', summary[0])
+ self.check_content_summary_size(tree, summary, 22)
+ self.assertEqual(False, summary[2])
+ self.assertSubset((summary[3],),
+ (None, '0c352290ae1c26ca7f97d5b2906c4624784abd60'))
+
def test_file_content_summary_non_exec(self):
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/path'])
=== modified file 'bzrlib/tests/per_workingtree/test_smart_add.py'
--- a/bzrlib/tests/per_workingtree/test_smart_add.py 2009-09-28 02:02:30 +0000
+++ b/bzrlib/tests/per_workingtree/test_smart_add.py 2009-11-08 04:49:06 +0000
@@ -17,6 +17,7 @@
"""Test that we can use smart_add on all Tree implementations."""
from cStringIO import StringIO
+import sys
from bzrlib import (
add,
@@ -53,7 +54,12 @@
def assertFilenameSkipped(self, filename):
tree = self.make_branch_and_tree('tree')
- self.build_tree(['tree/'+filename])
+ try:
+ self.build_tree(['tree/'+filename])
+ except errors.NoSuchFile:
+ if sys.platform == 'win32':
+ raise tests.TestNotApplicable('Cannot create files named %r on'
+ ' win32' % (filename,))
tree.smart_add(['tree'])
self.assertEqual(None, tree.path2id(filename))
=== modified file 'bzrlib/tests/per_workingtree/test_workingtree.py'
--- a/bzrlib/tests/per_workingtree/test_workingtree.py 2009-08-20 04:09:58 +0000
+++ b/bzrlib/tests/per_workingtree/test_workingtree.py 2009-11-08 05:28:57 +0000
@@ -513,30 +513,37 @@
def test_merge_revert(self):
from bzrlib.merge import merge_inner
- self.thisFailsStrictLockCheck()
this = self.make_branch_and_tree('b1')
- open('b1/a', 'wb').write('a test\n')
- this.add('a')
- open('b1/b', 'wb').write('b test\n')
- this.add('b')
+ self.build_tree_contents([('b1/a', 'a test\n'), ('b1/b', 'b test\n')])
+ this.add(['a', 'b'])
this.commit(message='')
base = this.bzrdir.clone('b2').open_workingtree()
- open('b2/a', 'wb').write('b test\n')
+ self.build_tree_contents([('b2/a', 'b test\n')])
other = this.bzrdir.clone('b3').open_workingtree()
- open('b3/a', 'wb').write('c test\n')
- open('b3/c', 'wb').write('c test\n')
+ self.build_tree_contents([('b3/a', 'c test\n'), ('b3/c', 'c test\n')])
other.add('c')
- open('b1/b', 'wb').write('q test\n')
- open('b1/d', 'wb').write('d test\n')
+ self.build_tree_contents([('b1/b', 'q test\n'), ('b1/d', 'd test\n')])
+ # Note: If we don't lock this before calling merge_inner, then we get a
+ # lock-contention failure. This probably indicates something
+ # weird going on inside merge_inner. Probably something about
+ # calling bt = this_tree.basis_tree() in one lock, and then
+ # locking both this_tree and bt separately, causing a dirstate
+ # locking race.
+ this.lock_write()
+ self.addCleanup(this.unlock)
merge_inner(this.branch, other, base, this_tree=this)
- self.assertNotEqual(open('b1/a', 'rb').read(), 'a test\n')
+ a = open('b1/a', 'rb')
+ try:
+ self.assertNotEqual(a.read(), 'a test\n')
+ finally:
+ a.close()
this.revert()
- self.assertEqual(open('b1/a', 'rb').read(), 'a test\n')
- self.assertIs(os.path.exists('b1/b.~1~'), True)
- self.assertIs(os.path.exists('b1/c'), False)
- self.assertIs(os.path.exists('b1/a.~1~'), False)
- self.assertIs(os.path.exists('b1/d'), True)
+ self.assertFileEqual('a test\n', 'b1/a')
+ self.failUnlessExists('b1/b.~1~')
+ self.failIfExists('b1/c')
+ self.failIfExists('b1/a.~1~')
+ self.failUnlessExists('b1/d')
def test_update_updates_bound_branch_no_local_commits(self):
# doing an update in a tree updates the branch its bound to too.
=== modified file 'bzrlib/tests/script.py'
--- a/bzrlib/tests/script.py 2009-09-24 06:53:43 +0000
+++ b/bzrlib/tests/script.py 2009-11-08 20:28:36 +0000
@@ -217,7 +217,8 @@
# Specifying None means: any output is accepted
return
if actual is None:
- test_case.fail('Unexpected: %s' % actual)
+ test_case.fail('We expected output: %r, but found None'
+ % (expected,))
matching = self.output_checker.check_output(
expected, actual, self.check_options)
if not matching:
@@ -289,30 +290,31 @@
try:
inputs.append(self._read_input(None, in_name))
except IOError, e:
- if e.errno == errno.ENOENT:
+ # Some filenames are illegal on Windows and generate EINVAL
+ # rather than just saying the filename doesn't exist
+ if e.errno in (errno.ENOENT, errno.EINVAL):
return (1, None,
'%s: No such file or directory\n' % (in_name,))
+ raise
# Basically cat copy input to output
output = ''.join(inputs)
# Handle output redirections
try:
output = self._write_output(output, out_name, out_mode)
except IOError, e:
- if e.errno == errno.ENOENT:
+ # If out_name cannot be created, we may get 'ENOENT', however if
+ # out_name is something like '', we can get EINVAL
+ if e.errno in (errno.ENOENT, errno.EINVAL):
return 1, None, '%s: No such file or directory\n' % (out_name,)
+ raise
return 0, output, None
def do_echo(self, test_case, input, args):
(in_name, out_name, out_mode, args) = _scan_redirection_options(args)
- if input and args:
- raise SyntaxError('Specify parameters OR use redirection')
+ if input or in_name:
+ raise SyntaxError('echo doesn\'t read from stdin')
if args:
input = ' '.join(args)
- try:
- input = self._read_input(input, in_name)
- except IOError, e:
- if e.errno == errno.ENOENT:
- return 1, None, '%s: No such file or directory\n' % (in_name,)
# Always append a \n'
input += '\n'
# Process output
@@ -321,8 +323,9 @@
try:
output = self._write_output(output, out_name, out_mode)
except IOError, e:
- if e.errno == errno.ENOENT:
+ if e.errno in (errno.ENOENT, errno.EINVAL):
return 1, None, '%s: No such file or directory\n' % (out_name,)
+ raise
return 0, output, None
def _get_jail_root(self, test_case):
=== modified file 'bzrlib/tests/test_directory_service.py'
--- a/bzrlib/tests/test_directory_service.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/test_directory_service.py 2009-11-10 04:58:31 +0000
@@ -16,18 +16,23 @@
"""Test directory service implementation"""
-from bzrlib import errors
+from bzrlib import (
+ errors,
+ urlutils,
+ )
from bzrlib.directory_service import DirectoryServiceRegistry, directories
from bzrlib.tests import TestCase, TestCaseWithTransport
from bzrlib.transport import get_transport
-from bzrlib import urlutils
class FooService(object):
"""A directory service that maps the name to a FILE url"""
+ # eg 'file:///foo' on Linux, or 'file:///C:/foo' on Windows
+ base = urlutils.local_path_to_url('/foo')
+
def look_up(self, name, url):
- return 'file:///foo' + name
+ return self.base + name
class TestDirectoryLookup(TestCase):
@@ -43,14 +48,15 @@
self.assertEqual('bar', suffix)
def test_dereference(self):
- self.assertEqual('file:///foobar',
+ self.assertEqual(FooService.base + 'bar',
self.registry.dereference('foo:bar'))
self.assertEqual('baz:qux', self.registry.dereference('baz:qux'))
def test_get_transport(self):
directories.register('foo:', FooService, 'Map foo URLs to http urls')
self.addCleanup(lambda: directories.remove('foo:'))
- self.assertEqual('file:///foobar/', get_transport('foo:bar').base)
+ self.assertEqual(FooService.base + 'bar/',
+ get_transport('foo:bar').base)
class TestAliasDirectory(TestCaseWithTransport):
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2009-10-15 04:01:26 +0000
+++ b/bzrlib/tests/test_osutils.py 2009-11-10 07:01:56 +0000
@@ -126,33 +126,51 @@
class TestRename(tests.TestCaseInTempDir):
+ def create_file(self, filename, content):
+ f = open(filename, 'wb')
+ try:
+ f.write(content)
+ finally:
+ f.close()
+
+ def _fancy_rename(self, a, b):
+ osutils.fancy_rename(a, b, rename_func=os.rename,
+ unlink_func=os.unlink)
+
def test_fancy_rename(self):
# This should work everywhere
- def rename(a, b):
- osutils.fancy_rename(a, b,
- rename_func=os.rename,
- unlink_func=os.unlink)
-
- open('a', 'wb').write('something in a\n')
- rename('a', 'b')
+ self.create_file('a', 'something in a\n')
+ self._fancy_rename('a', 'b')
self.failIfExists('a')
self.failUnlessExists('b')
self.check_file_contents('b', 'something in a\n')
- open('a', 'wb').write('new something in a\n')
- rename('b', 'a')
+ self.create_file('a', 'new something in a\n')
+ self._fancy_rename('b', 'a')
self.check_file_contents('a', 'something in a\n')
+ def test_fancy_rename_fails_source_missing(self):
+ # An exception should be raised, and the target should be left in place
+ self.create_file('target', 'data in target\n')
+ self.assertRaises((IOError, OSError), self._fancy_rename,
+ 'missingsource', 'target')
+ self.failUnlessExists('target')
+ self.check_file_contents('target', 'data in target\n')
+
+ def test_fancy_rename_fails_if_source_and_target_missing(self):
+ self.assertRaises((IOError, OSError), self._fancy_rename,
+ 'missingsource', 'missingtarget')
+
def test_rename(self):
# Rename should be semi-atomic on all platforms
- open('a', 'wb').write('something in a\n')
+ self.create_file('a', 'something in a\n')
osutils.rename('a', 'b')
self.failIfExists('a')
self.failUnlessExists('b')
self.check_file_contents('b', 'something in a\n')
- open('a', 'wb').write('new something in a\n')
+ self.create_file('a', 'new something in a\n')
osutils.rename('b', 'a')
self.check_file_contents('a', 'something in a\n')
=== modified file 'bzrlib/tests/test_script.py'
--- a/bzrlib/tests/test_script.py 2009-09-17 14:15:15 +0000
+++ b/bzrlib/tests/test_script.py 2009-11-08 20:28:36 +0000
@@ -262,14 +262,6 @@
2>: No such file or directory
""")
- def test_echo_bogus_input_file(self):
- # We need a backing file sysytem for that test so it can't be in
- # TestEcho
- self.run_script("""
-$ echo <file
-2>file: No such file or directory
-""")
-
def test_echo_bogus_output_file(self):
# We need a backing file sysytem for that test so it can't be in
# TestEcho
@@ -338,6 +330,11 @@
"""
self.assertRaises(SyntaxError, self.run_script, story)
+ def test_echo_input(self):
+ self.assertRaises(SyntaxError, self.run_script, """
+ $ echo <foo
+ """)
+
def test_echo_to_output(self):
retcode, out, err = self.run_command(['echo'], None, '\n', None)
self.assertEquals('\n', out)
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2009-10-26 06:44:40 +0000
+++ b/bzrlib/tests/test_transform.py 2009-11-10 19:40:13 +0000
@@ -2470,8 +2470,6 @@
self.assertIs(None, summary[3])
def test_change_executability(self):
- if not osutils.supports_executable():
- raise TestNotApplicable()
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/path'])
tree.add('path')
@@ -2491,10 +2489,7 @@
# size must be known
self.assertEqual(len('contents'), summary[1])
# not executable
- if osutils.supports_executable():
- self.assertEqual(False, summary[2])
- else:
- self.assertEqual(None, summary[2])
+ self.assertEqual(False, summary[2])
# will not have hash (not cheap to determine)
self.assertIs(None, summary[3])
=== modified file 'bzrlib/tests/test_win32utils.py'
--- a/bzrlib/tests/test_win32utils.py 2009-11-11 04:03:33 +0000
+++ b/bzrlib/tests/test_win32utils.py 2009-11-16 20:52:38 +0000
@@ -32,18 +32,20 @@
from bzrlib.win32utils import glob_expand, get_app_path
-# Features
-# --------
-
-class _NeedsGlobExpansionFeature(Feature):
+class _BackslashDirSeparatorFeature(tests.Feature):
def _probe(self):
- return sys.platform == 'win32'
+ try:
+ os.lstat(os.getcwd() + '\\')
+ except OSError:
+ return False
+ else:
+ return True
def feature_name(self):
- return 'Internally performed glob expansion'
+ return "Filesystem treats '\\' as a directory separator."
-NeedsGlobExpansionFeature = _NeedsGlobExpansionFeature()
+BackslashDirSeparatorFeature = _BackslashDirSeparatorFeature()
class _RequiredModuleFeature(Feature):
@@ -70,19 +72,9 @@
# Tests
# -----
-class TestNeedsGlobExpansionFeature(TestCase):
-
- def test_available(self):
- self.assertEqual(sys.platform == 'win32',
- NeedsGlobExpansionFeature.available())
-
- def test_str(self):
- self.assertTrue("performed" in str(NeedsGlobExpansionFeature))
-
-
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
- _test_needs_features = [NeedsGlobExpansionFeature]
+ _test_needs_features = []
def test_empty_tree(self):
self.build_tree([])
@@ -92,22 +84,28 @@
[['*'], ['*']],
[['a', 'a'], ['a', 'a']]])
- def test_tree_ascii(self):
- """Checks the glob expansion and path separation char
- normalization"""
+ def build_ascii_tree(self):
self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
'b', 'b1', 'b2', 'b3',
'c/', 'c/c1', 'c/c2',
'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
+
+ def build_unicode_tree(self):
+ self.requireFeature(UnicodeFilenameFeature)
+ self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/',
+ u'\u1235/\u1235'])
+
+ def test_tree_ascii(self):
+ """Checks the glob expansion and path separation char
+ normalization"""
+ self.build_ascii_tree()
self._run_testset([
# no wildcards
[[u'a'], [u'a']],
[[u'a', u'a' ], [u'a', u'a']],
- [[u'A'], [u'A']],
[[u'd'], [u'd']],
[[u'd/'], [u'd/']],
- [[u'd\\'], [u'd/']],
# wildcards
[[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
@@ -115,18 +113,35 @@
[[u'a?'], [u'a1', u'a2']],
[[u'a??'], [u'a11', u'a.1']],
[[u'b[1-2]'], [u'b1', u'b2']],
- [[u'A?'], [u'a1', u'a2']],
[[u'd/*'], [u'd/d1', u'd/d2', u'd/e']],
+ [[u'?/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
+ [[u'*/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
+ [[u'*/'], [u'c/', u'd/']],
+ ])
+
+ def test_backslash_globbing(self):
+ self.requireFeature(BackslashDirSeparatorFeature)
+ self.build_ascii_tree()
+ self._run_testset([
+ [[u'd\\'], [u'd/']],
[[u'd\\*'], [u'd/d1', u'd/d2', u'd/e']],
[[u'?\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
[[u'*\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
- [[u'*/'], [u'c/', u'd/']],
- [[u'*\\'], [u'c/', u'd/']]])
+ [[u'*\\'], [u'c/', u'd/']],
+ ])
+
+ def test_case_insensitive_globbing(self):
+ self.requireFeature(tests.CaseInsCasePresFilenameFeature)
+ self.build_ascii_tree()
+ self._run_testset([
+ [[u'A'], [u'A']],
+ [[u'A?'], [u'a1', u'a2']],
+ ])
def test_tree_unicode(self):
"""Checks behaviour with non-ascii filenames"""
- self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/', u'\u1235/\u1235'])
+ self.build_unicode_tree()
self._run_testset([
# no wildcards
[[u'\u1234'], [u'\u1234']],
@@ -142,16 +157,26 @@
[[u'\u1235/?'], [u'\u1235/\u1235']],
[[u'\u1235/*'], [u'\u1235/\u1235']],
+ [[u'?/'], [u'\u1235/']],
+ [[u'*/'], [u'\u1235/']],
+ [[u'?/?'], [u'\u1235/\u1235']],
+ [[u'*/*'], [u'\u1235/\u1235']],
+ ])
+
+ def test_unicode_backslashes(self):
+ self.requireFeature(BackslashDirSeparatorFeature)
+ self.build_unicode_tree()
+ self._run_testset([
+ # no wildcards
+ [[u'\u1235\\'], [u'\u1235/']],
+ [[u'\u1235\\\u1235'], [u'\u1235/\u1235']],
[[u'\u1235\\?'], [u'\u1235/\u1235']],
[[u'\u1235\\*'], [u'\u1235/\u1235']],
- [[u'?/'], [u'\u1235/']],
- [[u'*/'], [u'\u1235/']],
[[u'?\\'], [u'\u1235/']],
[[u'*\\'], [u'\u1235/']],
- [[u'?/?'], [u'\u1235/\u1235']],
- [[u'*/*'], [u'\u1235/\u1235']],
[[u'?\\?'], [u'\u1235/\u1235']],
- [[u'*\\*'], [u'\u1235/\u1235']]])
+ [[u'*\\*'], [u'\u1235/\u1235']],
+ ])
def _run_testset(self, testset):
for pattern, expected in testset:
@@ -356,3 +381,13 @@
def test_no_single_quote_supported(self):
self.assertCommandLine(["add", "let's-do-it.txt"],
"add let's-do-it.txt")
+
+ def test_case_insensitive_globs(self):
+ self.requireFeature(tests.CaseInsCasePresFilenameFeature)
+ self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
+ self.assertCommandLine([u'A/b.c'], 'A/B*')
+
+ def test_backslashes(self):
+ self.requireFeature(BackslashDirSeparatorFeature)
+ self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
+ self.assertCommandLine([u'a/b.c'], 'a\\b*')
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2009-10-29 21:13:16 +0000
+++ b/bzrlib/transform.py 2009-11-10 05:26:00 +0000
@@ -1973,7 +1973,7 @@
statval = os.lstat(limbo_name)
size = statval.st_size
if not supports_executable():
- executable = None
+ executable = False
else:
executable = statval.st_mode & S_IEXEC
else:
@@ -1981,8 +1981,7 @@
executable = None
if kind == 'symlink':
link_or_sha1 = os.readlink(limbo_name).decode(osutils._fs_enc)
- if supports_executable():
- executable = tt._new_executability.get(trans_id, executable)
+ executable = tt._new_executability.get(trans_id, executable)
return kind, size, executable, link_or_sha1
def iter_changes(self, from_tree, include_unchanged=False,
=== modified file 'bzrlib/transport/sftp.py'
--- a/bzrlib/transport/sftp.py 2009-06-10 03:56:49 +0000
+++ b/bzrlib/transport/sftp.py 2009-11-11 07:35:08 +0000
@@ -917,7 +917,7 @@
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self._socket.bind(('localhost', 0))
self._socket.listen(1)
- self.port = self._socket.getsockname()[1]
+ self.host, self.port = self._socket.getsockname()[:2]
self._stop_event = threading.Event()
def stop(self):
@@ -1045,7 +1045,8 @@
def _get_sftp_url(self, path):
"""Calculate an sftp url to this server for path."""
- return 'sftp://foo:bar@localhost:%d/%s' % (self._listener.port, path)
+ return 'sftp://foo:bar@%s:%d/%s' % (self._listener.host,
+ self._listener.port, path)
def log(self, message):
"""StubServer uses this to log when a new server is created."""
=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py 2009-10-06 14:40:37 +0000
+++ b/bzrlib/workingtree.py 2009-11-10 09:14:34 +0000
@@ -636,6 +636,10 @@
def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
file_id = self.path2id(path)
+ if file_id is None:
+ # For unversioned files on win32, we just assume they are not
+ # executable
+ return False
return self._inventory[file_id].executable
def _is_executable_from_path_and_stat_from_stat(self, path, stat_result):
More information about the bazaar-commits
mailing list