1560
1565
child.map(None, ("baz",), "val")
1561
1566
node.add_node("b", child)
1563
key_filter = (('foo',), ('fob',), ('bar',), ('baz',))
1568
# Note that 'ram' doesn't match anything, so it should be freely
1570
key_filter = (('foo',), ('fob',), ('bar',), ('baz',), ('ram',))
1564
1571
for child, node_key_filter in node._iter_nodes(None,
1565
1572
key_filter=key_filter):
1566
# each child could matches two key filters, so make sure they were
1573
# each child could match two key filters, so make sure they were
1567
1574
# both included.
1568
1575
self.assertEqual(2, len(node_key_filter))
1577
def make_fo_fa_node(self):
1578
node = InternalNode('f')
1580
child.set_maximum_size(100)
1581
child.map(None, ("foo",), "val")
1582
child.map(None, ("fob",), "val")
1583
node.add_node('fo', child)
1585
child.set_maximum_size(100)
1586
child.map(None, ("far",), "val")
1587
child.map(None, ("faz",), "val")
1588
node.add_node("fa", child)
1591
def test__iter_nodes_single_entry(self):
1592
node = self.make_fo_fa_node()
1593
key_filter = [('foo',)]
1594
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1595
self.assertEqual(1, len(nodes))
1596
self.assertEqual(key_filter, nodes[0][1])
1598
def test__iter_nodes_single_entry_misses(self):
1599
node = self.make_fo_fa_node()
1600
key_filter = [('bar',)]
1601
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1602
self.assertEqual(0, len(nodes))
1604
def test__iter_nodes_mixed_key_width(self):
1605
node = self.make_fo_fa_node()
1606
key_filter = [('foo', 'bar'), ('foo',), ('fo',), ('b',)]
1607
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1608
self.assertEqual(1, len(nodes))
1609
matches = key_filter[:]
1610
matches.remove(('b',))
1611
self.assertEqual(sorted(matches), sorted(nodes[0][1]))
1613
def test__iter_nodes_match_all(self):
1614
node = self.make_fo_fa_node()
1615
key_filter = [('foo', 'bar'), ('foo',), ('fo',), ('f',)]
1616
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1617
self.assertEqual(2, len(nodes))
1619
def test__iter_nodes_fixed_widths_and_misses(self):
1620
node = self.make_fo_fa_node()
1621
# foo and faa should both match one child, baz should miss
1622
key_filter = [('foo',), ('faa',), ('baz',)]
1623
nodes = list(node._iter_nodes(None, key_filter=key_filter))
1624
self.assertEqual(2, len(nodes))
1625
for node, matches in nodes:
1626
self.assertEqual(1, len(matches))
1570
1628
def test_iteritems_empty_new(self):
1571
1629
node = InternalNode()
1572
1630
self.assertEqual([], sorted(node.iteritems(None)))
2060
2118
(aac_key, [(('aac',), 'target1')]),
2061
2119
(bba_key, [(('bba',), 'target2')]),
2062
2120
], [target1, target2], [basis1, basis2])
2122
def test_multiple_maps_overlapping_common_new(self):
2123
# Test that when a node found through the interesting_keys iteration
2124
# for *some roots* and also via the uninteresting keys iteration, that
2125
# it is still scanned for uninteresting refs and items, because its
2126
# not truely new. This requires 2 levels of InternalNodes to expose,
2127
# because of the way the bootstrap in _find_children_info works.
2128
# This suggests that the code is probably amenable to/benefit from
2130
# How does this test work?
2131
# 1) We need a second level InternalNode present in a basis tree.
2132
# 2) We need a left side new tree that uses that InternalNode
2133
# 3) We need a right side new tree that does not use that InternalNode
2134
# at all but that has an unchanged *value* that was reachable inside
2136
basis = self.get_map_key({
2137
# InternalNode, unchanged in left:
2140
# Forces an internalNode at 'a'
2143
left = self.get_map_key({
2144
# All of basis unchanged
2148
# And a new top level node so the root key is different
2151
right = self.get_map_key({
2152
# A value that is unchanged from basis and thus should be filtered
2156
basis_map = CHKMap(self.get_chk_bytes(), basis)
2157
self.assertEqualDiff(
2159
" 'a' InternalNode\n"
2161
" ('aaa',) 'left'\n"
2163
" ('abb',) 'right'\n"
2165
" ('ccc',) 'common'\n",
2166
basis_map._dump_tree())
2167
# Get left expected data
2168
left_map = CHKMap(self.get_chk_bytes(), left)
2169
self.assertEqualDiff(
2171
" 'a' InternalNode\n"
2173
" ('aaa',) 'left'\n"
2175
" ('abb',) 'right'\n"
2177
" ('ccc',) 'common'\n"
2179
" ('ddd',) 'change'\n",
2180
left_map._dump_tree())
2181
# Keys from left side target
2182
l_d_key = left_map._root_node._items['d'].key()
2183
# Get right expected data
2184
right_map = CHKMap(self.get_chk_bytes(), right)
2185
self.assertEqualDiff(
2187
" ('abb',) 'right'\n",
2188
right_map._dump_tree())
2189
# Keys from the right side target - none, the root is enough.
2191
self.expectFailure("we don't properly filter different depths",
2192
self.assertIterInteresting,
2195
(l_d_key, [(('ddd',), 'change')]),
2196
], [left, right], [basis])
2197
self.assertIterInteresting(
2200
(l_d_key, [(('ddd',), 'change')]),
2201
], [left, right], [basis])
2203
def test_multiple_maps_similar(self):
2204
# We want to have a depth=2 tree, with multiple entries in each leaf
2206
basis = self.get_map_key({
2207
('aaa',): 'unchanged',
2208
('abb',): 'will change left',
2209
('caa',): 'unchanged',
2210
('cbb',): 'will change right',
2212
left = self.get_map_key({
2213
('aaa',): 'unchanged',
2214
('abb',): 'changed left',
2215
('caa',): 'unchanged',
2216
('cbb',): 'will change right',
2218
right = self.get_map_key({
2219
('aaa',): 'unchanged',
2220
('abb',): 'will change left',
2221
('caa',): 'unchanged',
2222
('cbb',): 'changed right',
2224
basis_map = CHKMap(self.get_chk_bytes(), basis)
2225
self.assertEqualDiff(
2228
" ('aaa',) 'unchanged'\n"
2229
" ('abb',) 'will change left'\n"
2231
" ('caa',) 'unchanged'\n"
2232
" ('cbb',) 'will change right'\n",
2233
basis_map._dump_tree())
2234
# Get left expected data
2235
left_map = CHKMap(self.get_chk_bytes(), left)
2236
self.assertEqualDiff(
2239
" ('aaa',) 'unchanged'\n"
2240
" ('abb',) 'changed left'\n"
2242
" ('caa',) 'unchanged'\n"
2243
" ('cbb',) 'will change right'\n",
2244
left_map._dump_tree())
2245
# Keys from left side target
2246
l_a_key = left_map._root_node._items['a'].key()
2247
l_c_key = left_map._root_node._items['c'].key()
2248
# Get right expected data
2249
right_map = CHKMap(self.get_chk_bytes(), right)
2250
self.assertEqualDiff(
2253
" ('aaa',) 'unchanged'\n"
2254
" ('abb',) 'will change left'\n"
2256
" ('caa',) 'unchanged'\n"
2257
" ('cbb',) 'changed right'\n",
2258
right_map._dump_tree())
2259
r_a_key = right_map._root_node._items['a'].key()
2260
r_c_key = right_map._root_node._items['c'].key()
2261
self.assertIterInteresting(
2264
(l_a_key, [(('abb',), 'changed left')]),
2265
(r_c_key, [(('cbb',), 'changed right')]),
2266
], [left, right], [basis])