def test_01_block_unrelated_component_interaction(self):
        """
        If foo/trunk or foo/branches/* is being copied, make sure the dest is
        also rooted in either foo/branches or foo/tags.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = 'component root path copied to unrelated component'
        paths = [ p.replace('/', '') for p in conf.standard_layout ]
        with chdir(repo.wc):
            for component in ('foo', 'bar'):
                svn.mkdir(component)
                for path in paths:
                    dot()
                    target = '/'.join((component, path))
                    svn.mkdir(target)
                svn.ci(component)

            dot()
            svn.cp('foo/trunk', 'foo/branches/1.x')
            svn.ci()

            dot()
            svn.cp('foo/branches/1.x', 'foo/tags/1.0')
            svn.ci()

            dot()
            svn.up()

            dot()
            svn.cp('foo/trunk', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/branches/1.x', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/tags/1.0', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/tags/1.0', 'bar/tags/1.0')
            with ensure_blocked(self, error):
                svn.ci('bar')
예제 #2
0
    def test_01_block_unrelated_component_interaction(self):
        """
        If foo/trunk or foo/branches/* is being copied, make sure the dest is
        also rooted in either foo/branches or foo/tags.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = 'component root path copied to unrelated component'
        paths = [p.replace('/', '') for p in conf.standard_layout]
        with chdir(repo.wc):
            for component in ('foo', 'bar'):
                svn.mkdir(component)
                for path in paths:
                    dot()
                    target = '/'.join((component, path))
                    svn.mkdir(target)
                svn.ci(component)

            dot()
            svn.cp('foo/trunk', 'foo/branches/1.x')
            svn.ci()

            dot()
            svn.cp('foo/branches/1.x', 'foo/tags/1.0')
            svn.ci()

            dot()
            svn.up()

            dot()
            svn.cp('foo/trunk', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/branches/1.x', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/tags/1.0', 'bar/branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('bar')

            dot()
            svn.cp('foo/tags/1.0', 'bar/tags/1.0')
            with ensure_blocked(self, error):
                svn.ci('bar')
    def test_03_rename(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        tree = {
            'test.txt': bulk_chargen(100),
        }
        repo.build(tree, prefix='trunk')

        with chdir(repo.wc):
            dot()
            svn.add('trunk/test.txt')
            dot()
            svn.ci('trunk/test.txt', m='Adding test.txt...')

        dot()
        error = e.BlockedFileExtension
        with chdir(repo.wc):
            svn.mv('trunk/test.txt', 'trunk/test.dll')
            dot()
            with ensure_blocked(self, error):
                svn.ci('trunk', m='Renaming test.txt to test.dll...')
                dot()
예제 #4
0
    def test_01_under_then_over(self):
        repo = self.create_repo()
        conf = repo.conf

        dot()
        conf.set_max_file_size_in_bytes(1024)

        svn = repo.svn
        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = { '512-then-1025-bytes.txt': bulk_chargen(512) }
        repo.build(tree, prefix='trunk')

        with chdir(repo.wc):
            dot()
            svn.add('trunk/512-then-1025-bytes.txt')
            svn.ci('trunk', m='Permitted...')

        dot()
        tree = { '512-then-1025-bytes.txt': bulk_chargen(1025) }
        repo.build(tree, prefix='trunk')

        error = format_file_exceeds_max_size_error(1025, 1024)
        with chdir(repo.wc):
            dot()
            with ensure_blocked(self, error):
                svn.ci('trunk', m='At limit')
예제 #5
0
    def test_01_under_then_over(self):
        repo = self.create_repo()
        conf = repo.conf

        dot()
        conf.set_max_file_size_in_bytes(1024)

        svn = repo.svn
        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = {'512-then-1025-bytes.txt': bulk_chargen(512)}
        repo.build(tree, prefix='trunk')

        with chdir(repo.wc):
            dot()
            svn.add('trunk/512-then-1025-bytes.txt')
            svn.ci('trunk', m='Permitted...')

        dot()
        tree = {'512-then-1025-bytes.txt': bulk_chargen(1025)}
        repo.build(tree, prefix='trunk')

        error = format_file_exceeds_max_size_error(1025, 1024)
        with chdir(repo.wc):
            dot()
            with ensure_blocked(self, error):
                svn.ci('trunk', m='At limit')
예제 #6
0
    def test_04_rm_standard_layout(self):
        """
        Given:
            /trunk/
            /tags/
            /branches/
        Make sure we can't rmdir any of the paths.
        """
        repo = self.create_repo()
        svn = repo.svn

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)
        dot()

        error = e.TopLevelRepoDirectoryRemoved
        paths = [p.replace('/', '') for p in conf.standard_layout]
        with chdir(repo.wc):
            for path in paths:
                dot()
                svn.rm(path)
                with ensure_blocked(self, error):
                    svn.ci(path)
예제 #7
0
    def test_03_rename(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        tree = {
            'test.txt': bulk_chargen(100),
        }
        repo.build(tree, prefix='trunk')

        with chdir(repo.wc):
            dot()
            svn.add('trunk/test.txt')
            dot()
            svn.ci('trunk/test.txt', m='Adding test.txt...')

        dot()
        error = e.BlockedFileExtension
        with chdir(repo.wc):
            svn.mv('trunk/test.txt', 'trunk/test.dll')
            dot()
            with ensure_blocked(self, error):
                svn.ci('trunk', m='Renaming test.txt to test.dll...')
                dot()
    def test_04_rm_standard_layout(self):
        """
        Given:
            /trunk/
            /tags/
            /branches/
        Make sure we can't rmdir any of the paths.
        """
        repo = self.create_repo()
        svn = repo.svn

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)
        dot()

        error = e.TopLevelRepoDirectoryRemoved
        paths = [ p.replace('/', '') for p in conf.standard_layout ]
        with chdir(repo.wc):
            for path in paths:
                dot()
                svn.rm(path)
                with ensure_blocked(self, error):
                    svn.ci(path)
예제 #9
0
    def test_02_set_repo_readonly(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        is_repo_readonly = evnadmin.is_repo_readonly
        set_repo_readonly = evnadmin.set_repo_readonly
        unset_repo_readonly = evnadmin.unset_repo_readonly

        dot()
        expected = 'no'
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        tree = {'test1.txt': bulk_chargen(100)}
        repo.build(tree, prefix='trunk')

        dot()
        with chdir(repo.wc):
            dot()
            svn.add('trunk/test1.txt')
            dot()
            svn.ci('trunk', m='Adding test1.txt')

        dot()
        set_repo_readonly(repo.path)

        dot()
        expected = 'yes'
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        dot()
        tree = {
            'test2.txt': bulk_chargen(200),
        }
        repo.build(tree, prefix='trunk')

        error = 'This repository cannot be committed to at the present time'
        with ensure_blocked(self, error):
            with chdir(repo.wc):
                dot()
                svn.add('trunk/test2.txt')
                dot()
                svn.ci('trunk', m='Adding test2.txt')

        dot()
        unset_repo_readonly(repo.path)

        dot()
        expected = 'no'
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        dot()
        with chdir(repo.wc):
            dot()
            dot()
            svn.ci('trunk', m='Adding test2.txt')
예제 #10
0
    def test_02_set_repo_readonly(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        is_repo_readonly = evnadmin.is_repo_readonly
        set_repo_readonly = evnadmin.set_repo_readonly
        unset_repo_readonly = evnadmin.unset_repo_readonly

        dot()
        expected = "no"
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        tree = {"test1.txt": bulk_chargen(100)}
        repo.build(tree, prefix="trunk")

        dot()
        with chdir(repo.wc):
            dot()
            svn.add("trunk/test1.txt")
            dot()
            svn.ci("trunk", m="Adding test1.txt")

        dot()
        set_repo_readonly(repo.path)

        dot()
        expected = "yes"
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        dot()
        tree = {"test2.txt": bulk_chargen(200)}
        repo.build(tree, prefix="trunk")

        error = "This repository cannot be committed to at the present time"
        with ensure_blocked(self, error):
            with chdir(repo.wc):
                dot()
                svn.add("trunk/test2.txt")
                dot()
                svn.ci("trunk", m="Adding test2.txt")

        dot()
        unset_repo_readonly(repo.path)

        dot()
        expected = "no"
        actual = is_repo_readonly(repo.path)
        self.assertEqual(expected, actual)

        dot()
        with chdir(repo.wc):
            dot()
            dot()
            svn.ci("trunk", m="Adding test2.txt")
    def test_02_ra_when_enabled(self):
        repo = self.create_repo(checkout=False)
        conf = repo.conf
        svn = repo.svn

        dot()
        error = KnownRootPathCopiedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('trunk/foo'), m='Copy')
예제 #12
0
    def test_02_ra_when_enabled(self):
        repo = self.create_repo(checkout=False)
        conf = repo.conf
        svn = repo.svn

        dot()
        error = KnownRootPathCopiedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('trunk/foo'), m='Copy')
예제 #13
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        error = e.BranchDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/branches/1.x/'), m='Create branch manually')

        dot()
        evnadmin.disable(repo.name)
        svn.mkdir(repo.ra('/branches/1.x/'), m='Create branch manually2')

        dot()
        evn_props_r2_expected = {
            'errors': {
                '/branches/1.x/': [e.BranchDirectoryCreatedManually],
            },
            'roots': {
                '/trunk/': {
                    'created': 1
                },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)
        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/branches/1.x/',
            revision='2',
            root_type='branch',
        )
        dot()
        evnadmin.unset_repo_readonly(repo.name)
        evnadmin.analyze(repo.name)

        dot()
        evn_props_r2_expected = {
            'roots': {
                '/trunk/': {
                    'created': 1
                },
                '/branches/1.x/': {
                    'created': 2,
                    'copies': {},
                    'creation_method': 'created',
                },
            },
        }
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)
    def test_02_ra(self):
        repo = self.create_repo(checkout=False)
        svn = repo.svn

        dot()
        svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Tagging 1.0')

        error = KnownRootPathCopiedToKnownRootSubtreePath
        dot()
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Tagging 1.0')
예제 #15
0
    def test_02_evn_enabled(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        # Make sure the roots on r1 are as we expect.
        dot()
        roots_r1_expected = {
            '/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots, roots_r1_expected)

        # Copy the path.
        dot()
        svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Copy')

        # Try copy it again; ensure it's blocked.
        dot()
        error = KnownRootPathCopiedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Copy again')

        # Check roots.
        dot()
        roots_r1_expected = {
            '/trunk/': {
                'copies': {
                    1: [('/tags/1.0/', 2)]
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r2_expected = {
            '/tags/1.0/': {
                'copied_from': ('/trunk/', 1),
                'copies': {},
                'created': 2,
                'creation_method': 'copied',
                'errors': [],
            },
            '/trunk/': {
                'created': 1
            },
        }
        roots_r2 = repo.roots_at(2)
        self.assertEqual(roots_r2, roots_r2_expected)
예제 #16
0
    def test_02_ra(self):
        repo = self.create_repo(checkout=False)
        svn = repo.svn

        dot()
        svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Tagging 1.0')

        error = KnownRootPathCopiedToKnownRootSubtreePath
        dot()
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Tagging 1.0')
예제 #17
0
    def test_01_tag_and_branch_creation_detection(self):
        repo = self.create_repo()
        conf = repo.conf
        conf.set_custom_hook_classname(self.classname)
        svn = repo.svn

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        error = 'is_branch_create: /branches/1.x/'
        with chdir(repo.wc):
            svn.cp('trunk', 'branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('branches/1.x', m='Branching...')

        dot()
        error = 'is_tag_create: /tags/1.1/'
        with chdir(repo.wc):
            svn.cp('trunk', 'tags/1.1')
            with ensure_blocked(self, error):
                svn.ci('tags/1.1', m='Tagging...')
    def test_02_evn_enabled(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        # Make sure the roots on r1 are as we expect.
        dot()
        roots_r1_expected = {
            '/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots, roots_r1_expected)

        # Copy the path.
        dot()
        svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Copy')

        # Try copy it again; ensure it's blocked.
        dot()
        error = KnownRootPathCopiedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.copy(repo.ra('trunk'), repo.ra('tags/1.0'), m='Copy again')

        # Check roots.
        dot()
        roots_r1_expected = {
            '/trunk/': {
                'copies': {
                    1: [('/tags/1.0/', 2)]
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r2_expected = {
            '/tags/1.0/': {
                'copied_from': ('/trunk/', 1),
                'copies': {},
                'created': 2,
                'creation_method': 'copied',
                'errors': [],
            },
            '/trunk/': { 'created': 1 },
        }
        roots_r2 = repo.roots_at(2)
        self.assertEqual(roots_r2, roots_r2_expected)
    def test_01_evn_enabled(self):
        repo = self.create_repo(multi=True)
        conf = repo.conf
        svn = repo.svn

        dot()
        make_std_layout(repo)

        dot()
        self.assertEqual(repo.roots_at(1), {
            '/foo/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            },
        })

        dot()
        self.assertEqual(repo.roots_at(2), {
            '/foo/trunk/': { 'created': 1 },
            '/bar/trunk/': {
                'copies': {},
                'created': 2,
                'creation_method': 'created',
            },
        })

        dot()
        self.assertEqual(repo.roots, {
            '/foo/trunk/': { 'created': 1 },
            '/bar/trunk/': {
                'copies': {},
                'created': 2,
                'creation_method': 'created',
            },
        })


        dot()
        error = KnownRootPathRenamedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.move(repo.ra('/foo/trunk'), repo.ra('/bar/trunk'), m='cp')

        dot()
        self.assertEqual(repo.roots, {
            '/foo/trunk/': { 'created': 1 },
            '/bar/trunk/': {
                'copies': {},
                'created': 2,
                'creation_method': 'created',
            },
        })
예제 #20
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        error = e.BranchDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/branches/1.x/'), m='Create branch manually')

        dot()
        evnadmin.disable(repo.name)
        svn.mkdir(repo.ra('/branches/1.x/'), m='Create branch manually2')

        dot()
        evn_props_r2_expected = {
            'errors': {
                '/branches/1.x/': [ e.BranchDirectoryCreatedManually ],
            },
            'roots': {
                '/trunk/': { 'created': 1 },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)
        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/branches/1.x/',
            revision='2',
            root_type='branch',
        )
        dot()
        evnadmin.unset_repo_readonly(repo.name)
        evnadmin.analyze(repo.name)

        dot()
        evn_props_r2_expected = {
            'roots': {
                '/trunk/': { 'created': 1 },
                '/branches/1.x/': {
                    'created': 2,
                    'copies': {},
                    'creation_method': 'created',
                },
            },
        }
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)
예제 #21
0
    def test_01_wc_when_enabled(self):
        # This appears to be blocked by svn.exe with an error message along
        # the lines of:
        #   Cannot copy path '/trunk' into its own child '/trunk/foo'
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        error = 'Cannot copy path'
        dot()
        with chdir(repo.wc):
            with ensure_blocked(self, error):
                svn.copy('trunk', 'trunk/foo')
                svn.ci('trunk', m='Copy trunk')
    def test_01_wc_when_enabled(self):
        # This appears to be blocked by svn.exe with an error message along
        # the lines of:
        #   Cannot copy path '/trunk' into its own child '/trunk/foo'
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        error = 'Cannot copy path'
        dot()
        with chdir(repo.wc):
            with ensure_blocked(self, error):
                svn.copy('trunk', 'trunk/foo')
                svn.ci('trunk', m='Copy trunk')
    def test_05_block_n_deep_non_standard_dirs(self):
        """
        Prevent any > two-level deep directories from being created if they're
        not a standard directory.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = e.InvalidTopLevelRepoComponentDirectoryCreated
        paths = [ p.replace('/', '') for p in conf.standard_layout ]
        with chdir(repo.wc):
            dot()
            svn.mkdir('foo')
            svn.ci()

            dot()
            svn.mkdir('foo/bar')
            svn.mkdir('foo/bar/tmp')
            with ensure_blocked(self, error):
                svn.ci()

            dot()
            svn.mkdir('viper')
            svn.mkdir('viper/eagle')
            svn.mkdir('viper/eagle/tomcat')
            with ensure_blocked(self, error):
                svn.ci('viper')

            dot()
            svn.mkdir('fulcrum')
            svn.mkdir('fulcrum/flanker')
            svn.mkdir('fulcrum/flanker/foxbat')
            svn.mkdir('fulcrum/flanker/foxbat/tags')
            svn.mkdir('fulcrum/flanker/foxbat/trunk')
            svn.mkdir('fulcrum/flanker/foxbat/branches')
            with ensure_blocked(self, error):
                svn.ci('fulcrum')
예제 #24
0
    def test_05_block_n_deep_non_standard_dirs(self):
        """
        Prevent any > two-level deep directories from being created if they're
        not a standard directory.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = e.InvalidTopLevelRepoComponentDirectoryCreated
        paths = [p.replace('/', '') for p in conf.standard_layout]
        with chdir(repo.wc):
            dot()
            svn.mkdir('foo')
            svn.ci()

            dot()
            svn.mkdir('foo/bar')
            svn.mkdir('foo/bar/tmp')
            with ensure_blocked(self, error):
                svn.ci()

            dot()
            svn.mkdir('viper')
            svn.mkdir('viper/eagle')
            svn.mkdir('viper/eagle/tomcat')
            with ensure_blocked(self, error):
                svn.ci('viper')

            dot()
            svn.mkdir('fulcrum')
            svn.mkdir('fulcrum/flanker')
            svn.mkdir('fulcrum/flanker/foxbat')
            svn.mkdir('fulcrum/flanker/foxbat/tags')
            svn.mkdir('fulcrum/flanker/foxbat/trunk')
            svn.mkdir('fulcrum/flanker/foxbat/branches')
            with ensure_blocked(self, error):
                svn.ci('fulcrum')
예제 #25
0
    def test_01_wc(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        with chdir(repo.wc):
            svn.copy('trunk', 'tags/1.0')
            svn.ci('tags', m='Tag trunk')

        error = 'known root path copied to known root subtree path'
        with chdir(repo.wc):
            with ensure_blocked(self, error):
                svn.copy('trunk', 'tags/1.0')
                svn.ci('tags/1.0', m='Incorrect copy')
    def test_01_wc(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        with chdir(repo.wc):
            svn.copy('trunk', 'tags/1.0')
            svn.ci('tags', m='Tag trunk')

        error = 'known root path copied to known root subtree path'
        with chdir(repo.wc):
            with ensure_blocked(self, error):
                svn.copy('trunk', 'tags/1.0')
                svn.ci('tags/1.0', m='Incorrect copy')
    def test_02_standard_layout_blocked(self):
        """
        Ensure top-level standard layout directories can't be created.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        actual = svn.ls(repo.uri)
        self.assertEqual('', actual)

        error = e.StandardLayoutTopLevelDirectoryCreatedInMultiComponentRepo
        paths = [ p.replace('/', '') for p in conf.standard_layout ]
        with chdir(repo.wc):
            for path in paths:
                dot()
                svn.mkdir(path)
                with ensure_blocked(self, error):
                    svn.ci(path)
예제 #28
0
    def test_02_standard_layout_blocked(self):
        """
        Ensure top-level standard layout directories can't be created.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        actual = svn.ls(repo.uri)
        self.assertEqual('', actual)

        error = e.StandardLayoutTopLevelDirectoryCreatedInMultiComponentRepo
        paths = [p.replace('/', '') for p in conf.standard_layout]
        with chdir(repo.wc):
            for path in paths:
                dot()
                svn.mkdir(path)
                with ensure_blocked(self, error):
                    svn.ci(path)
예제 #29
0
    def test_04_block_two_deep_non_standard_dirs(self):
        """
        Prevent any two-level deep directories from being created if they're
        not a standard directory.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = e.InvalidTopLevelRepoComponentDirectoryCreated
        paths = [p.replace('/', '') for p in conf.standard_layout]
        with chdir(repo.wc):
            dot()
            svn.mkdir('foo')
            svn.ci()

            dot()
            svn.mkdir('foo/bar')
            with ensure_blocked(self, error):
                svn.ci()
    def test_04_block_two_deep_non_standard_dirs(self):
        """
        Prevent any two-level deep directories from being created if they're
        not a standard directory.
        """
        repo = self.create_repo(multi=True)
        svn = repo.svn

        error = e.InvalidTopLevelRepoComponentDirectoryCreated
        paths = [ p.replace('/', '') for p in conf.standard_layout ]
        with chdir(repo.wc):
            dot()
            svn.mkdir('foo')
            svn.ci()

            dot()
            svn.mkdir('foo/bar')
            with ensure_blocked(self, error):
                svn.ci()
예제 #31
0
    def test_01_basic(self):
        """
        Make sure trunk can't be re-copied within a branch.
        Reported by: @jamieechlin
        """
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        roots_r1 = {
            '/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(roots_r1, repo.roots)

        dot()
        with chdir(repo.wc):
            svn.cp('trunk', 'branches/1.x')
            svn.ci(m='Branching 1.x.')

        roots_r2 = {
            '/trunk/': { 'created': 1 },
            '/branches/1.x/': {
                'copied_from': ('/trunk/', 1),
                'copies': {},
                'created': 2,
                'creation_method': 'copied',
                'errors': []
            },
        }
        self.assertEqual(roots_r2, repo.roots)

        dot()
        error = 'known root path copied to known root subtree path'
        with chdir(repo.wc):
            svn.cp('trunk', 'branches/1.x')
            with ensure_blocked(self, error):
                svn.ci('branches/1.x', m='Copying trunk to branches/1.x.')
예제 #32
0
    def test_02_add_new(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = {
            'test.dll': bulk_chargen(100),
        }
        repo.build(tree, prefix='trunk')

        error = e.BlockedFileExtension
        with chdir(repo.wc):
            dot()
            svn.add('trunk/test.dll')
            with ensure_blocked(self, error):
                svn.ci('trunk/test.dll', m='Adding test.dll...')
    def test_02_add_new(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = {
            'test.dll': bulk_chargen(100),
        }
        repo.build(tree, prefix='trunk')

        error = e.BlockedFileExtension
        with chdir(repo.wc):
            dot()
            svn.add('trunk/test.dll')
            with ensure_blocked(self, error):
                svn.ci('trunk/test.dll', m='Adding test.dll...')
예제 #34
0
    def test_01_over_limit(self):
        repo = self.create_repo()
        conf = repo.conf
        conf.set_max_file_size_in_bytes(1024)

        svn = repo.svn

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        over = 1025
        tree = {'over.txt': bulk_chargen(over)}
        repo.build(tree, prefix='trunk')

        error = format_file_exceeds_max_size_error(over, 1024)
        with chdir(repo.wc):
            dot()
            svn.add('trunk/over.txt')
            with ensure_blocked(self, error):
                svn.ci('trunk', m='Over limit')
예제 #35
0
    def test_01_over_limit(self):
        repo = self.create_repo()
        conf = repo.conf
        conf.set_max_file_size_in_bytes(1024)

        svn = repo.svn

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        over = 1025
        tree = { 'over.txt': bulk_chargen(over) }
        repo.build(tree, prefix='trunk')

        error = format_file_exceeds_max_size_error(over, 1024)
        with chdir(repo.wc):
            dot()
            svn.add('trunk/over.txt')
            with ensure_blocked(self, error):
                svn.ci('trunk', m='Over limit')
예제 #36
0
    def test_02_non_exempt(self):
        repo = self.create_repo()
        conf = repo.conf
        conf.set('main', 'exempt-symlinks-from-blocked-file-extensions', '0')
        conf.save()
        svn = repo.svn

        dot()
        self.assertFalse(conf.exempt_symlinks_from_blocked_file_extensions)

        dot()
        tree = {'target': bulk_chargen(100)}
        repo.build(tree, prefix='trunk')
        trunk = join_path(repo.wc, 'trunk')
        error = e.BlockedFileExtension
        with chdir(trunk):
            dot()
            os.symlink('target', 'target.so')
            svn.add('target.so')
            with ensure_blocked(self, error):
                svn.ci('target.so', m='Adding symlink.')
    def test_02_non_exempt(self):
        repo = self.create_repo()
        conf = repo.conf
        conf.set('main', 'exempt-symlinks-from-blocked-file-extensions', '0')
        conf.save()
        svn = repo.svn

        dot()
        self.assertFalse(conf.exempt_symlinks_from_blocked_file_extensions)

        dot()
        tree = { 'target': bulk_chargen(100) }
        repo.build(tree, prefix='trunk')
        trunk = join_path(repo.wc, 'trunk')
        error = e.BlockedFileExtension
        with chdir(trunk):
            dot()
            os.symlink('target', 'target.so')
            svn.add('target.so')
            with ensure_blocked(self, error):
                svn.ci('target.so', m='Adding symlink.')
예제 #38
0
    def test_01_exempt(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        self.assertTrue(conf.exempt_symlinks_from_blocked_file_extensions)

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = {'target': bulk_chargen(100)}
        repo.build(tree, prefix='trunk')
        trunk = join_path(repo.wc, 'trunk')
        error = e.BlockedFileExtension
        with chdir(trunk):
            dot()
            os.symlink('target', 'target.so')
            self.assertTrue(os.path.islink('target.so'))
            svn.add('target')
            svn.add('target.so')
            svn.ci('.', m='Adding target + symlink.')

            dot()
            svn.mv('target', 'target.dll')
            with ensure_blocked(self, error):
                svn.ci('.', m='Renaming target...')

            dot()
            svn.revert('target', 'target.dll')

            dot()
            os.rename('target.so', 'target.exe')
            self.assertTrue(os.path.islink('target.exe'))
            #evnadmin = repo.evnadmin
            #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')
            svn.rm('target.so')
            svn.add('target.exe')
            svn.ci('.', m='Renaming target.so to target.exe.')
    def test_01_exempt(self):
        repo = self.create_repo()
        conf = repo.conf
        svn = repo.svn

        dot()
        self.assertTrue(conf.exempt_symlinks_from_blocked_file_extensions)

        #evnadmin = repo.evnadmin
        #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')

        dot()
        tree = { 'target': bulk_chargen(100) }
        repo.build(tree, prefix='trunk')
        trunk = join_path(repo.wc, 'trunk')
        error = e.BlockedFileExtension
        with chdir(trunk):
            dot()
            os.symlink('target', 'target.so')
            self.assertTrue(os.path.islink('target.so'))
            svn.add('target')
            svn.add('target.so')
            svn.ci('.', m='Adding target + symlink.')

            dot()
            svn.mv('target', 'target.dll')
            with ensure_blocked(self, error):
                svn.ci('.', m='Renaming target...')

            dot()
            svn.revert('target', 'target.dll')

            dot()
            os.rename('target.so', 'target.exe')
            self.assertTrue(os.path.islink('target.exe'))
            #evnadmin = repo.evnadmin
            #evnadmin.enable_remote_debug(repo.path, hook='pre-commit')
            svn.rm('target.so')
            svn.add('target.exe')
            svn.ci('.', m='Renaming target.so to target.exe.')
    def test_01_basic(self):
        """
        Given:
            /trunk/
            /tags/
            /branches/
        Make sure we can't create:
            /bar/
        """
        repo = self.create_repo()
        svn = repo.svn

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)
        dot()

        expected = e.InvalidTopLevelRepoDirectoryCreated
        with chdir(repo.wc):
            svn.mkdir('bar')
            with ensure_blocked(self, expected):
                svn.ci()
                dot()
예제 #41
0
    def test_01_basic(self):
        """
        Given:
            /trunk/
            /tags/
            /branches/
        Make sure we can't create:
            /bar/
        """
        repo = self.create_repo()
        svn = repo.svn

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)
        dot()

        expected = e.InvalidTopLevelRepoDirectoryCreated
        with chdir(repo.wc):
            svn.mkdir('bar')
            with ensure_blocked(self, expected):
                svn.ci()
                dot()
예제 #42
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin
        evnadmin.disable(repo.path)

        dot()
        tree = {'foo/moo/bar.txt': bulk_chargen(100)}
        repo.build(tree, prefix='branches')
        with chdir(repo.wc):
            # r2
            svn.add('branches/foo')
            svn.ci('branches/foo', m='Initializing foo component.')

        dot()
        evnadmin.enable(repo.path)
        error = 'valid root subtree path renamed to valid root path'
        with ensure_blocked(self, error):
            svn.mv(repo.ra('/branches/foo/moo'),
                   repo.ra('/branches/bar/'),
                   m='Branch')

        dot()
        evnadmin.disable(repo.path)
        # r3
        svn.mv(repo.ra('/branches/foo/moo/'),
               repo.ra('/branches/bar/'),
               m='Branch')

        dot()
        evn_props_r3_expected = {
            'errors': {
                '/branches/bar/': [error],
            },
            'roots': {
                '/trunk/': {
                    'created': 1
                },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(3)['evn'], evn_props_r3_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/branches/bar/',
            revision='3',
            root_type='branch',
        )
        evnadmin.enable(repo.name)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evn_props_r3_expected = {
            'roots': {
                '/trunk/': {
                    'created': 1
                },
                '/branches/bar/': {
                    'copies': {},
                    'created': 3,
                    'creation_method': 'renamed',
                    'renamed_from': ('/branches/foo/moo/', 2),
                },
            },
        }
        self.assertEqual(repo.revprops_at(3)['evn'], evn_props_r3_expected)
예제 #43
0
    def test_01(self):
        repo = self.create_repo(component_depth='-1')
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        evnadmin.disable(repo.name)

        dot()
        svn.mkdir(repo.ra('/head/'), m='Create head')

        dot()
        error = 'repo is not set readonly'
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/head/',
                revision='1',
                root_type='trunk',
            )

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/head/',
            revision='1',
            root_type='trunk',
        )

        dot()
        error = 'hint already exists'
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/head/',
                revision='1',
                root_type='trunk',
            )

        dot()
        evnadmin.enable(repo.name)

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots, roots_r1_expected)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        svn.mkdir(repo.ra('/stable/'), m='mkdir')

        dot()
        svn.copy(repo.ra('/head/'), repo.ra('/stable/1/'), m="Branch")

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {
                    2: [('/stable/1/', 3)]
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r2_expected = {
            '/head/': { 'created': 1 },
            '/stable/1/': {
                'copies': {},
                'created': 3,
                'copied_from': ('/head/', 2),
                'creation_method': 'copied',
                'errors': [],
            },
        }
        self.assertEqual(repo.roots, roots_r2_expected)

        dot()
        # r4
        svn.mkdir(repo.ra('/stable/2-broken/'), m='Create broken branch')

        dot()
        roots_r3_expected = {
            '/head/': { 'created': 1 },
            '/stable/1/': { 'created': 3 },
        }
        self.assertEqual(repo.roots, roots_r3_expected)

        dot()
        evnadmin.add_branches_basedir(repo.name, basedir='/stable/')

        dot()
        error = e.BranchDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/stable/2-blocked/'), m='Create broken branch')

        dot()
        # r5
        svn.copy(repo.ra('/head/'), repo.ra('/stable/2/'), m="Branch")

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {
                    2: [('/stable/1/', 3)],
                    4: [('/stable/2/', 5)],
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r5_expected = {
            '/head/': { 'created': 1 },
            '/stable/1/': { 'created': 3 },
            '/stable/2/': {
                'copies': {},
                'created': 5,
                'copied_from': ('/head/', 4),
                'creation_method': 'copied',
                'errors': [],
            },
        }
        self.assertEqual(repo.roots_at(5), roots_r5_expected)

        dot()
        evnadmin.remove_branches_basedir(repo.name, basedir='/stable/')

        dot()
        # r6
        svn.mkdir(repo.ra('/stable/3-broken/'), m='Create broken branch')

        # r7
        dot()
        svn.mkdir(repo.ra('/releng/'), m='Create directory')

        dot()
        evnadmin.add_tags_basedir(repo.name, basedir='/releng/')
        error = 'unknown path copied to valid root path'
        with ensure_blocked(self, error):
            svn.copy(
                repo.ra('/stable/3-broken/'),
                repo.ra('/releng/3/'),
                m='Create broken tag',
            )

        dot()
        evnadmin.disable(repo.name)

        dot()
        evnadmin.remove_tags_basedir(repo.name, basedir='/releng/')
        # r8
        svn.copy(
            repo.ra('/stable/3-broken/'),
            repo.ra('/releng/3/'),
            m='Create broken tag',
        )

        dot()
        # r9
        svn.copy(
            repo.ra('/stable/3-broken/'),
            repo.ra('/releng/3-take2/'),
            m='Create another broken tag',
        )

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        args = ('/stable/3-broken/', 5)
        error = 'no such path %s in revision %d' % args
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/stable/3-broken/',
                revision='5',
                root_type='branch',
            )

        dot()
        args = ('/stable/3-broken/', 7)
        error = "path %s already existed in revision %d;" % args
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/stable/3-broken/',
                revision='7',
                root_type='branch',
            )

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/stable/3-broken/',
            revision='6',
            root_type='branch',
        )

        dot()
        evnadmin.add_root_exclusion(
            repo.name,
            root_exclusion='/releng/3-take2/',
        )

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evnadmin.enable(repo.name)

        dot()
        roots_r6_expected = {
            '/head/': { 'created': 1 },
            '/stable/1/': { 'created': 3 },
            '/stable/2/': { 'created': 5 },
            '/stable/3-broken/': {
                'created': 6,
                'creation_method': 'created',
                'copies': {
                    7: [('/releng/3/', 8)],
                    8: [('/releng/3-take2/', 9)]
                },
            },
        }
        self.assertEqual(repo.roots_at(6), roots_r6_expected)

        dot()
        roots_r7_expected = {
            '/head/': { 'created': 1 },
            '/stable/1/': { 'created': 3 },
            '/stable/2/': { 'created': 5 },
            '/stable/3-broken/': { 'created': 6 },
        }
        self.assertEqual(repo.roots_at(7), roots_r7_expected)

        dot()
        evn_props_r8_expected = {
            'notes': {
                '/releng/3/': [ 'known root path copied to unknown path' ],
            },
            'roots': {
                '/head/': { 'created': 1 },
                '/stable/1/': { 'created': 3 },
                '/stable/2/': { 'created': 5 },
                '/stable/3-broken/': { 'created': 6 },
                '/releng/3/': {
                    'errors': [],
                    'copies': {},
                    'created': 8,
                    'creation_method': 'copied',
                    'copied_from': ('/stable/3-broken/', 7),
                },
            },
        }
        self.assertEqual(repo.revprops_at(8)['evn'], evn_props_r8_expected)

        dot()
        evn_props_r9_expected = {
            'notes': {
                '/releng/3-take2/': [ 'known root path copied to unknown path' ],
            },
            'roots': {
                '/head/': { 'created': 1 },
                '/stable/1/': { 'created': 3 },
                '/stable/2/': { 'created': 5 },
                '/stable/3-broken/': { 'created': 6 },
                '/releng/3/': { 'created': 8 },
            },
        }
        self.assertEqual(repo.revprops_at(9)['evn'], evn_props_r9_expected)
예제 #44
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin
        evnadmin.disable(repo.path)

        dot()
        tree = { 'foo/moo/bar.txt': bulk_chargen(100) }
        repo.build(tree, prefix='branches')
        with chdir(repo.wc):
            # r2
            svn.add('branches/foo')
            svn.ci('branches/foo', m='Initializing foo component.')

        dot()
        evnadmin.enable(repo.path)
        error = 'valid root subtree path renamed to valid root path'
        with ensure_blocked(self, error):
            svn.mv(repo.ra('/branches/foo/moo'),
                   repo.ra('/branches/bar/'),
                   m='Branch')

        dot()
        evnadmin.disable(repo.path)
        # r3
        svn.mv(repo.ra('/branches/foo/moo/'),
               repo.ra('/branches/bar/'), m='Branch')

        dot()
        evn_props_r3_expected = {
            'errors': {
                '/branches/bar/': [ error ],
            },
            'roots': {
                '/trunk/': { 'created': 1 },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(3)['evn'], evn_props_r3_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/branches/bar/',
            revision='3',
            root_type='branch',
        )
        evnadmin.enable(repo.name)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evn_props_r3_expected = {
            'roots': {
                '/trunk/': { 'created': 1 },
                '/branches/bar/': {
                    'copies': {},
                    'created': 3,
                    'creation_method': 'renamed',
                    'renamed_from': ('/branches/foo/moo/', 2),
                },
            },
        }
        self.assertEqual(repo.revprops_at(3)['evn'], evn_props_r3_expected)
예제 #45
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        # Disable so we can mkdir ^/other
        dot()
        evnadmin.disable(repo.path)
        svn.mkdir(repo.ra("/other/"), m="Creating other directory")

        dot()
        evnadmin.enable(repo.path)
        svn.cp(repo.ra("/trunk/"), repo.ra("/branches/1.x/"), m="Branching")
        svn.cp(repo.ra("/branches/1.x/"), repo.ra("/tags/1.0/"), m="Tagging")
        svn.cp(repo.ra("/branches/1.x/"), repo.ra("/tags/1.1/"), m="Tagging")
        svn.cp(repo.ra("/branches/1.x/"), repo.ra("/tags/1.2/"), m="Tagging")

        # Lazy (quick) test of roots.
        dot()
        expected_roots = set(("/trunk/", "/branches/1.x/", "/tags/1.0/", "/tags/1.1/", "/tags/1.2/"))
        actual_roots = set(repo.roots.keys())
        self.assertEqual(expected_roots, actual_roots)

        is_repo_admin = lambda u: evnadmin.is_repo_admin(repo.name, u=u)
        add_repo_admin = lambda u: evnadmin.add_repo_admin(repo.name, u=u)
        show_repo_admins = lambda: evnadmin.show_repo_admins(repo.name)
        remove_repo_admin = lambda u: evnadmin.remove_repo_admin(repo.name, u=u)

        dot()
        username = svn.username
        self.assertEqual(is_repo_admin(username), "no")
        self.assertEqual(is_repo_admin("laskdjflsdkjf"), "no")

        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.cp(repo.ra("/tags/1.0/"), repo.ra("/other/1.0/"), m="Tagging")

        dot()
        error = "commits with errors can only be forced through by"
        with ensure_blocked(self, error):
            svn.cp(repo.ra("/tags/1.0/"), repo.ra("/other/1.0/"), m="IGNORE ERRORS")

        # dot()
        # error = e.TagCopied
        # with ensure_blocked(self, error):
        #    svn.cp(repo.ra('/tags/1.0/'), repo.ra('/other/1.0/'),
        #           m=EVN_ERROR_CONFIRMATIONS[e.TagCopied])

        dot()
        add_repo_admin(username)
        self.assertEqual(is_repo_admin(username), "yes")

        # Make sure we're still blocked if we're an admin but we haven't
        # explicitly included IGNORE ERRORS.
        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.cp(repo.ra("/tags/1.0/"), repo.ra("/other/1.0/"), m="Tagging")

        dot()
        error = e.TagCopied
        svn.cp(repo.ra("/tags/1.0/"), repo.ra("/other/1.0/"), m="IGNORE ERRORS")

        # dot()
        # error = e.TagRemoved
        # svn.rm(repo.ra('/tags/1.1/'), m=EVN_ERROR_CONFIRMATIONS[error])

        with chdir(repo.wc):
            svn.up()
            svn.cp("tags/1.2", "other/1.2")
            svn.cp("trunk", "other/foobar")
            svn.cp("branches/1.x", "other/1.x")
            svn.ci(m="IGNORE ERRORS")
예제 #46
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        # Disable so we can mkdir ^/other
        dot()
        evnadmin.disable(repo.path)
        with chdir(repo.wc):
            svn.mkdir('other')
            svn.mkdir('keep')
            svn.ci()

        dot()
        evnadmin.enable(repo.path)
        svn.cp(repo.ra('/trunk/'), repo.ra('/branches/1.x/'), m='Branching')
        svn.cp(repo.ra('/branches/1.x/'), repo.ra('/tags/1.0/'), m='Tagging')

        # Lazy (quick) test of roots.
        dot()
        expected_roots = set(('/trunk/', '/branches/1.x/', '/tags/1.0/'))
        actual_roots = set(repo.roots.keys())
        self.assertEqual(expected_roots, actual_roots)

        # Add ourselves as a repo admin so that we can force through the next
        # commit.
        dot()
        evnadmin.add_repo_admin(repo.name, username=svn.username)
        expected = 'yes'
        actual = evnadmin.is_repo_admin(repo.name, username=svn.username)
        self.assertEqual(expected, actual)

        dot()
        with chdir(repo.wc):
            svn.up()
            svn.cp('trunk', 'other/foobar')
            svn.cp('branches/1.x', 'other/1.x')
            svn.cp('tags/1.0', 'other/1.0')
            svn.ci(m='IGNORE ERRORS')

        evn_props_r5_expected = {
            'errors': {
                '/other/1.0/': [
                    'tag copied',
                    'known root path copied to unknown path',
                ],
                '/other/1.x/': [ 'known root path copied to unknown path' ],
                '/other/foobar/': [ 'known root path copied to unknown path' ],
            },
            'roots': {
                '/branches/1.x/': { 'created': 3 },
                '/other/1.0/': {
                    'copied_from': ('/tags/1.0/', 4),
                    'copies': {},
                    'created': 5,
                    'creation_method': 'copied',
                    'errors': [
                        'tag copied',
                        'known root path copied to unknown path',
                    ],
                },
                '/other/1.x/': {
                    'copied_from': ('/branches/1.x/', 4),
                    'copies': {},
                    'created': 5,
                    'creation_method': 'copied',
                    'errors': ['known root path copied to unknown path'],
                },
                '/other/foobar/': {
                    'copied_from': ('/trunk/', 4),
                    'copies': {},
                    'created': 5,
                    'creation_method': 'copied',
                    'errors': ['known root path copied to unknown path'],
                },
                '/tags/1.0/': { 'created': 4 },
                '/trunk/': { 'created': 1 }
            }
        }
        self.assertEqual(repo.revprops_at(5)['evn'], evn_props_r5_expected)

        dot()
        error = e.RootAncestorRemoved
        with ensure_blocked(self, error):
            svn.rm(repo.ra('/other/'))

        dot()
        svn.rm(repo.ra('/other/'), m='IGNORE ERRORS')

        evn_props_r6_expected = {
            'errors': {
                '/other/': [
                    e.RootAncestorRemoved,
                    e.MultipleRootsAffectedByRemove,
                ],
            },
            'roots' : {
                '/branches/1.x/': {'created': 3},
                '/tags/1.0/': {'created': 4},
                '/trunk/': {'created': 1},
            }
        }
        self.assertEqual(repo.revprops_at(6)['evn'], evn_props_r6_expected)

        evn_brprops_expected_after_r6 = {
            'component_depth': 0,
            'last_rev': 6,
            'version': 1,
            'root_ancestor_actions': {
                '/other/': {
                    6: [
                        {
                            'action': 'removed',
                            'num_roots_removed': 3,
                        },
                    ],
                },
            },
        }
        self.assertEqual(
            repo.revprops_at(0)['evn'],
            evn_brprops_expected_after_r6,
        )
    def test_01(self):
        """
        Create a single-component repo, then convert to multi-component.
        """
        repo = self.create_repo()

        svn = repo.svn
        name = repo.name
        evnadmin = repo.evnadmin

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)

        dot()
        self.assertEqual(0, repo.component_depth)

        dot()
        roots = {
            '/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(roots, repo.roots)

        dot()
        with chdir(repo.wc):
            svn.cp('trunk', 'branches/1.x')
            svn.ci(m='Branching 1.x.')

        dot()
        with chdir(repo.wc):
            svn.cp('branches/1.x', 'tags/1.1')
            svn.ci(m='Tagging 1.1.')

        dot()
        error = 'root ancestor path renamed to unknown path'
        with chdir(repo.wc):
            svn.up()
            svn.mkdir('foo')
            svn.mv('tags', 'foo')
            svn.mv('trunk', 'foo')
            svn.mv('branches', 'foo')
            with ensure_blocked(self, error):
                svn.ci()

        dot()
        evnadmin.disable(name)
        with chdir(repo.wc):
            svn.ci()
        evnadmin.set_repo_component_depth(repo.name, multi=True)
        evnadmin.enable(name)

        roots = {
            '/foo/branches/1.x/': {
                'copies': {},
                'created': 4,
                'creation_method': 'renamed_indirectly',
                'errors': ['root ancestor path renamed to unknown path'],
                'renamed_from': ('/branches/1.x/', 3),
                'renamed_indirectly_from': (
                    '/branches/',
                    '/foo/branches/',
                ),
            },
            '/foo/tags/1.1/': {
                'copies': {},
                'created': 4,
                'creation_method': 'renamed_indirectly',
                'errors': ['root ancestor path renamed to unknown path'],
                'renamed_from': ('/tags/1.1/', 3),
                'renamed_indirectly_from': (
                    '/tags/',
                    '/foo/tags/',
                ),
            },
            '/foo/trunk/': {
                'copies': {},
                 'created': 4,
                 'creation_method': 'renamed',
                 'errors': [],
                 'renamed_from': ('/trunk/', 3)
            }
        }

        self.assertEqual(roots, repo.roots)
예제 #48
0
    def test_01(self):
        repo = self.create_repo(component_depth='-1')
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        evnadmin.disable(repo.name)

        dot()
        svn.mkdir(repo.ra('/head/'), m='Create head')

        dot()
        error = 'repo is not set readonly'
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/head/',
                revision='1',
                root_type='trunk',
            )

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/head/',
            revision='1',
            root_type='trunk',
        )

        dot()
        error = 'hint already exists'
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/head/',
                revision='1',
                root_type='trunk',
            )

        dot()
        evnadmin.enable(repo.name)

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots, roots_r1_expected)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        svn.mkdir(repo.ra('/stable/'), m='mkdir')

        dot()
        svn.copy(repo.ra('/head/'), repo.ra('/stable/1/'), m="Branch")

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {
                    2: [('/stable/1/', 3)]
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r2_expected = {
            '/head/': {
                'created': 1
            },
            '/stable/1/': {
                'copies': {},
                'created': 3,
                'copied_from': ('/head/', 2),
                'creation_method': 'copied',
                'errors': [],
            },
        }
        self.assertEqual(repo.roots, roots_r2_expected)

        dot()
        # r4
        svn.mkdir(repo.ra('/stable/2-broken/'), m='Create broken branch')

        dot()
        roots_r3_expected = {
            '/head/': {
                'created': 1
            },
            '/stable/1/': {
                'created': 3
            },
        }
        self.assertEqual(repo.roots, roots_r3_expected)

        dot()
        evnadmin.add_branches_basedir(repo.name, basedir='/stable/')

        dot()
        error = e.BranchDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/stable/2-blocked/'), m='Create broken branch')

        dot()
        # r5
        svn.copy(repo.ra('/head/'), repo.ra('/stable/2/'), m="Branch")

        dot()
        roots_r1_expected = {
            '/head/': {
                'copies': {
                    2: [('/stable/1/', 3)],
                    4: [('/stable/2/', 5)],
                },
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(repo.roots_at(1), roots_r1_expected)

        dot()
        roots_r5_expected = {
            '/head/': {
                'created': 1
            },
            '/stable/1/': {
                'created': 3
            },
            '/stable/2/': {
                'copies': {},
                'created': 5,
                'copied_from': ('/head/', 4),
                'creation_method': 'copied',
                'errors': [],
            },
        }
        self.assertEqual(repo.roots_at(5), roots_r5_expected)

        dot()
        evnadmin.remove_branches_basedir(repo.name, basedir='/stable/')

        dot()
        # r6
        svn.mkdir(repo.ra('/stable/3-broken/'), m='Create broken branch')

        # r7
        dot()
        svn.mkdir(repo.ra('/releng/'), m='Create directory')

        dot()
        evnadmin.add_tags_basedir(repo.name, basedir='/releng/')
        error = 'unknown path copied to valid root path'
        with ensure_blocked(self, error):
            svn.copy(
                repo.ra('/stable/3-broken/'),
                repo.ra('/releng/3/'),
                m='Create broken tag',
            )

        dot()
        evnadmin.disable(repo.name)

        dot()
        evnadmin.remove_tags_basedir(repo.name, basedir='/releng/')
        # r8
        svn.copy(
            repo.ra('/stable/3-broken/'),
            repo.ra('/releng/3/'),
            m='Create broken tag',
        )

        dot()
        # r9
        svn.copy(
            repo.ra('/stable/3-broken/'),
            repo.ra('/releng/3-take2/'),
            m='Create another broken tag',
        )

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        args = ('/stable/3-broken/', 5)
        error = 'no such path %s in revision %d' % args
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/stable/3-broken/',
                revision='5',
                root_type='branch',
            )

        dot()
        args = ('/stable/3-broken/', 7)
        error = "path %s already existed in revision %d;" % args
        with ensure_fails(self, error):
            evnadmin.add_root_hint(
                repo.name,
                path='/stable/3-broken/',
                revision='7',
                root_type='branch',
            )

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/stable/3-broken/',
            revision='6',
            root_type='branch',
        )

        dot()
        evnadmin.add_root_exclusion(
            repo.name,
            root_exclusion='/releng/3-take2/',
        )

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evnadmin.enable(repo.name)

        dot()
        roots_r6_expected = {
            '/head/': {
                'created': 1
            },
            '/stable/1/': {
                'created': 3
            },
            '/stable/2/': {
                'created': 5
            },
            '/stable/3-broken/': {
                'created': 6,
                'creation_method': 'created',
                'copies': {
                    7: [('/releng/3/', 8)],
                    8: [('/releng/3-take2/', 9)]
                },
            },
        }
        self.assertEqual(repo.roots_at(6), roots_r6_expected)

        dot()
        roots_r7_expected = {
            '/head/': {
                'created': 1
            },
            '/stable/1/': {
                'created': 3
            },
            '/stable/2/': {
                'created': 5
            },
            '/stable/3-broken/': {
                'created': 6
            },
        }
        self.assertEqual(repo.roots_at(7), roots_r7_expected)

        dot()
        evn_props_r8_expected = {
            'notes': {
                '/releng/3/': ['known root path copied to unknown path'],
            },
            'roots': {
                '/head/': {
                    'created': 1
                },
                '/stable/1/': {
                    'created': 3
                },
                '/stable/2/': {
                    'created': 5
                },
                '/stable/3-broken/': {
                    'created': 6
                },
                '/releng/3/': {
                    'errors': [],
                    'copies': {},
                    'created': 8,
                    'creation_method': 'copied',
                    'copied_from': ('/stable/3-broken/', 7),
                },
            },
        }
        self.assertEqual(repo.revprops_at(8)['evn'], evn_props_r8_expected)

        dot()
        evn_props_r9_expected = {
            'notes': {
                '/releng/3-take2/': ['known root path copied to unknown path'],
            },
            'roots': {
                '/head/': {
                    'created': 1
                },
                '/stable/1/': {
                    'created': 3
                },
                '/stable/2/': {
                    'created': 5
                },
                '/stable/3-broken/': {
                    'created': 6
                },
                '/releng/3/': {
                    'created': 8
                },
            },
        }
        self.assertEqual(repo.revprops_at(9)['evn'], evn_props_r9_expected)
예제 #49
0
    def test_01(self):
        """
        Create a single-component repo, then convert to multi-component.
        """
        repo = self.create_repo()

        svn = repo.svn
        name = repo.name
        evnadmin = repo.evnadmin

        expected = conf.standard_layout
        raw = svn.ls(repo.uri)
        actual = frozenset(format_dir(l) for l in raw.splitlines())
        self.assertEqual(expected, actual)

        dot()
        self.assertEqual(0, repo.component_depth)

        dot()
        roots = {
            '/trunk/': {
                'copies': {},
                'created': 1,
                'creation_method': 'created',
            }
        }
        self.assertEqual(roots, repo.roots)

        dot()
        with chdir(repo.wc):
            svn.cp('trunk', 'branches/1.x')
            svn.ci(m='Branching 1.x.')

        dot()
        with chdir(repo.wc):
            svn.cp('branches/1.x', 'tags/1.1')
            svn.ci(m='Tagging 1.1.')

        dot()
        error = 'root ancestor path renamed to unknown path'
        with chdir(repo.wc):
            svn.up()
            svn.mkdir('foo')
            svn.mv('tags', 'foo')
            svn.mv('trunk', 'foo')
            svn.mv('branches', 'foo')
            with ensure_blocked(self, error):
                svn.ci()

        dot()
        evnadmin.disable(name)
        with chdir(repo.wc):
            svn.ci()
        evnadmin.set_repo_component_depth(repo.name, multi=True)
        evnadmin.enable(name)

        roots = {
            '/foo/branches/1.x/': {
                'copies': {},
                'created': 4,
                'creation_method': 'renamed_indirectly',
                'errors': ['root ancestor path renamed to unknown path'],
                'renamed_from': ('/branches/1.x/', 3),
                'renamed_indirectly_from': (
                    '/branches/',
                    '/foo/branches/',
                ),
            },
            '/foo/tags/1.1/': {
                'copies': {},
                'created': 4,
                'creation_method': 'renamed_indirectly',
                'errors': ['root ancestor path renamed to unknown path'],
                'renamed_from': ('/tags/1.1/', 3),
                'renamed_indirectly_from': (
                    '/tags/',
                    '/foo/tags/',
                ),
            },
            '/foo/trunk/': {
                'copies': {},
                'created': 4,
                'creation_method': 'renamed',
                'errors': [],
                'renamed_from': ('/trunk/', 3)
            }
        }

        self.assertEqual(roots, repo.roots)
예제 #50
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        # Disable so we can mkdir ^/other
        dot()
        evnadmin.disable(repo.path)
        svn.mkdir(repo.ra('/other/'), m='Creating other directory')

        dot()
        evnadmin.enable(repo.path)
        svn.cp(repo.ra('/trunk/'), repo.ra('/branches/1.x/'), m='Branching')
        svn.cp(repo.ra('/branches/1.x/'), repo.ra('/tags/1.0/'), m='Tagging')
        svn.cp(repo.ra('/branches/1.x/'), repo.ra('/tags/1.1/'), m='Tagging')
        svn.cp(repo.ra('/branches/1.x/'), repo.ra('/tags/1.2/'), m='Tagging')

        # Lazy (quick) test of roots.
        dot()
        expected_roots = set((
            '/trunk/',
            '/branches/1.x/',
            '/tags/1.0/',
            '/tags/1.1/',
            '/tags/1.2/',
        ))
        actual_roots = set(repo.roots.keys())
        self.assertEqual(expected_roots, actual_roots)

        is_repo_admin = lambda u: evnadmin.is_repo_admin(repo.name, u=u)
        add_repo_admin = lambda u: evnadmin.add_repo_admin(repo.name, u=u)
        show_repo_admins = lambda: evnadmin.show_repo_admins(repo.name)
        remove_repo_admin = lambda u: evnadmin.remove_repo_admin(repo.name,
                                                                 u=u)

        dot()
        username = svn.username
        self.assertEqual(is_repo_admin(username), 'no')
        self.assertEqual(is_repo_admin('laskdjflsdkjf'), 'no')

        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.cp(repo.ra('/tags/1.0/'), repo.ra('/other/1.0/'), m='Tagging')

        dot()
        error = 'commits with errors can only be forced through by'
        with ensure_blocked(self, error):
            svn.cp(repo.ra('/tags/1.0/'),
                   repo.ra('/other/1.0/'),
                   m='IGNORE ERRORS')

        #dot()
        #error = e.TagCopied
        #with ensure_blocked(self, error):
        #    svn.cp(repo.ra('/tags/1.0/'), repo.ra('/other/1.0/'),
        #           m=EVN_ERROR_CONFIRMATIONS[e.TagCopied])

        dot()
        add_repo_admin(username)
        self.assertEqual(is_repo_admin(username), 'yes')

        # Make sure we're still blocked if we're an admin but we haven't
        # explicitly included IGNORE ERRORS.
        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.cp(repo.ra('/tags/1.0/'), repo.ra('/other/1.0/'), m='Tagging')

        dot()
        error = e.TagCopied
        svn.cp(repo.ra('/tags/1.0/'),
               repo.ra('/other/1.0/'),
               m='IGNORE ERRORS')

        #dot()
        #error = e.TagRemoved
        #svn.rm(repo.ra('/tags/1.1/'), m=EVN_ERROR_CONFIRMATIONS[error])

        with chdir(repo.wc):
            svn.up()
            svn.cp('tags/1.2', 'other/1.2')
            svn.cp('trunk', 'other/foobar')
            svn.cp('branches/1.x', 'other/1.x')
            svn.ci(m='IGNORE ERRORS')
예제 #51
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        error = e.TagDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/tags/1.x/'), m='Create tag manually')

        dot()
        evnadmin.disable(repo.name)
        svn.mkdir(repo.ra('/tags/1.x/'), m='Create tag manually2')

        dot()
        evn_props_r2_expected = {
            'errors': {
                '/tags/1.x/': [ e.TagDirectoryCreatedManually ],
            },
            'roots': {
                '/trunk/': { 'created': 1 },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/tags/1.x/',
            revision='2',
            root_type='tag',
        )
        evnadmin.analyze(repo.name)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evn_props_r2_expected = {
            'roots': {
                '/trunk/': { 'created': 1 },
                '/tags/1.x/': {
                    'created': 2,
                    'copies': {},
                    'creation_method': 'created',
                },
            },
        }
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        svn.up(repo.wc)

        dot()
        error = e.TagModified
        tagdir = join_path(repo.wc, 'tags/1.x')
        with chdir(tagdir):
            tree = { 'test.txt': bulk_chargen(100) }
            repo.build(tree, prefix='tags/1.x')
            dot()
            svn.add('test.txt')
            with ensure_blocked(self, error):
                dot()
                svn.ci('test.txt', m='Modifying tag')

        dot()
        error = e.TagRemoved
        with ensure_blocked(self, error):
            svn.rm(repo.ra('tags/1.x'), m='Deleting tag.')

        dot()
        error = e.TagRenamed
        with ensure_blocked(self, error):
            svn.mv(repo.ra('tags/1.x'), repo.ra('tags/2.x'), m='Renaming tag.')

        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.copy(repo.ra('tags/1.x'), repo.ra('tags/2.x'), m='Copying tag.')
예제 #52
0
    def test_01(self):
        repo = self.create_repo()
        svn = repo.svn
        evnadmin = repo.evnadmin

        dot()
        error = e.TagDirectoryCreatedManually
        with ensure_blocked(self, error):
            svn.mkdir(repo.ra('/tags/1.x/'), m='Create tag manually')

        dot()
        evnadmin.disable(repo.name)
        svn.mkdir(repo.ra('/tags/1.x/'), m='Create tag manually2')

        dot()
        evn_props_r2_expected = {
            'errors': {
                '/tags/1.x/': [e.TagDirectoryCreatedManually],
            },
            'roots': {
                '/trunk/': {
                    'created': 1
                },
            },
        }
        evnadmin.enable(repo.name)
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        evnadmin.set_repo_readonly(repo.name)

        dot()
        evnadmin.add_root_hint(
            repo.name,
            path='/tags/1.x/',
            revision='2',
            root_type='tag',
        )
        evnadmin.analyze(repo.name)

        dot()
        evnadmin.unset_repo_readonly(repo.name)

        dot()
        evn_props_r2_expected = {
            'roots': {
                '/trunk/': {
                    'created': 1
                },
                '/tags/1.x/': {
                    'created': 2,
                    'copies': {},
                    'creation_method': 'created',
                },
            },
        }
        self.assertEqual(repo.revprops_at(2)['evn'], evn_props_r2_expected)

        dot()
        svn.up(repo.wc)

        dot()
        error = e.TagModified
        tagdir = join_path(repo.wc, 'tags/1.x')
        with chdir(tagdir):
            tree = {'test.txt': bulk_chargen(100)}
            repo.build(tree, prefix='tags/1.x')
            dot()
            svn.add('test.txt')
            with ensure_blocked(self, error):
                dot()
                svn.ci('test.txt', m='Modifying tag')

        dot()
        error = e.TagRemoved
        with ensure_blocked(self, error):
            svn.rm(repo.ra('tags/1.x'), m='Deleting tag.')

        dot()
        error = e.TagRenamed
        with ensure_blocked(self, error):
            svn.mv(repo.ra('tags/1.x'), repo.ra('tags/2.x'), m='Renaming tag.')

        dot()
        error = e.TagCopied
        with ensure_blocked(self, error):
            svn.copy(repo.ra('tags/1.x'),
                     repo.ra('tags/2.x'),
                     m='Copying tag.')
예제 #53
0
    def test_01_evn_enabled(self):
        repo = self.create_repo(multi=True)
        conf = repo.conf
        svn = repo.svn

        dot()
        make_std_layout(repo)

        dot()
        self.assertEqual(
            repo.roots_at(1), {
                '/foo/trunk/': {
                    'copies': {},
                    'created': 1,
                    'creation_method': 'created',
                },
            })

        dot()
        self.assertEqual(
            repo.roots_at(2), {
                '/foo/trunk/': {
                    'created': 1
                },
                '/bar/trunk/': {
                    'copies': {},
                    'created': 2,
                    'creation_method': 'created',
                },
            })

        dot()
        self.assertEqual(
            repo.roots, {
                '/foo/trunk/': {
                    'created': 1
                },
                '/bar/trunk/': {
                    'copies': {},
                    'created': 2,
                    'creation_method': 'created',
                },
            })

        dot()
        error = KnownRootPathRenamedToKnownRootSubtreePath
        with ensure_blocked(self, error):
            svn.move(repo.ra('/foo/trunk'), repo.ra('/bar/trunk'), m='cp')

        dot()
        self.assertEqual(
            repo.roots, {
                '/foo/trunk/': {
                    'created': 1
                },
                '/bar/trunk/': {
                    'copies': {},
                    'created': 2,
                    'creation_method': 'created',
                },
            })