elastic / elasticsearch-rs

Official Elasticsearch Rust Client
https://www.elastic.co/guide/en/elasticsearch/client/rust-api/current/index.html
Apache License 2.0
695 stars 71 forks source link

Add yaml test runner project #98

Closed russcam closed 4 years ago

russcam commented 4 years ago

This PR adds a yaml_test_runner package to the repository. This package produces a binary that can be invoked to

  1. download yaml tests from Elasticsearch repository for a given branch
  2. use yaml tests in conjunction with rest specs to generate integration tests for each test defined in yaml.

As an example, the following cat.aliases test

---
"Simple alias with json body through format argument":

  - do:
        indices.create:
            index: test

  - do:
        indices.put_alias:
            index: test
            name:  test_alias

  - do:
      cat.aliases:
        format: json

  - match: {0.alias: test_alias}
  - match: {0.index: test}
  - match: {0.filter: "-"}
  - match: {0.routing\.index: "-"}
  - match: {0.routing\.search: "-"}

generates the following test (use directives omitted for brevity)

#[tokio::test]
async fn simple_alias_with_json_body_through_format_argument() -> Result<(), failure::Error> {
    let client = client::create();
    client::general_oss_setup(&client).await?;
    let response = client
        .indices()
        .create(IndicesCreateParts::Index("test"))
        .send()
        .await?;
    let response = client
        .indices()
        .put_alias(IndicesPutAliasParts::IndexName(&["test"], "test_alias"))
        .send()
        .await?;
    let response = client
        .cat()
        .aliases(CatAliasesParts::None)
        .format("json")
        .send()
        .await?;
    let (method, status_code, text, json) = util::read_response(response).await?;
    assert_match!(json[0]["alias"], json!("test_alias"));
    assert_match!(json[0]["index"], json!("test"));
    assert_match!(json[0]["filter"], json!("-"));
    assert_match!(json[0]["routing.index"], json!("-"));
    assert_match!(json[0]["routing.search"], json!("-"));
    Ok(())
}

Tests are generated in a tests directory in the yaml_test_runner package so that they can be invoked with cargo test.

The yaml_test_runner package takes dependencies on both api_generator and elasticsearch packages. It uses the Api model from the former to ascertain how to generate client calls from the values defined in yaml, and uses the latter in executing tests.

The typical flow to generate and run tests is

  1. Define ELASTICSEARCH_VERSION environment variable

    export ELASTICSEARCH_VERSION=elasticsearch-oss:7.7.0-SNAPSHOT

    This is used to determine which test suite to generate, based on whether the version uses the default distribution (xpack suite), or the oss distribution (oss suite).

  2. Run yaml_test_runner

    cargo run -p yaml_test_runner -- \
        --branch <elasticsearch branch> \
        --token <token> \
        --path "<path to rest specs>"

    where

    • --branch is the elasticsearch branch to target to download yaml tests
    • --token is a GitHub access token to use to download the yaml tests using the content API
    • --path is the path to download rest specs to
  3. Run the generated tests

    cargo test -p yaml_test_runner -- --test-threads=1

    The tests must be run synchronously, so a single thread must be used.

Closes #19

mwilliammyers commented 4 years ago

Woah! This is huge! 🎉

Just a drive-by comment: not that it matters much, but once_cell might be preferable over lazy_static because it has an (arguably) cleaner API, that doesn't require macros, uses newer rust features etc. The API is also being proposed for inclusion in std.

mwilliammyers commented 4 years ago

Just noticed lazy_static in the codebase already. Maybe I can open a PR after this one lands to migrate to once_cell, if that is the direction we want to go?

I am finally getting the time to migrate my project over to this crate and so I will have more time to dig into things; I figure PRs like that will help me get re-familiarized with the code...

russcam commented 4 years ago

Just noticed lazy_static in the codebase already. Maybe I can open a PR after this one lands to migrate to once_cell, if that is the direction we want to go?

Had a look at once_cell, seems like a better API than lazy_static, so I would be +1 on a PR to moving over to replacing lazy_static with it.

I am finally getting the time to migrate my project over to this crate and so I will have more time to dig into things; I figure PRs like that will help me get re-familiarized with the code...

Awesome! 😃

mwilliammyers commented 4 years ago

Ok! I will open a PR for once_cell ASAP

russcam commented 4 years ago

@mwilliammyers I've brought in once_cell into the yaml_test_runner to create a singleton client for all of the yaml tests, which has made a massive difference to test run times 😄

About to merge this in and release a new client package