add a test which panics in a mock subgraph and handles the response#918
add a test which panics in a mock subgraph and handles the response#918
Conversation
The panic is captured in the tower-http stack and translated into an INTERNAL_SERVER_ERROR (500). By the time this reaches the query planner, the error is interpreted as a "service closed", which is what the test expects.
✅ Deploy Preview for apollo-router-docs canceled.
|
|
@garypen your pull request is missing a changelog! |
o0Ignition0o
left a comment
There was a problem hiding this comment.
LGTM! Have you been able to see which tests in our suite are currently passing for the wrong reasons ?
|
I added a comment here #878 (comment) I don't know if it's related |
|
Is it not the case that this does not use tower_http because we are just executing directly against the query plan? |
|
There are some spurious panics and the concerning thing is that mockall panicking doesn't seem to cause the tests to fail. The faulty tests I found are: Fixing the last two tests is straightforward. They are both missing a This is a problem that needs some more thought, since we'll never know when a mockall panic may creep into the tests (without manually inspecting logs for panics.)... |
I'm not sure, is the quick answer. "Something" is handling the panics and tower-http seemed the most likely explanation, but it really needs more digging to confirm this. |
mock_service_builder
// the second last one should have the right APQ header and the full query string
// even though the query string wasn't provided by the client
.expect_call()
.times(1)
.returning(move |req| {
let body = req.originating_request.body();
let as_json = body.extensions.get("persistedQuery").unwrap();
let persisted_query: PersistedQuery =
serde_json_bytes::from_value(as_json.clone()).unwrap();
assert_eq!(persisted_query.sha256hash, hash3);
assert!(body.query.is_some());
let hash = hex::decode(hash3.as_bytes()).unwrap();
assert!(!query_matches_hash(
body.query.clone().unwrap_or_default().as_str(),
hash.as_slice()
));
Ok(RouterResponse::fake_builder().build())
});is the mock that doesnt seem to be called. |
|
Ok the first test was a mistake I've made. diff --git a/apollo-router-core/src/layers/apq.rs b/apollo-router-core/src/layers/apq.rs
index fff4babe..665e3ef3 100644
--- a/apollo-router-core/src/layers/apq.rs
+++ b/apollo-router-core/src/layers/apq.rs
@@ -244,7 +244,6 @@ mod apq_tests {
async fn it_doesnt_update_the_cache_if_the_hash_is_not_valid() {
let hash = Cow::from("ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b36");
let hash2 = hash.clone();
- let hash3 = hash.clone();
let expected_apq_miss_error = crate::Error {
message: "PersistedQueryNotFound".to_string(),
@@ -285,34 +284,9 @@ mod apq_tests {
.build()
.expect("expecting valid request"))
});
- mock_service_builder
- // the second last one should have the right APQ header and the full query string
- // even though the query string wasn't provided by the client
- .expect_call()
- .times(1)
- .returning(move |req| {
- let body = req.originating_request.body();
- let as_json = body.extensions.get("persistedQuery").unwrap();
-
- let persisted_query: PersistedQuery =
- serde_json_bytes::from_value(as_json.clone()).unwrap();
-
- assert_eq!(persisted_query.sha256hash, hash3);
-
- assert!(body.query.is_some());
-
- let hash = hex::decode(hash3.as_bytes()).unwrap();
-
- assert!(!query_matches_hash(
- body.query.clone().unwrap_or_default().as_str(),
- hash.as_slice()
- ));
-
- Ok(RouterResponse::fake_builder()
- .build()
- .expect("expecting valid request"))
- });
+ // the last call should be an APQ error.
+ // the provided hash was wrong, so the query wasn't inserted into the cache.
let mock_service = mock_service_builder.build();will do |
and the panics are eaten up by the tower Buffer layer.
Jeremy suggested the fix for this test.
I applied this change in: 283f51a |
Which is the use of the buffer() functionality in tower and not the catch-panic in tower-http (which we aren't using, but maybe we should?)
…vice_closed` test This appears to test an intended-enough behaviour. Originally introduced: #918 Comment outdated as of: #1440 This is a behaviour change compared to #1440, but the intended behaviour from #918. What's a bit worrying is that this depends on the internal composition of our pipeline, but is externally observable?
The panic is captured in the tower-http stack and translated into an
INTERNAL_SERVER_ERROR (500). By the time this reaches the query planner,
the error is interpreted as a "service closed", which is what the test
expects.
fixes: #878