Skip to content

Commit

Permalink
Add more unit test
Browse files Browse the repository at this point in the history
Signed-off-by: Junwei Dai <[email protected]>
  • Loading branch information
Junwei Dai committed Dec 18, 2024
1 parent 615a4b6 commit 820849b
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.util.List;
import java.util.Objects;

import static org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken;

/**
* Detailed information about a processor execution in a search pipeline.
*
Expand Down Expand Up @@ -167,7 +169,10 @@ public static ProcessorExecutionDetail fromXContent(XContentParser parser) throw
long durationMillis = 0;
Object inputData = null;
Object outputData = null;

if (parser.currentToken() != XContentParser.Token.START_OBJECT) {
parser.nextToken();
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser);
}
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
String fieldName = parser.currentName();
parser.nextToken();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.opensearch.search.aggregations.AggregationsTests;
import org.opensearch.search.aggregations.InternalAggregations;
import org.opensearch.search.internal.InternalSearchResponse;
import org.opensearch.search.pipeline.ProcessorExecutionDetail;
import org.opensearch.search.profile.SearchProfileShardResults;
import org.opensearch.search.profile.SearchProfileShardResultsTests;
import org.opensearch.search.suggest.Suggest;
Expand Down Expand Up @@ -312,6 +313,10 @@ public void testToXContent() {
hit.score(2.0f);
SearchHit[] hits = new SearchHit[] { hit };
String dummyId = UUID.randomUUID().toString();
List<ProcessorExecutionDetail> processorResults = List.of(
new ProcessorExecutionDetail("processor1", 50, List.of(1), List.of(1)),
new ProcessorExecutionDetail("processor2", 30, List.of(3), List.of(3))
);
{
SearchResponse response = new SearchResponse(
new InternalSearchResponse(
Expand All @@ -323,7 +328,7 @@ public void testToXContent() {
null,
1,
List.of(new DummySearchExtBuilder(dummyId)),
Collections.emptyList()
processorResults
),
null,
0,
Expand Down Expand Up @@ -356,8 +361,24 @@ public void testToXContent() {
{
expectedString.append("{\"dummy\":\"" + dummyId + "\"}");
}
expectedString.append(",\"processor_results\":");
expectedString.append("[");
for (int i = 0; i < processorResults.size(); i++) {
ProcessorExecutionDetail detail = processorResults.get(i);
expectedString.append("{");
expectedString.append("\"processor_name\":\"").append(detail.getProcessorName()).append("\",");
expectedString.append("\"duration_millis\":").append(detail.getDurationMillis()).append(",");
expectedString.append("\"input_data\":").append(detail.getInputData()).append(",");
expectedString.append("\"output_data\":").append(detail.getOutputData());
expectedString.append("}");
if (i < processorResults.size() - 1) {
expectedString.append(",");
}
}
expectedString.append("]");
}
expectedString.append("}");

assertEquals(expectedString.toString(), Strings.toString(MediaTypeRegistry.JSON, response));
List<SearchExtBuilder> searchExtBuilders = response.getInternalResponse().getSearchExtBuilders();
assertEquals(1, searchExtBuilders.size());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.search.pipeline;

import org.opensearch.common.io.stream.BytesStreamOutput;
import org.opensearch.common.xcontent.XContentHelper;
import org.opensearch.common.xcontent.json.JsonXContent;
import org.opensearch.core.common.bytes.BytesReference;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.xcontent.DeprecationHandler;
import org.opensearch.core.xcontent.MediaType;
import org.opensearch.core.xcontent.MediaTypeRegistry;
import org.opensearch.core.xcontent.ToXContent;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.test.OpenSearchTestCase;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class ProcessorExecutionDetailTests extends OpenSearchTestCase {

public void testSerializationRoundtrip() throws IOException {
ProcessorExecutionDetail detail = new ProcessorExecutionDetail("testProcessor", 123L, Map.of("key", "value"), List.of(1, 2, 3));
ProcessorExecutionDetail deserialized;
try (BytesStreamOutput output = new BytesStreamOutput()) {
detail.writeTo(output);
try (StreamInput input = output.bytes().streamInput()) {
deserialized = new ProcessorExecutionDetail(input);
}
}
assertEquals("testProcessor", deserialized.getProcessorName());
assertEquals(123L, deserialized.getDurationMillis());
assertEquals(Map.of("key", "value"), deserialized.getInputData());
assertEquals(List.of(1, 2, 3), deserialized.getOutputData());
}

public void testAddMethods() {
ProcessorExecutionDetail detail = new ProcessorExecutionDetail("testProcessor");
detail.addTook(456L);
detail.addInput(Map.of("newKey", "newValue"));
detail.addOutput(List.of(4, 5, 6));
assertEquals(456L, detail.getDurationMillis());
assertEquals(Map.of("newKey", "newValue"), detail.getInputData());
assertEquals(List.of(4, 5, 6), detail.getOutputData());
}

public void testEqualsAndHashCode() {
ProcessorExecutionDetail detail1 = new ProcessorExecutionDetail("processor1", 100L, "input1", "output1");
ProcessorExecutionDetail detail2 = new ProcessorExecutionDetail("processor1", 100L, "input1", "output1");
ProcessorExecutionDetail detail3 = new ProcessorExecutionDetail("processor2", 200L, "input2", "output2");

assertEquals(detail1, detail2);
assertNotEquals(detail1, detail3);
assertEquals(detail1.hashCode(), detail2.hashCode());
assertNotEquals(detail1.hashCode(), detail3.hashCode());
}

public void testToString() {
ProcessorExecutionDetail detail = new ProcessorExecutionDetail("processorZ", 500L, "inputData", "outputData");
String expected =
"ProcessorExecutionDetail{processorName='processorZ', durationMillis=500, inputData=inputData, outputData=outputData}";
assertEquals(expected, detail.toString());
}

public void testToXContent() throws IOException {
ProcessorExecutionDetail detail = new ProcessorExecutionDetail("testProcessor", 123L, Map.of("key1", "value1"), List.of(1, 2, 3));

XContentBuilder actualBuilder = XContentBuilder.builder(JsonXContent.jsonXContent);
detail.toXContent(actualBuilder, ToXContent.EMPTY_PARAMS);

String expected = "{"
+ " \"processor_name\": \"testProcessor\","
+ " \"duration_millis\": 123,"
+ " \"input_data\": {\"key1\": \"value1\"},"
+ " \"output_data\": [1, 2, 3]"
+ "}";

XContentParser expectedParser = JsonXContent.jsonXContent.createParser(
this.xContentRegistry(),
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
expected
);
XContentBuilder expectedBuilder = XContentBuilder.builder(JsonXContent.jsonXContent);
expectedBuilder.generator().copyCurrentStructure(expectedParser);

assertEquals(
XContentHelper.convertToMap(BytesReference.bytes(expectedBuilder), false, (MediaType) MediaTypeRegistry.JSON),
XContentHelper.convertToMap(BytesReference.bytes(actualBuilder), false, (MediaType) MediaTypeRegistry.JSON)
);
}

public void testFromXContent() throws IOException {
String json = "{"
+ " \"processor_name\": \"testProcessor\","
+ " \"duration_millis\": 123,"
+ " \"input_data\": {\"key1\": \"value1\"},"
+ " \"output_data\": [1, 2, 3]"
+ "}";

try (
XContentParser parser = JsonXContent.jsonXContent.createParser(
this.xContentRegistry(),
DeprecationHandler.THROW_UNSUPPORTED_OPERATION,
json
)
) {
ProcessorExecutionDetail detail = ProcessorExecutionDetail.fromXContent(parser);

assertEquals("testProcessor", detail.getProcessorName());
assertEquals(123L, detail.getDurationMillis());
assertEquals(Map.of("key1", "value1"), detail.getInputData());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,116 @@ public void testVerbosePipelineExecution() throws Exception {
assertEquals("scale_request_size", executionDetails.get(0).getProcessorName());
assertEquals("fixed_score", executionDetails.get(1).getProcessorName());
}
public void testVerbosePipelineWithRequestProcessorOnly() throws Exception {
SearchPipelineService searchPipelineService = createWithProcessors();

// Only request processors
SearchPipelineMetadata metadata = new SearchPipelineMetadata(
Map.of(
"request_only_pipeline",
new PipelineConfiguration(
"request_only_pipeline",
new BytesArray(
"{"
+ "\"request_processors\" : [ { \"scale_request_size\": { \"scale\" : 2 } } ]"
+ "}"
),
MediaTypeRegistry.JSON
)
)
);

ClusterState initialState = ClusterState.builder(new ClusterName("_name")).build();
ClusterState updatedState = ClusterState.builder(initialState)
.metadata(Metadata.builder().putCustom(SearchPipelineMetadata.TYPE, metadata))
.build();

searchPipelineService.applyClusterState(new ClusterChangedEvent("clusterStateUpdated", updatedState, initialState));

SearchRequest searchRequest = new SearchRequest().source(SearchSourceBuilder.searchSource().size(10)).pipeline("request_only_pipeline");
searchRequest.source().verbosePipeline(true);

PipelinedRequest pipelinedRequest = syncTransformRequest(
searchPipelineService.resolvePipeline(searchRequest, indexNameExpressionResolver)
);

// Mock response
SearchResponseSections sections = new SearchResponseSections(
new SearchHits(new SearchHit[0], new TotalHits(0, TotalHits.Relation.EQUAL_TO), 0.0f),
null,
null,
false,
null,
null,
1,
List.of(),
List.of()
);

SearchResponse searchResponse = new SearchResponse(sections, null, 0, 0, 0, 0, null, null);
SearchResponse transformedResponse = syncTransformResponse(pipelinedRequest, searchResponse);
List<ProcessorExecutionDetail> executionDetails = transformedResponse.getInternalResponse().getProcessorResult();

assertNotNull(executionDetails);
assertEquals(1, executionDetails.size());
assertEquals("scale_request_size", executionDetails.get(0).getProcessorName());
}

public void testVerbosePipelineWithResponseProcessorOnly() throws Exception {
SearchPipelineService searchPipelineService = createWithProcessors();

// Only response processors
SearchPipelineMetadata metadata = new SearchPipelineMetadata(
Map.of(
"response_only_pipeline",
new PipelineConfiguration(
"response_only_pipeline",
new BytesArray(
"{"
+ "\"response_processors\": [ { \"fixed_score\": { \"score\": 5.0 } } ]"
+ "}"
),
MediaTypeRegistry.JSON
)
)
);

ClusterState initialState = ClusterState.builder(new ClusterName("_name")).build();
ClusterState updatedState = ClusterState.builder(initialState)
.metadata(Metadata.builder().putCustom(SearchPipelineMetadata.TYPE, metadata))
.build();

searchPipelineService.applyClusterState(new ClusterChangedEvent("clusterStateUpdated", updatedState, initialState));

SearchRequest searchRequest = new SearchRequest().source(SearchSourceBuilder.searchSource().size(10)).pipeline("response_only_pipeline");
searchRequest.source().verbosePipeline(true);

PipelinedRequest pipelinedRequest = syncTransformRequest(
searchPipelineService.resolvePipeline(searchRequest, indexNameExpressionResolver)
);

// Mock response
SearchResponseSections sections = new SearchResponseSections(
new SearchHits(new SearchHit[0], new TotalHits(0, TotalHits.Relation.EQUAL_TO), 0.0f),
null,
null,
false,
null,
null,
1,
List.of(),
List.of()
);

SearchResponse searchResponse = new SearchResponse(sections, null, 0, 0, 0, 0, null, null);
SearchResponse transformedResponse = syncTransformResponse(pipelinedRequest, searchResponse);
List<ProcessorExecutionDetail> executionDetails = transformedResponse.getInternalResponse().getProcessorResult();

assertNotNull(executionDetails);
assertEquals(1, executionDetails.size());
assertEquals("fixed_score", executionDetails.get(0).getProcessorName());
}


private SearchSourceBuilder createDefaultSearchSourceBuilder() {
return SearchSourceBuilder.searchSource().size(10);
Expand Down

0 comments on commit 820849b

Please sign in to comment.