Skip to content

gh-131178: Add tests for http.server command-line interface #132540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

ggqlq
Copy link

@ggqlq ggqlq commented Apr 15, 2025

@python-cla-bot
Copy link

python-cla-bot bot commented Apr 15, 2025

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app
Copy link

bedevere-app bot commented Apr 15, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Apr 15, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@ggqlq ggqlq changed the title Add tests for http.server command-line interface gh-131178: Add tests for http.server command-line interface Apr 15, 2025
@ggqlq ggqlq requested a review from donBarbos April 16, 2025 08:32
Copy link
Contributor

@donBarbos donBarbos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't read everything carefully yet, but this is what catches my eye first

ggqlq and others added 9 commits April 16, 2025 21:31
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
@ggqlq ggqlq requested a review from donBarbos April 16, 2025 14:28
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
@ggqlq ggqlq requested a review from donBarbos April 16, 2025 14:48
@donBarbos
Copy link
Contributor

you don't have to request for a review, i still get notifications after your changes :)

and it seems that News entry is not needed here. we have a devguide (very useful to read) and it also lists when it is worth writing: https://devguide.python.org/core-developers/committing/#updating-news-and-what-s-new-in-python

@bedevere-app
Copy link

bedevere-app bot commented Apr 16, 2025

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

self.default_port = 8000
self.default_bind = None
self.default_protocol = 'HTTP/1.0'
self.default_directory = os.getcwd()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused var

Suggested change
self.default_directory = os.getcwd()

Comment on lines +1562 to +1569
def text_normalizer(self, string):
return textwrap.dedent(string).strip()

def invoke_httpd(self, args=[]):
output = StringIO()
with contextlib.redirect_stdout(output):
server._main(args)
return self.text_normalizer(output.getvalue())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. text_normalizer function is only used once, why not get rid of it
  2. mutable variable as a default argument is bad practice
Suggested change
def text_normalizer(self, string):
return textwrap.dedent(string).strip()
def invoke_httpd(self, args=[]):
output = StringIO()
with contextlib.redirect_stdout(output):
server._main(args)
return self.text_normalizer(output.getvalue())
def invoke_httpd(self, *args):
output = StringIO()
with contextlib.redirect_stdout(output):
server._main(args)
return textwrap.dedent(output.getvalue()).strip()

for option in options:
with self.assertRaises(SystemExit):
output = self.invoke_httpd([option])
self.assertIn('usage:', output)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer next method:

Suggested change
self.assertIn('usage:', output)
self.assertStartsWith(output, 'usage: ')


@unittest.skipIf(ssl is None, "requires ssl")
@mock.patch('http.server.test')
def test_tls_flag(self, mock_func):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the output of the result is directed outwards, need to catch it.
my actual output for python ./Lib/test/test_httpservers.py:

...............................................................usage: test_httpservers.py [-h] [--cgi] [-b ADDRESS] [-d DIRECTORY] [-p VERSION] [--tls-cert PATH] [--tls-key PATH]
                           [--tls-password-file PATH]
                           [port]
test_httpservers.py: error: --tls-key requires --tls-cert to be set
usage: test_httpservers.py [-h] [--cgi] [-b ADDRESS] [-d DIRECTORY] [-p VERSION] [--tls-cert PATH] [--tls-key PATH]
                           [--tls-password-file PATH]
                           [port]
test_httpservers.py: error: --tls-password-file requires --tls-cert to be set
usage: test_httpservers.py [-h] [--cgi] [-b ADDRESS] [-d DIRECTORY] [-p VERSION] [--tls-cert PATH] [--tls-key PATH]
                           [--tls-password-file PATH]
                           [port]
test_httpservers.py: error: Failed to read TLS password file: [Errno 2] No such file or directory: '/tmp/98555ec389358504f26d72f0915689fe'
.usage: test_httpservers.py [-h] [--cgi] [-b ADDRESS] [-d DIRECTORY] [-p VERSION] [--tls-cert PATH] [--tls-key PATH]
                           [--tls-password-file PATH]
                           [port]
test_httpservers.py: error: unrecognized arguments: --unknown-flag
........................
----------------------------------------------------------------------
Ran 88 tests in 2.865s

OK

for port in ports:
with self.subTest(port=port):
self.invoke_httpd([str(port)])
mock_func.assert_called_once_with(HandlerClass=self.default_handler, ServerClass=self.default_server,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you wrap similar lines to fit into 79 characters?
I didn't mark all such lines, but I think you can easily find them yourself :)

and if possible, try not to pass optional arguments

ports = [8000, 65535,]
for port in ports:
with self.subTest(port=port):
self.invoke_httpd([str(port)])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you tell me how to ensure that the server does not continue to work?
Sorry in advance, I just couldn't find such logic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants