~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2006-10-16 01:25:46 UTC
  • mfrom: (2071 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2080.
  • Revision ID: john@arbash-meinel.com-20061016012546-d01a0740671b4d73
[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
from bzrlib.transport import get_transport
72
72
import bzrlib.transport
73
73
from bzrlib.transport.local import LocalRelpathServer
 
74
from bzrlib.transport.memory import MemoryServer
74
75
from bzrlib.transport.readonly import ReadonlyServer
75
76
from bzrlib.trace import mutter
76
77
from bzrlib.tests import TestUtil
86
87
 
87
88
MODULES_TO_TEST = []
88
89
MODULES_TO_DOCTEST = [
89
 
                      bzrlib.branch,
90
90
                      bzrlib.bundle.serializer,
91
 
                      bzrlib.commands,
92
91
                      bzrlib.errors,
93
92
                      bzrlib.export,
94
93
                      bzrlib.inventory,
96
95
                      bzrlib.lockdir,
97
96
                      bzrlib.merge3,
98
97
                      bzrlib.option,
99
 
                      bzrlib.osutils,
100
98
                      bzrlib.store,
101
 
                      bzrlib.transport,
102
99
                      ]
103
100
 
104
101
 
394
391
        # This is still a little bogus, 
395
392
        # but only a little. Folk not using our testrunner will
396
393
        # have to delete their temp directories themselves.
397
 
        test_root = TestCaseInTempDir.TEST_ROOT
 
394
        test_root = TestCaseWithMemoryTransport.TEST_ROOT
398
395
        if result.wasSuccessful() or not self.keep_output:
399
396
            if test_root is not None:
400
397
                # If LANG=C we probably have created some bogus paths
418
415
                self.stream.writeln(
419
416
                    "Failed tests working directories are in '%s'\n" %
420
417
                    test_root)
421
 
        TestCaseInTempDir.TEST_ROOT = None
 
418
        TestCaseWithMemoryTransport.TEST_ROOT = None
422
419
        if self.pb is not None:
423
420
            self.pb.clear()
424
421
        return result
703
700
 
704
701
    def _cleanEnvironment(self):
705
702
        new_env = {
 
703
            'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
706
704
            'HOME': os.getcwd(),
707
705
            'APPDATA': os.getcwd(),
708
706
            'BZR_EMAIL': None,
1107
1105
 
1108
1106
BzrTestBase = TestCase
1109
1107
 
 
1108
 
 
1109
class TestCaseWithMemoryTransport(TestCase):
 
1110
    """Common test class for tests that do not need disk resources.
 
1111
 
 
1112
    Tests that need disk resources should derive from TestCaseWithTransport.
 
1113
 
 
1114
    TestCaseWithMemoryTransport sets the TEST_ROOT variable for all bzr tests.
 
1115
 
 
1116
    For TestCaseWithMemoryTransport the test_home_dir is set to the name of
 
1117
    a directory which does not exist. This serves to help ensure test isolation
 
1118
    is preserved. test_dir is set to the TEST_ROOT, as is cwd, because they
 
1119
    must exist. However, TestCaseWithMemoryTransport does not offer local
 
1120
    file defaults for the transport in tests, nor does it obey the command line
 
1121
    override, so tests that accidentally write to the common directory should
 
1122
    be rare.
 
1123
    """
 
1124
 
 
1125
    TEST_ROOT = None
 
1126
    _TEST_NAME = 'test'
 
1127
 
 
1128
 
 
1129
    def __init__(self, methodName='runTest'):
 
1130
        # allow test parameterisation after test construction and before test
 
1131
        # execution. Variables that the parameteriser sets need to be 
 
1132
        # ones that are not set by setUp, or setUp will trash them.
 
1133
        super(TestCaseWithMemoryTransport, self).__init__(methodName)
 
1134
        self.transport_server = default_transport
 
1135
        self.transport_readonly_server = None
 
1136
 
 
1137
    def failUnlessExists(self, path):
 
1138
        """Fail unless path, which may be abs or relative, exists."""
 
1139
        self.failUnless(osutils.lexists(path))
 
1140
 
 
1141
    def failIfExists(self, path):
 
1142
        """Fail if path, which may be abs or relative, exists."""
 
1143
        self.failIf(osutils.lexists(path))
 
1144
        
 
1145
    def get_transport(self):
 
1146
        """Return a writeable transport for the test scratch space"""
 
1147
        t = get_transport(self.get_url())
 
1148
        self.assertFalse(t.is_readonly())
 
1149
        return t
 
1150
 
 
1151
    def get_readonly_transport(self):
 
1152
        """Return a readonly transport for the test scratch space
 
1153
        
 
1154
        This can be used to test that operations which should only need
 
1155
        readonly access in fact do not try to write.
 
1156
        """
 
1157
        t = get_transport(self.get_readonly_url())
 
1158
        self.assertTrue(t.is_readonly())
 
1159
        return t
 
1160
 
 
1161
    def get_readonly_server(self):
 
1162
        """Get the server instance for the readonly transport
 
1163
 
 
1164
        This is useful for some tests with specific servers to do diagnostics.
 
1165
        """
 
1166
        if self.__readonly_server is None:
 
1167
            if self.transport_readonly_server is None:
 
1168
                # readonly decorator requested
 
1169
                # bring up the server
 
1170
                self.get_url()
 
1171
                self.__readonly_server = ReadonlyServer()
 
1172
                self.__readonly_server.setUp(self.__server)
 
1173
            else:
 
1174
                self.__readonly_server = self.transport_readonly_server()
 
1175
                self.__readonly_server.setUp()
 
1176
            self.addCleanup(self.__readonly_server.tearDown)
 
1177
        return self.__readonly_server
 
1178
 
 
1179
    def get_readonly_url(self, relpath=None):
 
1180
        """Get a URL for the readonly transport.
 
1181
 
 
1182
        This will either be backed by '.' or a decorator to the transport 
 
1183
        used by self.get_url()
 
1184
        relpath provides for clients to get a path relative to the base url.
 
1185
        These should only be downwards relative, not upwards.
 
1186
        """
 
1187
        base = self.get_readonly_server().get_url()
 
1188
        if relpath is not None:
 
1189
            if not base.endswith('/'):
 
1190
                base = base + '/'
 
1191
            base = base + relpath
 
1192
        return base
 
1193
 
 
1194
    def get_server(self):
 
1195
        """Get the read/write server instance.
 
1196
 
 
1197
        This is useful for some tests with specific servers that need
 
1198
        diagnostics.
 
1199
 
 
1200
        For TestCaseWithMemoryTransport this is always a MemoryServer, and there
 
1201
        is no means to override it.
 
1202
        """
 
1203
        if self.__server is None:
 
1204
            self.__server = MemoryServer()
 
1205
            self.__server.setUp()
 
1206
            self.addCleanup(self.__server.tearDown)
 
1207
        return self.__server
 
1208
 
 
1209
    def get_url(self, relpath=None):
 
1210
        """Get a URL (or maybe a path) for the readwrite transport.
 
1211
 
 
1212
        This will either be backed by '.' or to an equivalent non-file based
 
1213
        facility.
 
1214
        relpath provides for clients to get a path relative to the base url.
 
1215
        These should only be downwards relative, not upwards.
 
1216
        """
 
1217
        base = self.get_server().get_url()
 
1218
        if relpath is not None and relpath != '.':
 
1219
            if not base.endswith('/'):
 
1220
                base = base + '/'
 
1221
            # XXX: Really base should be a url; we did after all call
 
1222
            # get_url()!  But sometimes it's just a path (from
 
1223
            # LocalAbspathServer), and it'd be wrong to append urlescaped data
 
1224
            # to a non-escaped local path.
 
1225
            if base.startswith('./') or base.startswith('/'):
 
1226
                base += relpath
 
1227
            else:
 
1228
                base += urlutils.escape(relpath)
 
1229
        return base
 
1230
 
 
1231
    def _make_test_root(self):
 
1232
        if TestCaseWithMemoryTransport.TEST_ROOT is not None:
 
1233
            return
 
1234
        i = 0
 
1235
        while True:
 
1236
            root = u'test%04d.tmp' % i
 
1237
            try:
 
1238
                os.mkdir(root)
 
1239
            except OSError, e:
 
1240
                if e.errno == errno.EEXIST:
 
1241
                    i += 1
 
1242
                    continue
 
1243
                else:
 
1244
                    raise
 
1245
            # successfully created
 
1246
            TestCaseWithMemoryTransport.TEST_ROOT = osutils.abspath(root)
 
1247
            break
 
1248
        # make a fake bzr directory there to prevent any tests propagating
 
1249
        # up onto the source directory's real branch
 
1250
        bzrdir.BzrDir.create_standalone_workingtree(
 
1251
            TestCaseWithMemoryTransport.TEST_ROOT)
 
1252
 
 
1253
    def makeAndChdirToTestDir(self):
 
1254
        """Create a temporary directories for this one test.
 
1255
        
 
1256
        This must set self.test_home_dir and self.test_dir and chdir to
 
1257
        self.test_dir.
 
1258
        
 
1259
        For TestCaseWithMemoryTransport we chdir to the TEST_ROOT for this test.
 
1260
        """
 
1261
        os.chdir(TestCaseWithMemoryTransport.TEST_ROOT)
 
1262
        self.test_dir = TestCaseWithMemoryTransport.TEST_ROOT
 
1263
        self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
 
1264
        
 
1265
    def make_branch(self, relpath, format=None):
 
1266
        """Create a branch on the transport at relpath."""
 
1267
        repo = self.make_repository(relpath, format=format)
 
1268
        return repo.bzrdir.create_branch()
 
1269
 
 
1270
    def make_bzrdir(self, relpath, format=None):
 
1271
        try:
 
1272
            # might be a relative or absolute path
 
1273
            maybe_a_url = self.get_url(relpath)
 
1274
            segments = maybe_a_url.rsplit('/', 1)
 
1275
            t = get_transport(maybe_a_url)
 
1276
            if len(segments) > 1 and segments[-1] not in ('', '.'):
 
1277
                try:
 
1278
                    t.mkdir('.')
 
1279
                except errors.FileExists:
 
1280
                    pass
 
1281
            if format is None:
 
1282
                format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
1283
            return format.initialize_on_transport(t)
 
1284
        except errors.UninitializableFormat:
 
1285
            raise TestSkipped("Format %s is not initializable." % format)
 
1286
 
 
1287
    def make_repository(self, relpath, shared=False, format=None):
 
1288
        """Create a repository on our default transport at relpath."""
 
1289
        made_control = self.make_bzrdir(relpath, format=format)
 
1290
        return made_control.create_repository(shared=shared)
 
1291
 
 
1292
    def make_branch_and_memory_tree(self, relpath):
 
1293
        """Create a branch on the default transport and a MemoryTree for it."""
 
1294
        b = self.make_branch(relpath)
 
1295
        return memorytree.MemoryTree.create_on_branch(b)
 
1296
 
 
1297
    def overrideEnvironmentForTesting(self):
 
1298
        os.environ['HOME'] = self.test_home_dir
 
1299
        os.environ['APPDATA'] = self.test_home_dir
 
1300
        
 
1301
    def setUp(self):
 
1302
        super(TestCaseWithMemoryTransport, self).setUp()
 
1303
        self._make_test_root()
 
1304
        _currentdir = os.getcwdu()
 
1305
        def _leaveDirectory():
 
1306
            os.chdir(_currentdir)
 
1307
        self.addCleanup(_leaveDirectory)
 
1308
        self.makeAndChdirToTestDir()
 
1309
        self.overrideEnvironmentForTesting()
 
1310
        self.__readonly_server = None
 
1311
        self.__server = None
 
1312
 
1110
1313
     
1111
 
class TestCaseInTempDir(TestCase):
 
1314
class TestCaseInTempDir(TestCaseWithMemoryTransport):
1112
1315
    """Derived class that runs a test within a temporary directory.
1113
1316
 
1114
1317
    This is useful for tests that need to create a branch, etc.
1121
1324
    InTempDir is an old alias for FunctionalTestCase.
1122
1325
    """
1123
1326
 
1124
 
    TEST_ROOT = None
1125
 
    _TEST_NAME = 'test'
1126
1327
    OVERRIDE_PYTHON = 'python'
1127
1328
 
1128
1329
    def check_file_contents(self, filename, expect):
1133
1334
            self.log("actually: %r" % contents)
1134
1335
            self.fail("contents of %s not as expected" % filename)
1135
1336
 
1136
 
    def _make_test_root(self):
1137
 
        if TestCaseInTempDir.TEST_ROOT is not None:
1138
 
            return
1139
 
        i = 0
1140
 
        while True:
1141
 
            root = u'test%04d.tmp' % i
1142
 
            try:
1143
 
                os.mkdir(root)
1144
 
            except OSError, e:
1145
 
                if e.errno == errno.EEXIST:
1146
 
                    i += 1
1147
 
                    continue
1148
 
                else:
1149
 
                    raise
1150
 
            # successfully created
1151
 
            TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
1152
 
            break
1153
 
        # make a fake bzr directory there to prevent any tests propagating
1154
 
        # up onto the source directory's real branch
1155
 
        bzrdir.BzrDir.create_standalone_workingtree(TestCaseInTempDir.TEST_ROOT)
1156
 
 
1157
 
    def setUp(self):
1158
 
        super(TestCaseInTempDir, self).setUp()
1159
 
        self._make_test_root()
1160
 
        _currentdir = os.getcwdu()
 
1337
    def makeAndChdirToTestDir(self):
 
1338
        """See TestCaseWithMemoryTransport.makeAndChdirToTestDir().
 
1339
        
 
1340
        For TestCaseInTempDir we create a temporary directory based on the test
 
1341
        name and then create two subdirs - test and home under it.
 
1342
        """
1161
1343
        # shorten the name, to avoid test failures due to path length
1162
1344
        short_id = self.id().replace('bzrlib.tests.', '') \
1163
1345
                   .replace('__main__.', '')[-100:]
1180
1362
                os.mkdir(self.test_dir)
1181
1363
                os.chdir(self.test_dir)
1182
1364
                break
1183
 
        os.environ['HOME'] = self.test_home_dir
1184
 
        os.environ['APPDATA'] = self.test_home_dir
1185
 
        def _leaveDirectory():
1186
 
            os.chdir(_currentdir)
1187
 
        self.addCleanup(_leaveDirectory)
1188
 
        
 
1365
 
1189
1366
    def build_tree(self, shape, line_endings='native', transport=None):
1190
1367
        """Build a test tree according to a pattern.
1191
1368
 
1232
1409
    def build_tree_contents(self, shape):
1233
1410
        build_tree_contents(shape)
1234
1411
 
1235
 
    def failUnlessExists(self, path):
1236
 
        """Fail unless path, which may be abs or relative, exists."""
1237
 
        self.failUnless(osutils.lexists(path))
1238
 
 
1239
 
    def failIfExists(self, path):
1240
 
        """Fail if path, which may be abs or relative, exists."""
1241
 
        self.failIf(osutils.lexists(path))
1242
 
        
1243
1412
    def assertFileEqual(self, content, path):
1244
1413
        """Fail if path does not contain 'content'."""
1245
1414
        self.failUnless(osutils.lexists(path))
1261
1430
    readwrite one must both define get_url() as resolving to os.getcwd().
1262
1431
    """
1263
1432
 
1264
 
    def __init__(self, methodName='testMethod'):
1265
 
        super(TestCaseWithTransport, self).__init__(methodName)
1266
 
        self.__readonly_server = None
1267
 
        self.__server = None
1268
 
        self.transport_server = default_transport
1269
 
        self.transport_readonly_server = None
1270
 
 
1271
 
    def get_readonly_url(self, relpath=None):
1272
 
        """Get a URL for the readonly transport.
1273
 
 
1274
 
        This will either be backed by '.' or a decorator to the transport 
1275
 
        used by self.get_url()
1276
 
        relpath provides for clients to get a path relative to the base url.
1277
 
        These should only be downwards relative, not upwards.
1278
 
        """
1279
 
        base = self.get_readonly_server().get_url()
1280
 
        if relpath is not None:
1281
 
            if not base.endswith('/'):
1282
 
                base = base + '/'
1283
 
            base = base + relpath
1284
 
        return base
1285
 
 
1286
 
    def get_readonly_server(self):
1287
 
        """Get the server instance for the readonly transport
1288
 
 
1289
 
        This is useful for some tests with specific servers to do diagnostics.
1290
 
        """
1291
 
        if self.__readonly_server is None:
1292
 
            if self.transport_readonly_server is None:
1293
 
                # readonly decorator requested
1294
 
                # bring up the server
1295
 
                self.get_url()
1296
 
                self.__readonly_server = ReadonlyServer()
1297
 
                self.__readonly_server.setUp(self.__server)
1298
 
            else:
1299
 
                self.__readonly_server = self.transport_readonly_server()
1300
 
                self.__readonly_server.setUp()
1301
 
            self.addCleanup(self.__readonly_server.tearDown)
1302
 
        return self.__readonly_server
1303
 
 
1304
1433
    def get_server(self):
1305
 
        """Get the read/write server instance.
 
1434
        """See TestCaseWithMemoryTransport.
1306
1435
 
1307
1436
        This is useful for some tests with specific servers that need
1308
1437
        diagnostics.
1313
1442
            self.addCleanup(self.__server.tearDown)
1314
1443
        return self.__server
1315
1444
 
1316
 
    def get_url(self, relpath=None):
1317
 
        """Get a URL (or maybe a path) for the readwrite transport.
1318
 
 
1319
 
        This will either be backed by '.' or to an equivalent non-file based
1320
 
        facility.
1321
 
        relpath provides for clients to get a path relative to the base url.
1322
 
        These should only be downwards relative, not upwards.
1323
 
        """
1324
 
        base = self.get_server().get_url()
1325
 
        if relpath is not None and relpath != '.':
1326
 
            if not base.endswith('/'):
1327
 
                base = base + '/'
1328
 
            # XXX: Really base should be a url; we did after all call
1329
 
            # get_url()!  But sometimes it's just a path (from
1330
 
            # LocalAbspathServer), and it'd be wrong to append urlescaped data
1331
 
            # to a non-escaped local path.
1332
 
            if base.startswith('./') or base.startswith('/'):
1333
 
                base += relpath
1334
 
            else:
1335
 
                base += urlutils.escape(relpath)
1336
 
        return base
1337
 
 
1338
 
    def get_transport(self):
1339
 
        """Return a writeable transport for the test scratch space"""
1340
 
        t = get_transport(self.get_url())
1341
 
        self.assertFalse(t.is_readonly())
1342
 
        return t
1343
 
 
1344
 
    def get_readonly_transport(self):
1345
 
        """Return a readonly transport for the test scratch space
1346
 
        
1347
 
        This can be used to test that operations which should only need
1348
 
        readonly access in fact do not try to write.
1349
 
        """
1350
 
        t = get_transport(self.get_readonly_url())
1351
 
        self.assertTrue(t.is_readonly())
1352
 
        return t
1353
 
 
1354
 
    def make_branch(self, relpath, format=None):
1355
 
        """Create a branch on the transport at relpath."""
1356
 
        repo = self.make_repository(relpath, format=format)
1357
 
        return repo.bzrdir.create_branch()
1358
 
 
1359
 
    def make_bzrdir(self, relpath, format=None):
1360
 
        try:
1361
 
            # might be a relative or absolute path
1362
 
            maybe_a_url = self.get_url(relpath)
1363
 
            segments = maybe_a_url.rsplit('/', 1)
1364
 
            t = get_transport(maybe_a_url)
1365
 
            if len(segments) > 1 and segments[-1] not in ('', '.'):
1366
 
                try:
1367
 
                    t.mkdir('.')
1368
 
                except errors.FileExists:
1369
 
                    pass
1370
 
            if format is None:
1371
 
                format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
1372
 
            return format.initialize_on_transport(t)
1373
 
        except errors.UninitializableFormat:
1374
 
            raise TestSkipped("Format %s is not initializable." % format)
1375
 
 
1376
 
    def make_repository(self, relpath, shared=False, format=None):
1377
 
        """Create a repository on our default transport at relpath."""
1378
 
        made_control = self.make_bzrdir(relpath, format=format)
1379
 
        return made_control.create_repository(shared=shared)
1380
 
 
1381
 
    def make_branch_and_memory_tree(self, relpath):
1382
 
        """Create a branch on the default transport and a MemoryTree for it."""
1383
 
        b = self.make_branch(relpath)
1384
 
        return memorytree.MemoryTree.create_on_branch(b)
1385
 
 
1386
1445
    def make_branch_and_tree(self, relpath, format=None):
1387
1446
        """Create a branch on the transport and a tree locally.
1388
1447
 
1430
1489
            self.fail("path %s is not a directory; has mode %#o"
1431
1490
                      % (relpath, mode))
1432
1491
 
 
1492
    def setUp(self):
 
1493
        super(TestCaseWithTransport, self).setUp()
 
1494
        self.__server = None
 
1495
        self.transport_server = default_transport
 
1496
 
1433
1497
 
1434
1498
class ChrootedTestCase(TestCaseWithTransport):
1435
1499
    """A support class that provides readonly urls outside the local namespace.
1461
1525
def run_suite(suite, name='test', verbose=False, pattern=".*",
1462
1526
              stop_on_failure=False, keep_output=False,
1463
1527
              transport=None, lsprof_timed=None, bench_history=None):
1464
 
    TestCaseInTempDir._TEST_NAME = name
1465
1528
    TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1466
1529
    if verbose:
1467
1530
        verbosity = 2
1551
1614
                   'bzrlib.tests.test_inv',
1552
1615
                   'bzrlib.tests.test_knit',
1553
1616
                   'bzrlib.tests.test_lazy_import',
 
1617
                   'bzrlib.tests.test_lazy_regex',
1554
1618
                   'bzrlib.tests.test_lockdir',
1555
1619
                   'bzrlib.tests.test_lockable_files',
1556
1620
                   'bzrlib.tests.test_log',
1622
1686
    for m in MODULES_TO_TEST:
1623
1687
        suite.addTest(loader.loadTestsFromModule(m))
1624
1688
    for m in MODULES_TO_DOCTEST:
1625
 
        suite.addTest(doctest.DocTestSuite(m))
 
1689
        try:
 
1690
            suite.addTest(doctest.DocTestSuite(m))
 
1691
        except ValueError, e:
 
1692
            print '**failed to get doctest for: %s\n%s' %(m,e)
 
1693
            raise
1626
1694
    for name, plugin in bzrlib.plugin.all_plugins().items():
1627
1695
        if getattr(plugin, 'test_suite', None) is not None:
1628
1696
            suite.addTest(plugin.test_suite())