[py-svn] r37909 - in py/trunk/py/test/rsession: . testing

hpk at codespeak.net hpk at codespeak.net
Sun Feb 4 15:05:04 CET 2007


Author: hpk
Date: Sun Feb  4 15:05:01 2007
New Revision: 37909

Added:
   py/trunk/py/test/rsession/testing/test_hostmanage.py
      - copied, changed from r37886, py/trunk/py/test/rsession/testing/test_rsync.py
Removed:
   py/trunk/py/test/rsession/testing/test_rsync.py
Modified:
   py/trunk/py/test/rsession/hostmanage.py
   py/trunk/py/test/rsession/master.py
   py/trunk/py/test/rsession/rsession.py
   py/trunk/py/test/rsession/slave.py
   py/trunk/py/test/rsession/testing/test_master.py
   py/trunk/py/test/rsession/testing/test_rest.py
   py/trunk/py/test/rsession/testing/test_rsession.py
   py/trunk/py/test/rsession/testing/test_slave.py
Log:
a much much much larger refactoring than i originally
intended at this point:

* HostManager and HostRSync are now acting
  more locally, also easier to test. 

* HostInfo deals with setting up gateways now 

* HostManager, HostRSync and HostInfo are 
  all tested now in test_hostmanage.py 
  (and do not involve a full startup of RSessions) 

* for rsyncing, the original directory structure
  (relative to config.topdir) is preserved on the
  other side, this makes "dist_rsync_roots" relatively
  clean now (but it doesn't pick up things on the fly,
  only initialises at the beginning)

* added lots of tests

* removed more occurences of pkgdir

* streamlined and simplified some tests

* removed lots of tests that do not appear to test
  specifically enough (and caused trouble for
  the refactoring)

* removed lots of (but not all, i guess) test-specific
  functionality in hostmanage.py and a bit in rsession.py

* removed HostOptions() in favour of rather directly
  accessing config values



Modified: py/trunk/py/test/rsession/hostmanage.py
==============================================================================
--- py/trunk/py/test/rsession/hostmanage.py	(original)
+++ py/trunk/py/test/rsession/hostmanage.py	Sun Feb  4 15:05:01 2007
@@ -2,32 +2,59 @@
 import py
 import time
 import thread, threading 
-from py.__.test.rsession.master import \
-     setup_slave, MasterNode
+from py.__.test.rsession.master import MasterNode
+from py.__.test.rsession.slave import setup_slave
+
 from py.__.test.rsession import report 
 
 class HostInfo(object):
     """ Class trying to store all necessary attributes
     for host
     """
-    host_ids = {}
+    _hostname2list = {}
+    localdest = None
     
-    def __init__(self, hostname, relpath=None):
-        self.hostid = self._getuniqueid(hostname)
-        self.hostname = hostname
-        self.relpath = relpath
-
-    def _getuniqueid(cls, hostname):
-        if not hostname in cls.host_ids:
-            cls.host_ids[hostname] = 0
-            return hostname
-        retval = hostname + '_' + str(cls.host_ids[hostname])
-        cls.host_ids[hostname] += 1
-        return retval
-    _getuniqueid = classmethod(_getuniqueid)
+    def __init__(self, spec):
+        parts = spec.split(':', 1)
+        self.hostname = parts.pop(0)
+        if parts:
+            self.relpath = parts[0]
+        else:
+            self.relpath = "pytestcache-" + self.hostname 
+        self.hostid = self._getuniqueid(self.hostname) 
+
+    def _getuniqueid(self, hostname):
+        l = self._hostname2list.setdefault(hostname, [])
+        hostid = hostname + "_" * len(l)
+        l.append(hostid)
+        return hostid
+
+    def initgateway(self, python="python"):
+        assert not hasattr(self, 'gw')
+        if self.hostname == "localhost": 
+            gw = py.execnet.PopenGateway(python=python)
+        else:
+            gw = py.execnet.SshGateway(self.hostname, 
+                                       remotepython=python)
+        self.gw = gw
+        channel = gw.remote_exec("""
+            import os
+            targetdir = %r
+            if not os.path.isabs(targetdir):
+                homedir = os.environ['HOME']
+                targetdir = os.path.join(homedir, targetdir)
+            if not os.path.exists(targetdir):
+                os.makedirs(targetdir)
+            channel.send(os.path.abspath(targetdir))
+        """ % self.relpath)
+        self.gw_remotepath = channel.receive()
+        #print "initialized", gw, "with remotepath", self.gw_remotepath
+        if self.hostname == "localhost":
+            self.localdest = py.path.local(self.gw_remotepath)
+            assert self.localdest.check(dir=1)
 
     def __str__(self):
-        return "<HostInfo %s>" % (self.hostname,)
+        return "<HostInfo %s:%s>" % (self.hostname, self.relpath)
 
     def __hash__(self):
         return hash(self.hostid)
@@ -39,138 +66,77 @@
         return not self == other
 
 class HostRSync(py.execnet.RSync):
-    """ An rsync wrapper which filters out *~, .svn/ and *.pyc
+    """ RSyncer that filters out common files 
     """
-    def __init__(self, config):
-        py.execnet.RSync.__init__(self, delete=True)
-        self.config = config
+    def __init__(self, *args, **kwargs):
+        self._synced = {}
+        super(HostRSync, self).__init__(*args, **kwargs)
 
     def filter(self, path):
-        if path.endswith('.pyc') or path.endswith('~'):
-            return False
-        dir, base = os.path.split(path)
-        try:
-            name = "dist_rsync_roots" 
-            rsync_roots = self.config.conftest.rget_path(name, dir)
-        except AttributeError:
-            rsync_roots = None
-        if base == '.svn':
-            return False
-        if rsync_roots is None:
-            return True
-        return base in rsync_roots
-
-class DummyGateway(object):
-    pass
-
-class HostOptions(object):
-    """ Dummy container for host options, not to keep that
-    as different function parameters, mostly related to
-    tests only
-    """
-    def __init__(self, remote_python="python",
-                 optimise_localhost=True, do_sync=True,
-                 create_gateways=True):
-        self.remote_python = remote_python
-        self.optimise_localhost = optimise_localhost
-        self.do_sync = do_sync
-        self.create_gateways = create_gateways
+        path = py.path.local(path)
+        if not path.ext in ('.pyc', '.pyo'):
+            if not path.basename.endswith('~'): 
+                if path.check(dotfile=0):
+                    return True
+
+    def add_target_host(self, host, destrelpath=None, finishedcallback=None):
+        key = host.hostname, host.relpath 
+        if key in self._synced:
+            if finishedcallback:
+                finishedcallback()
+            return False 
+        self._synced[key] = True
+        # the follow attributes are set from host.initgateway()
+        gw = host.gw
+        remotepath = host.gw_remotepath
+        if destrelpath is not None:
+            remotepath = os.path.join(remotepath, destrelpath)
+        super(HostRSync, self).add_target(gw, 
+                                          remotepath, 
+                                          finishedcallback)
+        return True # added the target
 
 class HostManager(object):
-    def __init__(self, sshhosts, config, options=HostOptions()):
+    def __init__(self, sshhosts, config):
         self.sshhosts = sshhosts
         self.config = config
-        self.options = options
-        if not options.create_gateways:
-            self.prepare_gateways = self.prepare_dummy_gateways
-        #assert pkgdir.join("__init__.py").check(), (
-        #    "%s probably wrong" %(pkgdir,))
-
-    def prepare_dummy_gateways(self):
-        for host in self.sshhosts:
-            gw = DummyGateway()
-            host.gw = gw
-            gw.host = host
-        return self.sshhosts
-
-    def prepare_ssh_gateway(self, host):
-        if self.options.remote_python is None:
-            gw = py.execnet.SshGateway(host.hostname)
-        else:
-            gw = py.execnet.SshGateway(host.hostname,
-                                       remotepython=self.options.remote_python)
-        return gw
-
-    def prepare_popen_rsync_gateway(self, host):
-        """ Popen gateway, but with forced rsync
-        """
-        from py.__.execnet.register import PopenCmdGateway
-        gw = PopenCmdGateway("cd ~; python -u -c 'exec input()'")
-        if not host.relpath.startswith("/"):
-            host.relpath = os.environ['HOME'] + '/' + host.relpath
-        return gw
-
-    def prepare_popen_gateway(self, host):
-        if self.options.remote_python is None:
-            gw = py.execnet.PopenGateway()
-        else:
-            gw = py.execnet.PopenGateway(python=self.options.remote_python)
-        host.relpath = str(self.config.topdir)
-        return gw
 
     def prepare_gateways(self):
+        dist_remotepython = self.config.getvalue("dist_remotepython")
         for host in self.sshhosts:
-            if host.hostname == 'localhost':
-                if not self.options.optimise_localhost:
-                    gw = self.prepare_popen_rsync_gateway(host)
-                else:
-                    gw = self.prepare_popen_gateway(host)
-            else:
-                gw = self.prepare_ssh_gateway(host)
-            host.gw = gw
-            gw.host = host
-        return self.sshhosts
-
-    def need_rsync(self, rsynced, hostname, remoterootpath):
-        if (hostname, remoterootpath) in rsynced:
-            return False
-        if hostname == 'localhost' and self.options.optimise_localhost:
-            return False
-        return True
+            host.initgateway(python=dist_remotepython)
+            host.gw.host = host # XXX would like to avoid it
 
-    def init_hosts(self, reporter, done_dict={}):
+    def init_rsync(self, reporter):
+        # send each rsync roots  
+        roots = self.config.getvalue_pathlist("dist_rsync_roots")
+        if roots is None:
+            roots = [self.config.topdir]
+        self.prepare_gateways()
+        rsync = HostRSync()
+        for root in roots: 
+            destrelpath = root.relto(self.config.topdir)
+            for host in self.sshhosts:
+                reporter(report.HostRSyncing(host))
+                def donecallback():
+                    reporter(report.HostReady(host))
+                rsync.add_target_host(host, destrelpath, 
+                                      finishedcallback=donecallback)
+            rsync.send(root)
+
+    def init_hosts(self, reporter, done_dict=None):
         if done_dict is None:
             done_dict = {}
-
-        hosts = self.prepare_gateways()
-        
-        # rsyncing
-        rsynced = {}
-
-        if self.options.do_sync:
-            rsync = HostRSync(self.config)
-        for host in hosts:
-            if not self.need_rsync(rsynced, host.hostname, host.relpath):
-                reporter(report.HostReady(host))
-                continue
-            rsynced[(host.hostname, host.relpath)] = True
-            def done(host=host):
-                reporter(report.HostReady(host))
-            reporter(report.HostRSyncing(host))
-            if self.options.do_sync:
-                rsync.add_target(host.gw, host.relpath, done)
-        if not self.options.do_sync:
-            return # for testing only
-        rsync.send(self.config.topdir)
         # hosts ready
+        self.init_rsync(reporter)
         return self.setup_nodes(reporter, done_dict)
 
     def setup_nodes(self, reporter, done_dict):
         nodes = []
         for host in self.sshhosts:
-            ch = setup_slave(host.gw, host.relpath, self.config)
-            nodes.append(MasterNode(ch, reporter, done_dict))
-    
+            if hasattr(host.gw, 'remote_exec'): # otherwise dummy for tests :/
+                ch = setup_slave(host, self.config)
+                nodes.append(MasterNode(ch, reporter, done_dict))
         return nodes
 
     def teardown_hosts(self, reporter, channels, nodes,

Modified: py/trunk/py/test/rsession/master.py
==============================================================================
--- py/trunk/py/test/rsession/master.py	(original)
+++ py/trunk/py/test/rsession/master.py	Sun Feb  4 15:05:01 2007
@@ -74,14 +74,3 @@
         waiter()
     return all_tests
 
-def setup_slave(gateway, pkgpath, config):
-    from py.__.test.rsession import slave
-    import os
-    ch = gateway.remote_exec(str(py.code.Source(slave.setup, "setup()")))
-    #if hasattr(gateway, 'sshaddress'):
-    #    assert not os.path.isabs(pkgpath)
-    ch.send(str(pkgpath))
-    ch.send(config.make_repr(defaultconftestnames))
-    return ch
-
-defaultconftestnames = ['dist_nicelevel']

Modified: py/trunk/py/test/rsession/rsession.py
==============================================================================
--- py/trunk/py/test/rsession/rsession.py	(original)
+++ py/trunk/py/test/rsession/rsession.py	Sun Feb  4 15:05:01 2007
@@ -10,9 +10,8 @@
 
 from py.__.test.rsession import report
 from py.__.test.rsession.master import \
-     setup_slave, MasterNode, dispatch_loop, itemgen, randomgen
-from py.__.test.rsession.hostmanage import HostInfo, HostOptions, HostManager
-
+     MasterNode, dispatch_loop, itemgen, randomgen
+from py.__.test.rsession.hostmanage import HostInfo, HostManager
 from py.__.test.rsession.local import local_loop, plain_runner, apigen_runner,\
     box_runner
 from py.__.test.rsession.reporter import LocalReporter, RemoteReporter
@@ -24,24 +23,12 @@
         An abstract session executes collectors/items through a runner. 
 
     """
-    def __init__(self, config, optimise_localhost=True):
-        super(AbstractSession, self).__init__(config=config)
-        self.optimise_localhost = optimise_localhost
-
     def fixoptions(self):
         option = self.config.option 
         if option.runbrowser and not option.startserver:
             #print "--runbrowser implies --startserver"
             option.startserver = True
         super(AbstractSession, self).fixoptions()
-        
-    def getpkgdir(path):
-        path = py.path.local(path)
-        pkgpath = path.pypkgpath()
-        if pkgpath is None:
-            pkgpath = path
-        return pkgpath
-    getpkgdir = staticmethod(getpkgdir)
 
     def init_reporter(self, reporter, sshhosts, reporter_class, arg=""):
         """ This initialises so called `reporter` class, which will
@@ -115,18 +102,6 @@
         self.checkfun = checkfun
         return new_reporter, checkfun
 
-def parse_directories(sshhosts):
-    """ Parse sshadresses of hosts to have distinct hostname/hostdir
-    """
-    directories = {}
-    for host in sshhosts:
-        m = re.match("^(.*?):(.*)$", host.hostname)
-        if m:
-            host.hostname = m.group(1)
-            host.relpath = m.group(2) + "-" + host.hostname
-        else:
-            host.relpath = "pytestcache-%s" % host.hostname
-
 class RSession(AbstractSession):
     """ Remote version of session
     """
@@ -151,7 +126,7 @@
         """ main loop for running tests. """
         args = self.config.args
 
-        sshhosts, remotepython = self.read_distributed_config()
+        sshhosts = self._getconfighosts()
         reporter, startserverflag = self.init_reporter(reporter,
             sshhosts, RemoteReporter)
         reporter, checkfun = self.wrap_reporter(reporter)
@@ -159,9 +134,7 @@
         reporter(report.TestStarted(sshhosts))
 
         done_dict = {}
-        hostopts = HostOptions(remote_python=remotepython,
-                            optimise_localhost=self.optimise_localhost)
-        hostmanager = HostManager(sshhosts, self.config, hostopts)
+        hostmanager = HostManager(sshhosts, self.config)
         try:
             nodes = hostmanager.init_hosts(reporter, done_dict)
             reporter(report.RsyncFinished())
@@ -191,14 +164,9 @@
             self.kill_server(startserverflag)
             raise
 
-    def read_distributed_config(self):
-        """ Read from conftest file the configuration of distributed testing
-        """
-        sshhosts = [HostInfo(i) for i in
-                    self.config.getvalue("dist_hosts")]
-        parse_directories(sshhosts)
-        remotepython = self.config.getvalue("dist_remotepython")
-        return sshhosts, remotepython
+    def _getconfighosts(self):
+        return [HostInfo(spec) for spec in
+                                    self.config.getvalue("dist_hosts")]
 
     def dispatch_tests(self, nodes, reporter, checkfun, done_dict):
         colitems = self.config.getcolitems()
@@ -262,7 +230,7 @@
             print >>sys.stderr, 'building documentation'
             capture = py.io.StdCaptureFD()
             try:
-                pkgdir = self.getpkgdir(self.config.args[0])
+                pkgdir = py.path.local(self.config.args[0]).pypkgpath()
                 apigen.build(pkgdir,
                              DocStorageAccessor(self.docstorage),
                              capture)
@@ -272,7 +240,7 @@
     def init_runner(self):
         if self.config.option.apigen:
             from py.__.apigen.tracer.tracer import Tracer, DocStorage
-            pkgdir = self.getpkgdir(self.config.args[0])
+            pkgdir = py.path.local(self.config.args[0]).pypkgpath()
             apigen = py.path.local(self.config.option.apigen).pyimport()
             if not hasattr(apigen, 'get_documentable_items'):
                 raise NotImplementedError("Provided script does not seem "
@@ -288,4 +256,3 @@
                 return box_runner
             return plain_runner
 
-

Modified: py/trunk/py/test/rsession/slave.py
==============================================================================
--- py/trunk/py/test/rsession/slave.py	(original)
+++ py/trunk/py/test/rsession/slave.py	Sun Feb  4 15:05:01 2007
@@ -106,6 +106,15 @@
     while nextitem is not None:
         nextitem = receive()
 
+defaultconftestnames = ['dist_nicelevel']
+def setup_slave(host, config): 
+    channel = host.gw.remote_exec(str(py.code.Source(setup, "setup()")))
+    configrepr = config.make_repr(defaultconftestnames)
+    #print "sending configrepr", configrepr
+    channel.send(host.gw_remotepath)
+    channel.send(configrepr) 
+    return channel
+
 def setup():
     def callback_gen(channel, queue, info):
         def callback(item):
@@ -116,19 +125,16 @@
                 sys.exit(0)
             queue.put(item)
         return callback
-
+    # our current dir is the topdir
     import os, sys
-    basedir = channel.receive()   # path is ready 
+    basedir = channel.receive()
     config_repr = channel.receive()
     # setup defaults...
     sys.path.insert(0, basedir)
     import py
     config = py.test.config
-    if config._initialized:
-        config = config._reparse([basedir])
-        config.merge_repr(config_repr)
-    else:
-        config.initdirect(basedir, config_repr)
+    assert not config._initialized 
+    config.initdirect(basedir, config_repr)
     if not config.option.nomagic:
         py.magic.invoke(assertion=1)
     from py.__.test.rsession.slave import slave_main, PidInfo

Copied: py/trunk/py/test/rsession/testing/test_hostmanage.py (from r37886, py/trunk/py/test/rsession/testing/test_rsync.py)
==============================================================================
--- py/trunk/py/test/rsession/testing/test_rsync.py	(original)
+++ py/trunk/py/test/rsession/testing/test_hostmanage.py	Sun Feb  4 15:05:01 2007
@@ -3,28 +3,135 @@
 """
 
 import py
-from py.__.test.rsession.hostmanage import HostRSync
+from py.__.test.rsession.hostmanage import HostRSync 
+from py.__.test.rsession.hostmanage import HostInfo, HostManager 
 
-def test_rsync():
-    tmpdir = py.test.ensuretemp("rsync_rsession")
-    tmpdir.ensure("a", dir=True)
-    tmpdir.ensure("b", dir=True)
-    tmpdir.ensure("conftest.py").write(py.code.Source("""
-    dist_rsyncroots = ['a']
-    """))
-    tmpdir.join("a").ensure("x")
-    adir = tmpdir.join("a").ensure("xy", dir=True)
-    adir.ensure("conftest.py").write(py.code.Source("""
-    dist_rsyncroots = ['b', 'conftest.py']
-    """))
-    adir.ensure("a", dir=True)
-    adir.ensure("b", dir=True)
-    config = py.test.config._reparse([str(tmpdir)])
-    h = HostRSync(config)
-    h.sourcedir = config.topdir
-    assert h.filter(str(tmpdir.join("a")))
-    assert not h.filter(str(tmpdir.join("b")))
-    assert h.filter(str(tmpdir.join("a").join("x")))
-    assert h.filter(str(adir.join("conftest.py")))
-    assert not h.filter(str(adir.join("a")))
-    assert h.filter(str(adir.join("b")))
+class DirSetup:
+    def setup_method(self, method):
+        name = "%s.%s" %(self.__class__.__name__, method.func_name)
+        self.tmpdir = py.test.ensuretemp(name)
+        self.source = self.tmpdir.ensure("source", dir=1)
+        self.dest = self.tmpdir.join("dest")
+
+class TestHostInfo:
+    def test_defaultpath(self):
+        x = HostInfo("localhost")
+        assert x.hostname == "localhost"
+        assert x.relpath == "pytestcache-" + x.hostname 
+
+    def test_path(self):
+        x = HostInfo("localhost:/tmp")
+        assert x.relpath == "/tmp"
+        assert x.hostname == "localhost"
+
+    def test_hostid(self):
+        x = HostInfo("localhost")
+        y = HostInfo("localhost")
+        assert x.hostid != y.hostid 
+        x = HostInfo("localhost:/tmp")
+        y = HostInfo("localhost")
+        assert x.hostid != y.hostid 
+
+    def test_non_existing_hosts(self):
+        host = HostInfo("alskdjalsdkjasldkajlsd")
+        py.test.raises((py.process.cmdexec.Error, IOError, EOFError), 
+                       host.initgateway)
+
+    def test_initgateway_localhost_relpath(self):
+        name = "pytestcache-localhost"
+        x = HostInfo("localhost:%s" % name)
+        x.initgateway()
+        assert x.gw
+        try:
+            homedir = py.path.local(py.std.os.environ['HOME'])
+            expected = homedir.join(name) 
+            assert x.gw_remotepath == str(expected)
+            assert x.localdest == expected 
+        finally:
+            x.gw.exit()
+
+
+    def test_initgateway_ssh_and_remotepath(self):
+        option = py.test.config.option
+        if option.sshtarget is None: 
+            py.test.skip("no known ssh target, use -S to set one")
+        x = HostInfo("%s" % (option.sshtarget, ))
+        x.initgateway()
+        assert x.gw
+        assert x.gw_remotepath.endswith(x.relpath)
+        channel = x.gw.remote_exec("""
+            import os
+            homedir = os.environ['HOME']
+            relpath = channel.receive()
+            path = os.path.join(homedir, relpath)
+            channel.send(path) 
+        """)
+        channel.send(x.relpath)
+        res = channel.receive()
+        assert res == x.gw_remotepath
+        assert x.localdest is None
+
+class TestSyncing(DirSetup): 
+    def test_hrsync_filter(self):
+        self.source.ensure("dir", "file.txt")
+        self.source.ensure(".svn", "entries")
+        self.source.ensure(".somedotfile", "moreentries")
+        self.source.ensure("somedir", "editfile~")
+        syncer = HostRSync()
+        l = list(self.source.visit(rec=syncer.filter,
+                                   fil=syncer.filter))
+        assert len(l) == 3
+        basenames = [x.basename for x in l]
+        assert 'dir' in basenames
+        assert 'file.txt' in basenames
+        assert 'somedir' in basenames
+
+    def test_hrsync_one_host(self):
+        h1 = HostInfo("localhost:%s" % self.dest)
+        finished = []
+        rsync = HostRSync()
+        h1.initgateway()
+        rsync.add_target_host(h1)
+        self.source.join("hello.py").write("world")
+        rsync.send(self.source)
+        assert self.dest.join("hello.py").check()
+
+    def test_hrsync_same_host_twice(self):
+        h1 = HostInfo("localhost:%s" % self.dest)
+        h2 = HostInfo("localhost:%s" % self.dest)
+        finished = []
+        rsync = HostRSync()
+        l = []
+        h1.initgateway()
+        res1 = rsync.add_target_host(h1)
+        assert res1
+        res2 = rsync.add_target_host(h2)
+        assert not res2
+
+class TestHostManager(DirSetup):
+    def test_hostmanager_init_rsync_topdir(self):
+        dir2 = self.source.ensure("dir1", "dir2", dir=1)
+        dir2.ensure("hello")
+        config = py.test.config._reparse([self.source])
+        hm = HostManager([HostInfo("localhost:" + str(self.dest))], config)
+        events = []
+        hm.init_rsync(reporter=events.append)
+        assert self.dest.join("dir1").check()
+        assert self.dest.join("dir1", "dir2").check()
+        assert self.dest.join("dir1", "dir2", 'hello').check()
+
+    def test_hostmanager_init_rsync_rsync_roots(self):
+        dir2 = self.source.ensure("dir1", "dir2", dir=1)
+        dir2.ensure("hello")
+        self.source.ensure("bogusdir", "file")
+        self.source.join("conftest.py").write(py.code.Source("""
+            dist_rsync_roots = ['dir1/dir2']
+        """))
+        config = py.test.config._reparse([self.source])
+        hm = HostManager([HostInfo("localhost:" + str(self.dest))], config)
+        events = []
+        hm.init_rsync(reporter=events.append)
+        assert self.dest.join("dir1").check()
+        assert self.dest.join("dir1", "dir2").check()
+        assert self.dest.join("dir1", "dir2", 'hello').check()
+        assert not self.dest.join("bogus").check()

Modified: py/trunk/py/test/rsession/testing/test_master.py
==============================================================================
--- py/trunk/py/test/rsession/testing/test_master.py	(original)
+++ py/trunk/py/test/rsession/testing/test_master.py	Sun Feb  4 15:05:01 2007
@@ -9,18 +9,19 @@
 if sys.platform == 'win32':
     py.test.skip("rsession is unsupported on Windows.")
 
-from py.__.test.rsession.master import dispatch_loop, setup_slave, MasterNode, randomgen
+from py.__.test.rsession.master import dispatch_loop, MasterNode, randomgen
+from py.__.test.rsession.slave import setup_slave 
 from py.__.test.rsession.outcome import ReprOutcome, Outcome 
-from py.__.test.rsession.testing.test_slave import funcpass_spec, funcfail_spec, funchang_spec
 from py.__.test.rsession import report
 from py.__.test.rsession.hostmanage import HostInfo
 
 def setup_module(mod):
     # bind an empty config
-    config = py.test.config._reparse([])
+    mod.tmpdir = tmpdir = py.test.ensuretemp(mod.__name__)
+    # to avoid rsyncing
+    config = py.test.config._reparse([tmpdir])
     config._overwrite('dist_taskspernode', 10)
-    mod.pkgdir = py.path.local(py.__file__).dirpath().dirpath()
-    mod.rootcol = py.test.collect.Directory(mod.pkgdir)
+    mod.rootcol = config._getcollector(tmpdir)
 
 class DummyGateway(object):
     def __init__(self):
@@ -92,46 +93,69 @@
             node.pending.pop()
     dispatch_loop(masternodes, itemgenerator, shouldstop, waiter=waiter)
 
-def test_slave_setup():
-    gw = py.execnet.PopenGateway()
-    config = py.test.config._reparse([])
-    channel = setup_slave(gw, pkgdir, config)
-    spec = rootcol._getitembynames(funcpass_spec)._get_collector_trail()
-    channel.send(spec)
-    output = ReprOutcome(channel.receive())
-    assert output.passed
-    channel.send(42)
-    channel.waitclose(10)
-    gw.exit()
-
-def test_slave_running():
-    def simple_report(event):
-        if not isinstance(event, report.ReceivedItemOutcome):
-            return
-        item = event.item
-        if item.code.name == 'funcpass':
-            assert event.outcome.passed
-        else:
-            assert not event.outcome.passed
-    
-    def open_gw():
-        gw = py.execnet.PopenGateway()
-        gw.host = HostInfo("localhost")
-        gw.host.gw = gw
-        config = py.test.config._reparse([])
-        channel = setup_slave(gw, pkgdir, config)
-        mn = MasterNode(channel, simple_report, {})
-        return mn
-    
-    master_nodes = [open_gw(), open_gw(), open_gw()]
-    funcpass_item = rootcol._getitembynames(funcpass_spec)
-    funcfail_item = rootcol._getitembynames(funcfail_spec)
-    itemgenerator = iter([funcfail_item] + 
-                         [funcpass_item] * 5 + [funcfail_item] * 5)
-    shouldstop = lambda : False
-    dispatch_loop(master_nodes, itemgenerator, shouldstop)
+class TestSlave:
+    def setup_class(cls):
+        cls.tmpdir = tmpdir = py.test.ensuretemp(cls.__name__)
+        pkgpath = tmpdir.join("pkg")
+        pkgpath.ensure("__init__.py")
+        pkgpath.join("test_something.py").write(py.code.Source("""
+            def funcpass(): 
+                pass
+
+            def funcfail():
+                raise AssertionError("hello world")
+        """))
+        cls.config = py.test.config._reparse([tmpdir])
+        assert cls.config.topdir == tmpdir
+        cls.rootcol = cls.config._getcollector(tmpdir)
+
+    def _gettrail(self, *names):
+        item = self.rootcol._getitembynames(names)
+        return self.config.get_collector_trail(item) 
+        
+    def test_slave_setup(self):
+        host = HostInfo("localhost:%s" %(self.tmpdir,))
+        host.initgateway()
+        channel = setup_slave(host, self.config)
+        spec = self._gettrail("pkg", "test_something.py", "funcpass")
+        print "sending", spec
+        channel.send(spec)
+        output = ReprOutcome(channel.receive())
+        assert output.passed
+        channel.send(42)
+        channel.waitclose(10)
+        host.gw.exit()
+
+    def test_slave_running(self):
+        py.test.skip("XXX test broken, needs refactoring")
+        def simple_report(event):
+            if not isinstance(event, report.ReceivedItemOutcome):
+                return
+            item = event.item
+            if item.code.name == 'funcpass':
+                assert event.outcome.passed
+            else:
+                assert not event.outcome.passed
+        
+        def open_gw():
+            gw = py.execnet.PopenGateway()
+            gw.host = HostInfo("localhost")
+            gw.host.gw = gw
+            config = py.test.config._reparse([tmpdir])
+            channel = setup_slave(gw.host, config)
+            mn = MasterNode(channel, simple_report, {})
+            return mn
+        
+        master_nodes = [open_gw(), open_gw(), open_gw()]
+        funcpass_item = rootcol._getitembynames(funcpass_spec)
+        funcfail_item = rootcol._getitembynames(funcfail_spec)
+        itemgenerator = iter([funcfail_item] + 
+                             [funcpass_item] * 5 + [funcfail_item] * 5)
+        shouldstop = lambda : False
+        dispatch_loop(master_nodes, itemgenerator, shouldstop)
 
 def test_slave_running_interrupted():
+    py.test.skip("XXX test broken, needs refactoring")
     #def simple_report(event):
     #    if not isinstance(event, report.ReceivedItemOutcome):
     #        return
@@ -146,7 +170,7 @@
         gw = py.execnet.PopenGateway()
         gw.host = HostInfo("localhost")
         gw.host.gw = gw
-        config = py.test.config._reparse([])
+        config = py.test.config._reparse([tmpdir])
         channel = setup_slave(gw, pkgdir, config)
         mn = MasterNode(channel, reports.append, {})
         return mn, gw, channel

Modified: py/trunk/py/test/rsession/testing/test_rest.py
==============================================================================
--- py/trunk/py/test/rsession/testing/test_rest.py	(original)
+++ py/trunk/py/test/rsession/testing/test_rest.py	Sun Feb  4 15:05:01 2007
@@ -52,7 +52,7 @@
                                      'localhost\n\n')
     
     def test_report_HostRSyncing(self):
-        event = report.HostRSyncing(HostInfo('localhost', '/foo/bar'))
+        event = report.HostRSyncing(HostInfo('localhost:/foo/bar'))
         reporter.report(event)
         assert stdout.getvalue() == ('::\n\n   localhost: RSYNC ==> '
                                      '/foo/bar\n\n')

Modified: py/trunk/py/test/rsession/testing/test_rsession.py
==============================================================================
--- py/trunk/py/test/rsession/testing/test_rsession.py	(original)
+++ py/trunk/py/test/rsession/testing/test_rsession.py	Sun Feb  4 15:05:01 2007
@@ -4,38 +4,16 @@
 
 import py
 from py.__.test.rsession import report
-from py.__.test.rsession.rsession import RSession, parse_directories,\
-    parse_directories
-from py.__.test.rsession.hostmanage import HostOptions, HostManager,\
-     HostInfo
+from py.__.test.rsession.rsession import RSession 
+from py.__.test.rsession.hostmanage import HostManager, HostInfo
 from py.__.test.rsession.testing.test_slave import funcfail_spec,\
     funcpass_spec, funcskip_spec, funcprint_spec, funcprintfail_spec, \
     funcoptioncustom_spec
 
 def setup_module(mod):
     mod.pkgdir = py.path.local(py.__file__).dirpath()
+    mod.tmpdir = py.test.ensuretemp(mod.__name__)
 
-def test_setup_non_existing_hosts(): 
-    setup_events = []
-    hosts = [HostInfo("alskdjalsdkjasldkajlsd")]
-    config = py.test.config._reparse([])
-    hm = HostManager(hosts, config)
-    cmd = "hm.init_hosts(setup_events.append)"
-    py.test.raises((py.process.cmdexec.Error, IOError, EOFError), cmd)
-    #assert setup_events
-
-def test_getpkdir():
-    one = pkgdir.join("initpkg.py")
-    two = pkgdir.join("path", "__init__.py")
-    p1 = RSession.getpkgdir(one)
-    p2 = RSession.getpkgdir(two) 
-    assert p1 == p2
-    assert p1 == pkgdir 
-
-def test_getpkdir_no_inits():
-    tmp = py.test.ensuretemp("getpkdir1")
-    fn = tmp.ensure("hello.py")
-    assert RSession.getpkgdir(fn) == fn
 
 #def test_make_colitems():
 #    one = pkgdir.join("initpkg.py")
@@ -74,10 +52,11 @@
 
 class TestRSessionRemote: 
     def test_example_distribution_minus_x(self):
+        destdir = py.test.ensuretemp("example_dist_dest_x")
         tmpdir = py.test.ensuretemp("example_distribution_minus_x")
         tmpdir.ensure("sub", "conftest.py").write(py.code.Source("""
-            dist_hosts = [%r]
-        """ % ('localhost',)))
+            dist_hosts = ['localhost:%s']
+        """ % destdir))
         tmpdir.ensure("sub", "__init__.py")
         tmpdir.ensure("sub", "test_one.py").write(py.code.Source("""
             def test_1(): 
@@ -92,8 +71,7 @@
             def test_4(someargs):
                 pass
         """))
-        args = [str(tmpdir.join("sub")), "-x"]
-        config = py.test.config._reparse(args)
+        config = py.test.config._reparse([tmpdir.join("sub"), '-x'])
         rsession = RSession(config)
         allevents = []
         rsession.main(reporter=allevents.append)
@@ -102,13 +80,14 @@
         assert len(testevents) == 3
         assert rsession.checkfun()
 
-    def test_example_distribution(self):
+    def test_distribution_rsync_roots_example(self):
+        destdir = py.test.ensuretemp("example_dist_destdir")
         subdir = "sub_example_dist"
         tmpdir = py.test.ensuretemp("example_distribution")
         tmpdir.ensure(subdir, "conftest.py").write(py.code.Source("""
-            dist_hosts = [%r]
+            dist_hosts = ["localhost:%s"]
             dist_rsync_roots = ["%s", "../py"]
-        """ % ('localhost', tmpdir.join(subdir), )))
+        """ % (destdir, tmpdir.join(subdir), )))
         tmpdir.ensure(subdir, "__init__.py")
         tmpdir.ensure(subdir, "test_one.py").write(py.code.Source("""
             def test_1(): 
@@ -124,16 +103,18 @@
             def test_6():
                 import py
                 assert py.__file__ != '%s'
-        """ % (str(tmpdir.join(subdir)), py.__file__)))
-        tmpdir.join("py").mksymlinkto(py.path.local(py.__file__).dirpath())
-        args = [str(tmpdir.join(subdir))]
-        config = py.test.config._reparse(args)
-        rsession = RSession(config, optimise_localhost=False)
+        """ % (tmpdir.join(subdir), py.__file__)))
+        destdir.join("py").mksymlinkto(py.path.local(py.__file__).dirpath())
+        config = py.test.config._reparse([tmpdir.join(subdir)])
+        assert config.topdir == tmpdir
+        assert not tmpdir.join("__init__.py").check()
+        rsession = RSession(config)
         allevents = []
         rsession.main(reporter=allevents.append) 
         testevents = [x for x in allevents 
                         if isinstance(x, report.ReceivedItemOutcome)]
         assert len(testevents)
+        print testevents
         passevents = [i for i in testevents if i.outcome.passed]
         failevents = [i for i in testevents if i.outcome.excinfo]
         skippedevents = [i for i in testevents if i.outcome.skipped]
@@ -156,13 +137,11 @@
         
     def test_setup_teardown_ssh(self):
         hosts = [HostInfo('localhost')]
-        parse_directories(hosts)
         setup_events = []
         teardown_events = []
         
-        config = py.test.config._reparse([])
-        opts = HostOptions(optimise_localhost=False)
-        hm = HostManager(hosts, config, opts)
+        config = py.test.config._reparse([tmpdir])
+        hm = HostManager(hosts, config)
         nodes = hm.init_hosts(setup_events.append)
         hm.teardown_hosts(teardown_events.append, 
                        [node.channel for node in nodes], nodes)
@@ -184,12 +163,10 @@
 
     def test_setup_teardown_run_ssh(self):
         hosts = [HostInfo('localhost')]
-        parse_directories(hosts)
         allevents = []
         
         config = py.test.config._reparse([])
-        opts = HostOptions(optimise_localhost=False)
-        hm = HostManager(hosts, config, opts)
+        hm = HostManager(hosts, config)
         nodes = hm.init_hosts(allevents.append)
         
         from py.__.test.rsession.testing.test_executor \
@@ -223,47 +200,11 @@
         passed_stdout = [i for i in passed if i.outcome.stdout.find('samfing') != -1]
         assert len(passed_stdout) == len(nodes), passed
 
-    def test_config_pass(self):
-        """ Tests options object passing master -> server
-        """
-        allevents = []
-        hosts = [HostInfo('localhost')]
-        parse_directories(hosts)
-        config = py.test.config._reparse([])
-        config._overwrite('custom', 'custom')
-        # we need to overwrite default list to serialize
-        from py.__.test.rsession.master import defaultconftestnames
-        defaultconftestnames.append("custom")
-        try:
-            opts = HostOptions(optimise_localhost=False)
-            hm = HostManager(hosts, config, opts)
-            nodes = hm.init_hosts(allevents.append)
-
-            rootcol = py.test.collect.Directory(pkgdir.dirpath())
-            itempass = rootcol._getitembynames(funcoptioncustom_spec)
-
-            for node in nodes:
-                node.send(itempass)
-
-            hm.teardown_hosts(allevents.append, [node.channel for node in nodes], nodes)
-            events = [i for i in allevents 
-                            if isinstance(i, report.ReceivedItemOutcome)]
-            passed = [i for i in events 
-                            if i.outcome.passed]
-            skipped = [i for i in events 
-                            if i.outcome.skipped]
-            assert len(passed) == 1 * len(nodes)
-            assert len(skipped) == 0
-            assert len(events) == len(passed)
-        finally:
-            defaultconftestnames.remove("custom")
-    
     def test_nice_level(self):
         """ Tests if nice level behaviour is ok
         """
         allevents = []
         hosts = [HostInfo('localhost')]
-        parse_directories(hosts)
         tmpdir = py.test.ensuretemp("nice")
         tmpdir.ensure("__init__.py")
         tmpdir.ensure("conftest.py").write(py.code.Source("""
@@ -283,45 +224,6 @@
                         if isinstance(x, report.ReceivedItemOutcome)]
         passevents = [x for x in testevents if x.outcome.passed]
         assert len(passevents) == 1
-    
-class XxxTestDirectories(object):
-    # need complete rewrite, and unsure if it makes sense at all
-    def test_simple_parse(self):
-        sshhosts = [HostInfo(i) for i in ['h1', 'h2', 'h3']]
-        parse_directories(sshhosts)
-    
-    def test_sophisticated_parse(self):
-        sshhosts = ['a at h1:/tmp', 'h2:tmp', 'h3']
-        dirs = parse_directories(sshhosts)
-        assert py.builtin.sorted(
-            dirs.values()) == ['/tmp', 'pytestcache', 'tmp']
-    
-    def test_parse_multiple_hosts(self):
-        hosts = ['h1', 'h1', 'h1:/tmp']
-        dirs = parse_directories(hosts)
-        assert dirs == {(0, 'h1'): 'pytestcache', (1, 'h1'): 'pytestcache', 
-            (2, 'h1'):'/tmp'}
-
-class TestInithosts(object):
-    def test_inithosts(self):
-        testevents = []
-        hostnames = ['h1:/tmp', 'h1:/tmp', 'h1:/other', 'h2', 'h2:home']
-        hosts = [HostInfo(i) for i in hostnames]
-        parse_directories(hosts)
-        config = py.test.config._reparse([])
-        opts = HostOptions(do_sync=False, create_gateways=False)
-        hm = HostManager(hosts, config, opts)
-        nodes = hm.init_hosts(testevents.append)        
-        events = [i for i in testevents if isinstance(i, report.HostRSyncing)]
-        assert len(events) == 4
-        assert events[0].host.hostname == 'h1'
-        assert events[0].host.relpath == '/tmp-h1'
-        assert events[1].host.hostname == 'h1'
-        assert events[1].host.relpath == '/other-h1'
-        assert events[2].host.hostname == 'h2'
-        assert events[2].host.relpath == 'pytestcache-h2'
-        assert events[3].host.hostname == 'h2'
-        assert events[3].host.relpath == 'home-h2'
         
 def test_rsession_no_disthost():
     tmpdir = py.test.ensuretemp("rsession_no_disthost")

Deleted: /py/trunk/py/test/rsession/testing/test_rsync.py
==============================================================================
--- /py/trunk/py/test/rsession/testing/test_rsync.py	Sun Feb  4 15:05:01 2007
+++ (empty file)
@@ -1,30 +0,0 @@
-
-""" RSync filter test
-"""
-
-import py
-from py.__.test.rsession.hostmanage import HostRSync
-
-def test_rsync():
-    tmpdir = py.test.ensuretemp("rsync_rsession")
-    tmpdir.ensure("a", dir=True)
-    tmpdir.ensure("b", dir=True)
-    tmpdir.ensure("conftest.py").write(py.code.Source("""
-    dist_rsyncroots = ['a']
-    """))
-    tmpdir.join("a").ensure("x")
-    adir = tmpdir.join("a").ensure("xy", dir=True)
-    adir.ensure("conftest.py").write(py.code.Source("""
-    dist_rsyncroots = ['b', 'conftest.py']
-    """))
-    adir.ensure("a", dir=True)
-    adir.ensure("b", dir=True)
-    config = py.test.config._reparse([str(tmpdir)])
-    h = HostRSync(config)
-    h.sourcedir = config.topdir
-    assert h.filter(str(tmpdir.join("a")))
-    assert not h.filter(str(tmpdir.join("b")))
-    assert h.filter(str(tmpdir.join("a").join("x")))
-    assert h.filter(str(adir.join("conftest.py")))
-    assert not h.filter(str(adir.join("a")))
-    assert h.filter(str(adir.join("b")))

Modified: py/trunk/py/test/rsession/testing/test_slave.py
==============================================================================
--- py/trunk/py/test/rsession/testing/test_slave.py	(original)
+++ py/trunk/py/test/rsession/testing/test_slave.py	Sun Feb  4 15:05:01 2007
@@ -11,6 +11,7 @@
     py.test.skip("rsession is unsupported on Windows.")
 
 def setup_module(module):
+    module.tmpdir = py.test.ensuretemp(module.__name__)
     module.rootdir = py.path.local(py.__file__).dirpath().dirpath()
     module.rootcol = py.test.collect.Directory(rootdir)
 
@@ -107,64 +108,11 @@
     assert not outcome.setupfailure 
     assert outcome.excinfo
 
-def test_slave_main_simple(): 
-    res = []
-    failitem = rootcol._getitembynames(funcfail_spec)
-    passitem = rootcol._getitembynames(funcpass_spec)
-    q = [None, 
-         passitem._get_collector_trail(),
-         failitem._get_collector_trail()
-        ]
-    config = py.test.config._reparse([])
-    pidinfo = PidInfo()
-    slave_main(q.pop, res.append, str(rootdir), config, pidinfo)
-    assert len(res) == 2
-    res_repr = [ReprOutcome(r) for r in res]
-    assert not res_repr[0].passed and res_repr[1].passed
-
 def test_slave_run_different_stuff():
     node = gettestnode()
     node.run(rootcol._getitembynames("py doc log.txt".split()).
              _get_collector_trail())
 
-def test_slave_setup_exit():
-    tmp = py.test.ensuretemp("slaveexit")
-    tmp.ensure("__init__.py")
-    q = py.std.Queue.Queue()
-    config = py.test.config._reparse([tmp])
-    
-    class C:
-        res = []
-        def __init__(self):
-            self.q = [str(tmp),
-                config.make_repr(conftestnames=['dist_nicelevel']),
-                funchang_spec,
-                42,
-                funcpass_spec]
-            self.q.reverse()
-    
-        def receive(self):
-            return self.q.pop()
-        
-        def setcallback(self, callback):
-            import thread
-            def f():
-                while 1:
-                    callback(self.q.pop())
-            f()
-            #thread.start_new_thread(f, ())
-
-        def close(self):
-            pass
-        
-        send = res.append
-    try:
-        exec py.code.Source(setup, "setup()").compile() in {'channel':C()}
-    except SystemExit:
-        pass
-    else:
-        py.test.fail("Did not exit")
-
 def test_pidinfo():
     if not hasattr(os, 'fork') or not hasattr(os, 'waitpid'):
         py.test.skip("Platform does not support fork")



More information about the pytest-commit mailing list