Skip to content

Commit

Permalink
fix(grpc): Load dependency proto files through reflection when availa…
Browse files Browse the repository at this point in the history
…ble (#2683)

Co-authored-by: Kiryl Mialeshka <[email protected]>
Co-authored-by: Tushar Mathur <[email protected]>
  • Loading branch information
3 people authored Aug 17, 2024
1 parent 2383d3b commit 12092ec
Show file tree
Hide file tree
Showing 16 changed files with 176 additions and 36 deletions.
52 changes: 50 additions & 2 deletions src/core/proto_reader/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,14 @@ impl GrpcReflection {
.execute(json!({"file_containing_symbol": service}))
.await?;

request_proto(resp).await
request_proto(resp)
}

/// Makes `Get File` request to grpc reflection server
pub async fn get_file(&self, file_path: &str) -> Result<FileDescriptorProto> {
let resp = self.execute(json!({"file_by_filename": file_path})).await?;

request_proto(resp)
}

async fn execute(&self, body: serde_json::Value) -> Result<ReflectionResponse> {
Expand Down Expand Up @@ -158,7 +165,7 @@ impl GrpcReflection {
}

/// For extracting `FileDescriptorProto` from `CustomResponse`
async fn request_proto(response: ReflectionResponse) -> Result<FileDescriptorProto> {
fn request_proto(response: ReflectionResponse) -> Result<FileDescriptorProto> {
let file_descriptor_resp = response
.file_descriptor_response
.context("Expected fileDescriptorResponse but found none")?;
Expand Down Expand Up @@ -196,6 +203,16 @@ mod grpc_fetch {
BASE64_STANDARD.decode(bytes).unwrap()
}

fn get_dto_file_descriptor() -> Vec<u8> {
let mut path = PathBuf::from(file!());
path.pop();
path.push("fixtures/dto_b64.txt");

let bytes = std::fs::read(path).unwrap();

BASE64_STANDARD.decode(bytes).unwrap()
}

fn start_mock_server() -> httpmock::MockServer {
httpmock::MockServer::start()
}
Expand Down Expand Up @@ -228,6 +245,37 @@ mod grpc_fetch {
Ok(())
}

#[tokio::test]
async fn test_dto_file() -> Result<()> {
let server = start_mock_server();

let http_reflection_file_mock = server.mock(|when, then| {
when.method(httpmock::Method::POST)
.path("/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo")
.body("\0\0\0\0\u{10}\u{1a}\u{0e}news_dto.proto");
then.status(200).body(get_dto_file_descriptor());
});

let grpc_reflection = GrpcReflection::new(
format!("http://localhost:{}", server.port()),
crate::core::runtime::test::init(None),
);

let runtime = crate::core::runtime::test::init(None);
let resp = grpc_reflection.get_file("news_dto.proto").await?;

let content = runtime
.file
.read(tailcall_fixtures::protobuf::NEWS_DTO)
.await?;
let expected = protox_parse::parse("news_dto.proto", &content)?;

assert_eq!(expected.name(), resp.name());

http_reflection_file_mock.assert();
Ok(())
}

#[tokio::test]
async fn test_resp_list_all() -> Result<()> {
let server = start_mock_server();
Expand Down
2 changes: 1 addition & 1 deletion src/core/proto_reader/fixtures/descriptor_b64.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
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
1 change: 1 addition & 0 deletions src/core/proto_reader/fixtures/dto_b64.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AAAABHESEBoObmV3c19kdG8ucHJvdG8i3AgK2QgKDm5ld3NfZHRvLnByb3RvEgRuZXdzGhtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8ihAEKBE5ld3MSDgoCaWQYASABKAVSAmlkEhQKBXRpdGxlGAIgASgJUgV0aXRsZRISCgRib2R5GAMgASgJUgRib2R5EhwKCXBvc3RJbWFnZRgEIAEoCVIJcG9zdEltYWdlEiQKBnN0YXR1cxgFIAEoDjIMLm5ld3MuU3RhdHVzUgZzdGF0dXMiGAoGTmV3c0lkEg4KAmlkGAEgASgFUgJpZCIwCg5NdWx0aXBsZU5ld3NJZBIeCgNpZHMYASADKAsyDC5uZXdzLk5ld3NJZFIDaWRzIioKCE5ld3NMaXN0Eh4KBG5ld3MYASADKAsyCi5uZXdzLk5ld3NSBG5ld3MqLwoGU3RhdHVzEg0KCVBVQkxJU0hFRBAAEgkKBURSQUZUEAESCwoHREVMRVRFRBACSusFCgYSBAAAGCwKCAoBDBIDAAASCggKAQISAwIADQoJCgIDABIDBAAlCgoKAgUAEgQGAAoBCgoKAwUAARIDBgULCgsKBAUAAgASAwcCEAoMCgUFAAIAARIDBwILCgwKBQUAAgACEgMHDg8KCwoEBQACARIDCAIMCgwKBQUAAgEBEgMIAgcKDAoFBQACAQISAwgKCwoLCgQFAAICEgMJAg4KDAoFBQACAgESAwkCCQoMCgUFAAICAhIDCQwNCgoKAgQAEgQMABIBCgoKAwQAARIDDAgMCgsKBAQAAgASAw0CDwoMCgUEAAIABRIDDQIHCgwKBQQAAgABEgMNCAoKDAoFBAACAAMSAw0NDgoLCgQEAAIBEgMOAhMKDAoFBAACAQUSAw4CCAoMCgUEAAIBARIDDgkOCgwKBQQAAgEDEgMOERIKCwoEBAACAhIDDwISCgwKBQQAAgIFEgMPAggKDAoFBAACAgESAw8JDQoMCgUEAAICAxIDDxARCgsKBAQAAgMSAxACFwoMCgUEAAIDBRIDEAIICgwKBQQAAgMBEgMQCRIKDAoFBAACAwMSAxAVFgoLCgQEAAIEEgMRAhQKDAoFBAACBAYSAxECCAoMCgUEAAIEARIDEQkPCgwKBQQAAgQDEgMREhMKCQoCBAESAxQAIAoKCgMEAQESAxQIDgoLCgQEAQIAEgMUER4KDAoFBAECAAUSAxQRFgoMCgUEAQIAARIDFBcZCgwKBQQBAgADEgMUHB0KCQoCBAISAxYAMwoKCgMEAgESAxYIFgoLCgQEAgIAEgMWGTEKDAoFBAICAAQSAxYZIQoMCgUEAgIABhIDFiIoCgwKBQQCAgABEgMWKSwKDAoFBAICAAMSAxYvMAoJCgIEAxIDGAAsCgoKAwQDARIDGAgQCgsKBAQDAgASAxgTKgoMCgUEAwIABBIDGBMbCgwKBQQDAgAGEgMYHCAKDAoFBAMCAAESAxghJQoMCgUEAwIAAxIDGCgpYgZwcm90bzM=
56 changes: 46 additions & 10 deletions src/core/proto_reader/reader.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use std::collections::{HashMap, VecDeque};
use std::path::{Path, PathBuf};
use std::sync::Arc;

use anyhow::Context;
use futures_util::future::join_all;
use futures_util::future::{join_all, BoxFuture};
use futures_util::FutureExt;
use prost_reflect::prost_types::{FileDescriptorProto, FileDescriptorSet};
use protox::file::{FileResolver, GoogleFileResolver};

use crate::core::proto_reader::fetch::GrpcReflection;
use crate::core::resource_reader::{Cached, ResourceReader};
use crate::core::runtime::TargetRuntime;

#[derive(Clone)]
pub struct ProtoReader {
reader: ResourceReader<Cached>,
runtime: TargetRuntime,
Expand All @@ -29,7 +32,7 @@ impl ProtoReader {

/// Fetches proto files from a grpc server (grpc reflection)
pub async fn fetch<T: AsRef<str>>(&self, url: T) -> anyhow::Result<Vec<ProtoMetadata>> {
let grpc_reflection = GrpcReflection::new(url.as_ref(), self.runtime.clone());
let grpc_reflection = Arc::new(GrpcReflection::new(url.as_ref(), self.runtime.clone()));

let mut proto_metadata = vec![];
let service_list = grpc_reflection.list_all_files().await?;
Expand All @@ -39,7 +42,9 @@ impl ProtoReader {
}
let file_descriptor_proto = grpc_reflection.get_by_service(&service).await?;
Self::check_package(&file_descriptor_proto)?;
let descriptors = self.resolve(file_descriptor_proto, None).await?;
let descriptors = self
.reflection_resolve(grpc_reflection.clone(), file_descriptor_proto)
.await?;
let metadata = ProtoMetadata {
descriptor_set: FileDescriptorSet { file: descriptors },
path: url.as_ref().to_string(),
Expand All @@ -64,7 +69,7 @@ impl ProtoReader {
Self::check_package(&file_read)?;

let descriptors = self
.resolve(file_read, PathBuf::from(path.as_ref()).parent())
.file_resolve(file_read, PathBuf::from(path.as_ref()).parent())
.await?;
let metadata = ProtoMetadata {
descriptor_set: FileDescriptorSet { file: descriptors },
Expand All @@ -73,12 +78,15 @@ impl ProtoReader {
Ok(metadata)
}

/// Performs BFS to import all nested proto files
async fn resolve(
/// Used as a helper file to resolve dependencies proto files
async fn resolve_dependencies<F>(
&self,
parent_proto: FileDescriptorProto,
parent_path: Option<&Path>,
) -> anyhow::Result<Vec<FileDescriptorProto>> {
resolve_fn: F,
) -> anyhow::Result<Vec<FileDescriptorProto>>
where
F: Fn(&str) -> BoxFuture<'_, anyhow::Result<FileDescriptorProto>>,
{
let mut descriptors: HashMap<String, FileDescriptorProto> = HashMap::new();
let mut queue = VecDeque::new();
queue.push_back(parent_proto.clone());
Expand All @@ -87,7 +95,7 @@ impl ProtoReader {
let futures: Vec<_> = file
.dependency
.iter()
.map(|import| self.read_proto(import, parent_path))
.map(|import| resolve_fn(import))
.collect();

let results = join_all(futures).await;
Expand All @@ -108,6 +116,34 @@ impl ProtoReader {
Ok(descriptors_vec)
}

/// Used to resolve dependencies proto files using file reader
async fn file_resolve(
&self,
parent_proto: FileDescriptorProto,
parent_path: Option<&Path>,
) -> anyhow::Result<Vec<FileDescriptorProto>> {
self.resolve_dependencies(parent_proto, |import| {
let parent_path = parent_path.map(|p| p.to_path_buf());
let this = self.clone();

async move { this.read_proto(import, parent_path.as_deref()).await }.boxed()
})
.await
}

/// Used to resolve dependencies proto files using reflection
async fn reflection_resolve(
&self,
grpc_reflection: Arc<GrpcReflection>,
parent_proto: FileDescriptorProto,
) -> anyhow::Result<Vec<FileDescriptorProto>> {
self.resolve_dependencies(parent_proto, |file| {
let grpc_reflection = Arc::clone(&grpc_reflection);
async move { grpc_reflection.get_file(file).await }.boxed()
})
.await
}

/// Tries to load well-known google proto files and if not found uses normal
/// file and http IO to resolve them
async fn read_proto<T: AsRef<str>>(
Expand Down Expand Up @@ -180,7 +216,7 @@ mod test_proto_config {

let reader = ProtoReader::init(ResourceReader::<Cached>::cached(runtime.clone()), runtime);
let file_descriptors = reader
.resolve(reader.read_proto(&test_file, None).await?, Some(test_dir))
.file_resolve(reader.read_proto(&test_file, None).await?, Some(test_dir))
.await?;
for file in file_descriptors
.iter()
Expand Down
2 changes: 2 additions & 0 deletions tailcall-cloudflare/tests/cf_tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ describe("fetch", () => {
let placeholder_batch = (await readFile("../examples/jsonplaceholder_batch.graphql")).toString()
let grpc = (await readFile("../examples/grpc.graphql")).toString()
let news_proto = (await readFile("../tailcall-fixtures/fixtures/protobuf/news.proto")).toString()
let news_dto_proto = (await readFile("../tailcall-fixtures/fixtures/protobuf/news_dto.proto")).toString()

let bucket = await mf.getR2Bucket("MY_R2")
await bucket.put("examples/grpc.graphql", grpc)
await bucket.put("examples/../tailcall-fixtures/fixtures/protobuf/news.proto", news_proto)
await bucket.put("examples/../tailcall-fixtures/fixtures/protobuf/news_dto.proto", news_dto_proto)
await bucket.put("tailcall-fixtures/fixtures/protobuf/news.proto", grpc)
await bucket.put("examples/jsonplaceholder.graphql", placeholder)
await bucket.put("examples/jsonplaceholder_batch.graphql", placeholder_batch)
Expand Down
9 changes: 9 additions & 0 deletions tailcall-fixtures/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Tailcall fixtures

Package that contains configs and fixtures used in tests and examples to be shared among different parts of tailcall plus helper functions to resolve these files in tests.

## gRPC binary files

Instructions to generate those files:

1. go to `src/core/proto_reader/fetch.rs`
2. modify `GrpcReflection.execute` function to print the request `body` as string and response `body` as base64 encoded
3. convert the base64 into bin files using online base64 to file websites or manually
4. rename the files and replace the old ones
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
23 changes: 2 additions & 21 deletions tailcall-fixtures/fixtures/protobuf/news.proto
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
syntax = "proto3";

import "google/protobuf/empty.proto";

package news;

enum Status {
PUBLISHED = 0;
DRAFT = 1;
DELETED = 2;
}

message News {
int32 id = 1;
string title = 2;
string body = 3;
string postImage = 4;
Status status = 5;
}
import "news_dto.proto";
import "google/protobuf/empty.proto";

service NewsService {
rpc GetAllNews(google.protobuf.Empty) returns (NewsList) {}
Expand All @@ -26,9 +13,3 @@ service NewsService {
rpc EditNews(News) returns (News) {}
rpc AddNews(News) returns (News) {}
}

message NewsId { int32 id = 1; }

message MultipleNewsId { repeated NewsId ids = 1; }

message NewsList { repeated News news = 1; }
25 changes: 25 additions & 0 deletions tailcall-fixtures/fixtures/protobuf/news_dto.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
syntax = "proto3";

package news;

import "google/protobuf/empty.proto";

enum Status {
PUBLISHED = 0;
DRAFT = 1;
DELETED = 2;
}

message News {
int32 id = 1;
string title = 2;
string body = 3;
string postImage = 4;
Status status = 5;
}

message NewsId { int32 id = 1; }

message MultipleNewsId { repeated NewsId ids = 1; }

message NewsList { repeated News news = 1; }
7 changes: 7 additions & 0 deletions tests/core/snapshots/grpc-reflection.md_client.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type News {
body: String
id: Int
postImage: String
status: Status
title: String
}

Expand All @@ -41,6 +42,12 @@ type Query {
news: NewsData!
}

enum Status {
DELETED
DRAFT
PUBLISHED
}

scalar UInt128

scalar UInt16
Expand Down
7 changes: 7 additions & 0 deletions tests/core/snapshots/grpc-reflection.md_merged.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ schema
query: Query
}

enum Status {
DELETED
DRAFT
PUBLISHED
}

type News {
body: String
id: Int
postImage: String
status: Status
title: String
}

Expand Down
28 changes: 26 additions & 2 deletions tests/execution/grpc-reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ type News {
title: String
body: String
postImage: String
status: Status
}

enum Status {
PUBLISHED
DRAFT
DELETED
}
```

Expand All @@ -31,15 +38,32 @@ type News {
textBody: \0\0\0\0\x02:\0
response:
status: 200
fileBody: grpc/reflection/news-list-services.bin
fileBody: grpc/reflection/list-services.bin

- request:
method: POST
url: http://localhost:50051/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo
textBody: \0\0\0\0\x12\"\x10news.NewsService
response:
status: 200
fileBody: grpc/reflection/news-service-descriptor.bin
fileBody: grpc/reflection/news-service.bin

- request:
method: POST
url: http://localhost:50051/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo
textBody: \0\0\0\0\x1d\x1a\x1bgoogle/protobuf/empty.proto
expectedHits: 2
response:
status: 200
fileBody: grpc/reflection/protobuf_empty.bin

- request:
method: POST
url: http://localhost:50051/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo
textBody: \0\0\0\0\x10\x1a\x0enews_dto.proto
response:
status: 200
fileBody: grpc/reflection/news_dto.bin

- request:
method: POST
Expand Down

2 comments on commit 12092ec

@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 268 tests
test run_execution_spec::add-field-index-list.md ... ok
test run_execution_spec::add-field-many-list.md ... ok
test run_execution_spec::add-field-many.md ... ok
test run_execution_spec::add-field-modify.md ... ok
test run_execution_spec::add-field-with-modify.md ... ok
test run_execution_spec::add-field-with-composition.md ... ok
test run_execution_spec::add-field.md ... ok
test run_execution_spec::apollo-tracing.md ... ok
test run_execution_spec::async-cache-disabled.md ... ok
test run_execution_spec::async-cache-enable-multiple-resolvers.md ... ok
test run_execution_spec::async-cache-enabled.md ... ok
test run_execution_spec::async-cache-global.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-disabled.md ... ok
test run_execution_spec::auth.md ... ok
test run_execution_spec::batching-default.md ... ok
test run_execution_spec::batching-group-by-default.md ... ok
test run_execution_spec::batching-group-by-optional-key.md ... ok
test run_execution_spec::batching-group-by.md ... ok
test run_execution_spec::batching-post.md ... ok
test run_execution_spec::batching.md ... ok
test run_execution_spec::cache-control.md ... ok
test run_execution_spec::caching.md ... ok
test run_execution_spec::call-graphql-datasource.md ... ok
test run_execution_spec::caching-collision.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-false.md ... ok
test run_execution_spec::cors-allow-cred-true.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-010.md ... ok
test run_execution_spec::graphql-conformance-003.md ... FAILED
test run_execution_spec::graphql-conformance-013.md ... FAILED
test run_execution_spec::graphql-conformance-016.md ... ok
test run_execution_spec::graphql-conformance-014.md ... ok
test run_execution_spec::graphql-conformance-017.md ... ok
test run_execution_spec::graphql-conformance-015.md ... FAILED
test run_execution_spec::graphql-conformance-http-002.md ... ok
test run_execution_spec::graphql-conformance-http-001.md ... ok
test run_execution_spec::graphql-conformance-http-003.md ... FAILED
test run_execution_spec::graphql-conformance-http-005.md ... FAILED
test run_execution_spec::graphql-conformance-http-004.md ... FAILED
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-011.md ... ok
test run_execution_spec::graphql-conformance-http-006.md ... FAILED
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 ... FAILED
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 ... FAILED
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-scalar.md ... ok
test run_execution_spec::test-custom-types.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-enum-description.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-expr-scalar-as-string.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-baseurl.md ... ok
test run_execution_spec::test-http-batchKey.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-js-request-response-2.md ... ok
test run_execution_spec::test-lack-resolver.md ... ok
test run_execution_spec::test-merge-batch.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-list-args.md ... ok
test run_execution_spec::test-merge-query.md ... ok
test run_execution_spec::test-merge-union.md ... ok
test run_execution_spec::test-missing-argument-on-all-resolvers.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-merge-server-sdl.md ... ok
test run_execution_spec::test-merge-right-with-link-config.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-modify.md ... ok
test run_execution_spec::test-multi-interface.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-link.md ... ok
test run_execution_spec::test-nested-value.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.md ... ok
test run_execution_spec::test-query-documentation.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-response-header-merge.md ... ok
test run_execution_spec::test-ref-other.md ... ok
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-scalars.md ... ok
test run_execution_spec::test-union-ambiguous.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 ... FAILED
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-003.md ----
test panicked: snapshot assertion for 'graphql-conformance-003.md_1' failed in line 202

---- 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-015.md ----
test panicked: snapshot assertion for 'graphql-conformance-015.md_0' failed in line 202

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

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

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

---- run_execution_spec::graphql-conformance-http-006.md ----
test panicked: snapshot assertion for 'graphql-conformance-http-006.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::graphql-conformance-http-015.md ----
test panicked: snapshot assertion for 'graphql-conformance-http-015.md_0' failed in line 202

---- run_execution_spec::grpc-oneof.md ----
test panicked: snapshot assertion for 'grpc-oneof.md_0' failed in line 202

---- run_execution_spec::test-union.md ----
test panicked: snapshot assertion for 'test-union.md_4' failed in line 202

failures:
run_execution_spec::graphql-conformance-003.md
run_execution_spec::graphql-conformance-013.md
run_execution_spec::graphql-conformance-015.md
run_execution_spec::graphql-conformance-http-003.md
run_execution_spec::graphql-conformance-http-005.md
run_execution_spec::graphql-conformance-http-004.md
run_execution_spec::graphql-conformance-http-006.md
run_execution_spec::graphql-conformance-http-013.md
run_execution_spec::graphql-conformance-http-015.md
run_execution_spec::grpc-oneof.md
run_execution_spec::test-union.md

test result: FAILED. 257 passed; 11 failed; 0 ignored; 0 measured; 0 filtered out; finished in 13.77s

@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 7.45ms 3.93ms 162.61ms 79.03%
Req/Sec 3.42k 140.66 3.75k 88.17%

408091 requests in 30.00s, 2.05GB read

Requests/sec: 13601.20

Transfer/sec: 69.81MB

Please sign in to comment.