Skip to content

Add yaml test runner project #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 130 commits into from
May 28, 2020
Merged

Add yaml test runner project #98

merged 130 commits into from
May 28, 2020

Conversation

russcam
Copy link
Contributor

@russcam russcam commented May 21, 2020

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).

  1. 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

  1. 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

russcam added 30 commits March 11, 2020 12:15
WIP

This commit is the start of the yaml test runner binary.

- Download yaml tests from GitHub to local filesystem
- Read yaml tests
This commit changes the api_generator package to expose it as a library to
yaml_test_runner, whilst also still compiling it as a runnable binary. This allows
the generator modules to be used in the yaml_test_runner where they will be
needed to generate tests, by inspecting the ASTs produced by the generator.

Move last_downloaded_version marker file into rest_specs directory so that
the yaml_test_runner can use/reuse downloaded rest specs when running locally,
by easily inspecting the downloaded version.

Renamed api_generator module in api_generator to simply generator.
This commit simplifies some functions by changing
return types to Result<(), failure::Error>
This commit starts generating tests from the steps read from yaml so far.
run cargo fmt
indent accumulated errors
@mwilliammyers
Copy link
Contributor

mwilliammyers commented May 21, 2020

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
Copy link
Contributor

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
Copy link
Contributor Author

russcam commented May 25, 2020

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
Copy link
Contributor

Ok! I will open a PR for once_cell ASAP

@russcam
Copy link
Contributor Author

russcam commented May 28, 2020

@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

@russcam russcam merged commit 27b8ac9 into master May 28, 2020
russcam added a commit that referenced this pull request May 28, 2020
This commit adds a new package to the repository,
yaml_test_runner, that

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

Having a yaml test runner for the client brings it in
line with the other official Elasticsearch clients.

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

The api_generator package is now exposed as a library
to yaml_test_runner package, whilst also still compiling it as a
runnable binary to generate the client. This allows the generator modules
to be used in the yaml_test_runner where they are used to generate tests,
by inspecting the ASTs produced by the api_generator.

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.

Other pertinent changes in this commit:

* impl From<> for TrackTotalHits for i64 and bool
* Define expand_wildcards param as a collection
* Handle url serialization of enum collections

  Updates serialize_coll_qs to handle serializing
  a collection of types that implement Serialize to a comma separated
  query string value. This is only needed
  for enums and strings, but (mis)uses serde_json serialize to
  achieve this, since serde_urlencoded does not support such a format.
  We could probably implement a serde Serializer for this later on.

* Credentials set before setting any other headers in transport
  to allow headers to overwrite values.
* Update TypeKind::None to TypeKind::Unknown(String)
  Better handle new types when introduced

Closes #19

(cherry picked from commit 27b8ac9)
russcam added a commit that referenced this pull request May 28, 2020
This commit adds a new package to the repository,
yaml_test_runner, that

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

Having a yaml test runner for the client brings it in
line with the other official Elasticsearch clients.

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

The api_generator package is now exposed as a library
to yaml_test_runner package, whilst also still compiling it as a
runnable binary to generate the client. This allows the generator modules
to be used in the yaml_test_runner where they are used to generate tests,
by inspecting the ASTs produced by the api_generator.

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.

Other pertinent changes in this commit:

* impl From<> for TrackTotalHits for i64 and bool
* Define expand_wildcards param as a collection
* Handle url serialization of enum collections

  Updates serialize_coll_qs to handle serializing
  a collection of types that implement Serialize to a comma separated
  query string value. This is only needed
  for enums and strings, but (mis)uses serde_json serialize to
  achieve this, since serde_urlencoded does not support such a format.
  We could probably implement a serde Serializer for this later on.

* Credentials set before setting any other headers in transport
  to allow headers to overwrite values.
* Update TypeKind::None to TypeKind::Unknown(String)
  Better handle new types when introduced

Closes #19

(cherry picked from commit 27b8ac9)
@russcam russcam added enhancement New feature or request v7.7.1-alpha.1 labels May 29, 2020
@russcam russcam deleted the enhancement/yaml-test-runner branch May 29, 2020 01:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request v7.7.1-alpha.1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Implement YAML test runner
2 participants