[Python-Dev] New test failure, test_socket, WinXP

Brett C. bac at OCF.Berkeley.EDU
Tue Jul 6 07:00:53 CEST 2004


Tim Peters wrote:
>>>Fails every time, in release and debug builds:
>>>
>>>test test_socket failed -- Traceback (most recent call last):
>>>File "C:\Code\python\lib\test\test_socket.py", line 311, in testGetServBy
>>>    eq(socket.getservbyport(port2), service)
>>>AssertionError: 'http' != 'www'
>>>
> 
> 
> [Brett C.]
> 
>>Does it pass if you change "www" to "http" on line 292?
> 
> 
> Yup!  I'm not going to check that in, though -- I don't really know what
> this test is doing.
> 

So I found out why it might be failing on your box and not on other 
people's: do you get an exception raised when you call 
``socket.getservbyname('ssh', 'tcp')``?  I bet you do and I bet everyone 
else who has this test passing doesn't or has an exception for 'www' as 
well.  I just removed 'ssh' as an option and that led to a failure 
because it then tested 'www'.

So what follows is just a long explanation of the test and how I figured 
out what was happening so people know what I did to come to this 
conclusion and to possibly help anyone out who is curious about this 
networking stuff.  If you only want to know what I suggest to fix the 
test, just jump past the <rambling> tags.

<rambling>

OK, so here is how the test works (Lib/test/test_socket.py:287):

* finds a protocol that socket.getservbyname(proto, 'tcp') recognizes 
('www' in this case, which is assigned to 'service') and save the 
returned port (assigned to 'port'; the value is 80 in this case)
* checks that the port in the previous step matches what is returned by 
socket.getservbyname(proto) (that is set to 'port2' which is used in the 
failing test, so we know it is set to 80)
* <skip UDP stuff>
* check that what is returned by socket.getservbyport(port2) equals what 
is in 'service' (in other words ``socket.getservbyport(80)=="www"``); 
THIS IS THE FAILURE

Obviously socket.getservbyport() is returning "http" instead of "www". 
If you look at Modules/socketmodule.c:2910 where socket_getservbyport() 
starts, you will see the thing just calls getservbyport().

Now, if you read pg. 251 or 255 in 'UNIX Networking Programming: Vol 1, 
Second Edition", you will see, as Guido pointed out in another email, 
getservbyport() usually gets its info from /etc/services 
(\Windows\system32\drivers\etc\services for you Windows users, or you 
can go to http://www.iana.org/assignments/port-numbers to get the 
official list).  Now for Guido, Tim, and myself, the line for port 80 is 
``http  80/tcp   www   www-http``, with that going <name> 
<port>/<protocol> <alias> <alias>.

All of this is info is returned in a servent struct which contains the 
name, aliases, port, and protocol.  In socketmodule.c the code returns 
what is in the equivalent name field in the servent struct.

</rambling>

What does this all mean?  It means Tim's failure is legit; 
socket.getservbyport() is supposed to return "http" based on what his OS 
has listed for port 80.  The rest of us never hit it either because 
'ssh' came up as a legit protocol or 'www' failed.  Either way 'www' 
doesn't get down to the socket.getservbyport() test.

Couple options on fixing.  We can just change it to 'http' to make it 
proper for what it returns if we don't care about testing for aliases. 
If we do care about checking for aliases we should, if the test fails, 
take the returned result and feed it into socket.getservbyname() and 
compare the return value; if they match the test actually does pass.

Personally I am +1 on changing 'www' to 'http' in the test and moving 
on.  I am +0 on leaving it but adding the extra test of feeding 
differing results into socket.getservbyname() to catch alias->name 
issues like this since it does do an extra test (but that assumes the OS 
will have an alias of 'www').

Oh, and cvs annotate says Barry was the last one to touch both the 'for' 
loop statement and the socket.getservbyport() test lines.  =)

-Brett


More information about the Python-Dev mailing list