~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_matchers.py

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2010 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Tests of bzrlib test matchers."""
 
18
 
 
19
from testtools.matchers import *
 
20
 
 
21
from bzrlib.smart.client import CallHookParams
 
22
 
 
23
from bzrlib.tests import (
 
24
    CapturedCall,
 
25
    TestCase,
 
26
    TestCaseWithTransport,
 
27
    )
 
28
from bzrlib.tests.matchers import *
 
29
 
 
30
 
 
31
class StubTree(object):
 
32
    """Stubg for testing."""
 
33
 
 
34
    def __init__(self, lock_status):
 
35
        self._is_locked = lock_status
 
36
 
 
37
    def __str__(self):
 
38
        return u'I am da tree'
 
39
 
 
40
    def is_locked(self):
 
41
        return self._is_locked
 
42
 
 
43
 
 
44
class FakeUnlockable(object):
 
45
    """Something that can be unlocked."""
 
46
 
 
47
    def unlock(self):
 
48
        pass
 
49
 
 
50
 
 
51
class TestReturnsUnlockable(TestCase):
 
52
 
 
53
    def test___str__(self):
 
54
        matcher = ReturnsUnlockable(StubTree(True))
 
55
        self.assertEqual(
 
56
            'ReturnsUnlockable(lockable_thing=I am da tree)',
 
57
            str(matcher))
 
58
 
 
59
    def test_match(self):
 
60
        stub_tree = StubTree(False)
 
61
        matcher = ReturnsUnlockable(stub_tree)
 
62
        self.assertThat(matcher.match(lambda:FakeUnlockable()), Equals(None))
 
63
 
 
64
    def test_mismatch(self):
 
65
        stub_tree = StubTree(True)
 
66
        matcher = ReturnsUnlockable(stub_tree)
 
67
        mismatch = matcher.match(lambda:FakeUnlockable())
 
68
        self.assertNotEqual(None, mismatch)
 
69
        self.assertThat(mismatch.describe(), Equals("I am da tree is locked"))
 
70
 
 
71
 
 
72
class TestMatchesAncestry(TestCaseWithTransport):
 
73
 
 
74
    def test__str__(self):
 
75
        matcher = MatchesAncestry("A repository", "arevid")
 
76
        self.assertEqual(
 
77
            "MatchesAncestry(repository='A repository', "
 
78
            "revision_id='arevid')",
 
79
            str(matcher))
 
80
 
 
81
    def test_match(self):
 
82
        b = self.make_branch_builder('.')
 
83
        b.start_series()
 
84
        revid1 = b.build_commit()
 
85
        revid2 = b.build_commit()
 
86
        b.finish_series()
 
87
        branch = b.get_branch()
 
88
        m = MatchesAncestry(branch.repository, revid2)
 
89
        self.assertThat([revid2, revid1], m)
 
90
        self.assertThat([revid1, revid2], m)
 
91
        m = MatchesAncestry(branch.repository, revid1)
 
92
        self.assertThat([revid1], m)
 
93
        m = MatchesAncestry(branch.repository, "unknown")
 
94
        self.assertThat(["unknown"], m)
 
95
 
 
96
    def test_mismatch(self):
 
97
        b = self.make_branch_builder('.')
 
98
        b.start_series()
 
99
        revid1 = b.build_commit()
 
100
        revid2 = b.build_commit()
 
101
        b.finish_series()
 
102
        branch = b.get_branch()
 
103
        m = MatchesAncestry(branch.repository, revid1)
 
104
        mismatch = m.match([])
 
105
        self.assertIsNot(None, mismatch)
 
106
        self.assertEquals(
 
107
            "mismatched ancestry for revision '%s' was ['%s'], expected []" % (
 
108
                revid1, revid1),
 
109
            mismatch.describe())
 
110
 
 
111
 
 
112
class TestHasLayout(TestCaseWithTransport):
 
113
 
 
114
    def test__str__(self):
 
115
        matcher = HasLayout([("a", "a-id")])
 
116
        self.assertEqual("HasLayout([('a', 'a-id')])", str(matcher))
 
117
 
 
118
    def test_match(self):
 
119
        t = self.make_branch_and_tree('.')
 
120
        self.build_tree(['a', 'b/', 'b/c'])
 
121
        t.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
 
122
        self.assertThat(t, HasLayout(['', 'a', 'b/', 'b/c']))
 
123
        self.assertThat(t, HasLayout(
 
124
            [('', t.get_root_id()),
 
125
             ('a', 'a-id'),
 
126
             ('b/', 'b-id'),
 
127
             ('b/c', 'c-id')]))
 
128
 
 
129
    def test_mismatch(self):
 
130
        t = self.make_branch_and_tree('.')
 
131
        self.build_tree(['a', 'b/', 'b/c'])
 
132
        t.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
 
133
        mismatch = HasLayout(['a']).match(t)
 
134
        self.assertIsNot(None, mismatch)
 
135
        self.assertEquals(
 
136
            "['a'] != [u'', u'a', u'b/', u'b/c']",
 
137
            mismatch.describe())
 
138
 
 
139
    def test_no_dirs(self):
 
140
        # Some tree/repository formats do not support versioned directories
 
141
        t = self.make_branch_and_tree('.')
 
142
        t.has_versioned_directories = lambda: False
 
143
        self.build_tree(['a', 'b/', 'b/c'])
 
144
        t.add(['a', 'b', 'b/c'], ['a-id', 'b-id', 'c-id'])
 
145
        self.assertIs(None, HasLayout(['', 'a', 'b/', 'b/c']).match(t))
 
146
        self.assertIs(None, HasLayout(['', 'a', 'b/', 'b/c', 'd/']).match(t))
 
147
        mismatch = HasLayout([u'', u'a', u'd/']).match(t)
 
148
        self.assertIsNot(None, mismatch)
 
149
        self.assertEquals(
 
150
            "[u'', u'a'] != [u'', u'a', u'b/', u'b/c']",
 
151
            mismatch.describe())
 
152
 
 
153
 
 
154
class TestContainsNoVfsCalls(TestCase):
 
155
 
 
156
    def _make_call(self, method, args):
 
157
        return CapturedCall(CallHookParams(method, args, None, None, None), 0)
 
158
 
 
159
    def test__str__(self):
 
160
        self.assertEqual("ContainsNoVfsCalls()", str(ContainsNoVfsCalls()))
 
161
 
 
162
    def test_empty(self):
 
163
        self.assertIs(None, ContainsNoVfsCalls().match([]))
 
164
 
 
165
    def test_no_vfs_calls(self):
 
166
        calls = [self._make_call("Branch.get_config_file", [])]
 
167
        self.assertIs(None, ContainsNoVfsCalls().match(calls))
 
168
 
 
169
    def test_ignores_unknown(self):
 
170
        calls = [self._make_call("unknown", [])]
 
171
        self.assertIs(None, ContainsNoVfsCalls().match(calls))
 
172
 
 
173
    def test_match(self):
 
174
        calls = [self._make_call("append", ["file"]),
 
175
                 self._make_call("Branch.get_config_file", [])]
 
176
        mismatch = ContainsNoVfsCalls().match(calls)
 
177
        self.assertIsNot(None, mismatch)
 
178
        self.assertEquals([calls[0].call], mismatch.vfs_calls)
 
179
        self.assertEquals("no VFS calls expected, got: append('file')""",
 
180
                mismatch.describe())