Files
mongo/test/suite/test_backup01.py
2016-01-04 17:57:02 -05:00

194 lines
7.3 KiB
Python

#!/usr/bin/env python
#
# Public Domain 2014-2016 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 = self.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()