summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/test/suite/test_backup01.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/test/suite/test_backup01.py')
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup01.py193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/test/suite/test_backup01.py b/src/third_party/wiredtiger/test/suite/test_backup01.py
new file mode 100644
index 00000000000..f6e9cd87291
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_backup01.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2015 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import glob
+import os
+import shutil
+import string
+from suite_subprocess import suite_subprocess
+import wiredtiger, wttest
+from helper import compare_files,\
+ complex_populate, complex_populate_lsm, simple_populate
+
+# test_backup.py
+# Utilities: wt backup
+# Test backup (both backup cursors and the wt backup command).
+class test_backup(wttest.WiredTigerTestCase, suite_subprocess):
+ dir='backup.dir' # Backup directory name
+
+ pfx = 'test_backup'
+ objs = [
+ ( 'file:' + pfx + '.1', simple_populate, 0),
+ ( 'file:' + pfx + '.2', simple_populate, 0),
+ ('table:' + pfx + '.3', simple_populate, 0),
+ ('table:' + pfx + '.4', simple_populate, 0),
+ ('table:' + pfx + '.5', complex_populate, 0),
+ ('table:' + pfx + '.6', complex_populate, 0),
+ ('table:' + pfx + '.7', complex_populate_lsm, 1),
+ ('table:' + pfx + '.8', complex_populate_lsm, 1),
+ ]
+
+ # Populate a set of objects.
+ def populate(self, skiplsm):
+ for i in self.objs:
+ if i[2]:
+ if skiplsm:
+ continue
+ i[1](self, i[0], 'key_format=S', 100)
+
+ # Compare the original and backed-up files using the wt dump command.
+ def compare(self, uri):
+ self.runWt(['dump', uri], outfilename='orig')
+ self.runWt(['-h', self.dir, 'dump', uri], outfilename='backup')
+ self.assertEqual(True, compare_files(self, 'orig', 'backup'))
+
+ # Test simple backup cursor open/close.
+ def test_cursor_simple(self):
+ cursor = self.session.open_cursor('backup:', None, None)
+ cursor.close()
+
+ # Test you can't have more than one backup cursor open at a time.
+ def test_cursor_single(self):
+ cursor = self.session.open_cursor('backup:', None, None)
+ msg = '/there is already a backup cursor open/'
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.open_cursor('backup:', None, None), msg)
+ cursor.close()
+
+ # Test backup of a database using the wt backup command.
+ def test_backup_database(self):
+ self.populate(0)
+ os.mkdir(self.dir)
+ self.runWt(['backup', self.dir])
+
+ # Make sure all the files were copied.
+ self.runWt(['list'], outfilename='outfile.orig')
+ self.runWt(['-h', self.dir, 'list'], outfilename='outfile.backup')
+ self.assertEqual(
+ True, compare_files(self, 'outfile.orig', 'outfile.backup'))
+
+ # And that the contents are the same.
+ for i in self.objs:
+ self.compare(i[0])
+
+ # Check that a URI doesn't exist, both the meta-data and the file names.
+ def confirmPathDoesNotExist(self, uri):
+ conn = wiredtiger.wiredtiger_open(self.dir)
+ session = conn.open_session()
+ self.assertRaises(wiredtiger.WiredTigerError,
+ lambda: session.open_cursor(uri, None, None))
+ conn.close()
+
+ self.assertEqual(
+ glob.glob(self.dir + '*' + uri.split(":")[1] + '*'), [],
+ 'confirmPathDoesNotExist: URI exists, file name matching \"' +
+ uri.split(":")[1] + '\" found')
+
+ # Backup a set of chosen tables/files using the wt backup command.
+ def backup_table(self, l):
+ # Remove any previous backup directories.
+ shutil.rmtree(self.dir, ignore_errors=True)
+ os.mkdir(self.dir)
+
+ # Build a command line of objects to back up and run wt.
+ o = 'backup'
+ for i in range(0, len(self.objs)):
+ if i in l:
+ o += ' -t ' + self.objs[i][0]
+ o += ' ' + self.dir
+ self.runWt(o.split())
+
+ # Confirm the objects we backed up exist, with correct contents.
+ for i in range(0, len(self.objs)):
+ if i in l:
+ self.compare(self.objs[i][0])
+
+ # Confirm the other objects don't exist.
+ for i in range(0, len(self.objs)):
+ if i not in l:
+ self.confirmPathDoesNotExist(self.objs[i][0])
+
+ # Test backup of database subsets.
+ def test_backup_table(self):
+ self.populate(0)
+ self.backup_table([0,2,4,6])
+ self.backup_table([1,3,5,7])
+ self.backup_table([0,1,2])
+ self.backup_table([3,4,5])
+ self.backup_table([5,6,7])
+
+ # Test cursor reset runs through the list twice.
+ def test_cursor_reset(self):
+ self.populate(0)
+ cursor = self.session.open_cursor('backup:', None, None)
+ i = 0
+ while True:
+ ret = cursor.next()
+ if ret != 0:
+ break
+ i += 1
+ self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
+ total = i * 2
+ cursor.reset()
+ while True:
+ ret = cursor.next()
+ if ret != 0:
+ break
+ i += 1
+ self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
+ self.assertEqual(i, total)
+
+ # Test that named checkpoints can't be deleted while backup cursors are
+ # open, but that normal checkpoints continue to work.
+ def test_checkpoint_delete(self):
+ # You cannot name checkpoints including LSM tables, skip those.
+ self.populate(1)
+
+ # Confirm checkpoints are being deleted.
+ self.session.checkpoint("name=one")
+ self.session.checkpoint("name=two,drop=(one)")
+ self.assertRaises(wiredtiger.WiredTigerError,
+ lambda: self.session.open_cursor(
+ self.objs[0][0], None, "checkpoint=one"))
+
+ # Confirm opening a backup cursor causes checkpoint to fail if dropping
+ # a named checkpoint, but does not stop a default checkpoint.
+ cursor = self.session.open_cursor('backup:', None, None)
+ self.session.checkpoint()
+ msg = '/checkpoints cannot be deleted during a hot backup/'
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.checkpoint("name=three,drop=(two)"), msg)
+ self.session.checkpoint()
+ self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
+ lambda: self.session.checkpoint("name=three,drop=(two)"), msg)
+ self.session.checkpoint()
+ cursor.close()
+
+if __name__ == '__main__':
+ wttest.run()