[MERGE] [Bug 215426] Re: MemoryError - recv for HTTPthroughProxy
Eric Holmberg
eholmberg at arrow.com
Thu May 1 16:53:38 BST 2008
Hi Andrew,
I'm putting together another email with the new patch, but just wanted
to respond to your email (see inline responses).
> Eric Holmberg wrote:
> [...]
> >
> > More comments below on the test -- but if we leave the
> TCP/IP code in
> > the system, is there a better way to find an available port
> -- I think
> > Idle actually tries random ports.
>
> Listen on port 0. The OS will find a free port for you if
> you do that. You should be able to find examples of doing
> this elsewhere in the test suite.
A nice, simple approach :) For the in-use error, I had to set the
SO_REUSEADDR option for the server socket since it was in shut-down mode
and Linux wouldn't allow immediate re-use (Windows did allow it).
Actual code was sock_server.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1).
That said, I've actually removed the socket code and switched to mock
objects instead per everybody's advice.
> >
> > Does test.http_response.ReadSocket actually send data over the real
> > TCP/IP stack? This test was designed to do that to verify that the
> > dreaded MemoryError exception doesn't occur with 1x and 3x
> the block
> > size.
>
> I'm not sure we want to try provoke the MemoryError from recv
> in our test suite.
> I suspect the exact conditions to trigger it don't just
> depend on platform, or platform version, but also what else
> is running on that system (and how much RAM it has) at the
> time. i.e. I wouldn't be surprised if a system with more
> free RAM had its kernel internally allocate more buffer space.
>
> So it seems hard to me to reliably trigger the recv error, or
> even know if we can trigger the error. So I'm ok with not
> writing an automated test for that.
Yes, that is very true. Even on the Windows systems that I got the
problem to occur on, the failure point was dependent upon the load on
the TCP/IP stack. I could run wget while the test was running and get
the problem to occur at a lower socket.recv read size. Under a Linux
virtual machine, I wasn't able to get the failure to occur, but to be
fair to Windows, I didn't have the same services (NTLM proxy client,
Pylons app) running under Linux. Glaring conclusion is that this
definitely is not something that we want to test to failure.
> > Without running the data through the TCP/IP stack, I don't
> see why I'm
> > bothering to write these tests since the pre-existing tests already
> > provide code-coverage of the code that I have added.
>
> Because _read_limited is only being covered indirectly.
> There's no explicit tests making sure that it never tries to
> read more than _read_limited_buf_size at a time. Although
> every line of code is getting used by the existing tests, I
> don't think this aspect of the logic is actually being
> checked. If I replace "min(size,
> self._read_limited_buf_size)" with just "size" in your patch,
> I don't get any failures (apart from 'Address already in
> use', which I get with an unmodified patch)
>
> Also, testing that it only reads at most
> _read_limited_buf_size at a time is something that can best
> be tested directly, without intervening layers (like
> HTTP) getting in the way. Although you may need to make
> _read_limited a function rather than a method of RangeFile to
> make it easy to unit test directly like that.
Point taken -- I'll go on my test results of large block sizes in the
range of 2 MB to 4 MB cause failures on some machines and set a
conservative 512KB limit for the block size. . . And then just test the
block-size functionality. Thinking about it more, if I use the TCP/IP
stack for the test, I really need to verify that I can get both a
successful run and a failure run to be sure that the tests are working,
so the mock object test is going to be the best approach.
> I don't think we should be striving for utter perfection
> here, as the code is fairly simple. A single test that
> "_read_limited" for some large number (e.g.
> 1.5x the limit) will call "read" on the underlying file-like
> object with smaller numbers would be ample, I think.
>
<sigh> Reality always seems to get in the way of perfection :P I added
three tests -- two of them handle testing of the different code paths
for read to EOF and read N bytes and a third tests the sub-cases of read
N bytes where N is <, =, and > than the maximum block size.
Regards,
Eric Holmberg
More information about the bazaar
mailing list