1
# Copyright (C) 2008 Canonical Ltd
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for maps built on a CHK versionedfiles facility."""
19
from bzrlib.chk_map import CHKMap, RootNode, ValueNode
20
from bzrlib.tests import TestCaseWithTransport
23
class TestDumbMap(TestCaseWithTransport):
25
def get_chk_bytes(self):
26
# The eassiest way to get a CHK store is a development3 repository and
27
# then work with the chk_bytes attribute directly.
28
repo = self.make_repository(".", format="development3")
30
self.addCleanup(repo.unlock)
31
repo.start_write_group()
32
self.addCleanup(repo.abort_write_group)
35
def read_bytes(self, chk_bytes, key):
36
stream = chk_bytes.get_record_stream([key], 'unordered', True)
37
return stream.next().get_bytes_as("fulltext")
39
def assertHasABMap(self, chk_bytes):
40
root_key = ('sha1:5c464bbd8fecba1aa2574c6d2eb26813d622ce17',)
42
"chkroot:\na\x00sha1:cb29f32e561a1b7f862c38ccfd6bc7c7d892f04b\n",
43
self.read_bytes(chk_bytes, root_key))
46
self.read_bytes(chk_bytes,
47
("sha1:cb29f32e561a1b7f862c38ccfd6bc7c7d892f04b",)))
49
def assertHasEmptyMap(self, chk_bytes):
50
root_key = ('sha1:572d8da882e1ebf0f50f1e2da2d7a9cadadf4db5',)
51
self.assertEqual("chkroot:\n", self.read_bytes(chk_bytes, root_key))
53
def test_from_dict_empty(self):
54
chk_bytes = self.get_chk_bytes()
55
root_key = CHKMap.from_dict(chk_bytes, {})
56
self.assertEqual(('sha1:572d8da882e1ebf0f50f1e2da2d7a9cadadf4db5',),
58
self.assertHasEmptyMap(chk_bytes)
60
def test_from_dict_ab(self):
61
chk_bytes = self.get_chk_bytes()
62
root_key = CHKMap.from_dict(chk_bytes, {"a":"b"})
63
self.assertEqual(('sha1:5c464bbd8fecba1aa2574c6d2eb26813d622ce17',),
65
self.assertHasABMap(chk_bytes)
67
def test_apply_empty_ab(self):
68
# applying a delta (None, "a", "b") to an empty chkmap generates the
69
# same map as from_dict_ab.
70
chk_bytes = self.get_chk_bytes()
71
root_key = CHKMap.from_dict(chk_bytes, {})
72
chkmap = CHKMap(chk_bytes, root_key)
73
new_root = chkmap.apply_delta([(None, "a", "b")])
74
self.assertEqual(('sha1:5c464bbd8fecba1aa2574c6d2eb26813d622ce17',),
76
self.assertHasABMap(chk_bytes)
77
# The update should have left us with an in memory root node, with an
79
self.assertEqual(new_root, chkmap._root_node._key)
81
def test_apply_ab_empty(self):
82
# applying a delta ("a", None, None) to an empty chkmap generates the
83
# same map as from_dict_ab.
84
chk_bytes = self.get_chk_bytes()
85
root_key = CHKMap.from_dict(chk_bytes, {"a":"b"})
86
chkmap = CHKMap(chk_bytes, root_key)
87
new_root = chkmap.apply_delta([("a", None, None)])
88
self.assertEqual(('sha1:572d8da882e1ebf0f50f1e2da2d7a9cadadf4db5',),
90
self.assertHasEmptyMap(chk_bytes)
91
# The update should have left us with an in memory root node, with an
93
self.assertEqual(new_root, chkmap._root_node._key)
95
def test_iteritems_empty(self):
96
chk_bytes = self.get_chk_bytes()
97
root_key = CHKMap.from_dict(chk_bytes, {})
98
chkmap = CHKMap(chk_bytes, root_key)
99
self.assertEqual([], list(chkmap.iteritems()))
101
def test_iteritems_two_items(self):
102
chk_bytes = self.get_chk_bytes()
103
root_key = CHKMap.from_dict(chk_bytes,
104
{"a":"content here", "b":"more content"})
105
chkmap = CHKMap(chk_bytes, root_key)
106
self.assertEqual([("a", "content here"), ("b", "more content")],
107
sorted(list(chkmap.iteritems())))
110
class TestRootNode(TestCaseWithTransport):
112
def test_serialise_empty(self):
114
bytes = node.serialise()
115
self.assertEqual("chkroot:\n", bytes)
117
def test_add_child_resets_key(self):
119
node._key = ("something",)
120
node.add_child("c", ("sha1:1234",))
121
self.assertEqual(None, node._key)
123
def test_remove_child_removes_child(self):
125
node.add_child("a", ("sha1:4321",))
126
node.add_child("c", ("sha1:1234",))
127
node._key = ("something",)
128
node.remove_child("a")
129
self.assertEqual({"c":("sha1:1234",)}, node._nodes)
131
def test_remove_child_resets_key(self):
133
node.add_child("c", ("sha1:1234",))
134
node._key = ("something",)
135
node.remove_child("c")
136
self.assertEqual(None, node._key)
138
def test_deserialise(self):
139
# deserialising from a bytestring & key sets the nodes and the known
142
node.deserialise("chkroot:\nc\x00sha1:1234\n", ("foo",))
143
self.assertEqual({"c": ("sha1:1234",)}, node._nodes)
144
self.assertEqual(("foo",), node._key)
146
def test_serialise_with_child(self):
148
node.add_child("c", ("sha1:1234",))
149
bytes = node.serialise()
150
self.assertEqual("chkroot:\nc\x00sha1:1234\n", bytes)
153
class TestValueNode(TestCaseWithTransport):
155
def test_deserialise(self):
156
node = ValueNode.deserialise("chkvalue:\nfoo bar baz\n")
157
self.assertEqual("foo bar baz\n", node.value)
159
def test_serialise(self):
160
node = ValueNode("b")
161
bytes = node.serialise()
162
self.assertEqual("chkvalue:\nb", bytes)