-
Notifications
You must be signed in to change notification settings - Fork 241
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
Monomorphic clj-http tests for comparison #628
base: master
Are you sure you want to change the base?
Conversation
Accidentally used unreleased tests; head-with-body relied on unreleased code
Mimic clj-http tests' use of middleware Translate clj-http's middleware to Aleph's when possible Split default middleware into client and request parts - most middleware changes req maps, but wrap-exceptions and wrap-request-timing change the client fn. Add missing :reason-phrase resp key Add missing :url wrap-url key Directly compare response bodies as bytes when not InputStreams Ignore DSN resolution tests
OK, middleware should be working. I had to alter how Aleph handles them to support it though. Aleph confusingly combined two different types of middleware. Since it's inherently async, most middleware alters a request map; however, There's no observable behavior, but people relying on the |
I added a new :clj-http test selector, but unfortunately, it's hitting one of the tests that hang first thing. Todo:
|
Consider I will have a look at those tests next week. |
Ok... this one is tricky.
Netty uses this to generates the boundary on (Long/toHexString (.nextLong (io.netty.util.internal.PlatformDependent/threadLocalRandom)))
=> 624177513d77dcea while (-> (org.apache.http.entity.mime.MultipartEntityBuilder/create)
(.build)
(.getContent)
(bs/to-string))
=> "2FpTfsG9VvWrmeyeRtpEco02WjNrvZXqAzahT" ;; separators removed My take would be to special case the multipart tests to not account the boundary [1] : https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html |
@arnaudgeiser Thanks for digging into that. Which do you think will be more robust?
1 seems simpler, but I haven't considered any further issues of compression or encoding. (OTOH, differences in either of those could lead to difference in bytes even without multipart boundaries, which I haven't seen, so maybe it's not an issue.) |
Yes, I would go straight for 1. |
@arnaudgeiser Option 1 for multipart comparison won't work. Not only are the boundaries naturally different, since they're random strings, but the headers in each part differ. They differ by case, by order, and clj-http adds a Content-Length header that is uncommon, and has apparently caused problems elsewhere. We also name temp files, which get added as directives, differently. Even if we wanted to match the behavior, we couldn't do it for streaming bodies where we may not necessarily know the length when we write the headers. It might be nice to parse the remaining headers, but Netty annoyingly buries that code in private inner classes a zillion hierarchies deep, so we'd have to use something else, and this is already getting a bit out of hand. For now, I'm ignoring the headers and comparing just the multipart bodies. This turned up one bug, I think. In the tests |
I spent a bit of time on (let [bytes (util/utf8-bytes "byte-test")
stream (ByteArrayInputStream. bytes)
...] Here we are constructing a In the current situation, the clj-http client got the data. But if you shuffle those two lines [2] aleph will get the data while clj-http will hang waiting clj-http-resp (clj-http-request clj-http-ring-map)
aleph-resp @(http/request aleph-ring-map) [1] : https://github.com/clj-commons/aleph/pull/628/files#diff-5b192cc1db92f511c86757b4e7cabb888312e80a95ed9156d053054a210a1172R354 |
Let's not burn too much time on this issue. |
Ahh, good catch. Ironically, I ran into that exact issue earlier on, with needing to read clj-http's response stream twice, which is why I made Just pushed a fix. |
Copy streams used in request maps, so consuming one doesn't break the other
clj-http options that interop with Apache-specific stuff can't be tested
3822a76
to
3abf9c8
Compare
Do you want me to take over this Pull Request? |
Thanks, but I've got it. For the most part, it's turned up little new errors (we already knew we were pretty compatible with clj-http), so there's no urgency. |
Unless... you're dying to work on it? |
Not at all. |
I grabbed two of the more important test namespaces from clj-http, and altered the common
request
fn to simultaneously make requests with both clj-http and Aleph's client, and then compare the two, to the extent that it's possible.This is a bit of a first draft, but there's already some interesting issues. I expect there might be some bugs in the test comparison themselves, so extra eyes could help.
For now, there's no attempt to compare the async mode of the clj-http client, but in theory we can test those too, with
on-realized
.Notes:
I'm seeing discrepancies in the numbers for multipart upload tests. I know one or both of you have looked into that more than I have.Multipart now works. Number discrepancies inherent in how multipart requests built.There's some weird bug in theThis was due to the test being in an unreleased version. I shouldn't have copied straight from master...head-with-body
test, where it works in clj-http's test suite, but not ours. I don't mean the Aleph call is failing, I mean the clj-http call is failing in our version of the test, for some reason. Dunno what that's about. I thought it was some weird Jetty caching issue, since it seems related to consuming an InputStream and then trying to reuse it a second time.There's some DNS resolver errors. Haven't even glanced at those.I took a look, and I'm not sure there's a good way to fix these, since they depend on Apache DNS classes, and not a map of settings. Luckily, I think custom DNS resolvers are pretty rare. Suggest we ignore.client-test
side that are failing or hanging, and they should work in the aleph env, but they're not. Probably a bug in my alteredrequest
fn in theutil
ns. Even if the tests are irrelevant to us (like the clj-http conn pool tests), there might be something there, since they're failing.t-request-without-url-set
inring-request->netty-request
customMethodTest
seems to hang.InDonestatus-line-parsing
, we don't return a:reason-phrase
, which clj-http does.:redirect-strategy
option yet.:length
yet. If specified, should not transmit more than:length
bytes of the body.Anyway, it's still a bit messy, but it would be nice to get some issues out of this, and fix some bugs. The nil body vs empty body inputstream also needs a bit of feedback. Do we go for clj-http parity, or do people rely on that difference?