haskell-servant / servant-quickcheck

40 stars 21 forks source link

Bug in printing the method used for a failed request #56

Closed ghost closed 6 years ago

ghost commented 6 years ago

I don't know how general it is, and I'm currently investigating but I'll drop what I have know here for future reference.

Context

Using a simple API:

type API = "foo" :> Capture "x" Int :> "bar" :> Get '[JSON] Int

And a simple server:

server x = return 42

And the example test in servant-quickcheck with everything default and only the notAllowedContainsAllowHeader predicate.

Expected behavior

The predicate should fail, indicating that using an unallowed method caused an answer without an 'Allow' header (See Issue 489 in servant). We should observe an output similar to:

  1) my server follows the best practices
       Failed:
       Just Predicate failed
            Predicate: notAllowedContainsAllowHeader
            Request:
                 Method: "POST"
                 Path: /foo/0/bar
                 Headers:
                 Body: 
            Response:
                 Status code: 405
                 Headers:  "Transfer-Encoding": "chunked"
                           "Date": "Mon, 27 Aug 2018 12:52:17 GMT"
                           "Server": "Warp/3.2.23"
                 Body:

Actual behavior

What actually happens is nearly just that, except the method that is printed in the failure log is the actual correct method:

  1) my server follows the best practices
       Failed:
       Just Predicate failed
            Predicate: notAllowedContainsAllowHeader
            Request:
                 Method: "GET"
                 Path: /foo/0/bar
                 Headers:
                 Body: 
            Response:
                 Status code: 405
                 Headers:  "Transfer-Encoding": "chunked"
                           "Date": "Mon, 27 Aug 2018 12:52:17 GMT"
                           "Server": "Warp/3.2.23"
                 Body: 

Though we can confirm that a POST was sent:

 $ sudo tcpdump -vvAls0 -i lo | grep 'POST'                                                                                                                      
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
.<...<..POST /foo/0/bar HTTP/1.1

This is most confusing, since it inclines the user to believe his server answers with a 405 error to a method that is actually allowed on the endpoint, causing all sorts of FUD about servant's soundness.

I'll open a PR as soon as I have pinpointed the buggy code.

ghost commented 6 years ago

See #57 .