Extended UT Framework for Functional Correctness of query conversion#21060
Extended UT Framework for Functional Correctness of query conversion#21060nssuresh2007 wants to merge 1 commit intoopensearch-project:feature/datafusionfrom
Conversation
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
|
❌ Gradle check result for b859be5: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
Thanks @nssuresh2007 This PR adds a "golden file" testing layer that reads JSON files and validates:
I think it's worth considering how this fits with what we already have:
The golden file tests chain SearchSourceConverter + SearchResponseBuilder but still use mocked infrastructure (no cluster), so there's a fair bit of overlap with the existing unit tests. One concern is that maintenance burden could grow over time : for example, if a RelNode plan shape changes due to a refactor (even though semantics are correct), all golden files would need updating. A couple of alternatives worth considering: We could extend the existing internalClusterTest suite for each new query shape. These already test real execution against a single-node cluster: // In DslQueryIT.java
public void testRangeQuery() {
SearchResponse resp = executeQuery(indexName,
"{\"query\":{\"range\":{\"price\":{\"gte\":100}}}}");
assertEquals(RestStatus.OK, resp.status());
// validate actual hits from real execution
}If we want JSON-driven test cases for convenience, we could build that on top of integration test infrastructure. Two options that come to mind:
What do you think? Happy to discuss which approach makes the most sense here. |
|
@vinaykpud thanks for the feedback. This extended unit tests are needed for functional correctness of DSL plugin as a stand alone testing framework without OpenSearch cluster dependency. This requirement is not satisfied by the existing tests:
Hence this becomes necessary to have this extended UT to validate if the logic that we are currently adding is correct. Otherwise, we would be able to catch it very late in the development lifecycle until all downstream plugins are functional and testable. Also note that this is not a replacement for UT or IT, but it is complementary to the above. Please let me know if that helps to address your query. |
PR Code Analyzer ❗AI-powered 'Code-Diff-Analyzer' found issues on commit b03d5c1.
The table above displays the top 10 most important findings. Pull Requests Author(s): Please update your Pull Request according to the report above. Repository Maintainer(s): You can Thanks. |
| ExecutionResult result = new ExecutionResult(plan, rows); | ||
|
|
||
| // Build SearchResponse | ||
| var response = SearchResponseBuilder.build(List.of(result), 0L); |
There was a problem hiding this comment.
Forward path we'll use SearchSourceBuilder to convert to Calcite and handoff - but for reverse path, the plan is to get results as SearchResponseBuilder / SearchResponse to maintain result compatibility ?
For SQL / PPL , we might directly get back the rows, hence the question.
There was a problem hiding this comment.
but for reverse path, the plan is to get results as SearchResponseBuilder / SearchResponse to maintain result compatibility ?
Yes, that is the plan
| Path filePath = goldenFilePath(goldenFileName); | ||
| GoldenFileUpdater.update(filePath, actualPlan, tc.getExpectedOutputDsl()); | ||
| } else { | ||
| assertEquals( |
There was a problem hiding this comment.
In RedNode plan, should we validate schema as well at each level?
There was a problem hiding this comment.
Added check for field names as well to validate the schema: https://github.com/opensearch-project/OpenSearch/pull/21210/changes#diff-4ba3b789a12988b89c5caf2e9a4f2d50adea38008059768576b4303205ef820fR79
| private static void validate(GoldenTestCase testCase, Path filePath) { | ||
| requireNonNull(testCase.getTestName(), "testName", filePath); | ||
| requireNonNull(testCase.getIndexName(), "indexName", filePath); | ||
| requireNonNull(testCase.getIndexMapping(), "indexMapping", filePath); | ||
| requireNonNull(testCase.getInputDsl(), "inputDsl", filePath); | ||
| requireNonNull(testCase.getExpectedRelNodePlan(), "expectedRelNodePlan", filePath); | ||
| requireNonNull(testCase.getExecutionFieldNames(), "executionFieldNames", filePath); | ||
| requireNonNull(testCase.getExecutionRows(), "executionRows", filePath); | ||
| requireNonNull(testCase.getExpectedOutputDsl(), "expectedOutputDsl", filePath); | ||
| } |
There was a problem hiding this comment.
Instead of this, can we use @nonnull in GoldenTestCase class itself?
There was a problem hiding this comment.
Currently not able to find any library which uses NonNull annotation. Also currently other places in OpenSearch also use Objects.RequireNonNull only
| stripNonDeterministicFields(actualOutput); | ||
| stripNonDeterministicFields(expectedOutput); | ||
|
|
||
| assertEquals( |
There was a problem hiding this comment.
Bucket order also might not be deterministic for cases where OpenSearch use topK approach at a shard level. e.g. terms bucket aggregation with size parameter.
There was a problem hiding this comment.
Added sorting before comparing the buckets so that they would be deterministic: https://github.com/opensearch-project/OpenSearch/pull/21210/changes#diff-4ba3b789a12988b89c5caf2e9a4f2d50adea38008059768576b4303205ef820fR275
| * Removes non-deterministic fields (took, _shards) from a serialized | ||
| * SearchResponse map so that comparisons are stable. | ||
| */ | ||
| private void stripNonDeterministicFields(Map<String, Object> responseMap) { |
There was a problem hiding this comment.
Score also we will have to strip as it wo'nt be supported?
There was a problem hiding this comment.
6da2f20 to
03df0ce
Compare
Changes to test the end to end DSL query conversion without OpenSearch cluster. Currently adds support for match_all and terms with agg for the initial commit.
|
Apologies, since the forked repo branch got deleted by mistake raised new PR after re-creating it and addressed the comments: #21210 |
Changes to test the end to end DSL query conversion without OpenSearch cluster. Currently adds support for match_all and terms with agg for the initial commit.
Description
This feature introduces a golden-file-based unit test framework for the OpenSearch DSL query executor plugin (
sandbox/plugins/dsl-query-executor/). The framework validates the correctness of both the forward conversion path (DSL → RelNode) and the reverse conversion path (RelNode execution results → SearchResponse DSL output) by comparing actual outputs against pre-approved golden files. Each golden file encodes a complete test case: the input DSL, the expected RelNode logical plan, simulated execution rows, and the expected DSL output.Requirements
Related Issues
Resolves #[Issue number to be closed when this PR is merged]
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.