[py-svn] r36221 - in py/dist/py/test/rsession: . testing

fijal at codespeak.net fijal at codespeak.net
Mon Jan 8 10:09:17 CET 2007


Author: fijal
Date: Mon Jan  8 10:09:11 2007
New Revision: 36221

Modified:
   py/dist/py/test/rsession/hostmanage.py
   py/dist/py/test/rsession/master.py
   py/dist/py/test/rsession/rsession.py
   py/dist/py/test/rsession/testing/test_master.py
   py/dist/py/test/rsession/testing/test_rsession.py
   py/dist/py/test/rsession/web.py
Log:
Added rescheduling of tests when there are empty hosts.


Modified: py/dist/py/test/rsession/hostmanage.py
==============================================================================
--- py/dist/py/test/rsession/hostmanage.py	(original)
+++ py/dist/py/test/rsession/hostmanage.py	Mon Jan  8 10:09:11 2007
@@ -3,7 +3,7 @@
 import time
 import thread, threading 
 from py.__.test.rsession.master import \
-     setup_slave, MasterNode, dispatch_loop
+     setup_slave, MasterNode
 from py.__.test.rsession import report 
 from py.__.test.rsession.rsync import RSync
 

Modified: py/dist/py/test/rsession/master.py
==============================================================================
--- py/dist/py/test/rsession/master.py	(original)
+++ py/dist/py/test/rsession/master.py	Mon Jan  8 10:09:11 2007
@@ -35,24 +35,47 @@
             # send start report
             self.reporter(report.SendItem(self.channel, item))
 
+def itemgen(colitems, reporter, keyword, reporterror):
+    for x in colitems: 
+        for y in x.tryiter(reporterror = lambda x: reporterror(reporter, x), keyword = keyword):
+            yield y
+
+def randomgen(items, done_dict):
+    """ Generator, which randomly gets all the tests from items as long
+    as they're not in done_dict
+    """
+    import random
+    while items:
+        values = items.keys()
+        item = values[int(random.random()*len(values))]
+        if item in done_dict:
+            del items[item]
+        else:
+            yield item
+
 def dispatch_loop(masternodes, itemgenerator, shouldstop, 
-                  waiter = lambda: py.std.time.sleep(0.1)):
-    from py.__.test.rsession.rsession import session_options
+                  waiter = lambda: py.std.time.sleep(0.1),
+                  max_tasks_per_node=None):
+    if not max_tasks_per_node:
+        from py.__.test.rsession.rsession import session_options
     
-    max_tasks_per_node = session_options.max_tasks_per_node
+        max_tasks_per_node = session_options.max_tasks_per_node
+    all_tests = {}
     while 1:
         try:
             for node in masternodes:
                 if len(node.pending) < max_tasks_per_node:
                     item = itemgenerator.next()
+                    all_tests[item] = True
                     if shouldstop():
                         for _node in masternodes:
                             _node.send(StopIteration) # magic connector
-                        return
+                        return None
                     node.send(item)
         except StopIteration:
             break
         waiter()
+    return all_tests
 
 def setup_slave(gateway, pkgpath, options):
     from py.__.test.rsession import slave

Modified: py/dist/py/test/rsession/rsession.py
==============================================================================
--- py/dist/py/test/rsession/rsession.py	(original)
+++ py/dist/py/test/rsession/rsession.py	Mon Jan  8 10:09:11 2007
@@ -10,7 +10,7 @@
 
 from py.__.test.rsession import report
 from py.__.test.rsession.master import \
-     setup_slave, MasterNode, dispatch_loop
+     setup_slave, MasterNode, dispatch_loop, itemgen, randomgen
 from py.__.test.rsession.hostmanage import init_hosts, teardown_hosts
 
 from py.__.test.rsession.local import local_loop, plain_runner, apigen_runner,\
@@ -168,7 +168,7 @@
 class RSession(AbstractSession):
     """ Remote version of session
     """
-    def main(self, args, reporter=None):
+    def main(self, args, reporter=None, override_checkfun=None):
         """ main loop for running tests. """
         if not args: 
             args = [py.path.local()]
@@ -182,6 +182,8 @@
         session_options.bind_config(self.config)
         reporter, checkfun, startserverflag = self.init_reporter(reporter,
             sshhosts, RemoteReporter)
+        if override_checkfun:
+            checkfun = override_checkfun
         reporter(report.TestStarted(sshhosts))
         pkgdir = self.getpkgdir(args[0])
         colitems = self.make_colitems(args, baseon=pkgdir.dirpath())
@@ -190,21 +192,24 @@
         except:
             remotepython = None
 
+        done_dict = {}
         nodes = init_hosts(reporter, sshhosts, directories, pkgdir,
             rsync_roots, remotepython, remote_options=remote_options.d,
-            optimise_localhost=self.optimise_localhost)
+            optimise_localhost=self.optimise_localhost, done_dict=done_dict)
         reporter(report.RsyncFinished())
         
         keyword = self.config.option.keyword
-
-        def itemgen():
-            for x in colitems: 
-                for y in x.tryiter(reporterror = lambda x: self.reporterror(reporter, x), keyword = keyword):
-                    yield y 
         
-        itemgenerator = itemgen()
+        itemgenerator = itemgen(colitems, reporter, keyword, self.reporterror)
         try:
-            dispatch_loop(nodes, itemgenerator, checkfun)
+            all_tests = dispatch_loop(nodes, itemgenerator, checkfun)
+            if all_tests:
+                todo = {}
+                for key, value in all_tests.items():
+                    if key not in done_dict:
+                        todo[key] = True
+                rg = randomgen(todo, done_dict)
+                dispatch_loop(nodes, rg, lambda:False, max_tasks_per_node=1)
         finally:
             teardown_hosts(reporter, [node.channel for node in nodes], nodes, 
                 exitfirst=self.config.option.exitfirst)

Modified: py/dist/py/test/rsession/testing/test_master.py
==============================================================================
--- py/dist/py/test/rsession/testing/test_master.py	(original)
+++ py/dist/py/test/rsession/testing/test_master.py	Mon Jan  8 10:09:11 2007
@@ -9,7 +9,7 @@
 if sys.platform == 'win32':
     py.test.skip("rsession is unsupported on Windows.")
 
-from py.__.test.rsession.master import dispatch_loop, setup_slave, MasterNode
+from py.__.test.rsession.master import dispatch_loop, setup_slave, MasterNode, randomgen
 from py.__.test.rsession.outcome import ReprOutcome, Outcome 
 from py.__.test.rsession.testing.test_slave import funcpass_spec, funcfail_spec
 from py.__.test.rsession import report
@@ -118,3 +118,16 @@
                          [funcpass_item] * 5 + [funcfail_item] * 5)
     shouldstop = lambda : False
     dispatch_loop(master_nodes, itemgenerator, shouldstop)
+
+def test_randomgen():
+    d = {}
+    gen = randomgen({1:True, 2:True, 3:True}, d)
+    for i in range(100):
+        assert gen.next() in [1,2,3]
+    d[3] = True
+    for i in range(100):
+        assert gen.next() in [1,2]
+    d[2] = True
+    d[1] = True
+    py.test.raises(StopIteration, "gen.next()")
+

Modified: py/dist/py/test/rsession/testing/test_rsession.py
==============================================================================
--- py/dist/py/test/rsession/testing/test_rsession.py	(original)
+++ py/dist/py/test/rsession/testing/test_rsession.py	Mon Jan  8 10:09:11 2007
@@ -109,7 +109,8 @@
 ##        res = channel.receive()
 ##        assert res == "ok"
 
-    def test_example_distribution_minus_x(self): 
+    def test_example_distribution_minus_x(self):
+        #py.test.skip("Works, but does not test what it should")
         # XXX find a better way for the below 
         tmpdir = py.path.local(py.__file__).dirpath().dirpath()
         tmpdir.ensure("sub", "conftest.py").write(py.code.Source("""
@@ -131,7 +132,11 @@
         config, args = py.test.Config.parse(args)
         rsession = RSession(config)
         allevents = []
-        rsession.main(args, reporter=allevents.append) 
+        def check():
+            return [x for x in allevents if isinstance(x, report.ReceivedItemOutcome) and
+                    not x.outcome.passed]
+        
+        rsession.main(args, reporter=allevents.append, override_checkfun=check)
         testevents = [x for x in allevents 
                         if isinstance(x, report.ReceivedItemOutcome)]
         assert len(testevents) == 2

Modified: py/dist/py/test/rsession/web.py
==============================================================================
--- py/dist/py/test/rsession/web.py	(original)
+++ py/dist/py/test/rsession/web.py	Mon Jan  8 10:09:11 2007
@@ -24,11 +24,6 @@
 FUNCTION_LIST = ["main", "show_skip", "show_traceback", "show_info", "hide_info",
     "show_host", "hide_host"]
 
-def escape(s):
-    return s
-    #return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;"). \
-    #    replace("'", "\\'").replace(" ", "&nbsp;").replace("\n", "<br/>")
-
 try:
     try:
         if not session_options.import_pypy:
@@ -160,12 +155,12 @@
     
     def show_skip(self, item_name="aa"):
         return {'item_name': item_name,
-                           'reason': escape(self.skip_reasons[item_name])}
+                           'reason': self.skip_reasons[item_name]}
     show_skip = described(retval={"aa": "aa"})(show_skip)
     
     def show_fail(self, item_name="aa"):
         return {'item_name':item_name,
-                           'traceback':escape(str(self.fail_reasons[item_name])),
+                           'traceback':str(self.fail_reasons[item_name]),
                            'stdout':self.stdout[item_name],
                            'stderr':self.stderr[item_name]}
     show_fail = described(retval={"aa": "aa"})(show_fail)
@@ -260,7 +255,7 @@
             args['reason'] = str(event.excinfo.value)
         else:
             args = {}
-        args['event'] = escape(str(event))
+        args['event'] = str(event)
         args['type'] = event.__class__.__name__
         return args
 
@@ -287,6 +282,7 @@
         self.pending_events.put(event)
     
     def report_ItemStart(self, event):
+        #if isinstance(event.item, py.test.collect.Module):
         self.pending_events.put(event)
     
     def report_unknown(self, event):
@@ -391,7 +387,6 @@
 
             javascript_source = rpython2javascript(webjs,
                 FUNCTION_LIST, use_pdb=False)
-            # XXX: This did not work for some reason, no idea why
             open(str(js_name), "w").write(javascript_source)
             self.serve_data("text/javascript", javascript_source)
         else:


More information about the py-svn mailing list