apollo-smith

A test case generator for GraphQL language.

Crates.io Download docs.rs docs

About

The goal of apollo-smith is to generate valid GraphQL documents by sampling from all available possibilities of [GraphQL grammar].

We've written apollo-smith to use in fuzzing, but you may wish to use it for anything that requires GraphQL document generation.

apollo-smith is inspired by bytecodealliance's [wasm-smith] crate, and the [article written by Nick Fitzgerald] on writing test case generators in Rust.

This is still a work in progress, for outstanding issues, checkout out the [apollo-smith label] in our issue tracker.

Rust versions

apollo-smith is tested on the latest stable version of Rust. Older version may or may not be compatible.

Using apollo-smith with cargo fuzz

Define a new target with [cargo fuzz],

shell $ cargo fuzz add my_apollo_smith_fuzz_target

and add apollo-smith to your Cargo.toml:

```toml

fuzz/Cargo.toml

[dependencies] apollo-smith = "0.3.2" ```

It can then be used in a fuzz_target along with the [arbitrary] crate,

```rust,compilefail // fuzz/fuzztargets/myapollosmithfuzztarget.rs

![no_main]

use libfuzzersys::fuzztarget; use arbitrary::Unstructured; use apollo_smith::DocumentBuilder;

fuzztarget!(|input: &[u8]| { let mut u = Unstructured::new(input); let gqldoc = DocumentBuilder::new(&mut u)?; let document = gqldoc.finish(); let documentstr = String::from(document);

}); ```

and fuzzed with the following command:

shell $ cargo +nightly fuzz run my_apollo_smith_fuzz_target

Using apollo-smith with apollo-parser

You can use apollo-parser to generate valid operations in apollo-smith. This can be done with the parser-impl feature flag.

```toml

Cargo.toml

[dependencies] apollo-smith = { version = "0.3.1", features = ["parser-impl"] } ```

```rust,compile_fail use std::fs;

use apolloparser::Parser; use apollosmith::{Document, DocumentBuilder};

use libfuzzer_sys::arbitrary::{Result, Unstructured};

/// This generate an arbitrary valid GraphQL operation pub fn generatevalidoperation(input: &[u8]) {

let parser = Parser::new(&fs::read_to_string("supergraph.graphql").expect("cannot read file"));

let tree = parser.parse();
if !tree.errors().is_empty() {
    panic!("cannot parse the graphql file");
}

let mut u = Unstructured::new(input);

// Convert `apollo_parser::Document` into `apollo_smith::Document`.
let apollo_smith_doc = Document::from(tree.document());

// Create a `DocumentBuilder` given an existing document to match a schema.
let mut gql_doc = DocumentBuilder::with_document(&mut u, apollo_smith_doc)?;
let operation_def = gql_doc.operation_definition()?.unwrap();

Ok(operation_def.into())

} ```

Feature flags

Enable parser-impl feature in apollo-smith is used to convert apollo-parser types to apollo-smith types. This is useful when you require the test-case generator to generate documents based on a given schema.

```toml

Cargo.toml

[dependencies] apollo-smith = { version = "0.3.1", features = ["parser-impl"] } ```

Limitations

License

Licensed under either of

at your option.