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_txn10.py
30#   Transactions: commits and rollbacks
31#
32
33import fnmatch, os, shutil, time
34from suite_subprocess import suite_subprocess
35import wttest
36
37class test_txn10(wttest.WiredTigerTestCase, suite_subprocess):
38    t1 = 'table:test_txn10_1'
39    t2 = 'table:test_txn10_2'
40    create_params = 'key_format=i,value_format=i'
41    conn_config = 'log=(archive=false,enabled,file_max=100K),' + \
42                'transaction_sync=(method=dsync,enabled)'
43
44    def simulate_crash_restart(self, olddir, newdir):
45        ''' Simulate a crash from olddir and restart in newdir. '''
46        # with the connection still open, copy files to new directory
47        shutil.rmtree(newdir, ignore_errors=True)
48        os.mkdir(newdir)
49        for fname in os.listdir(olddir):
50            fullname = os.path.join(olddir, fname)
51            # Skip lock file on Windows since it is locked
52            if os.path.isfile(fullname) and \
53                "WiredTiger.lock" not in fullname and \
54                "Tmplog" not in fullname and \
55                "Preplog" not in fullname:
56                shutil.copy(fullname, newdir)
57        # close the original connection and open to new directory
58        self.close_conn()
59        self.conn = self.setUpConnectionOpen(newdir)
60        self.session = self.setUpSessionOpen(self.conn)
61
62    def test_recovery(self):
63        ''' Check for bugs in file ID allocation. '''
64
65        # Here's the strategy:
66        #    - Create a table (t1).
67        #    - Do a clean restart.
68        #    - Create another table (t2).
69        #    - Insert data into t2.
70        #    - Make recovery run.
71        #
72        # If we aren't tracking file IDs properly, it's possible that
73        # we'd end up apply the log records for t2 to table t1.
74        self.session.create(self.t1, self.create_params)
75        self.reopen_conn()
76        self.session.create(self.t2, self.create_params)
77        c = self.session.open_cursor(self.t2, None, None)
78        for i in range(10000):
79            c[i] = i + 1
80        c.close()
81        self.simulate_crash_restart(".", "RESTART")
82        c = self.session.open_cursor(self.t2, None, None)
83        i = 0
84        for key, value in c:
85            self.assertEqual(i, key)
86            self.assertEqual(i+1, value)
87            i += 1
88        self.assertEqual(i, 10000)
89        c.close()
90        c = self.session.open_cursor(self.t1, None, None)
91        i = 0
92        for key, value in c:
93            i += 1
94        self.assertEqual(i, 0)
95        c.close()
96
97if __name__ == '__main__':
98    wttest.run()
99