From 1b7b3bd0d4c92d8a2774106979a084485adf9f8a Mon Sep 17 00:00:00 2001
From: david-sarah <david-sarah@jacaranda.org>
Date: Sat, 3 Sep 2011 15:23:04 -0700
Subject: [PATCH] SFTP: add a comment about a subtle interaction between
 OverwriteableFileConsumer and GeneralSFTPFile, and test the case it is
 commenting on.

---
 src/allmydata/frontends/sftpd.py | 6 ++++++
 src/allmydata/test/test_sftp.py  | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/src/allmydata/frontends/sftpd.py b/src/allmydata/frontends/sftpd.py
index 59952a99..887786e7 100644
--- a/src/allmydata/frontends/sftpd.py
+++ b/src/allmydata/frontends/sftpd.py
@@ -461,6 +461,12 @@ class OverwriteableFileConsumer(PrefixingLogMixin):
         The caller must perform no more overwrites until the Deferred has fired."""
 
         if noisy: self.log(".read(%r, %r), current_size = %r" % (offset, length, self.current_size), level=NOISY)
+
+        # Note that the overwrite method is synchronous. When a write request is processed
+        # (e.g. a writeChunk request on the async queue of GeneralSFTPFile), overwrite will
+        # be called and will update self.current_size if necessary before returning. Therefore,
+        # self.current_size will be up-to-date for a subsequent call to this read method, and
+        # so it is correct to do the check for a read past the end-of-file here.
         if offset >= self.current_size:
             def _eof(): raise EOFError("read past end of file")
             return defer.execute(_eof)
diff --git a/src/allmydata/test/test_sftp.py b/src/allmydata/test/test_sftp.py
index 6095b18f..a45d71d0 100644
--- a/src/allmydata/test/test_sftp.py
+++ b/src/allmydata/test/test_sftp.py
@@ -913,6 +913,9 @@ class Handler(GridTestMixin, ShouldFailMixin, ReallyEqualMixin, unittest.TestCas
                       self.handler.openFile("small", sftp.FXF_READ | sftp.FXF_WRITE, {}))
         def _read_write(rwf):
             d2 = rwf.writeChunk(8, "0123")
+            # test immediate read starting after the old end-of-file
+            d2.addCallback(lambda ign: rwf.readChunk(11, 1))
+            d2.addCallback(lambda data: self.failUnlessReallyEqual(data, "3"))
             d2.addCallback(lambda ign: rwf.readChunk(0, 100))
             d2.addCallback(lambda data: self.failUnlessReallyEqual(data, "012345670123"))
             d2.addCallback(lambda ign: rwf.close())
-- 
2.45.2