Ticket #3462: t3462-2.diff

File t3462-2.diff, 5.2 KB (added by warner, 5 years ago)

new patch, adds tests

  • twisted/test/test_ftp.py

     
    99 
    1010import os 
    1111import errno 
     12from StringIO import StringIO 
    1213 
    1314from zope.interface import implements 
    1415 
     
    26162617 
    26172618    def test_write(self): 
    26182619        """ 
    2619         Test L{ftp.IWriteFile}: the implementation should have a receive method 
    2620         returning a C{Deferred} with fires with a consumer ready to receive 
    2621         data to be written. 
     2620        Test L{ftp.IWriteFile}: the implementation should have a receive 
     2621        method returning a C{Deferred} with fires with a consumer ready to 
     2622        receive data to be written. It should also have a close() method that 
     2623        returns a Deferred. 
    26222624        """ 
    26232625        content = 'elbbow\n' 
    26242626        def cbGet(writer): 
    2625             return writer.receive().addCallback(cbReceive) 
    2626         def cbReceive(consumer): 
     2627            return writer.receive().addCallback(cbReceive, writer) 
     2628        def cbReceive(consumer, writer): 
    26272629            producer = TestProducer(content, consumer) 
    26282630            consumer.registerProducer(None, True) 
    26292631            producer.start() 
    26302632            consumer.unregisterProducer() 
     2633            return writer.close().addCallback(cbClose) 
     2634        def cbClose(ignored): 
    26312635            self.assertEquals(self.getFileContent(), content) 
    26322636        return self.getFileWriter().addCallback(cbGet) 
    26332637 
     
    26692673        Return the content of the temporary file. 
    26702674        """ 
    26712675        return self.root.child(self.filename).getContent() 
     2676 
     2677 
     2678class CloseTestWriter: 
     2679    implements(ftp.IWriteFile) 
     2680    closeStarted = False 
     2681    def receive(self): 
     2682        self.s = StringIO() 
     2683        fc = ftp.FileConsumer(self.s) 
     2684        return defer.succeed(fc) 
     2685    def close(self): 
     2686        self.closeStarted = True 
     2687        return self.d 
     2688 
     2689class CloseTestShell: 
     2690    def openForWriting(self, segs): 
     2691        return defer.succeed(self.writer) 
     2692 
     2693class FTPCloseTest(unittest.TestCase): 
     2694    def test_write(self): 
     2695        # Confirm that FTP uploads (i.e. ftp_STOR) call and wait upon the 
     2696        # IWriteFile object's close() method. 
     2697        f = ftp.FTP() 
     2698        f.workingDirectory = ["root"] 
     2699        f.shell = CloseTestShell() 
     2700        f.shell.writer = CloseTestWriter() 
     2701        f.shell.writer.d = defer.Deferred() 
     2702        f.factory = ftp.FTPFactory() 
     2703        f.factory.timeOut = None 
     2704        f.makeConnection(StringIO()) 
     2705 
     2706        di = ftp.DTP() 
     2707        di.factory = ftp.DTPFactory(f) 
     2708        f.dtpInstance = di 
     2709        di.makeConnection(None)# 
     2710 
     2711        stor_done = [] 
     2712        d = f.ftp_STOR("path") 
     2713        d.addCallback(stor_done.append) 
     2714        # the writer is still receiving data 
     2715        self.assertFalse(f.shell.writer.closeStarted, "close() called early") 
     2716        di.dataReceived("some data here") 
     2717        self.assertFalse(f.shell.writer.closeStarted, "close() called early") 
     2718        di.connectionLost("reason is ignored") 
     2719        # now we should be waiting in close() 
     2720        self.assertTrue(f.shell.writer.closeStarted, "close() not called") 
     2721        self.assertFalse(stor_done) 
     2722        f.shell.writer.d.callback("allow close() to finish") 
     2723        self.assertTrue(stor_done) 
     2724 
     2725        return d # just in case an errback occurred 
  • twisted/protocols/ftp.py

     
    11221122                cons = ASCIIConsumerWrapper(cons) 
    11231123 
    11241124            d = self.dtpInstance.registerConsumer(cons) 
    1125             d.addCallbacks(cbSent, ebSent) 
    11261125 
    11271126            # Tell them what to doooo 
    11281127            if self.dtpInstance.isConnected: 
     
    11351134        def cbOpened(file): 
    11361135            d = file.receive() 
    11371136            d.addCallback(cbConsumer) 
     1137            d.addCallback(lambda ignored: file.close()) 
     1138            d.addCallbacks(cbSent, ebSent) 
    11381139            return d 
    11391140 
    11401141        def ebOpened(err): 
     
    15071508        @rtype: C{Deferred} of C{IConsumer} 
    15081509        """ 
    15091510 
     1511    def close(): 
     1512        """ 
     1513        Perform any post-write work that needs to be done. This method may 
     1514        only be invoked once on each provider, and will always be invoked 
     1515        after receive(). 
    15101516 
     1517        @rtype: C{Deferred} of anything: the value is ignored. The FTP client 
     1518        will not see their upload request complete until this Deferred has 
     1519        been fired. 
     1520        """ 
    15111521 
    15121522def _getgroups(uid): 
    15131523    """Return the primary and supplementary groups for the given UID. 
     
    18681878        # FileConsumer will close the file object 
    18691879        return defer.succeed(FileConsumer(self.fObj)) 
    18701880 
     1881    def close(self): 
     1882        return defer.succeed(None) 
    18711883 
    18721884 
    18731885class FTPRealm: 
  • twisted/vfs/adapters/ftp.py

     
    295295        """ 
    296296        return defer.succeed(IConsumer(self.node)) 
    297297 
     298    def close(self): 
     299        """ 
     300        Perform post-write actions. 
     301        """ 
     302        return defer.succeed(None) 
    298303 
    299304 
    300305class _FileToConsumerAdapter(object):