summaryrefslogtreecommitdiff
path: root/test/suite/wttest.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/suite/wttest.py')
-rw-r--r--test/suite/wttest.py229
1 files changed, 229 insertions, 0 deletions
diff --git a/test/suite/wttest.py b/test/suite/wttest.py
new file mode 100644
index 00000000000..1c5f0dabc11
--- /dev/null
+++ b/test/suite/wttest.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2008-2012 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.
+#
+# WiredTigerTestCase
+# parent class for all test cases
+#
+
+import unittest
+import sys
+import os
+import wiredtiger
+import traceback
+import time
+
+def removeAll(top):
+ if not os.path.isdir(top):
+ return
+ for root, dirs, files in os.walk(top, topdown=False):
+ for name in files:
+ os.remove(os.path.join(root, name))
+ for name in dirs:
+ os.rmdir(os.path.join(root, name))
+ os.rmdir(top)
+
+class WiredTigerTestCase(unittest.TestCase):
+ _globalSetup = False
+ _printOnceSeen = {}
+
+ @staticmethod
+ def globalSetup(preserveFiles = False, useTimestamp = False,
+ gdbSub = False, verbose = 1):
+ WiredTigerTestCase._preserveFiles = preserveFiles
+ if useTimestamp:
+ d = 'WT_TEST.' + time.strftime('%Y%m%d-%H%M%S', time.localtime())
+ else:
+ d = 'WT_TEST'
+ removeAll(d)
+ os.makedirs(d)
+ WiredTigerTestCase._parentTestdir = d
+ WiredTigerTestCase._resultfile = open(os.path.join(d, 'results.txt'), "w", 0) # unbuffered
+ WiredTigerTestCase._gdbSubprocess = gdbSub
+ WiredTigerTestCase._verbose = verbose
+ WiredTigerTestCase._globalSetup = True
+
+ def __init__(self, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+ if not self._globalSetup:
+ WiredTigerTestCase.globalSetup()
+
+ def __str__(self):
+ # when running with scenarios, if the number_scenarios() method
+ # is used, then each scenario is given a number, which can
+ # help distinguish tests.
+ scen = ''
+ if hasattr(self, 'scenario_number'):
+ scen = '(scenario ' + str(self.scenario_number) + ')'
+ return self.simpleName() + scen
+
+ def simpleName(self):
+ return "%s.%s.%s" % (self.__module__,
+ self.className(), self._testMethodName)
+
+ # Can be overridden
+ def setUpConnectionOpen(self, dir):
+ conn = wiredtiger.wiredtiger_open(dir, 'create,error_prefix="' +
+ self.shortid() + ': ' + '"')
+ self.pr(`conn`)
+ return conn
+
+ # Can be overridden
+ def setUpSessionOpen(self, conn):
+ return conn.open_session(None)
+
+ # Can be overridden
+ def close_conn(self):
+ """
+ Close the connection if already open.
+ """
+ if self.conn != None:
+ self.conn.close()
+ self.conn = None
+
+ def open_conn(self):
+ """
+ Open the connection if already closed.
+ """
+ if self.conn == None:
+ self.conn = self.setUpConnectionOpen(".")
+ self.session = self.setUpSessionOpen(self.conn)
+
+ def reopen_conn(self):
+ """
+ Reopen the connection.
+ """
+ self.close_conn()
+ self.open_conn()
+
+ def setUp(self):
+ if not hasattr(self.__class__, 'wt_ntests'):
+ self.__class__.wt_ntests = 0
+ self.__class__.wt_ntests += 1
+ self.testdir = os.path.join(WiredTigerTestCase._parentTestdir, self.className() + '.' + str(self.__class__.wt_ntests))
+ if WiredTigerTestCase._verbose > 2:
+ self.prhead('started in ' + self.testdir, True)
+ self.origcwd = os.getcwd()
+ removeAll(self.testdir)
+ if os.path.exists(self.testdir):
+ raise Exception(self.testdir + ": cannot remove directory");
+ os.makedirs(self.testdir)
+ try:
+ os.chdir(self.testdir)
+ self.conn = self.setUpConnectionOpen(".")
+ self.session = self.setUpSessionOpen(self.conn)
+ except:
+ os.chdir(self.origcwd)
+ raise
+
+ def tearDown(self):
+ self.pr('finishing')
+ self.close_conn()
+ os.chdir(self.origcwd)
+ # Clean up unless there's a failure
+ excinfo = sys.exc_info()
+ if excinfo == (None, None, None):
+ if not WiredTigerTestCase._preserveFiles:
+ removeAll(self.testdir)
+ else:
+ self.pr('preserving directory ' + self.testdir)
+ else:
+ self.pr('FAIL')
+ self.prexception(excinfo)
+ self.pr('preserving directory ' + self.testdir)
+ if WiredTigerTestCase._verbose > 2:
+ self.prhead('TEST COMPLETED')
+
+ @staticmethod
+ def printOnce(msg):
+ # There's a race condition with multiple threads,
+ # but we won't worry about it. We err on the side
+ # of printing the message too many times.
+ if not msg in WiredTigerTestCase._printOnceSeen:
+ WiredTigerTestCase._printOnceSeen[msg] = msg
+ print msg
+
+ def KNOWN_FAILURE(self, name):
+ myname = self.simpleName()
+ msg = '**** ' + myname + ' HAS A KNOWN FAILURE: ' + name + ' ****'
+ self.printOnce(msg)
+ self.skipTest('KNOWN FAILURE: ' + name)
+
+ def KNOWN_LIMITATION(self, name):
+ myname = self.simpleName()
+ msg = '**** ' + myname + ' HAS A KNOWN LIMITATION: ' + name + ' ****'
+ self.printOnce(msg)
+
+ @staticmethod
+ def printVerbose(level, message):
+ if level <= WiredTigerTestCase._verbose:
+ print message
+
+ def verbose(self, level, message):
+ WiredTigerTestCase.printVerbose(level, message)
+
+ def pr(self, s):
+ """
+ print a progress line for testing
+ """
+ msg = ' ' + self.shortid() + ': ' + s
+ WiredTigerTestCase._resultfile.write(msg + '\n')
+
+ def prhead(self, s, *beginning):
+ """
+ print a header line for testing, something important
+ """
+ msg = ''
+ if len(beginning) > 0:
+ msg += '\n'
+ msg += ' ' + self.shortid() + ': ' + s
+ print(msg)
+ WiredTigerTestCase._resultfile.write(msg + '\n')
+
+ def prexception(self, excinfo):
+ WiredTigerTestCase._resultfile.write('\n')
+ traceback.print_exception(excinfo[0], excinfo[1], excinfo[2], None, WiredTigerTestCase._resultfile)
+ WiredTigerTestCase._resultfile.write('\n')
+
+ def shortid(self):
+ return self.id().replace("__main__.","")
+
+ def className(self):
+ return self.__class__.__name__
+
+
+def runsuite(suite):
+ try:
+ return unittest.TextTestRunner(
+ verbosity=WiredTigerTestCase._verbose).run(suite)
+ except BaseException as e:
+ # This should not happen for regular test errors, unittest should catch everything
+ print('ERROR: running test: ', e)
+ raise e
+
+def run(name='__main__'):
+ result = runsuite(unittest.TestLoader().loadTestsFromName(name))
+ sys.exit(not result.wasSuccessful())