summaryrefslogtreecommitdiff
path: root/buildscripts
diff options
context:
space:
mode:
authorRichard Kreuter <richard@10gen.com>2010-05-13 16:07:26 -0400
committerRichard Kreuter <richard@10gen.com>2010-05-14 17:01:50 -0400
commit77abb3c61a4113591ae5b766e159d468ac1ee2cf (patch)
treede1f032ce88f7b284970fcd5bc7b36d70a985433 /buildscripts
parent13406e9ac473595cce04168daf3f25fd39f7bd6c (diff)
downloadmongo-77abb3c61a4113591ae5b766e159d468ac1ee2cf.tar.gz
smoke.py: new script for running tests. SERVER-253.
Diffstat (limited to 'buildscripts')
-rw-r--r--buildscripts/smoke.py215
1 files changed, 215 insertions, 0 deletions
diff --git a/buildscripts/smoke.py b/buildscripts/smoke.py
new file mode 100644
index 00000000000..2e4a5525e3c
--- /dev/null
+++ b/buildscripts/smoke.py
@@ -0,0 +1,215 @@
+#!/usr/bin/python
+
+from subprocess import Popen, PIPE, call
+import os
+import sys
+import utils
+import time
+import socket
+from optparse import OptionParser
+
+mongodExecutable = "./mongod"
+mongodPort = "32000"
+shellExecutable = "./mongo"
+continueOnFailure = False
+oneMongodPerTest = False
+
+# grumble
+class nothing(object):
+ def __enter__(self):
+ return self
+ def __exit__(self, type, value, traceback):
+ if value:
+ print >> sys.stderr, ">>>%s" % value
+# raise value
+
+class mongod(object):
+ def __init__(self, *args):
+ self.args = args
+ self.proc = None
+
+ def __enter__(self):
+ self.start()
+ return self
+
+ def __exit__(self, type, value, traceback):
+ try:
+ self.stop()
+ except Exception, e:
+ print >> sys.stderr, "error shutting down mongod"
+ print >> sys.stderr, e
+ if value:
+ raise value
+
+ def ensureTestDirs(self):
+ utils.ensureDir( "/tmp/unittest/" )
+ utils.ensureDir( "/data/" )
+ utils.ensureDir( "/data/db/" )
+
+ def checkMongoPort( self, port=27017 ):
+ sock = socket.socket()
+ sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+ sock.settimeout(1)
+ sock.connect(("localhost", int(port)))
+ sock.close()
+
+ def didMongodStart( self, port=mongodPort, timeout=20 ):
+ while timeout > 0:
+ time.sleep( 1 )
+ try:
+ self.checkMongoPort( int(port) )
+ return True
+ except Exception,e:
+ print( e )
+ timeout = timeout - 1
+ return False
+
+ def start(self):
+ global mongodPort
+ global mongod
+ if self.proc:
+ print >> sys.stderr, "probable bug: self.proc already set in start()"
+ return
+ self.ensureTestDirs()
+ dirName = "/data/db/sconsTests/"
+ utils.ensureDir( dirName )
+ argv = [mongodExecutable, "--port", str(mongodPort),
+ "--dbpath", dirName] + list(self.args)
+ print argv
+ self.proc = Popen(argv)
+ if not self.didMongodStart( mongodPort ):
+ raise Exception( "Failed to start mongod" )
+
+# def startMongodSmallOplog(env, target, source):
+# return startMongodWithArgs("--master", "--oplogSize", "10")
+
+ def stop(self):
+ if not self.proc:
+ print >> sys.stderr, "probable bug: self.proc unset in stop()"
+ return
+ if self.proc.poll() is not None:
+ raise Exception( "Failed to start mongod" )
+ try:
+ # This function not available in Python 2.5
+ self.proc.terminate()
+ except AttributeError:
+ if os.sys.platform == "windows":
+ import win32process
+ win32process.TerminateProcess(self.proc._handle, -1)
+ else:
+ from os import kill
+ kill( self.proc.pid, 15 )
+ self.proc.wait()
+
+class Bug(Exception):
+ pass
+
+class TestFailure(object):
+ pass
+
+class TestExitFailure(TestFailure):
+ def __init__(self, *args):
+ self.path = args[0]
+ self.status=args[1]
+ def __str__(self):
+ return "test %s exited with status %d" % (self.path, self.status)
+
+class TestServerFailure(TestFailure):
+ def __init__(self, *args):
+ self.path = args[0]
+ def __str__(self):
+ return 'mongod not ok after test %s' % self.path
+
+def runTest(path):
+ ext = os.path.splitext(path)[1]
+ if ext == ".js":
+ argv=[shellExecutable, "--port", mongodPort, path]
+ elif ext in ["", ".exe"]:
+ argv=[path, "--port", mongodPort]
+ else:
+ raise Bug("fell off in extenstion case: %s" % path)
+ print "Executing test: " + " ".join(argv)
+ p = Popen(argv)
+ r = p.wait()
+ if r != 0:
+ raise TestExitFailure(path, r)
+ if Popen( [ mongodExecutable, "msg", "ping", mongodPort ], stdout=PIPE ).communicate()[0].count( "****ok" ) == 0:
+ raise TestServerFailure(path)
+ if call( [ mongodExecutable, "msg", "ping", mongodPort ] ) != 0:
+ raise TestServerFailure(path)
+ print ""
+
+def runTests(tests):
+ winners = []
+ losers = {}
+ with nothing() if oneMongodPerTest else mongod() as nevermind:
+ for test in tests:
+ try:
+ with mongod() if oneMongodPerTest else nothing() as nevermind:
+ runTest(test)
+ winners.append(test)
+ except TestFailure, f:
+ try:
+ losers[f.path] = f.status
+ raise f
+ # If the server's hosed and we're not in oneMongodPerTest
+ # mode, there's nothing else we can do.
+ except TestServerFailure, f:
+ if not oneMongodPerTest:
+ report(winners, losers)
+ exit(1)
+ except TestFailure, f:
+ if not continueOnFailure:
+ report(winners, losers)
+ exit(1)
+
+ return (winners, losers)
+
+def report(winners, losers):
+ print "%d test%s succeeded" % (len(winners), '' if len(winners) == 1 else 's')
+ if losers:
+ print "The following tests failed:"
+ for loser in losers:
+ print "%s\t%d" % (loser, losers[loser])
+
+def main():
+ parser = OptionParser(usage="usage: smoke.py [OPTIONS] FILE*")
+ parser.add_option('--mongod', dest='mongodExecutable', default='./mongod',
+ help='Path to mongod to run (default "./mongod")')
+ parser.add_option('--port', dest='mongodPort', default="32000",
+ help='Port the mongod will bind to (default 32000)')
+ parser.add_option('--mongo', dest='shellExecutable', default="./mongo",
+ help='Path to mongo, for .js test files (default "./mongo")')
+ parser.add_option('--continue-on-failure', dest='continueOnFailure',
+ action="store_true", default=False,
+ help='If supplied, continue testing even after a failure')
+ parser.add_option('--one-mongod-per-test', dest='oneMongodPerTest',
+ action="store_true", default=False,
+ help='If supplied, run each test in a fresh mongod')
+ parser.add_option('--from-file', dest='File',
+ help="Run tests named in FILE, one test per line, '-' means stdin")
+ (options, tests) = parser.parse_args()
+
+
+ global mongodExecutable, mongodPort, shellExecutable, continueOnFailure, oneMongodPerTest
+ mongodExecutable = options.mongodExecutable if options.mongodExecutable else mongodExecutable
+ mongodPort = options.mongodPort if options.mongodPort else mongodPort
+ shellExecutable = options.shellExecutable if options.shellExecutable else shellExecutable
+ continueOnFailure = options.continueOnFailure if options.continueOnFailure else continueOnFailure
+ oneMongodPerTest = options.oneMongodPerTest if options.oneMongodPerTest else oneMongodPerTest
+
+ if options.File:
+ if options.File == '-':
+ tests = sys.stdin.readlines()
+ else:
+ with open(options.File) as f:
+ tests = f.readlines()
+
+ tests = [t.rstrip('\n') for t in tests]
+
+ (winners, losers) = runTests(tests)
+ report(winners, losers)
+ return 0
+
+if __name__ == "__main__":
+ main()