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_bug001.py
30#       Regression tests.
31
32import wiredtiger, wttest
33
34# Regression tests.
35class test_bug001(wttest.WiredTigerTestCase):
36
37    def create_implicit(self, uri, initial, middle, trailing):
38        self.session.create(uri, 'key_format=r,value_format=8t')
39        cursor = self.session.open_cursor(uri, None)
40
41        # Create a set of initial implicit records, followed by a set of real
42        # records, followed by a set of trailing implicit records.
43        r = initial
44        for i in range(0, middle):
45            r += 1
46            cursor[r] = 0xab
47        r += trailing
48        cursor[r + 1] = 0xbb
49        return (cursor)
50
51    # Test a bug where cursor movement inside implicit records failed.
52    def test_implicit_record_cursor_movement(self):
53        uri = 'file:xxx'
54        cursor = self.create_implicit(uri, 0, 50, 20)
55
56        # Check search inside trailing implicit keys.
57        for i in range(0, 5):
58            self.assertEqual(cursor[60 + i], 0x00)
59
60        # Check cursor next inside trailing implicit keys.
61        cursor.set_key(60)
62        self.assertEquals(cursor.search(), 0)
63        for i in range(0, 5):
64            self.assertEqual(cursor.get_key(), 60 + i)
65            self.assertEqual(cursor.get_value(), 0x00)
66            self.assertEqual(cursor.next(), 0)
67
68        # Check cursor prev inside trailing implicit keys.
69        cursor.set_key(60)
70        self.assertEquals(cursor.search(), 0)
71        for i in range(0, 5):
72            self.assertEqual(cursor.get_key(), 60 - i)
73            self.assertEqual(cursor.get_value(), 0x00)
74            self.assertEqual(cursor.prev(), 0)
75
76        self.assertEquals(cursor.close(), 0)
77        self.session.drop(uri)
78        cursor = self.create_implicit(uri, 20, 50, 0)
79
80        # Check search inside leading implicit keys.
81        for i in range(0, 5):
82            self.assertEqual(cursor[10 + i], 0x00)
83
84        # Check cursor next inside leading implicit keys.
85        cursor.set_key(10)
86        self.assertEquals(cursor.search(), 0)
87        for i in range(0, 5):
88            self.assertEqual(cursor.get_key(), 10 + i)
89            self.assertEqual(cursor.get_value(), 0x00)
90            self.assertEqual(cursor.next(), 0)
91
92        # Check cursor prev inside leading implicit keys.
93        cursor.set_key(10)
94        self.assertEquals(cursor.search(), 0)
95        for i in range(0, 5):
96            self.assertEqual(cursor.get_key(), 10 - i)
97            self.assertEqual(cursor.get_value(), 0x00)
98            self.assertEqual(cursor.prev(), 0)
99
100        self.assertEquals(cursor.close(), 0)
101        self.session.drop(uri)
102
103    # Test a bug where cursor remove inside implicit records looped infinitely.
104    def test_implicit_record_cursor_remove(self):
105        uri='file:xxx'
106        cursor = self.create_implicit(uri, 0, 50, 20)
107
108        # Check cursor next/remove inside trailing implicit keys.
109        cursor.set_key(62)
110        self.assertEquals(cursor.search(), 0)
111        for i in range(1, 5):
112            self.assertEquals(cursor.next(), 0)
113            self.assertEqual(cursor.get_key(), 62 + i)
114            self.assertEqual(cursor.get_value(), 0x00)
115            self.assertEquals(cursor.remove(), 0)
116
117        # Check cursor prev/remove inside trailing implicit keys.
118        cursor.set_key(68)
119        self.assertEquals(cursor.search(), 0)
120        for i in range(1, 5):
121            self.assertEquals(cursor.prev(), 0)
122            self.assertEqual(cursor.get_key(), 68 - i)
123            self.assertEqual(cursor.get_value(), 0x00)
124            self.assertEquals(cursor.remove(), 0)
125
126        self.assertEquals(cursor.close(), 0)
127        self.session.drop(uri)
128        cursor = self.create_implicit(uri, 20, 50, 0)
129
130        # Check cursor next/remove inside leading implicit keys.
131        cursor.set_key(2)
132        self.assertEquals(cursor.search(), 0)
133        for i in range(1, 5):
134            self.assertEquals(cursor.next(), 0)
135            self.assertEqual(cursor.get_key(), 2 + i)
136            self.assertEqual(cursor.get_value(), 0x00)
137            self.assertEquals(cursor.remove(), 0)
138
139        # Check cursor prev/remove inside leading implicit keys.
140        cursor.set_key(18)
141        self.assertEquals(cursor.search(), 0)
142        for i in range(1, 5):
143            self.assertEquals(cursor.prev(), 0)
144            self.assertEqual(cursor.get_key(), 18 - i)
145            self.assertEqual(cursor.get_value(), 0x00)
146            self.assertEquals(cursor.remove(), 0)
147
148        self.assertEquals(cursor.close(), 0)
149        self.session.drop(uri)
150
151if __name__ == '__main__':
152    wttest.run()
153