diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py index 1d08f34bf2589ad8feb61e2622771f0b09bc35b9..566bf391b172f0d283a236ed8c2089e5454e1174 100644 --- a/test/lib/test_suite.py +++ b/test/lib/test_suite.py @@ -98,6 +98,7 @@ class TestSuite: color_stdout(shortsep, "\n", schema='separator') failed_tests = [] try: + self.server.cleanup() for test in self.tests: color_stdout(test.name.ljust(48), schema='t_name') # for better diagnostics in case of a long-running test @@ -114,11 +115,9 @@ class TestSuite: failed_tests.append(test.name) color_stdout(shortsep, "\n", schema='separator') self.server.stop(silent=False) - self.server.cleanup() except (KeyboardInterrupt) as e: - color_stdout("\n", shortsep, "\n", schema='separator') + color_stdout("\n%s\n" % shortsep, schema='separator') self.server.stop(silent=False) - self.server.cleanup() raise if failed_tests: diff --git a/test/parallel_test_suite.py b/test/par-test-run.py similarity index 77% rename from test/parallel_test_suite.py rename to test/par-test-run.py index ab16cc453543c1f52cb16b89acebcbc0aa526a97..ecf3e68a0f689f48e739aa00210853936e4ce170 100755 --- a/test/parallel_test_suite.py +++ b/test/par-test-run.py @@ -29,10 +29,7 @@ logger.setLevel(logging.INFO) import pickle -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO +from StringIO import StringIO STATUS_TABLE = { 0: "pass", @@ -41,8 +38,7 @@ STATUS_TABLE = { 3: "fail" } -class Parallel_Manager(MBaseManager): - pass +class Parallel_Manager(MBaseManager): pass Parallel_Manager.register('Queue', multiprocessing.Queue) class Parallel_Process(MProcess): @@ -52,18 +48,19 @@ class Parallel_Process(MProcess): super(Parallel_Process, self).__init__(**kwargs) def run(self): + queuein = self._args[0] + queueout = self._args[1] while True: - logger.info("Process.run > getting job") - obj = self._args[0].get() - logger.info("Process.run > ok, it's great") + logger.debug("||_process.run > getting job") + obj = queuein.get() + logger.debug("||_process.run > ok, it's great") assert obj assert len(obj) == 2 assert callable(obj[0]) assert isinstance(obj[1], (tuple, list)) retv = obj[0](*obj[1]) - logger.info("Process.run > job is done, let's put into outqueue") - self._args[1].put(retv) - logger.info("Process.run > another iteration") + logger.debug("||_process.run > job is done, let's put into outqueue") + queueout.put(retv) class Parallel_PoolException(Exception): def __init__(self, message): @@ -88,9 +85,9 @@ class Parallel_Pool(object): self.jobs_out = 0 self.jobs_end = False self.status = Parallel_Pool.INITED - self._populate_pool() + self._populate() - def _populate_pool(self): + def _populate(self): assert(self.status == Parallel_Pool.INITED) for i in xrange(self.number): kwargs = { @@ -105,12 +102,12 @@ class Parallel_Pool(object): )) self.status = Parallel_Pool.POPULATED - def _repopulate_pool(self): + def _repopulate(self): assert(self.status >= Parallel_Pool.STARTED) - logger.info('_repopulate_pool > Begin repopulation') + logger.debug('||_pool.repopulate > Begin repopulation') for n, proc in enumerate(self.pool): if not proc.is_alive() and self.status != Parallel_Pool.ENDED: - logger.info("Manager: Process %s is dead (code %s). Recreating", + logger.debug("Manager: Process %s is dead (code %s). Recreating", repr(proc.name), proc.exitcode) self.pool[n] = Parallel_Process( group = None, @@ -121,31 +118,31 @@ class Parallel_Pool(object): ] ) self.jobs_out += 1 - logger.info('_repopulate_pool > Ending repopulation') + logger.debug('||_pool.repopulate > Ending repopulation') return 0 - def fill_wjobs(self, iterable=None): - logger.info('fill_wjobs > Entering') + def fill(self, iterable=None): + logger.debug('||_pool.fill > Entering') assert(self.status > Parallel_Pool.INITED and self.status < Parallel_Pool.ENDED) if iterable == None: raise Parallel_PoolException("Iterable must be defined \ - for 'Parallel_Pool.fill_wjobs'") + for '||_pool.fill'") jobs = iterable target = 0 while True: - self._repopulate_pool() + self._repopulate() try: while (not self.queuein.full() and target < 10 and not self.queueout.full()): - logger.info("I'll put a job now") + logger.debug("I'll put a job now") job = iterable.next() self.queuein.put(job) self.jobs_in += 1 target += 1 - logger.error("fill_wjobs > While stopped") + logger.debug("||_pool.fill > While stopped") except StopIteration: - logger.error("fill_wjobs > StopIteration") + logger.debug("||_pool.fill > StopIteration") self.jobs_end = True raise StopIteration yield @@ -174,6 +171,7 @@ class Parallel_Iterator(object): else: ans = self.pool.queueout.get(block=True, timeout=timeout) self.pool.jobs_out += 1 + return ans class Parallel_FilteredStream(object): def __init__(self): @@ -182,10 +180,10 @@ class Parallel_FilteredStream(object): def write(self, fragment): skipped = False - for line in fragment: + for line in fragment.splitlines(True): original_len = len(line.strip()) for pattern, replacement in self.filters: - line = re.sub(pattern, replacement, line) + line = pattern.sub(replacement, line) skipped = original_len and not line.strip() if skipped: break @@ -193,7 +191,7 @@ class Parallel_FilteredStream(object): self.stream.write(line) def push_filter(self, pattern, replacement): - self.filters.append([pattern, replacement]) + self.filters.append([re.compile(pattern), replacement]) def pop_filter(self): self.filters.pop() @@ -253,32 +251,35 @@ class Supervisor(object): admin = self.server.admin.ret_copy() yield [random.choice(self.tests), [sql, admin]] - def run_jobs(self, jobs): + def run(self, jobs): self.search_tests() - self.pool = Parallel_Pool(processes = 5) + self.pool = Parallel_Pool(processes = jobs) self.iterator = self.pool.run() - self.filler = self.pool.fill_wjobs(self.take_rand()) + self.filler = self.pool.fill(self.take_rand()) try: + self.server.cleanup() + logger.info("Tarantool.Instance > Server cleanuped") + logger.info("Tarantool.Instance > Server's path: %s", self.server.binary) self.server.deploy() - logger.info("TARANTOOL > Server deployed") + logger.info("Tarantool.Instance > Server deployed") try: while True: self.filler.next() - logger.info("run_jobs: Jobs filled %d %d" % + logger.debug("BigBrother.run > Jobs filled %d %d" % (self.pool.queuein.qsize(), self.pool.queueout.qsize())) while True: try: - logger.info("run_jobs > waiting for task") + logger.debug("BigBrother.run > waiting for task") task = self.iterator.next(1) - logger.info("run_jobs > took task") + logger.debug("BigBrother.run > took task") if task is None: - logger.info('Task return NONE') + logger.info('>>>> Test return NONE') continue stat = task.get_status() if stat.status != 3: - logger.info('Test %s finished' % repr(task.name)) + logger.info('>>>> Test %s finished' % repr(task.name)) else: - logger.info('Test %s failed with %s' % + logger.info('>>>> Test %s failed with %s' % (repr(task.name), stat.message)) except (QueueEmpty, StopIteration): break @@ -286,18 +287,16 @@ class Supervisor(object): pass finally: self.server.stop() - logger.info("TARANTOOL > Server stopped") - self.server.cleanup() - logger.info("TARANTOOL > Server cleanuped") + logger.info("Tarantool.Instance > Server stopped") class Parallel_Test(object): def __init__(self, name): rg = re.compile('.test.*') - self.id = uuid.uuid4().get_hex().replace('-', '')[0:6] - self.name = name - logger.info("__init__ > Entering test '%s'" % self.name) + self.name = name + self.reject = None + self.id = None + logger.debug("||_Test.__init__ > Entering test '%s'" % self.name) self.result = rg.sub('.result', name) - self.reject = rg.sub('.reject_%s' % self.id, name) self.is_executed = False self.is_executed_ok = False self.is_equal_result = False @@ -310,16 +309,18 @@ class Parallel_Test(object): pass def run(self, sql, admin): + self.id = uuid.uuid1().get_hex().replace('-', '')[0:6] + self.reject = re.sub('.test.*', '.reject_%s' % self.id, self.name) self.diagnostics = "unknown" save_stdout = sys.stdout self.test_stdout = Parallel_FilteredStream() try: sys.stdout = self.test_stdout - logger.info("Entering") + logger.debug("Entering") self.execute(sql, admin) self.is_executed_ok = True except Exception as e: - logger.error("Exception '%s' was thrown for '%s'" % (type(e), str(e))) + logger.error("||_Test.run > Exception '%s' was thrown for '%s'" % (type(e), str(e))) logger.error(traceback.format_exc()) with open(self.reject, 'a') as reject: traceback.print_exc(e, reject) @@ -341,7 +342,7 @@ class Parallel_Test(object): with open(self.reject, 'a') as reject: reject.write(self.test_stdout.getvalue()) - return 0 + return self def get_status(self): if self.is_executed_ok and self.is_equal_result: @@ -358,19 +359,19 @@ class Parallel_Test(object): def __call__(self, sql, admin): try: - logger.info("__call__ > Entering test '%s'" % self.name) - self.run(sql, admin) + logger.debug("||_Test.__call__ > Entering test '%s'" % self.name) + return self.run(sql, admin) except Exception as e: - logger.error("Exception '%s' was thrown for '%s'" % (type(e), str(e))) + logger.error("||_Test.__call__ > Exception '%s' was thrown for '%s'" % (type(e), str(e))) logger.error(traceback.format_exc()) class Parallel_FuncTest(Parallel_Test): def execute(self, sql, admin): execfile(self.name, dict(locals(), sql=sql, admin=admin)) -class Parallel_PythonTest(Parallel_FuncTest): - pass +class Parallel_PythonTest(Parallel_FuncTest): pass if __name__ == '__main__': + TarantoolServer.find_exe('..') sup = Supervisor() - sup.run_jobs(2) + sup.run(1) diff --git a/test/parallel/call.result b/test/parallel/call.result index b9f77a9f4c95db8257b4f8cb145fdbb5eff9abcd..c76e7645410d0ce21bc2624f83f99e8527bb9aa3 100644 --- a/test/parallel/call.result +++ b/test/parallel/call.result @@ -1,7 +1,7 @@ -box.schema.user.create('test', { password = 'test' }) +box.schema.user.create() --- ... -box.schema.user.grant('test', 'execute,read,write', 'universe') +box.schema.user.grant() --- ... function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end @@ -372,6 +372,6 @@ call space:delete(4) space:drop() --- ... -box.schema.user.drop('test') +box.schema.user.drop() --- ... diff --git a/test/parallel/call.test.py b/test/parallel/call.test.py index cba95b6cf7dde82d65172ab3d44f74723c4b3092..7a081c4f01b160abf240957e97e82d5d19ddfe4d 100644 --- a/test/parallel/call.test.py +++ b/test/parallel/call.test.py @@ -1,9 +1,16 @@ -import os import sys +import uuid +import random -admin("box.schema.user.create('test', { password = 'test' })") -admin("box.schema.user.grant('test', 'execute,read,write', 'universe')") -sql.authenticate('test', 'test') +login = 'u'+str(uuid.uuid4())[0:8] +passw = 'p'+str(uuid.uuid4())[0:8] + +sys.stdout.push_filter('box.schema.user.create.*', 'box.schema.user.create()') +sys.stdout.push_filter('box.schema.user.grant.*', 'box.schema.user.grant()') + +admin("box.schema.user.create('%s', { password = '%s' })" % (login, passw)) +admin("box.schema.user.grant('%s', 'execute,read,write', 'universe')" % (login)) +sql.authenticate(login, passw) admin("function f1() return 'testing', 1, false, -1, 1.123, 1e123, nil end") admin("f1()") sql("call f1()") @@ -121,4 +128,5 @@ sql("call field_x(4, 2)") sql("call space:delete(4)") admin("space:drop()") -admin("box.schema.user.drop('test')") +sys.stdout.push_filter('box.schema.user.drop(.*)', 'box.schema.user.drop()') +admin("box.schema.user.drop('%s')" % login) diff --git a/test/parallel/sql.result b/test/parallel/sql.result index 26ca867c0c7a5498a394f05dcbee24a61d299a90..0cbf7f8f9c6e70bcc87284521500d955b3ed58ad 100644 --- a/test/parallel/sql.result +++ b/test/parallel/sql.result @@ -1,7 +1,7 @@ -box.schema.user.create('test', { password = 'test' }) +box.schema.user.create() --- ... -box.schema.user.grant('test', 'execute,read,write', 'universe') +box.schema.user.grant() --- ... s = box.schema.create_space('tweedledum', { id = 0 }) @@ -334,9 +334,6 @@ insert into t0 values (4, 'world') --- - [4, 'world'] ... -s = box.space[0] ---- -... # # Bug#929654 - secondary hash index is not built with build_indexes() # @@ -590,7 +587,7 @@ delete from t0 where k0=3 --- - [3, 'Creature '] ... -box.schema.user.drop('test') +box.schema.user.drop() --- ... s:drop() diff --git a/test/parallel/sql.test.py b/test/parallel/sql.test.py index 4fec1be42929e4016eea55150ab6f2710547750a..386c1a6c9a967fb71531d0a909c725f5f5a00c78 100644 --- a/test/parallel/sql.test.py +++ b/test/parallel/sql.test.py @@ -1,11 +1,19 @@ sql.sort = True - +import sys +import uuid # # Prepare spaces # +login = 'u'+str(uuid.uuid4())[0:8] +passw = 'p'+str(uuid.uuid4())[0:8] + +sys.stdout.push_filter('box.schema.user.create.*', 'box.schema.user.create()') +sys.stdout.push_filter('box.schema.user.grant.*', 'box.schema.user.grant()') + +admin("box.schema.user.create('%s', { password = '%s' })" % (login, passw)) +admin("box.schema.user.grant('%s', 'execute,read,write', 'universe')" % (login)) +sql.authenticate(login, passw) -admin("box.schema.user.create('test', { password = 'test' })") -admin("box.schema.user.grant('test', 'execute,read,write', 'universe')") admin("s = box.schema.create_space('tweedledum', { id = 0 })") admin("s:create_index('primary', { type = 'tree', parts = { 1, 'str'} })") admin("s:create_index('secondary', { type = 'tree', unique = false, parts = {2, 'str'}})") @@ -15,7 +23,6 @@ print """# # "SELECT fails with a disjunct and small LIMIT" # https://bugs.launchpad.net/tarantool/+bug/729758 #""" -sql.authenticate('test', 'test') sql("insert into t0 values ('Doe', 'Richard')") sql("insert into t0 values ('Roe', 'Richard')") sql("insert into t0 values ('Woe', 'Richard')") @@ -202,7 +209,8 @@ admin("s.index[1]:max()") sql("delete from t0 where k0=1") sql("delete from t0 where k0=2") sql("delete from t0 where k0=3") -admin("box.schema.user.drop('test')") +sys.stdout.push_filter('box.schema.user.drop(.*)', 'box.schema.user.drop()') +admin("box.schema.user.drop('%s')" % login) admin("s:drop()") sql.sort = False diff --git a/test/test-run.py b/test/test-run.py index 38bad653c8dd1454fa20ecf0bd067c1fd0f14e27..77b651401e3f47b999053f79a28d69225a8386ed 100755 --- a/test/test-run.py +++ b/test/test-run.py @@ -111,6 +111,12 @@ class Options: default = "..", help = """Path to project build directory. Default: " + "../.""") + parser.add_argument( + "--stress", + dest = "builddir", + default = None, + help = """Name of streess TestSuite to run""") + parser.add_argument( "--vardir", dest = "vardir", @@ -164,10 +170,10 @@ def main(): suites = [TestSuite(suite_name, options.args) for suite_name in sorted(suite_names)] + TarantoolServer.find_exe(options.args.builddir) UnittestServer.find_exe(options.args.builddir) - for suite in suites: failed_tests.extend(suite.run_all()) except RuntimeError as e: