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 30import glob, os, shutil, string, subprocess 31import wiredtiger 32 33from wtdataset import SimpleDataSet, SimpleIndexDataSet, ComplexDataSet 34 35# python has a filecmp.cmp function, but different versions of python approach 36# file comparison differently. To make sure we get byte for byte comparison, 37# we define it here. 38def compare_files(self, filename1, filename2): 39 self.pr('compare_files: ' + filename1 + ', ' + filename2) 40 bufsize = 4096 41 if os.path.getsize(filename1) != os.path.getsize(filename2): 42 print 'file comparison failed: ' + filename1 + ' size ' +\ 43 str(os.path.getsize(filename1)) + ' != ' + filename2 +\ 44 ' size ' + str(os.path.getsize(filename2)) 45 return False 46 with open(filename1, "rb") as fp1: 47 with open(filename2, "rb") as fp2: 48 while True: 49 b1 = fp1.read(bufsize) 50 b2 = fp2.read(bufsize) 51 if b1 != b2: 52 return False 53 # files are identical size 54 if not b1: 55 return True 56 57# Iterate over a set of tables, ensuring that they have identical contents 58def compare_tables(self, session, uris, config=None): 59 cursors = list() 60 for next_uri in uris: 61 cursors.append(session.open_cursor(next_uri, None, config)) 62 63 try: 64 done = False 65 while not done: 66 keys = list() 67 for next_cursor in cursors: 68 if (next_cursor.next() == wiredtiger.WT_NOTFOUND): 69 done = True 70 break 71 keys.append(next_cursor.get_value()) 72 match = all(x == keys[0] for x in keys) 73 if not match: 74 return False 75 76 return True 77 finally: 78 for c in cursors: 79 c.close() 80 81# confirm a URI doesn't exist. 82def confirm_does_not_exist(self, uri): 83 self.pr('confirm_does_not_exist: ' + uri) 84 self.assertRaises(wiredtiger.WiredTigerError, 85 lambda: self.session.open_cursor(uri, None)) 86 self.assertEqual(glob.glob('*' + uri.split(":")[-1] + '*'), [], 87 'confirm_does_not_exist: URI exists, file name matching \"' + 88 uri.split(":")[1] + '\" found') 89 90# confirm a URI exists and is empty. 91def confirm_empty(self, uri): 92 self.pr('confirm_empty: ' + uri) 93 cursor = self.session.open_cursor(uri, None) 94 if cursor.value_format == '8t': 95 for key,val in cursor: 96 self.assertEqual(val, 0) 97 else: 98 self.assertEqual(cursor.next(), wiredtiger.WT_NOTFOUND) 99 cursor.close() 100 101# copy a WT home directory 102def copy_wiredtiger_home(olddir, newdir, aligned=True): 103 # unaligned copy requires 'dd', which may not be available on Windows 104 if not aligned and os.name == "nt": 105 raise AssertionError( 106 'copy_wiredtiger_home: unaligned copy impossible on Windows') 107 shutil.rmtree(newdir, ignore_errors=True) 108 os.mkdir(newdir) 109 for fname in os.listdir(olddir): 110 fullname = os.path.join(olddir, fname) 111 # Skip lock file, on Windows it is locked. 112 # Skip temporary log files. 113 if os.path.isfile(fullname) and "WiredTiger.lock" not in fullname and \ 114 "WiredTigerTmplog" not in fullname and \ 115 "WiredTigerPreplog" not in fullname: 116 # Use a dd command that does not align on a block boundary. 117 if aligned: 118 shutil.copy(fullname, newdir) 119 else: 120 fullname = os.path.join(olddir, fname) 121 inpf = 'if=' + fullname 122 outf = 'of=' + newdir + '/' + fullname 123 cmd_list = ['dd', inpf, outf, 'bs=300'] 124 a = subprocess.Popen(cmd_list) 125 a.wait() 126