]> arthur.barton.de Git - bup.git/blob - lib/bup/t/thashsplit.py
Use absolute_import from the __future__ everywhere
[bup.git] / lib / bup / t / thashsplit.py
1
2 from __future__ import absolute_import
3 from io import BytesIO
4
5 from wvtest import *
6
7 from bup import hashsplit, _helpers, helpers
8 from buptest import no_lingering_errors
9
10
11 def nr_regions(x, max_count=None):
12     return list(hashsplit._nonresident_page_regions(bytearray(x), 1, max_count))
13
14
15 @wvtest
16 def test_nonresident_page_regions():
17     with no_lingering_errors():
18         WVPASSEQ(nr_regions([]), [])
19         WVPASSEQ(nr_regions([1]), [])
20         WVPASSEQ(nr_regions([0]), [(0, 1)])
21         WVPASSEQ(nr_regions([1, 0]), [(1, 1)])
22         WVPASSEQ(nr_regions([0, 0]), [(0, 2)])
23         WVPASSEQ(nr_regions([1, 0, 1]), [(1, 1)])
24         WVPASSEQ(nr_regions([1, 0, 0]), [(1, 2)])
25         WVPASSEQ(nr_regions([0, 1, 0]), [(0, 1), (2, 1)])
26         WVPASSEQ(nr_regions([0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0]),
27                  [(0, 2), (5, 3), (9, 2)])
28         WVPASSEQ(nr_regions([2, 42, 3, 101]), [(0, 2)])
29         # Test limit
30         WVPASSEQ(nr_regions([0, 0, 0], None), [(0, 3)])
31         WVPASSEQ(nr_regions([0, 0, 0], 1), [(0, 1), (1, 1), (2, 1)])
32         WVPASSEQ(nr_regions([0, 0, 0], 2), [(0, 2), (2, 1)])
33         WVPASSEQ(nr_regions([0, 0, 0], 3), [(0, 3)])
34         WVPASSEQ(nr_regions([0, 0, 0], 4), [(0, 3)])
35         WVPASSEQ(nr_regions([0, 0, 1], None), [(0, 2)])
36         WVPASSEQ(nr_regions([0, 0, 1], 1), [(0, 1), (1, 1)])
37         WVPASSEQ(nr_regions([0, 0, 1], 2), [(0, 2)])
38         WVPASSEQ(nr_regions([0, 0, 1], 3), [(0, 2)])
39         WVPASSEQ(nr_regions([1, 0, 0], None), [(1, 2)])
40         WVPASSEQ(nr_regions([1, 0, 0], 1), [(1, 1), (2, 1)])
41         WVPASSEQ(nr_regions([1, 0, 0], 2), [(1, 2)])
42         WVPASSEQ(nr_regions([1, 0, 0], 3), [(1, 2)])
43         WVPASSEQ(nr_regions([1, 0, 0, 0, 1], None), [(1, 3)])
44         WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 1), [(1, 1), (2, 1), (3, 1)])
45         WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 2), [(1, 2), (3, 1)])
46         WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 3), [(1, 3)])
47         WVPASSEQ(nr_regions([1, 0, 0, 0, 1], 4), [(1, 3)])
48
49
50 @wvtest
51 def test_uncache_ours_upto():
52     history = []
53     def mock_fadvise_pages_done(f, ofs, len):
54         history.append((f, ofs, len))
55
56     with no_lingering_errors():
57         uncache_upto = hashsplit._uncache_ours_upto
58         page_size = helpers.sc_page_size
59         orig_pages_done = hashsplit._fadvise_pages_done
60         try:
61             hashsplit._fadvise_pages_done = mock_fadvise_pages_done
62             history = []
63             uncache_upto(42, 0, (0, 1), iter([]))
64             WVPASSEQ([], history)
65             uncache_upto(42, page_size, (0, 1), iter([]))
66             WVPASSEQ([(42, 0, 1)], history)
67             history = []
68             uncache_upto(42, page_size, (0, 3), iter([(5, 2)]))
69             WVPASSEQ([], history)
70             uncache_upto(42, 2 * page_size, (0, 3), iter([(5, 2)]))
71             WVPASSEQ([], history)
72             uncache_upto(42, 3 * page_size, (0, 3), iter([(5, 2)]))
73             WVPASSEQ([(42, 0, 3)], history)
74             history = []
75             uncache_upto(42, 5 * page_size, (0, 3), iter([(5, 2)]))
76             WVPASSEQ([(42, 0, 3)], history)
77             history = []
78             uncache_upto(42, 6 * page_size, (0, 3), iter([(5, 2)]))
79             WVPASSEQ([(42, 0, 3)], history)
80             history = []
81             uncache_upto(42, 7 * page_size, (0, 3), iter([(5, 2)]))
82             WVPASSEQ([(42, 0, 3), (42, 5, 2)], history)
83         finally:
84             hashsplit._fadvise_pages_done = orig_pages_done
85
86
87 @wvtest
88 def test_rolling_sums():
89     with no_lingering_errors():
90         WVPASS(_helpers.selftest())
91
92 @wvtest
93 def test_fanout_behaviour():
94
95     # Drop in replacement for bupsplit, but splitting if the int value of a
96     # byte >= BUP_BLOBBITS
97     basebits = _helpers.blobbits()
98     def splitbuf(buf):
99         ofs = 0
100         for c in buf:
101             ofs += 1
102             if ord(c) >= basebits:
103                 return ofs, ord(c)
104         return 0, 0
105
106     with no_lingering_errors():
107         old_splitbuf = _helpers.splitbuf
108         _helpers.splitbuf = splitbuf
109         old_BLOB_MAX = hashsplit.BLOB_MAX
110         hashsplit.BLOB_MAX = 4
111         old_BLOB_READ_SIZE = hashsplit.BLOB_READ_SIZE
112         hashsplit.BLOB_READ_SIZE = 10
113         old_fanout = hashsplit.fanout
114         hashsplit.fanout = 2
115
116         levels = lambda f: [(len(b), l) for b, l in
117             hashsplit.hashsplit_iter([f], True, None)]
118         # Return a string of n null bytes
119         z = lambda n: '\x00' * n
120         # Return a byte which will be split with a level of n
121         sb = lambda n: chr(basebits + n)
122
123         split_never = BytesIO(z(16))
124         split_first = BytesIO(z(1) + sb(3) + z(14))
125         split_end   = BytesIO(z(13) + sb(1) + z(2))
126         split_many  = BytesIO(sb(1) + z(3) + sb(2) + z(4) +
127                               sb(0) + z(4) + sb(5) + z(1))
128         WVPASSEQ(levels(split_never), [(4, 0), (4, 0), (4, 0), (4, 0)])
129         WVPASSEQ(levels(split_first), [(2, 3), (4, 0), (4, 0), (4, 0), (2, 0)])
130         WVPASSEQ(levels(split_end), [(4, 0), (4, 0), (4, 0), (2, 1), (2, 0)])
131         WVPASSEQ(levels(split_many),
132             [(1, 1), (4, 2), (4, 0), (1, 0), (4, 0), (1, 5), (1, 0)])
133
134         _helpers.splitbuf = old_splitbuf
135         hashsplit.BLOB_MAX = old_BLOB_MAX
136         hashsplit.BLOB_READ_SIZE = old_BLOB_READ_SIZE
137         hashsplit.fanout = old_fanout