Skip to content

Commit

Permalink
fix(grpc): handle union shared fields (#2757)
Browse files Browse the repository at this point in the history
Co-authored-by: Tushar Mathur <[email protected]>
  • Loading branch information
meskill and tusharmath authored Aug 28, 2024
1 parent aa669c4 commit 6caf179
Show file tree
Hide file tree
Showing 25 changed files with 1,114 additions and 112 deletions.
21 changes: 21 additions & 0 deletions src/core/blueprint/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ impl Index {
pub fn get_mutation(&self) -> Option<&str> {
self.schema.mutation.as_deref()
}

pub fn is_type_implements(&self, type_name: &str, type_or_interface: &str) -> bool {
if type_name == type_or_interface {
return true;
}

if let Some((Definition::Object(obj), _)) = self.map.get(type_name) {
obj.implements.contains(type_or_interface)
} else {
false
}
}
}

impl From<&Blueprint> for Index {
Expand Down Expand Up @@ -232,4 +244,13 @@ mod test {
index.schema.mutation = None;
assert_eq!(index.get_mutation(), None);
}

#[test]
fn test_is_type_implements() {
let index = setup();

assert!(index.is_type_implements("User", "Node"));
assert!(index.is_type_implements("Post", "Post"));
assert!(!index.is_type_implements("Node", "User"));
}
}
3 changes: 3 additions & 0 deletions src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,9 @@ impl Config {
stack.extend(field.args.values().map(|arg| arg.type_of.clone()));
stack.push(field.type_of.clone());
}
for interface in typ.implements.iter() {
stack.push(interface.clone())
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/core/generator/from_proto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl Context {

collect_types(
type_name.clone(),
base_type,
base_type.clone(),
&oneof_fields,
&mut union_types,
);
Expand All @@ -141,13 +141,17 @@ impl Context {
}

let mut union_ = Union::default();
let interface_name = format!("{type_name}__Interface");

for (type_name, ty) in union_types {
for (type_name, mut ty) in union_types {
ty.implements.insert(interface_name.clone());
union_.types.insert(type_name.clone());

self = self.insert_type(type_name, ty);
}

// base interface type
self.config.types.insert(interface_name, base_type);
self.config.unions.insert(type_name, union_);

self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ input oneof__Request__Var__Var1 {
usual: String
}

interface oneof__Request__Interface {
usual: String
}

interface oneof__Response__Interface {
usual: Int
}

union oneof__Request = oneof__Request__Var0__Var | oneof__Request__Var0__Var0 | oneof__Request__Var0__Var1 | oneof__Request__Var1__Var | oneof__Request__Var1__Var0 | oneof__Request__Var1__Var1 | oneof__Request__Var__Var | oneof__Request__Var__Var0 | oneof__Request__Var__Var1

union oneof__Response = oneof__Response__Var | oneof__Response__Var0 | oneof__Response__Var1 | oneof__Response__Var2
Expand All @@ -78,21 +86,21 @@ type oneof__Payload {
payload: String
}

type oneof__Response__Var {
type oneof__Response__Var implements oneof__Response__Interface {
usual: Int
}

type oneof__Response__Var0 {
type oneof__Response__Var0 implements oneof__Response__Interface {
payload: oneof__Payload!
usual: Int
}

type oneof__Response__Var1 {
type oneof__Response__Var1 implements oneof__Response__Interface {
command: oneof__Command!
usual: Int
}

type oneof__Response__Var2 {
type oneof__Response__Var2 implements oneof__Response__Interface {
response: String!
usual: Int
}
6 changes: 5 additions & 1 deletion src/core/ir/resolver_context_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,12 @@ impl SelectionField {
field: &crate::core::jit::Field<Nested<ConstValue>, ConstValue>,
) -> SelectionField {
let name = field.output_name.to_string();
let type_name = field.type_of.name();
let selection_set = field
.nested_iter(field.type_of.name())
.iter_only(|field| match &field.type_condition {
Some(type_condition) => type_condition == type_name,
None => true,
})
.map(Self::from_jit_field)
.collect();
let args = field
Expand Down
6 changes: 4 additions & 2 deletions src/core/jit/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl Builder {
.unwrap_or(field_name.to_owned()),
ir,
type_of,
type_condition: type_condition.to_string(),
type_condition: Some(type_condition.to_string()),
skip,
include,
args,
Expand All @@ -241,7 +241,9 @@ impl Builder {
name: "String".to_owned(),
non_null: true,
},
type_condition: type_condition.to_string(),
// __typename has a special meaning and could be applied
// to any type
type_condition: None,
skip,
include,
args: Vec::new(),
Expand Down
34 changes: 20 additions & 14 deletions src/core/jit/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,16 @@ where
// Check if the value is an array
if let Some(array) = value.as_array() {
join_all(array.iter().enumerate().map(|(index, value)| {
let type_name = value.get_type_name().unwrap_or(field.type_of.name());

join_all(field.nested_iter(type_name).map(|field| {
let ctx = ctx.with_value_and_field(value, field);
let data_path = data_path.clone().with_index(index);
async move { self.execute(&ctx, data_path).await }
}))
join_all(
self.request
.plan()
.field_iter_only(field, value)
.map(|field| {
let ctx = ctx.with_value_and_field(value, field);
let data_path = data_path.clone().with_index(index);
async move { self.execute(&ctx, data_path).await }
}),
)
}))
.await;
}
Expand All @@ -111,13 +114,16 @@ where
// TODO: Validate if the value is an Object
// Has to be an Object, we don't do anything while executing if its a Scalar
else {
let type_name = value.get_type_name().unwrap_or(field.type_of.name());

join_all(field.nested_iter(type_name).map(|child| {
let ctx = ctx.with_value_and_field(value, child);
let data_path = data_path.clone();
async move { self.execute(&ctx, data_path).await }
}))
join_all(
self.request
.plan()
.field_iter_only(field, value)
.map(|child| {
let ctx = ctx.with_value_and_field(value, child);
let data_path = data_path.clone();
async move { self.execute(&ctx, data_path).await }
}),
)
.await;
}

Expand Down
64 changes: 45 additions & 19 deletions src/core/jit/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
use super::Error;
use crate::core::blueprint::Index;
use crate::core::ir::model::IR;
use crate::core::ir::TypedValue;
use crate::core::json::JsonLike;

#[derive(Debug, Deserialize, Clone)]
Expand Down Expand Up @@ -65,6 +66,14 @@ impl<Extensions, Input> Field<Extensions, Input> {

skip == include
}

/// Returns the __typename of the value related to this field
pub fn value_type<'a, Output>(&'a self, value: &'a Output) -> &'a str
where
Output: TypedValue<'a>,
{
value.get_type_name().unwrap_or(self.type_of.name())
}
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -138,7 +147,7 @@ pub struct Field<Extensions, Input> {
/// The type could be anything from graphql type system:
/// interface, type, union, input type.
/// See [spec](https://spec.graphql.org/October2021/#sec-Type-Conditions)
pub type_condition: String,
pub type_condition: Option<String>,
pub skip: Option<Variable>,
pub include: Option<Variable>,
pub args: Vec<Arg<Input>>,
Expand Down Expand Up @@ -234,27 +243,15 @@ impl<Input> Field<Flat, Input> {
}

impl<Input> Field<Nested<Input>, Input> {
/// iters over children fields that are
/// related to passed `type_name` either
/// as direct field of the queried type or
/// field from fragment on type `type_name`
pub fn nested_iter<'a>(
/// iters over children fields that satisfies
/// passed filter_fn
pub fn iter_only<'a>(
&'a self,
type_name: &'a str,
mut filter_fn: impl FnMut(&'a Field<Nested<Input>, Input>) -> bool + 'a,
) -> impl Iterator<Item = &Field<Nested<Input>, Input>> + 'a {
self.extensions
.as_ref()
.map(move |nested| {
nested
.0
.iter()
// TODO: handle Interface and Union types here
// Right now only exact type name is used to check the set of fields
// but with Interfaces/Unions we need to check if that specific type
// is member of some Interface/Union and if so call the fragments for
// the related Interfaces/Unions
.filter(move |field| field.type_condition == type_name)
})
.map(move |nested| nested.0.iter().filter(move |&field| filter_fn(field)))
.into_iter()
.flatten()
}
Expand Down Expand Up @@ -351,7 +348,6 @@ pub struct OperationPlan<Input> {
flat: Vec<Field<Flat, Input>>,
operation_type: OperationType,
nested: Vec<Field<Nested<Input>, Input>>,

// TODO: drop index from here. Embed all the necessary information in each field of the plan.
pub index: Arc<Index>,
}
Expand Down Expand Up @@ -409,30 +405,37 @@ impl<Input> OperationPlan<Input> {
Self { flat: fields, nested, operation_type, index }
}

/// Returns a graphQL operation type
pub fn operation_type(&self) -> OperationType {
self.operation_type
}

/// Check if current graphQL operation is query
pub fn is_query(&self) -> bool {
self.operation_type == OperationType::Query
}

/// Returns a nested [Field] representation
pub fn as_nested(&self) -> &[Field<Nested<Input>, Input>] {
&self.nested
}

/// Returns an owned version of [Field] representation
pub fn into_nested(self) -> Vec<Field<Nested<Input>, Input>> {
self.nested
}

/// Returns a flat [Field] representation
pub fn as_parent(&self) -> &[Field<Flat, Input>] {
&self.flat
}

/// Search for a field with a specified [FieldId]
pub fn find_field(&self, id: FieldId) -> Option<&Field<Flat, Input>> {
self.flat.iter().find(|field| field.id == id)
}

/// Search for a field by specified path of nested fields
pub fn find_field_path<S: AsRef<str>>(&self, path: &[S]) -> Option<&Field<Flat, Input>> {
match path.split_first() {
None => None,
Expand All @@ -447,25 +450,48 @@ impl<Input> OperationPlan<Input> {
}
}

/// Returns number of fields in plan
pub fn size(&self) -> usize {
self.flat.len()
}

/// Check if the field is of scalar type
pub fn field_is_scalar<Extensions>(&self, field: &Field<Extensions, Input>) -> bool {
self.index.type_is_scalar(field.type_of.name())
}

/// Check if the field is of enum type
pub fn field_is_enum<Extensions>(&self, field: &Field<Extensions, Input>) -> bool {
self.index.type_is_enum(field.type_of.name())
}

/// Validate the value against enum variants of the field
pub fn field_validate_enum_value<Extensions>(
&self,
field: &Field<Extensions, Input>,
value: &str,
) -> bool {
self.index.validate_enum_value(field.type_of.name(), value)
}

/// Iterate over nested fields that are related to the __typename of the
/// value
pub fn field_iter_only<'a, Output>(
&'a self,
field: &'a Field<Nested<Input>, Input>,
value: &'a Output,
) -> impl Iterator<Item = &'a Field<Nested<Input>, Input>>
where
Output: TypedValue<'a>,
{
let value_type = field.value_type(value);

field.iter_only(move |field| match &field.type_condition {
Some(type_condition) => self.index.is_type_implements(value_type, type_condition),
// if there is no type_condition restriction then use this field
None => true,
})
}
}

#[derive(Clone, Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ expression: plan.into_nested()
output_name: "articles",
ir: "Some(..)",
type_of: [Post],
type_condition: "Query",
type_condition: Some(
"Query",
),
extensions: Some(
Nested(
[
Expand All @@ -19,7 +21,9 @@ expression: plan.into_nested()
output_name: "author",
ir: "Some(..)",
type_of: User,
type_condition: "Post",
type_condition: Some(
"Post",
),
extensions: Some(
Nested(
[
Expand All @@ -28,7 +32,9 @@ expression: plan.into_nested()
name: "id",
output_name: "identifier",
type_of: ID!,
type_condition: "User",
type_condition: Some(
"User",
),
directives: [],
},
],
Expand Down
Loading

2 comments on commit 6caf179

@github-actions
Copy link

Choose a reason for hiding this comment

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

running 269 tests
test run_execution_spec::add-field-index-list.md ... ok
test run_execution_spec::add-field-many.md ... ok
test run_execution_spec::add-field-many-list.md ... ok
test run_execution_spec::add-field-modify.md ... ok
test run_execution_spec::add-field-with-composition.md ... ok
test run_execution_spec::add-field-with-modify.md ... ok
test run_execution_spec::add-field.md ... ok
test run_execution_spec::async-cache-disabled.md ... ok
test run_execution_spec::apollo-tracing.md ... ok
test run_execution_spec::async-cache-enable-multiple-resolvers.md ... ok
test run_execution_spec::async-cache-global.md ... ok
test run_execution_spec::async-cache-enabled.md ... ok
test run_execution_spec::async-cache-inflight-request.md ... ok
test run_execution_spec::auth-protected-without-auth.md ... ok
test run_execution_spec::auth-basic.md ... ok
test run_execution_spec::auth-jwt.md ... ok
test run_execution_spec::batching-default.md ... ok
test run_execution_spec::batching-disabled.md ... ok
test run_execution_spec::auth.md ... ok
test run_execution_spec::batching-group-by-optional-key.md ... ok
test run_execution_spec::batching-group-by-default.md ... ok
test run_execution_spec::batching-group-by.md ... ok
test run_execution_spec::batching.md ... ok
test run_execution_spec::batching-post.md ... ok
test run_execution_spec::cache-control.md ... ok
test run_execution_spec::caching.md ... ok
test run_execution_spec::caching-collision.md ... ok
test run_execution_spec::call-graphql-datasource.md ... ok
test run_execution_spec::call-multiple-steps-piping.md ... ok
test run_execution_spec::call-mutation.md ... ok
test run_execution_spec::call-operator.md ... ok
test run_execution_spec::cors-allow-cred-true.md ... ok
test run_execution_spec::cors-allow-cred-false.md ... ok
test run_execution_spec::cors-invalid-expose-headers.md ... ok
test run_execution_spec::cors-invalid-headers.md ... ok
test run_execution_spec::cors-invalid-methods.md ... ok
test run_execution_spec::cors-invalid-origins.md ... ok
test run_execution_spec::cors-allow-cred-vary.md ... ok
test run_execution_spec::custom-headers.md ... ok
test run_execution_spec::dedupe_batch_query_execution.md ... ok
test run_execution_spec::default-value-arg.md ... ok
test run_execution_spec::experimental-headers-error.md ... ok
test run_execution_spec::default-value-config.md ... ok
test run_execution_spec::env-value.md ... ok
test run_execution_spec::graphql-conformance-002.md ... ok
test run_execution_spec::experimental-headers.md ... ok
test run_execution_spec::graphql-conformance-004.md ... ok
test run_execution_spec::graphql-conformance-005.md ... ok
test run_execution_spec::graphql-conformance-006.md ... ok
test run_execution_spec::graphql-conformance-007.md ... ok
test run_execution_spec::graphql-conformance-008.md ... ok
test run_execution_spec::graphql-conformance-009.md ... ok
test run_execution_spec::graphql-conformance-001.md ... ok
test run_execution_spec::graphql-conformance-011.md ... ok
test run_execution_spec::graphql-conformance-012.md ... ok
test run_execution_spec::graphql-conformance-003.md ... ok
test run_execution_spec::graphql-conformance-010.md ... ok
test run_execution_spec::graphql-conformance-014.md ... ok
test run_execution_spec::graphql-conformance-016.md ... ok
test run_execution_spec::graphql-conformance-017.md ... ok
test run_execution_spec::graphql-conformance-015.md ... ok
test run_execution_spec::graphql-conformance-013.md ... FAILED
test run_execution_spec::graphql-conformance-http-001.md ... ok
test run_execution_spec::graphql-conformance-http-002.md ... ok
test run_execution_spec::graphql-conformance-http-003.md ... ok
test run_execution_spec::graphql-conformance-http-004.md ... ok
test run_execution_spec::graphql-conformance-http-007.md ... ok
test run_execution_spec::graphql-conformance-http-008.md ... ok
test run_execution_spec::graphql-conformance-http-009.md ... ok
test run_execution_spec::graphql-conformance-http-005.md ... ok
test run_execution_spec::graphql-conformance-http-011.md ... ok
test run_execution_spec::graphql-conformance-http-006.md ... ok
test run_execution_spec::graphql-conformance-http-010.md ... ok
test run_execution_spec::graphql-conformance-http-012.md ... ok
test run_execution_spec::graphql-conformance-http-013.md ... FAILED
test run_execution_spec::graphql-conformance-http-016.md ... ok
test run_execution_spec::graphql-conformance-http-017.md ... ok
test run_execution_spec::graphql-conformance-http-014.md ... ok
test run_execution_spec::graphql-conformance-http-015.md ... ok
test run_execution_spec::graphql-dataloader-batch-request.md ... ok
test run_execution_spec::graphql-dataloader-no-batch-request.md ... ok
test run_execution_spec::graphql-datasource-errors.md ... ok
test run_execution_spec::graphql-datasource-mutation.md ... ok
test run_execution_spec::graphql-datasource-no-args.md ... ok
test run_execution_spec::graphql-datasource-query-directives.md ... ok
test run_execution_spec::graphql-datasource-with-empty-enum.md ... ok
test run_execution_spec::graphql-datasource-with-args.md ... ok
test run_execution_spec::graphql-datasource-with-mandatory-enum.md ... ok
test run_execution_spec::graphql-nested-datasource.md ... ok
test run_execution_spec::grpc-batch.md ... ok
test run_execution_spec::grpc-error.md ... ok
test run_execution_spec::grpc-json.md ... ok
test run_execution_spec::grpc-map.md ... ok
test run_execution_spec::grpc-oneof.md ... ok
test run_execution_spec::grpc-override-url-from-upstream.md ... ok
test run_execution_spec::grpc-proto-with-same-package.md ... ok
test run_execution_spec::grpc-reflection.md ... ok
test run_execution_spec::grpc-simple.md ... ok
test run_execution_spec::grpc-url-from-upstream.md ... ok
test run_execution_spec::https.md ... ok
test run_execution_spec::inline-field.md ... ok
test run_execution_spec::inline-index-list.md ... ok
test run_execution_spec::input-type-protected-error.md ... ok
test run_execution_spec::io-cache.md ... ok
test run_execution_spec::inline-many-list.md ... ok
test run_execution_spec::inline-many.md ... ok
test run_execution_spec::js-directive.md ... ok
test run_execution_spec::modified-field.md ... ok
test run_execution_spec::mutation-put.md ... ok
test run_execution_spec::mutation.md ... ok
test run_execution_spec::jsonplaceholder-call-post.md ... ok
test run_execution_spec::n-plus-one-list.md ... ok
test run_execution_spec::n-plus-one.md ... ok
test run_execution_spec::nested-objects.md ... ok
test run_execution_spec::nested-recursive-types.md ... ok
test run_execution_spec::nesting-level3.md ... ok
test run_execution_spec::nullable-arg-query.md ... ok
test run_execution_spec::omit-index-list.md ... ok
test run_execution_spec::predefined-scalar.md ... ok
test run_execution_spec::omit-resolved-by-parent.md ... ok
test run_execution_spec::recursive-types-no-resolver.md ... ok
test run_execution_spec::recursive-types-json.md ... ok
test run_execution_spec::omit-many.md ... ok
test run_execution_spec::recursive-types.md ... ok
test run_execution_spec::ref-other-nested.md ... ok
test run_execution_spec::ref-other.md ... ok
test run_execution_spec::related-fields-recursive.md ... ok
test run_execution_spec::rename-field.md ... ok
test run_execution_spec::request-to-upstream-batching.md ... ok
test run_execution_spec::resolve-with-headers.md ... ok
test run_execution_spec::resolve-with-vars.md ... ok
test run_execution_spec::resolved-by-parent.md ... ok
test run_execution_spec::rest-api-error.md ... ok
test run_execution_spec::rest-api-post.md ... ok
test run_execution_spec::rest-api.md ... ok
test run_execution_spec::showcase.md ... ok
test run_execution_spec::test-add-field-error.md ... ok
test run_execution_spec::simple-graphql.md ... ok
test run_execution_spec::simple-query.md ... ok
test run_execution_spec::test-add-field-list.md ... ok
test run_execution_spec::test-all-blueprint-errors.md ... ok
test run_execution_spec::test-batch-operator-post.md ... ok
test run_execution_spec::test-add-field.md ... ok
test run_execution_spec::test-add-link-to-empty-config.md ... ok
test run_execution_spec::test-call-operator-errors.md ... ok
test run_execution_spec::test-conflict-allowed-headers.md ... ok
test run_execution_spec::test-batching-group-by.md ... ok
test run_execution_spec::test-conflict-vars.md ... ok
test run_execution_spec::test-cache.md ... ok
test run_execution_spec::test-dbl-usage-many.md ... ok
test run_execution_spec::test-custom-types.md ... ok
test run_execution_spec::test-custom-scalar.md ... ok
test run_execution_spec::test-directives-undef-null-fields.md ... ok
test run_execution_spec::test-empty-link.md ... ok
test run_execution_spec::test-duplicated-link.md ... ok
test run_execution_spec::test-enable-jit.md ... ok
test run_execution_spec::test-description-many.md ... ok
test run_execution_spec::test-enum-aliases.md ... ok
test run_execution_spec::test-enum-empty.md ... ok
test run_execution_spec::test-enum-default.md ... ok
test run_execution_spec::test-enum-merge.md ... ok
test run_execution_spec::test-expr-error.md ... ok
test run_execution_spec::test-expr-scalar-as-string.md ... ok
test run_execution_spec::test-expr-with-add-field.md ... ok
test run_execution_spec::test-expr-with-inline.md ... ok
test run_execution_spec::test-enum-description.md ... ok
test run_execution_spec::test-enum.md ... ok
test run_execution_spec::test-field-already-implemented-from-Interface.md ... ok
test run_execution_spec::test-graphql-with-add-field.md ... ok
test run_execution_spec::test-graphqlsource-no-base-url.md ... ok
test run_execution_spec::test-expr-with-mustache.md ... ok
test run_execution_spec::test-groupby-without-batching.md ... ok
test run_execution_spec::test-grpc-group-by.md ... ok
test run_execution_spec::test-grpc-invalid-method-format.md ... ok
test run_execution_spec::test-grpc-invalid-proto-id.md ... ok
test run_execution_spec::test-grpc-missing-fields.md ... ok
test run_execution_spec::test-grpc-nested-data.md ... ok
test run_execution_spec::test-grpc-nested-optional.md ... ok
test run_execution_spec::test-grpc-optional.md ... ok
test run_execution_spec::test-grpc-proto-path.md ... ok
test run_execution_spec::test-grpc-service-method.md ... ok
test run_execution_spec::test-grpc-service.md ... ok
test run_execution_spec::test-expr.md ... ok
test run_execution_spec::test-hostname-faliure.md ... ok
test run_execution_spec::test-graphqlsource.md ... ok
test run_execution_spec::test-grpc.md ... ok
test run_execution_spec::test-http-batchKey.md ... ok
test run_execution_spec::test-http-baseurl.md ... ok
test run_execution_spec::test-http-with-add-field.md ... ok
test run_execution_spec::test-http-with-inline.md ... ok
test run_execution_spec::test-http-headers.md ... ok
test run_execution_spec::test-http-with-mustache-expr.md ... ok
test run_execution_spec::test-inline-error.md ... ok
test run_execution_spec::test-http-tmpl.md ... ok
test run_execution_spec::test-http.md ... ok
test run_execution_spec::test-inline-list.md ... ok
test run_execution_spec::test-inline.md ... ok
test run_execution_spec::test-input-out.md ... ok
test run_execution_spec::test-input-documentation.md ... ok
test run_execution_spec::test-input-with-arg-out.md ... ok
test run_execution_spec::test-interface-from-json.md ... ok
test run_execution_spec::test-invalid-query-in-http.md ... ok
test run_execution_spec::test-invalid-server.md ... ok
test run_execution_spec::test-js-multi-onRequest-handlers.md ... ok
test run_execution_spec::test-js-multiple-scripts.md ... ok
test run_execution_spec::test-interface-result.md ... ok
test run_execution_spec::test-interface.md ... ok
test run_execution_spec::test-lack-resolver.md ... ok
test run_execution_spec::test-js-request-response-2.md ... ok
test run_execution_spec::test-merge-batch.md ... ok
test run_execution_spec::test-list-args.md ... ok
test run_execution_spec::test-js-request-response.md ... ok
test run_execution_spec::test-merge-nested.md ... ok
test run_execution_spec::test-merge-query.md ... ok
test run_execution_spec::test-merge-right-with-link-config.md ... ok
test run_execution_spec::test-merge-union.md ... ok
test run_execution_spec::test-missing-mutation-resolver.md ... ok
test run_execution_spec::test-missing-query-resolver.md ... ok
test run_execution_spec::test-missing-root-types.md ... ok
test run_execution_spec::test-missing-schema-query.md ... ok
test run_execution_spec::test-missing-argument-on-all-resolvers.md ... ok
test run_execution_spec::test-merge-server-sdl.md ... ok
test run_execution_spec::test-multiple-config-types.md ... ok
test run_execution_spec::test-multiple-resolvable-directives-on-field.md ... ok
test run_execution_spec::test-multi-interface.md ... ok
test run_execution_spec::test-modify.md ... ok
test run_execution_spec::test-nested-input.md ... ok
test run_execution_spec::test-no-base-url.md ... ok
test run_execution_spec::test-nested-value.md ... ok
test run_execution_spec::test-nested-link.md ... ok
test run_execution_spec::test-null-in-array.md ... ok
test run_execution_spec::test-null-in-object.md ... ok
test run_execution_spec::test-optional-key-skip-empty.md ... ok
test run_execution_spec::test-omit-list.md ... ok
test run_execution_spec::test-omit.md ... ok
test run_execution_spec::test-params-as-body.md ... ok
test run_execution_spec::test-query-documentation.md ... ok
test run_execution_spec::test-query.md ... ok
test run_execution_spec::test-response-header-merge.md ... ok
test run_execution_spec::test-ref-other.md ... ok
test run_execution_spec::test-response-header-value.md ... ok
test run_execution_spec::test-response-headers-multi.md ... ok
test run_execution_spec::test-response-headers-name.md ... ok
test run_execution_spec::test-required-fields.md ... FAILED
test run_execution_spec::test-scalars-builtin.md ... ok
test run_execution_spec::test-scalars-integers.md ... ok
test run_execution_spec::test-scalars-validation.md ... ok
test run_execution_spec::test-server-base-types.md ... ok
test run_execution_spec::test-set-cookie-headers.md ... ok
test run_execution_spec::test-server-vars.md ... ok
test run_execution_spec::test-undefined-query.md ... ok
test run_execution_spec::test-static-value.md ... ok
test run_execution_spec::test-union-many-types.md ... ok
test run_execution_spec::test-union-same-types.md ... ok
test run_execution_spec::test-union-ambiguous.md ... ok
test run_execution_spec::test-scalars.md ... ok
test run_execution_spec::test-upstream-headers.md ... ok
test run_execution_spec::undeclared-type-no-base-url.md ... ok
test run_execution_spec::undeclared-type.md ... ok
test run_execution_spec::test-union.md ... ok
test run_execution_spec::upstream-batching.md ... ok
test run_execution_spec::test-upstream.md ... ok
test run_execution_spec::upstream-fail-request.md ... ok
test run_execution_spec::with-args-url.md ... ok
test run_execution_spec::with-args.md ... ok
test run_execution_spec::with-nesting.md ... ok
test run_execution_spec::yaml-nested-unions.md ... ok
test run_execution_spec::yaml-union-in-type.md ... ok
test run_execution_spec::yaml-union.md ... ok

failures:

---- run_execution_spec::graphql-conformance-013.md ----
test panicked: snapshot assertion for 'graphql-conformance-013.md_0' failed in line 202

---- run_execution_spec::graphql-conformance-http-013.md ----
test panicked: snapshot assertion for 'graphql-conformance-http-013.md_0' failed in line 202

---- run_execution_spec::test-required-fields.md ----
test panicked: snapshot assertion for 'test-required-fields.md_8' failed in line 202

failures:
run_execution_spec::graphql-conformance-013.md
run_execution_spec::graphql-conformance-http-013.md
run_execution_spec::test-required-fields.md

test result: FAILED. 266 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 18.97s

@github-actions
Copy link

Choose a reason for hiding this comment

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

Running 30s test @ http://localhost:8000/graphql

4 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev
Latency 6.75ms 3.37ms 119.97ms 78.11%
Req/Sec 3.77k 145.37 4.29k 90.50%

449770 requests in 30.01s, 2.25GB read

Requests/sec: 14985.06

Transfer/sec: 76.91MB

Please sign in to comment.