From 7b0a56d6fcbfbc651e76b71c1debdb3e02ef26fb Mon Sep 17 00:00:00 2001 From: Junqiu Lei Date: Mon, 22 Apr 2024 11:58:51 -0700 Subject: [PATCH] Add bwc tests Signed-off-by: Junqiu Lei --- qa/restart-upgrade/build.gradle | 14 +++ .../neuralsearch/bwc/KnnRadialSearchIT.java | 82 +++++++++++++ .../neuralsearch/bwc/MultiModalSearchIT.java | 37 +----- qa/rolling-upgrade/build.gradle | 14 +++ .../neuralsearch/bwc/KnnRadialSearchIT.java | 110 ++++++++++++++++++ .../neuralsearch/bwc/MultiModalSearchIT.java | 28 ----- .../query/NeuralQueryBuilder.java | 1 - 7 files changed, 225 insertions(+), 61 deletions(-) create mode 100644 qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java create mode 100644 qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java diff --git a/qa/restart-upgrade/build.gradle b/qa/restart-upgrade/build.gradle index 8fca43f3a..ce29c77ca 100644 --- a/qa/restart-upgrade/build.gradle +++ b/qa/restart-upgrade/build.gradle @@ -90,6 +90,13 @@ task testAgainstOldCluster(type: StandaloneRestIntegTestTask) { } } + // Excluding the k-NN radial search tests because we introduce this feature in 2.14 + if (ext.neural_search_bwc_version.startsWith("2.9") || ext.neural_search_bwc_version.startsWith("2.10") || ext.neural_search_bwc_version.startsWith("2.11") || ext.neural_search_bwc_version.startsWith("2.12") || ext.neural_search_bwc_version.startsWith("2.13")){ + filter { + excludeTestsMatching "org.opensearch.neuralsearch.bwc.KnnRadialSearchIT.*" + } + } + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}".getName()}") systemProperty 'tests.security.manager', 'false' @@ -139,6 +146,13 @@ task testAgainstNewCluster(type: StandaloneRestIntegTestTask) { } } + // Excluding the k-NN radial search tests because we introduce this feature in 2.14 + if (ext.neural_search_bwc_version.startsWith("2.9") || ext.neural_search_bwc_version.startsWith("2.10") || ext.neural_search_bwc_version.startsWith("2.11") || ext.neural_search_bwc_version.startsWith("2.12") || ext.neural_search_bwc_version.startsWith("2.13")){ + filter { + excludeTestsMatching "org.opensearch.neuralsearch.bwc.KnnRadialSearchIT.*" + } + } + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}".getName()}") systemProperty 'tests.security.manager', 'false' diff --git a/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java b/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java new file mode 100644 index 000000000..ff9170bce --- /dev/null +++ b/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java @@ -0,0 +1,82 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.opensearch.neuralsearch.bwc; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import static org.opensearch.neuralsearch.TestUtils.NODES_BWC_CLUSTER; +import static org.opensearch.neuralsearch.TestUtils.TEXT_IMAGE_EMBEDDING_PROCESSOR; +import static org.opensearch.neuralsearch.TestUtils.getModelId; +import org.opensearch.neuralsearch.query.NeuralQueryBuilder; + +public class KnnRadialSearchIT extends AbstractRestartUpgradeRestTestCase { + private static final String PIPELINE_NAME = "nlp-ingest-pipeline"; + private static final String TEST_FIELD = "passage_text"; + private static final String TEST_IMAGE_FIELD = "passage_image"; + private static final String TEXT = "Hello world"; + private static final String TEXT_1 = "Hello world a"; + private static final String TEST_IMAGE_TEXT = "/9j/4AAQSkZJRgABAQAASABIAAD"; + private static final String TEST_IMAGE_TEXT_1 = "/9j/4AAQSkZJRgbdwoeicfhoid"; + + // Test rolling-upgrade with kNN radial search + // Create Text Image Embedding Processor, Ingestion Pipeline and add document + // Validate radial query, pipeline and document count in restart-upgrade scenario + public void testKnnRadialSearch_E2EFlow() throws Exception { + waitForClusterHealthGreen(NODES_BWC_CLUSTER); + + if (isRunningAgainstOldCluster()) { + String modelId = uploadTextEmbeddingModel(); + loadModel(modelId); + createPipelineForTextImageProcessor(modelId, PIPELINE_NAME); + createIndexWithConfiguration( + getIndexNameForTest(), + Files.readString(Path.of(classLoader.getResource("processor/IndexMappingMultipleShard.json").toURI())), + PIPELINE_NAME + ); + addDocument(getIndexNameForTest(), "0", TEST_FIELD, TEXT, TEST_IMAGE_FIELD, TEST_IMAGE_TEXT); + } else { + String modelId = null; + try { + modelId = getModelId(getIngestionPipeline(PIPELINE_NAME), TEXT_IMAGE_EMBEDDING_PROCESSOR); + loadModel(modelId); + addDocument(getIndexNameForTest(), "1", TEST_FIELD, TEXT_1, TEST_IMAGE_FIELD, TEST_IMAGE_TEXT_1); + validateIndexQuery(modelId); + } finally { + wipeOfTestResources(getIndexNameForTest(), PIPELINE_NAME, modelId, null); + } + } + } + + private void validateIndexQuery(final String modelId) { + NeuralQueryBuilder neuralQueryBuilderWithMinScoreQuery = new NeuralQueryBuilder( + "passage_embedding", + TEXT, + TEST_IMAGE_TEXT, + modelId, + null, + null, + 0.01f, + null, + null + ); + Map responseWithMinScoreQuery = search(getIndexNameForTest(), neuralQueryBuilderWithMinScoreQuery, 1); + assertNotNull(responseWithMinScoreQuery); + + NeuralQueryBuilder neuralQueryBuilderWithMaxDistanceQuery = new NeuralQueryBuilder( + "passage_embedding", + TEXT, + TEST_IMAGE_TEXT, + modelId, + null, + 100000f, + null, + null, + null + ); + Map responseWithMaxDistanceQuery = search(getIndexNameForTest(), neuralQueryBuilderWithMaxDistanceQuery, 1); + assertNotNull(responseWithMaxDistanceQuery); + } +} diff --git a/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java b/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java index 466460547..cbe210911 100644 --- a/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java +++ b/qa/restart-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java @@ -50,10 +50,10 @@ public void testTextImageEmbeddingProcessor_E2EFlow() throws Exception { } } - private void validateTestIndex(final String modelId) { + private void validateTestIndex(final String modelId) throws Exception { int docCount = getDocCount(getIndexNameForTest()); assertEquals(2, docCount); - NeuralQueryBuilder neuralQueryBuilderWithKQuery = new NeuralQueryBuilder( + NeuralQueryBuilder neuralQueryBuilder = new NeuralQueryBuilder( "passage_embedding", TEXT, TEST_IMAGE_TEXT, @@ -64,35 +64,8 @@ private void validateTestIndex(final String modelId) { null, null ); - Map responseWithKQuery = search(getIndexNameForTest(), neuralQueryBuilderWithKQuery, 1); - assertNotNull(responseWithKQuery); - - NeuralQueryBuilder neuralQueryBuilderWithMinScoreQuery = new NeuralQueryBuilder( - "passage_embedding", - TEXT, - TEST_IMAGE_TEXT, - modelId, - null, - null, - 0.01f, - null, - null - ); - Map responseWithMinScoreQuery = search(getIndexNameForTest(), neuralQueryBuilderWithMinScoreQuery, 1); - assertNotNull(responseWithMinScoreQuery); - - NeuralQueryBuilder neuralQueryBuilderWithMaxDistanceQuery = new NeuralQueryBuilder( - "passage_embedding", - TEXT, - TEST_IMAGE_TEXT, - modelId, - null, - 10000f, - null, - null, - null - ); - Map responseWithMaxDistanceQuery = search(getIndexNameForTest(), neuralQueryBuilderWithMaxDistanceQuery, 1); - assertNotNull(responseWithMaxDistanceQuery); + Map response = search(getIndexNameForTest(), neuralQueryBuilder, 1); + assertNotNull(response); } + } diff --git a/qa/rolling-upgrade/build.gradle b/qa/rolling-upgrade/build.gradle index eedea2d2d..2265dddb8 100644 --- a/qa/rolling-upgrade/build.gradle +++ b/qa/rolling-upgrade/build.gradle @@ -90,6 +90,13 @@ task testAgainstOldCluster(type: StandaloneRestIntegTestTask) { } } + // Excluding the k-NN radial search tests because we introduce this feature in 2.14 + if (ext.neural_search_bwc_version.startsWith("2.9") || ext.neural_search_bwc_version.startsWith("2.10") || ext.neural_search_bwc_version.startsWith("2.11") || ext.neural_search_bwc_version.startsWith("2.12") || ext.neural_search_bwc_version.startsWith("2.13")){ + filter { + excludeTestsMatching "org.opensearch.neuralsearch.bwc.KnnRadialSearchIT.*" + } + } + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}".getName()}") systemProperty 'tests.security.manager', 'false' @@ -140,6 +147,13 @@ task testAgainstOneThirdUpgradedCluster(type: StandaloneRestIntegTestTask) { } } + // Excluding the k-NN radial search tests because we introduce this feature in 2.14 + if (ext.neural_search_bwc_version.startsWith("2.9") || ext.neural_search_bwc_version.startsWith("2.10") || ext.neural_search_bwc_version.startsWith("2.11") || ext.neural_search_bwc_version.startsWith("2.12") || ext.neural_search_bwc_version.startsWith("2.13")){ + filter { + excludeTestsMatching "org.opensearch.neuralsearch.bwc.KnnRadialSearchIT.*" + } + } + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}".getName()}") systemProperty 'tests.security.manager', 'false' diff --git a/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java b/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java new file mode 100644 index 000000000..04242b783 --- /dev/null +++ b/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/KnnRadialSearchIT.java @@ -0,0 +1,110 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.opensearch.neuralsearch.bwc; + +import static org.opensearch.neuralsearch.TestUtils.NODES_BWC_CLUSTER; +import static org.opensearch.neuralsearch.TestUtils.TEXT_IMAGE_EMBEDDING_PROCESSOR; +import static org.opensearch.neuralsearch.TestUtils.getModelId; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +import org.opensearch.neuralsearch.query.NeuralQueryBuilder; + +public class KnnRadialSearchIT extends AbstractRollingUpgradeTestCase { + private static final String PIPELINE_NAME = "nlp-ingest-pipeline"; + private static final String TEST_FIELD = "passage_text"; + private static final String TEST_IMAGE_FIELD = "passage_image"; + private static final String TEXT = "Hello world"; + private static final String TEXT_MIXED = "Hello world mixed"; + private static final String TEXT_UPGRADED = "Hello world upgraded"; + private static final String TEST_IMAGE_TEXT = "/9j/4AAQSkZJRgABAQAASABIAAD"; + private static final String TEST_IMAGE_TEXT_MIXED = "/9j/4AAQSkZJRgbdwoeicfhoid"; + private static final String TEST_IMAGE_TEXT_UPGRADED = "/9j/4AAQSkZJR8eydhgfwceocvlk"; + + private static final int NUM_DOCS_PER_ROUND = 1; + private static String modelId = ""; + + // Test rolling-upgrade with kNN radial search + // Create Text Image Embedding Processor, Ingestion Pipeline and add document + // Validate radial query, pipeline and document count in rolling-upgrade scenario + public void testKnnRadialSearch_E2EFlow() throws Exception { + waitForClusterHealthGreen(NODES_BWC_CLUSTER); + switch (getClusterType()) { + case OLD: + modelId = uploadTextImageEmbeddingModel(); + loadModel(modelId); + createPipelineForTextImageProcessor(modelId, PIPELINE_NAME); + createIndexWithConfiguration( + getIndexNameForTest(), + Files.readString(Path.of(classLoader.getResource("processor/IndexMappings.json").toURI())), + PIPELINE_NAME + ); + addDocument(getIndexNameForTest(), "0", TEST_FIELD, TEXT, TEST_IMAGE_FIELD, TEST_IMAGE_TEXT); + break; + case MIXED: + modelId = getModelId(getIngestionPipeline(PIPELINE_NAME), TEXT_IMAGE_EMBEDDING_PROCESSOR); + int totalDocsCountMixed; + if (isFirstMixedRound()) { + totalDocsCountMixed = NUM_DOCS_PER_ROUND; + validateIndexQueryOnUpgrade(totalDocsCountMixed, modelId, TEXT, TEST_IMAGE_TEXT); + addDocument(getIndexNameForTest(), "1", TEST_FIELD, TEXT_MIXED, TEST_IMAGE_FIELD, TEST_IMAGE_TEXT_MIXED); + } else { + totalDocsCountMixed = 2 * NUM_DOCS_PER_ROUND; + validateIndexQueryOnUpgrade(totalDocsCountMixed, modelId, TEXT_MIXED, TEST_IMAGE_TEXT_MIXED); + } + break; + case UPGRADED: + try { + modelId = getModelId(getIngestionPipeline(PIPELINE_NAME), TEXT_IMAGE_EMBEDDING_PROCESSOR); + int totalDocsCountUpgraded = 3 * NUM_DOCS_PER_ROUND; + loadModel(modelId); + addDocument(getIndexNameForTest(), "2", TEST_FIELD, TEXT_UPGRADED, TEST_IMAGE_FIELD, TEST_IMAGE_TEXT_UPGRADED); + validateIndexQueryOnUpgrade(totalDocsCountUpgraded, modelId, TEXT_UPGRADED, TEST_IMAGE_TEXT_UPGRADED); + } finally { + wipeOfTestResources(getIndexNameForTest(), PIPELINE_NAME, modelId, null); + } + break; + default: + throw new IllegalStateException("Unexpected value: " + getClusterType()); + } + } + + private void validateIndexQueryOnUpgrade(final int numberOfDocs, final String modelId, final String text, final String imageText) + throws Exception { + int docCount = getDocCount(getIndexNameForTest()); + assertEquals(numberOfDocs, docCount); + loadModel(modelId); + + NeuralQueryBuilder neuralQueryBuilderWithMinScoreQuery = new NeuralQueryBuilder( + "passage_embedding", + text, + imageText, + modelId, + null, + null, + 0.01f, + null, + null + ); + Map responseWithMinScore = search(getIndexNameForTest(), neuralQueryBuilderWithMinScoreQuery, 1); + assertNotNull(responseWithMinScore); + + NeuralQueryBuilder neuralQueryBuilderWithMaxDistanceQuery = new NeuralQueryBuilder( + "passage_embedding", + text, + imageText, + modelId, + null, + 100000f, + null, + null, + null + ); + Map responseWithMaxScore = search(getIndexNameForTest(), neuralQueryBuilderWithMaxDistanceQuery, 1); + assertNotNull(responseWithMaxScore); + } +} diff --git a/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java b/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java index b757126e4..c0efe0694 100644 --- a/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java +++ b/qa/rolling-upgrade/src/test/java/org/opensearch/neuralsearch/bwc/MultiModalSearchIT.java @@ -89,33 +89,5 @@ private void validateTestIndexOnUpgrade(final int numberOfDocs, final String mod ); Map responseWithKQuery = search(getIndexNameForTest(), neuralQueryBuilderWithKQuery, 1); assertNotNull(responseWithKQuery); - - NeuralQueryBuilder neuralQueryBuilderWithMinScoreQuery = new NeuralQueryBuilder( - "passage_embedding", - text, - imageText, - modelId, - null, - null, - 0.01f, - null, - null - ); - Map responseWithMinScore = search(getIndexNameForTest(), neuralQueryBuilderWithMinScoreQuery, 1); - assertNotNull(responseWithMinScore); - - NeuralQueryBuilder neuralQueryBuilderWithMaxDistanceQuery = new NeuralQueryBuilder( - "passage_embedding", - text, - imageText, - modelId, - null, - 10000f, - null, - null, - null - ); - Map responseWithMaxScore = search(getIndexNameForTest(), neuralQueryBuilderWithMaxDistanceQuery, 1); - assertNotNull(responseWithMaxScore); } } diff --git a/src/main/java/org/opensearch/neuralsearch/query/NeuralQueryBuilder.java b/src/main/java/org/opensearch/neuralsearch/query/NeuralQueryBuilder.java index 94d9b3481..986d6d96c 100644 --- a/src/main/java/org/opensearch/neuralsearch/query/NeuralQueryBuilder.java +++ b/src/main/java/org/opensearch/neuralsearch/query/NeuralQueryBuilder.java @@ -125,7 +125,6 @@ public NeuralQueryBuilder(StreamInput in) throws IOException { } else { this.k = in.readVInt(); } - this.k = in.readVInt(); this.filter = in.readOptionalNamedWriteable(QueryBuilder.class); if (isClusterOnOrAfterMinReqVersionForRadialSearch()) { this.maxDistance = in.readOptionalFloat();