Skip to main content

Testing

cURL

You are highly advised to use curl(1) to test your server. It is a command line tool that you can use to send HTTP requests to your server. cURL will be very useful when developing your server as it allows you to see the HTTP request headers. Feel free to read more on the cURL man page.

Here is what curl should look like on your HTTPd.

42sh$ curl -v http://127.0.0.1:4242
* Trying 127.0.0.1:4242...
* Connected to 127.0.0.1 (127.0.0.1) port 4242
> GET / HTTP/1.1
> Host: 127.0.0.1:4242
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sat, 01 Nov 2022 23:42:00 GMT
< Content-Length: 22
< Connection: close
<
<h1>Hello World !</h1>
* Closing connection

Every line starting with * is some meta information cURL will display.

Every line starting with > is the request that will be sent.

Every line starting with < is the response that HTTPd will send.

On the first line of the request, you will find the request-line:

  • GET is the method

  • / is the request target

  • HTTP/1.1 is the HTTP-version

The rest are headers generated by curl.

On the first line of the response, you will find the status line:

  • HTTP/1.1 is the HTTP-version

  • 200 is the status code

  • OK is the reason phrase

The rest are headers generated by HTTPd followed by the body.

To help you out, here is a non-exhaustive list of options you might find useful:

  • -i includes the HTTP headers and status-line of the response in the cURL output.

  • -I performs a HEAD request and displays the headers in the cURL output.

  • -v enables the cURL verbose mode.

  • -H includes extra headers or overrides existing ones in your request.

  • -X chooses the request method to use (GET, POST...).

  • -d sends the specified data in a POST or PUT request to the HTTP server.

Netcat

Netcat (binary called nc(1)) is a networking utility that is used to open connections and operate on them. It can be used, for instance, to check if ports are open, or to send irregular packets to a host. Once the connection opens, Netcat will forward data from standard input into the socket.

Multiple versions of Netcat exist. We are using the OpenBSD one.

42sh$ echo -ne 'GET /index.html HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc localhost 4242
HTTP/1.1 200 OK
Date: Sat, 01 Nov 2022 23:42:00 GMT
Content-Length: 22
Connection: close

<h1>Hello World !</h1>
tip

You can use nc -C <IP> <PORT> to have a better hands-on way of testing more complicated nonconforming requests and tricky IO situations.

42sh$ nc -C 127.0.0.1 8080

Creating a testsuite

You will need a functional testsuite to ensure your HTTP daemon is working properly and follows every requirement. It will also help you avoid regressions if used correctly.

Use Python or any other scripting language of your choice. However, we will not be able to help you with your testsuite if it is not written in Python. Python is a safe choice as it can be learned quickly, and has all the modules you may need to test your HTTP server.

Useful modules

The requests module is one of the best HTTP client APIs in Python. It is easy to use, well-documented, and complete.

However, this module will not be enough to test all the features we ask you to implement, especially the network problems. Take a look at the socket API to test some corner cases.

The subprocess module will be useful to launch your daemon before running your tests. You can also use it to verify the return value of your daemon and make sure it has properly exited.

Try to make things generic, to add new tests easily as your project grows.

Virtual Environment

You should use a virtualenv and pip to install the needed modules. Have a look at pylint, logging or subprocess. We strongly advise you to not use Python's os.run to run your daemon.

42sh$ python -m venv env
42sh$ source env/bin/activate
42sh$ python -m pip install -r requirements.txt
42sh$ ./<your testsuite>
tip

You can use pip freeze to generate a requirements.txt file containing all the modules installed in your environment.

42sh$ python -m pip freeze > requirements.txt
danger

Environment files are considered trash files. You should only provide your Python scripts.

Testing framework

To make your testsuite more readable and easier to maintain, you should use a test framework. You should use pytest.

It is a very powerful framework that will help you write your tests very quickly.

Pytest has some very easy conventions to follow to start writing tests. Your test files must be named test_*.py or *_test.py. Your test functions must be named test_*. You can read more about it in the pytest documentation.

You can also add very useful plugins such as pytest-timeout to make sure your tests get interrupted after a certain amount of time.

note

Code coverage measures the amount of code covered by your tests. It is an important metric to know how well your tests are and which tests you will need to add.

You can use pytest-cov to get a coverage report of your tests.

note

Your testsuite will most likely have to set up an environment and launch your binary before running the tests. We advise you to look into pytest fixtures to do so.