Skip to content

Commit

Permalink
Merge pull request #63 from hasura/latest-ndc-test
Browse files Browse the repository at this point in the history
Use latest ndc-spec, add test commands
  • Loading branch information
SamirTalwar authored Oct 19, 2023
2 parents cc4e2b2 + 5867bcf commit f025865
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 19 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions rust-connector-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ async-trait = "^0.1.68"
axum = "^0.6.18"
axum-macros = "^0.3.7"
clap = { version = "^4.3.9", features = ["derive", "env"] }
ndc-client = { git = "http://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.7" }
ndc-test = { git = "http://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.7" }
ndc-client = { git = "http://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.8" }
ndc-test = { git = "http://github.com/hasura/ndc-spec.git", tag = "v0.1.0-rc.8" }
http = "^0.2"
opentelemetry = { version = "^0.20", features = [
"rt-tokio",
Expand Down
90 changes: 75 additions & 15 deletions rust-connector-sdk/src/default_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ use ndc_test::report;
use prometheus::Registry;
use schemars::{schema::RootSchema, JsonSchema};
use serde::{de::DeserializeOwned, Serialize};
use std::error::Error;
use std::net;
use std::process::exit;
use std::{error::Error, path::PathBuf};
use tower_http::{cors::CorsLayer, trace::TraceLayer};

use self::v2_compat::SourceConfig;
Expand All @@ -51,6 +51,8 @@ enum Command {
#[command()]
Test(TestCommand),
#[command()]
Replay(ReplayCommand),
#[command()]
CheckHealth(CheckHealthCommand),
}

Expand Down Expand Up @@ -98,10 +100,20 @@ struct ServeConfigurationCommand {

#[derive(Clone, Parser)]
struct TestCommand {
#[arg(long, value_name = "PORT", env = "PORT")]
#[arg(long, value_name = "SEED", env = "SEED")]
seed: Option<String>,
#[arg(long, value_name = "CONFIGURATION_FILE", env = "CONFIGURATION_FILE")]
configuration: String,
#[arg(long, value_name = "DIRECTORY", env = "SNAPSHOTS_DIR")]
snapshots_dir: Option<PathBuf>,
}

#[derive(Clone, Parser)]
struct ReplayCommand {
#[arg(long, value_name = "CONFIGURATION_FILE", env = "CONFIGURATION_FILE")]
configuration: String,
#[arg(long, value_name = "DIRECTORY", env = "SNAPSHOTS_DIR")]
snapshots_dir: PathBuf,
}

#[derive(Clone, Parser)]
Expand Down Expand Up @@ -157,6 +169,7 @@ where
Command::Serve(serve_command) => serve::<C>(serve_command).await,
Command::Configuration(configure_command) => configuration::<C>(configure_command).await,
Command::Test(test_command) => test::<C>(test_command).await,
Command::Replay(replay_command) => replay::<C>(replay_command).await,
Command::CheckHealth(check_health_command) => check_health(check_health_command).await,
}
}
Expand Down Expand Up @@ -592,6 +605,19 @@ where
Err(err) => Err(ndc_test::Error::OtherError(err.into())),
}
}

async fn mutation(
&self,
request: ndc_client::models::MutationRequest,
) -> Result<ndc_client::models::MutationResponse, ndc_test::Error> {
match C::mutation(&self.configuration, &self.state, request)
.await
.and_then(JsonResponse::into_value)
{
Ok(response) => Ok(response),
Err(err) => Err(ndc_test::Error::OtherError(err.into())),
}
}
}

async fn test<C: Connector + 'static>(
Expand All @@ -602,9 +628,52 @@ where
C::Configuration: Sync + Send + 'static,
C::State: Send + Sync + 'static,
{
let test_configuration = ndc_test::TestConfiguration { seed: command.seed };
let test_configuration = ndc_test::TestConfiguration {
seed: command.seed,
snapshots_dir: command.snapshots_dir,
};

let connector = make_connector_adapter::<C>(command.configuration).await;
let results = ndc_test::test_connector(&test_configuration, &connector).await;

if !results.failures.is_empty() {
println!();
println!("{}", report(results));

let configuration_json = std::fs::read_to_string(command.configuration).unwrap();
exit(1)
}

Ok(())
}

async fn replay<C: Connector + 'static>(
command: ReplayCommand,
) -> Result<(), Box<dyn Error + Send + Sync>>
where
C::RawConfiguration: DeserializeOwned,
C::Configuration: Sync + Send + 'static,
C::State: Send + Sync + 'static,
{
let connector = make_connector_adapter::<C>(command.configuration).await;
let results = ndc_test::test_snapshots_in_directory(&connector, command.snapshots_dir).await;

if !results.failures.is_empty() {
println!();
println!("{}", report(results));

exit(1)
}

Ok(())
}

async fn make_connector_adapter<C: Connector + 'static>(
configuration_path: String,
) -> ConnectorAdapter<C>
where
C::RawConfiguration: DeserializeOwned,
{
let configuration_json = std::fs::read_to_string(configuration_path).unwrap();
let raw_configuration =
serde_json::de::from_str::<C::RawConfiguration>(configuration_json.as_str()).unwrap();
let configuration = C::validate_raw_configuration(raw_configuration)
Expand All @@ -616,21 +685,12 @@ where
.await
.unwrap();

let connector = ConnectorAdapter::<C> {
ConnectorAdapter::<C> {
configuration,
state,
};
let results = ndc_test::test_connector(&test_configuration, &connector).await;

if !results.failures.is_empty() {
println!();
println!("{}", report(results));

exit(1)
}

Ok(())
}

async fn check_health(
CheckHealthCommand { host, port }: CheckHealthCommand,
) -> Result<(), Box<dyn Error + Send + Sync>> {
Expand Down

0 comments on commit f025865

Please sign in to comment.