[py-svn] r36441 - py/dist/py/test/rsession

fijal at codespeak.net fijal at codespeak.net
Wed Jan 10 22:39:43 CET 2007


Author: fijal
Date: Wed Jan 10 22:39:39 2007
New Revision: 36441

Added:
   py/dist/py/test/rsession/rsync_remote.py
Modified:
   py/dist/py/test/rsession/rsync.py
Log:
Move remote part of rsync to separate file.


Modified: py/dist/py/test/rsession/rsync.py
==============================================================================
--- py/dist/py/test/rsession/rsync.py	(original)
+++ py/dist/py/test/rsession/rsync.py	Wed Jan 10 22:39:39 2007
@@ -6,7 +6,7 @@
 
     def __init__(self, **options):
         for name in options:
-            assert name in ('delete',)
+            assert name in ('delete','callback',)
         self.options = options
         self.channels = {}
         self.receivequeue = Queue()
@@ -32,16 +32,7 @@
         # send modified file to clients
         while self.channels:
             channel, req = self.receivequeue.get()
-            if req == 42:
-                for link in self.links:
-                    channel.send(link)
-                # completion marker, this host is done
-                channel.send(42)
-            elif req == 41:
-                finishedcallback = self.channels.pop(channel)
-                if finishedcallback:
-                    finishedcallback()
-            elif req is None:
+            if req is None:
                 # end-of-channel
                 if channel in self.channels:
                     # too early!  we must have got an error
@@ -50,21 +41,36 @@
                     raise IOError('connection unexpectedly closed: %s ' % (
                         channel.gateway,))
             else:
-                modified_rel_path, checksum = req
-                modifiedpath = os.path.join(self.sourcedir, *modified_rel_path)
-                f = open(modifiedpath, 'rb')
-                data = f.read()
-                f.close()
-                if checksum is not None and checksum == md5.md5(data).digest():
-                    data = None     # not really modified
+                command, data = req
+                if command == "links":
+                    for link in self.links:
+                        channel.send(link)
+                    # completion marker, this host is done
+                    channel.send(42)
+                elif command == "done":
+                    finishedcallback = self.channels.pop(channel)
+                    if finishedcallback:
+                        finishedcallback()
+                elif command == "ack":
+                    pass
+                elif command == "send":
+                    modified_rel_path, checksum = data
+                    modifiedpath = os.path.join(self.sourcedir, *modified_rel_path)
+                    f = open(modifiedpath, 'rb')
+                    data = f.read()
+                    f.close()
+                    if checksum is not None and checksum == md5.md5(data).digest():
+                        data = None     # not really modified
+                    else:
+                        # ! there is a reason for the interning:
+                        # sharing multiple copies of the file's data
+                        data = intern(data)
+                        #print channel.gateway.getremoteaddress(),
+                        #print '/'.join(modified_rel_path)
+                    channel.send(data)
+                    del data
                 else:
-                    # ! there is a reason for the interning:
-                    # sharing multiple copies of the file's data
-                    data = intern(data)
-                    #print channel.gateway.getremoteaddress(),
-                    #print '/'.join(modified_rel_path)
-                channel.send(data)
-                del data
+                    assert "Unknown command %s" % command
 
     def _broadcast(self, msg):
         for channel in self.channels:
@@ -104,87 +110,6 @@
         else:
             raise ValueError, "cannot sync %r" % (path,)
 
+REMOTE_SOURCE = py.path.local(__file__).dirpath().\
+                join('rsync_remote.py').open().read()
 
-REMOTE_SOURCE = """
-    import os, stat, shutil, md5
-    destdir, options = channel.receive() 
-    modifiedfiles = []
-
-    def remove(path):
-        assert path.startswith(destdir)
-        try:
-            os.unlink(path)
-        except OSError:
-            # assume it's a dir
-            shutil.rmtree(path)
-
-    def receive_directory_structure(path, relcomponents):
-        try:
-            st = os.lstat(path)
-        except OSError:
-            st = None
-        msg = channel.receive()
-        if isinstance(msg, list):
-            if st and not stat.S_ISDIR(st.st_mode):
-                os.unlink(path)
-                st = None
-            if not st:
-                os.makedirs(path)
-            entrynames = {}
-            for entryname in msg:
-                receive_directory_structure(os.path.join(path, entryname),
-                    relcomponents + [entryname])
-                entrynames[entryname] = True
-            if options.get('delete'): 
-                for othername in os.listdir(path):
-                    if othername not in entrynames:
-                        otherpath = os.path.join(path, othername)
-                        remove(otherpath)
-        elif msg is not None:
-            checksum = None
-            if st:
-                if stat.S_ISREG(st.st_mode):
-                    msg_mtime, msg_size = msg
-                    if msg_size != st.st_size:
-                        pass
-                    elif msg_mtime != st.st_mtime:
-                        f = open(path, 'rb')
-                        checksum = md5.md5(f.read()).digest()
-                        f.close()
-                    else:
-                        return    # already fine
-                else:
-                    remove(path)
-            channel.send((relcomponents, checksum))
-            modifiedfiles.append((path, msg))
-    receive_directory_structure(destdir, [])
-
-    STRICT_CHECK = False    # seems most useful this way for py.test
-
-    for path, (time, size) in modifiedfiles:
-        data = channel.receive()
-        if data is not None:
-            if STRICT_CHECK and len(data) != size:
-                raise IOError('file modified during rsync: %r' % (path,))
-            f = open(path, 'wb')
-            f.write(data)
-            f.close()
-        os.utime(path, (time, time))
-        del data
-    channel.send(42)
-    
-    msg = channel.receive()
-    while msg is not 42:
-        # we get symlink
-        _type, relpath, linkpoint = msg
-        assert _type == "link"
-        path = os.path.join(destdir, relpath)
-        try:
-            os.unlink(path)
-        except OSError:
-            pass
-        
-        os.symlink(os.path.join(destdir, linkpoint), path)
-        msg = channel.receive()
-    channel.send(41)
-"""

Added: py/dist/py/test/rsession/rsync_remote.py
==============================================================================
--- (empty file)
+++ py/dist/py/test/rsession/rsync_remote.py	Wed Jan 10 22:39:39 2007
@@ -0,0 +1,82 @@
+import os, stat, shutil, md5
+destdir, options = channel.receive() 
+modifiedfiles = []
+
+def remove(path):
+    assert path.startswith(destdir)
+    try:
+        os.unlink(path)
+    except OSError:
+        # assume it's a dir
+        shutil.rmtree(path)
+
+def receive_directory_structure(path, relcomponents):
+    try:
+        st = os.lstat(path)
+    except OSError:
+        st = None
+    msg = channel.receive()
+    if isinstance(msg, list):
+        if st and not stat.S_ISDIR(st.st_mode):
+            os.unlink(path)
+            st = None
+        if not st:
+            os.makedirs(path)
+        entrynames = {}
+        for entryname in msg:
+            receive_directory_structure(os.path.join(path, entryname),
+                relcomponents + [entryname])
+            entrynames[entryname] = True
+        if options.get('delete'): 
+            for othername in os.listdir(path):
+                if othername not in entrynames:
+                    otherpath = os.path.join(path, othername)
+                    remove(otherpath)
+    elif msg is not None:
+        checksum = None
+        if st:
+            if stat.S_ISREG(st.st_mode):
+                msg_mtime, msg_size = msg
+                if msg_size != st.st_size:
+                    pass
+                elif msg_mtime != st.st_mtime:
+                    f = open(path, 'rb')
+                    checksum = md5.md5(f.read()).digest()
+                    f.close()
+                else:
+                    return    # already fine
+            else:
+                remove(path)
+        channel.send(("send", (relcomponents, checksum)))
+        modifiedfiles.append((path, msg))
+receive_directory_structure(destdir, [])
+
+STRICT_CHECK = False    # seems most useful this way for py.test
+
+for path, (time, size) in modifiedfiles:
+    data = channel.receive()
+    channel.send(("ack", path))
+    if data is not None:
+        if STRICT_CHECK and len(data) != size:
+            raise IOError('file modified during rsync: %r' % (path,))
+        f = open(path, 'wb')
+        f.write(data)
+        f.close()
+    os.utime(path, (time, time))
+    del data
+channel.send(("links", None))
+
+msg = channel.receive()
+while msg is not 42:
+    # we get symlink
+    _type, relpath, linkpoint = msg
+    assert _type == "link"
+    path = os.path.join(destdir, relpath)
+    try:
+        os.unlink(path)
+    except OSError:
+        pass
+
+    os.symlink(os.path.join(destdir, linkpoint), path)
+    msg = channel.receive()
+channel.send(("done", None))


More information about the py-svn mailing list