Hello,

I found [1] the following 11 tests from `testenv` directory||fails when run on GNU Hurd:

1. Test-hsts.py
2. Test-https-k.py
3. Test--https.py
4. Test--https-crl.py
5. Test-pinnedpubkey-der-https.py
6. Test-pinnedpubkey-der-no-check-https.py
7. Test-pinnedpubkey-hash-https.py
8. Test-pinnedpubkey-hash-no-check-fail-https.py
9. Test-pinnedpubkey-pem-fail-https.py
10. Test-pinnedpubkey-pem-https.py
11. Test-k.py

Here is what happens when I run 'Test--https.py' in Python debugger:

```sh
env SSL_TESTS=1 python3 -m pdb ./Test--https.py
> /tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/Test--https.py(2)<module>()
-> from sys import exit
(Pdb) cont
Running Test Test--https.py
Traceback (most recent call last):
  File "/gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/pdb.py", line 1960, in main
    pdb._run(target)
  File "/gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/pdb.py", line 1754, in _run
    self.run(target.code)
  File "/gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/bdb.py", line 627, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/Test--https.py", line 54, in <module>
    ).begin ()
      ^^^^^^^^
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/test/http_test.py", line 35, in begin
    self.setup()
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/test/http_test.py", line 28, in setup
    self.server_setup()
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/test/base_test.py", line 88, in server_setup
    instance = self.instantiate_server_by(protocol)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/test/http_test.py", line 48, in instantiate_server_by
    server = {HTTP: HTTPd,
             ^^^^^^^^^^^^^
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/server/http/http_server.py", line 478, in __init__
    self.server_inst = self.server_class(addr, self.handler)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/guix-build-wget-1.25.0.drv-0/wget-1.25.0/testenv/server/http/http_server.py", line 56, in __init__
    self.server_bind()
  File "/gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/http/server.py", line 136, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/socketserver.py", line 478, in server_bind
    self.socket.bind(self.server_address)
OSError: [Errno 1073741846] Invalid argument
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /gnu/store/gsv7f12nhzvq6dchdw5hyg603y92b8di-python-3.12.12/lib/python3.12/socketserver.py(478)server_bind()
-> self.socket.bind(self.server_address)
(Pdb)
```

Tests 1-10 have very similar behavior: all their backtraces lead to
this piece of code in testenv/server/http/http_server.py:

```Python
class HTTPSServer(StoppableHTTPServer):
    """ The HTTPSServer class extends the StoppableHTTPServer class with
    additional support for secure connections through SSL. """

    def __init__(self, address, handler):
        import ssl
        BaseServer.__init__(self, address, handler)
        # step one up because test suite change directory away from $srcdir
        # (don't do that !!!)
        CERTFILE = os.path.abspath(os.path.join('..',
os.getenv('srcdir', '.'),
                                                'certs',
'server-cert.pem'))
        KEYFILE = os.path.abspath(os.path.join('..',
 os.getenv('srcdir', '.'),
                                               'certs',
 'server-key.pem'))
        ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER)
        ctx.load_cert_chain(CERTFILE, KEYFILE)
        self.socket = ctx.wrap_socket(
            sock=socket.socket(self.address_family, self.socket_type),
            server_side=True
        )
-->     self.server_bind()
        self.server_activate()
```

According to Python documentation on "TLS/SSL wrapper for socket objects' [2],
a socket.socket object that is wrapped with wrap_socket is assumed to be an
already listening socket (i.e binded and activated), but here it is not:
instead self.server_bind() and self.server_activate() bind and activate an already
wrapped socket (self.socket).

I rewrote this piece of code as follows:

```Python
class HTTPSServer(StoppableHTTPServer):
    """ The HTTPSServer class extends the StoppableHTTPServer class with
    additional support for secure connections through SSL. """

    def __init__(self, address, handler):
        import ssl
        # This also calls self.server_bind() and self.server_activate()
        # due to bind_and_activate=True default argument so that
        # self.socket becomes a listening socket:
        TCPServer.__init__(self, address, handler)
        # step one up because test suite change directory away from $srcdir
        # (don't do that !!!)
        CERTFILE = os.path.abspath(os.path.join('..',
os.getenv('srcdir', '.'),
                                                'certs',
'server-cert.pem'))
        KEYFILE = os.path.abspath(os.path.join('..',
 os.getenv('srcdir', '.'),
                                               'certs',
 'server-key.pem'))
        ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER)
        ctx.load_cert_chain(CERTFILE, KEYFILE)
        self.socket = ctx.wrap_socket(self.socket, server_side=True)
```

and it fixed tests 1-10.

Test 11 fails simply because `Test-k.py` is not aware that 'GNU' platform is also 'unix'.
It was easy to fix.

See also PR [3] that was submitted to the GNU Guix repo to fix these failing tests.

[1] https://codeberg.org/guix/guix/issues/11124
[2] https://docs.python.org/3.7/library/ssl.html#ssl.SSLContext.wrap_socket
[3] https://codeberg.org/guix/guix/pulls/11127
diff --git a/testenv/Test-k.py b/testenv/Test-k.py
index 342887c..3924e10 100755
--- a/testenv/Test-k.py
+++ b/testenv/Test-k.py
@@ -53,7 +53,7 @@ SubSite = WgetFile("site;sub:.html", site)
 LocalIndexPage = WgetFile("index.html", converted)
 
 print(platform.system())
-restrict = "unix" if platform.system() in ["Linux", "Darwin"] else "windows"
+restrict = "unix" if platform.system() in ["GNU", "Linux", "Darwin"] else "windows"
 
 WGET_OPTIONS = f"-k -r -nH --restrict-file-names={restrict}"
 WGET_URLS = [["index.html"]]
diff --git a/testenv/server/http/http_server.py b/testenv/server/http/http_server.py
index fd6121a..84c2d4b 100644
--- a/testenv/server/http/http_server.py
+++ b/testenv/server/http/http_server.py
@@ -1,6 +1,6 @@
 from http.server import HTTPServer, BaseHTTPRequestHandler
 from exc.server_error import ServerError, AuthError, NoBodyServerError
-from socketserver import BaseServer
+from socketserver import TCPServer
 from posixpath import basename, splitext
 from base64 import b64encode
 from random import random
@@ -36,7 +36,10 @@ class HTTPSServer(StoppableHTTPServer):
 
     def __init__(self, address, handler):
         import ssl
-        BaseServer.__init__(self, address, handler)
+        # This also calls self.server_bind() and self.server_activate()
+        # due to bind_and_activate=True default argument so that
+        # self.socket becomes a listening socket:
+        TCPServer.__init__(self, address, handler)
         # step one up because test suite change directory away from $srcdir
         # (don't do that !!!)
         CERTFILE = os.path.abspath(os.path.join('..',
@@ -49,12 +52,7 @@ class HTTPSServer(StoppableHTTPServer):
                                                'server-key.pem'))
         ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER)
         ctx.load_cert_chain(CERTFILE, KEYFILE)
-        self.socket = ctx.wrap_socket(
-            sock=socket.socket(self.address_family, self.socket_type),
-            server_side=True
-        )
-        self.server_bind()
-        self.server_activate()
+        self.socket = ctx.wrap_socket(self.socket, server_side=True)
 
 
 class _Handler(BaseHTTPRequestHandler):

Reply via email to