1#!/usr/bin/env python
2#
3# Public Domain 2014-2018 MongoDB, Inc.
4# Public Domain 2008-2014 WiredTiger, Inc.
5#
6# This is free and unencumbered software released into the public domain.
7#
8# Anyone is free to copy, modify, publish, use, compile, sell, or
9# distribute this software, either in source code form or as a compiled
10# binary, for any purpose, commercial or non-commercial, and by any
11# means.
12#
13# In jurisdictions that recognize copyright laws, the author or authors
14# of this software dedicate any and all copyright interest in the
15# software to the public domain. We make this dedication for the benefit
16# of the public at large and to the detriment of our heirs and
17# successors. We intend this dedication to be an overt act of
18# relinquishment in perpetuity of all present and future rights to this
19# software under copyright law.
20#
21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27# OTHER DEALINGS IN THE SOFTWARE.
28#
29# test_bug021.py
30#       Fixed-length column store implicit record operations test.
31
32import wiredtiger, wttest
33
34# Fixed-length column store implicit record operations test.
35class test_bug021(wttest.WiredTigerTestCase):
36    uri = 'file:test_bug021'
37
38    def create_implicit(self, initial, middle, trailing):
39        self.session.create(self.uri, 'key_format=r,value_format=8t')
40        cursor = self.session.open_cursor(self.uri, None)
41
42        # Create a set of initial implicit records, followed by a set of real
43        # records, followed by a set of trailing implicit records.
44        expected = [0] * (initial + middle + trailing + 2)
45        expected[0] = None
46        r = 0
47        for i in range(initial):
48            r += 1
49            expected[r] = 0x00
50        for i in range(middle):
51            r += 1
52            cursor[r] = expected[r] = 0xab
53        r += trailing
54        cursor[r + 1] = expected[r + 1] = 0xab
55        return (cursor, expected)
56
57    def check(self, expected):
58        c = self.session.open_cursor(self.uri, None)
59        actual = [None] * len(expected)
60        for k, v in c:
61                actual[k] = v
62        c.close()
63
64        if actual != expected:
65            print 'expected: ', expected
66            print '  actual: ', actual
67        self.assertEqual(expected, actual)
68
69    def test_implicit_record_cursor_insert_next(self):
70        cursor, current = self.create_implicit(0, 50, 20)
71        self.check(current)
72
73        # Check cursor next/operation inside trailing implicit keys.
74        cursor.set_key(62)
75        self.assertEquals(cursor.search(), 0)
76        self.assertEquals(cursor.next(), 0)
77        self.assertEquals(cursor.next(), 0)
78        cursor.set_value(3)
79        self.assertEquals(cursor.insert(), 0)
80        current[62 + 2] = 3
81        self.check(current)
82
83        # Check cursor prev/operation inside trailing implicit keys.
84        cursor.set_key(68)
85        self.assertEquals(cursor.search(), 0)
86        self.assertEquals(cursor.prev(), 0)
87        self.assertEquals(cursor.prev(), 0)
88        cursor.set_value(7)
89        self.assertEquals(cursor.insert(), 0)
90        current[68 - 2] = 7
91
92    def test_implicit_record_cursor_insert_prev(self):
93        cursor, current = self.create_implicit(20, 50, 0)
94        self.check(current)
95
96        # Check cursor next/operation inside leading implicit keys.
97        cursor.set_key(2)
98        self.assertEquals(cursor.search(), 0)
99        self.assertEquals(cursor.next(), 0)
100        self.assertEquals(cursor.next(), 0)
101        cursor.set_value(3)
102        self.assertEquals(cursor.insert(), 0)
103        current[2 + 2] = 3
104        self.check(current)
105
106        # Check cursor prev/operation inside leading implicit keys.
107        cursor.set_key(18)
108        self.assertEquals(cursor.search(), 0)
109        self.assertEquals(cursor.prev(), 0)
110        self.assertEquals(cursor.prev(), 0)
111        cursor.set_value(7)
112        self.assertEquals(cursor.insert(), 0)
113        current[18 - 2] = 7
114        self.check(current)
115
116    def test_implicit_record_cursor_remove_next(self):
117        cursor, current = self.create_implicit(0, 50, 20)
118        self.check(current)
119
120        # Check cursor next/operation inside trailing implicit keys.
121        cursor.set_key(62)
122        self.assertEquals(cursor.search(), 0)
123        for i in range(1, 5):
124            self.assertEquals(cursor.next(), 0)
125            self.assertEquals(cursor.remove(), 0)
126            current[62 + i] = 0
127        self.check(current)
128
129        # Check cursor prev/operation inside trailing implicit keys.
130        cursor.set_key(68)
131        self.assertEquals(cursor.search(), 0)
132        for i in range(1, 5):
133            self.assertEquals(cursor.prev(), 0)
134            self.assertEquals(cursor.remove(), 0)
135            current[68 - i] = 0
136        self.check(current)
137
138    def test_implicit_record_cursor_remove_prev(self):
139        cursor, current = self.create_implicit(20, 50, 0)
140        self.check(current)
141
142        # Check cursor next/operation inside leading implicit keys.
143        cursor.set_key(2)
144        self.assertEquals(cursor.search(), 0)
145        for i in range(1, 5):
146            self.assertEquals(cursor.next(), 0)
147            self.assertEquals(cursor.remove(), 0)
148            current[2 + i] = 0
149        self.check(current)
150
151        # Check cursor prev/operation inside leading implicit keys.
152        cursor.set_key(18)
153        self.assertEquals(cursor.search(), 0)
154        for i in range(1, 5):
155            current[18 - i] = 0
156            self.assertEquals(cursor.prev(), 0)
157            self.assertEquals(cursor.remove(), 0)
158            current[18 - i] = 0
159        self.check(current)
160
161    def test_implicit_record_cursor_update_next(self):
162        cursor, current = self.create_implicit(0, 50, 20)
163        self.check(current)
164
165        # Check cursor next/operation inside trailing implicit keys.
166        cursor.set_key(62)
167        self.assertEquals(cursor.search(), 0)
168        for i in range(1, 5):
169            self.assertEquals(cursor.next(), 0)
170            cursor.set_value(i)
171            self.session.breakpoint()
172            self.assertEquals(cursor.update(), 0)
173            current[62 + i] = i
174        self.check(current)
175
176        # Check cursor prev/operation inside trailing implicit keys.
177        cursor.set_key(68)
178        self.assertEquals(cursor.search(), 0)
179        for i in range(1, 5):
180            self.assertEquals(cursor.prev(), 0)
181            cursor.set_value(i)
182            self.assertEquals(cursor.update(), 0)
183            current[68 - i] = i
184        self.check(current)
185
186    def test_implicit_record_cursor_update_prev(self):
187        cursor, current = self.create_implicit(20, 50, 0)
188        self.check(current)
189
190        # Check cursor next/operation inside leading implicit keys.
191        cursor.set_key(2)
192        self.assertEquals(cursor.search(), 0)
193        for i in range(1, 5):
194            self.assertEquals(cursor.next(), 0)
195            cursor.set_value(i)
196            self.assertEquals(cursor.update(), 0)
197            current[2 + i] = i
198        self.check(current)
199
200        # Check cursor prev/operation inside leading implicit keys.
201        cursor.set_key(18)
202        self.assertEquals(cursor.search(), 0)
203        for i in range(1, 5):
204            current[18 - i] = 0
205            self.assertEquals(cursor.prev(), 0)
206            cursor.set_value(i)
207            self.assertEquals(cursor.update(), 0)
208            current[18 - i] = i
209        self.check(current)
210
211if __name__ == '__main__':
212    wttest.run()
213