1
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
1
# Copyright (C) 2008-2011, 2016 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for maps built on a CHK versionedfiles facility."""
19
from itertools import izip
28
from bzrlib.chk_map import (
26
from ..chk_map import (
34
from bzrlib.static_tuple import StaticTuple
32
from ..static_tuple import StaticTuple
37
35
class TestNode(tests.TestCase):
42
40
self.assertTrue(len(common) <= len(key))
43
41
self.assertStartsWith(prefix, common)
44
42
self.assertStartsWith(key, common)
45
self.assertEquals(expected_common, common)
43
self.assertEqual(expected_common, common)
47
45
def test_common_prefix(self):
48
46
self.assertCommonPrefix('beg', 'beg', 'begin')
226
224
" ('ddd',) 'initial ddd content'\n",
227
225
c_map._dump_tree())
229
def test_one_deep_map_16(self):
227
def test_root_only_aaa_ddd_16(self):
230
228
c_map = self.make_root_only_aaa_ddd_map(
231
229
search_key_func=chk_map._search_key_16)
232
230
# We use 'aaa' and 'ddd' because they happen to map to 'F' when using
380
378
# Leaf nodes must have identical contents
381
379
self.assertEqual(node_one._items, node_two._items)
382
self.assertEquals([], node_two_stack)
380
self.assertEqual([], node_two_stack)
384
382
def assertCanonicalForm(self, chkmap):
385
383
"""Assert that the chkmap is in 'canonical' form.
468
466
self.assertEqual(new_root, chkmap._root_node._key)
468
def test_apply_delete_to_internal_node(self):
469
# applying a delta should be convert an internal root node to a leaf
470
# node if the delta shrinks the map enough.
471
store = self.get_chk_bytes()
472
chkmap = CHKMap(store, None)
473
# Add three items: 2 small enough to fit in one node, and one huge to
474
# force multiple nodes.
475
chkmap._root_node.set_maximum_size(100)
476
chkmap.map(('small',), 'value')
477
chkmap.map(('little',), 'value')
478
chkmap.map(('very-big',), 'x' * 100)
479
# (Check that we have constructed the scenario we want to test)
480
self.assertIsInstance(chkmap._root_node, InternalNode)
481
# Delete the huge item so that the map fits in one node again.
482
delta = [(('very-big',), None, None)]
483
chkmap.apply_delta(delta)
484
self.assertCanonicalForm(chkmap)
485
self.assertIsInstance(chkmap._root_node, LeafNode)
470
487
def test_apply_new_keys_must_be_new(self):
471
488
# applying a delta (None, "a", "b") to a map with 'a' in it generates
1091
1108
basis_get = basis._store.get_record_stream
1092
1109
def get_record_stream(keys, order, fulltext):
1093
1110
if ('sha1:1adf7c0d1b9140ab5f33bb64c6275fa78b1580b7',) in keys:
1094
self.fail("'aaa' pointer was followed %r" % keys)
1111
raise AssertionError("'aaa' pointer was followed %r" % keys)
1095
1112
return basis_get(keys, order, fulltext)
1096
1113
basis._store.get_record_stream = get_record_stream
1097
1114
result = sorted(list(target.iter_changes(basis)))
1567
1584
prefix, result = list(node.map(None, ("blue",), "red"))
1568
1585
self.assertEqual("", prefix)
1569
1586
self.assertEqual(2, len(result))
1570
split_chars = set([result[0][0], result[1][0]])
1571
self.assertEqual(set(["f", "b"]), split_chars)
1587
split_chars = {result[0][0], result[1][0]}
1588
self.assertEqual({"f", "b"}, split_chars)
1572
1589
nodes = dict(result)
1573
1590
node = nodes["f"]
1574
1591
self.assertEqual({("foo bar",): "baz quux"}, self.to_dict(node, None))
1902
1919
# Ensure test validity: nothing paged in below the root.
1903
1920
self.assertEqual(2,
1904
1921
len([value for value in node._items.values()
1905
if type(value) is StaticTuple]))
1922
if isinstance(value, StaticTuple)]))
1906
1923
# now, mapping to k3 should add a k3 leaf
1907
1924
prefix, nodes = node.map(None, ('k3',), 'quux')
1908
1925
self.assertEqual("k", prefix)
1941
1958
# Ensure test validity: nothing paged in below the root.
1942
1959
self.assertEqual(2,
1943
1960
len([value for value in node._items.values()
1944
if type(value) is StaticTuple]))
1961
if isinstance(value, StaticTuple)]))
1945
1962
# now, mapping to k23 causes k22 ('k2' in node) to split into k22 and
1946
1963
# k23, which for simplicity in the current implementation generates
1947
1964
# a new internal node between node, and k22/k23.
2124
2141
c_map.map(('aaa',), 'new aaa content')
2125
2142
key2 = c_map._save()
2126
2143
diff = self.get_difference([key2], [key1])
2127
self.assertEqual(set([key1]), diff._all_old_chks)
2144
self.assertEqual({key1}, diff._all_old_chks)
2128
2145
self.assertEqual([], diff._old_queue)
2129
2146
self.assertEqual([], diff._new_queue)