Skip to content

Commit 56c2d19

Browse files
committed
Add transport tests, refactor toXContent tests
Signed-off-by: Andy Qin <[email protected]>
1 parent fe8a616 commit 56c2d19

12 files changed

+530
-43
lines changed

src/main/java/org/opensearch/neuralsearch/plugin/NeuralSearch.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import com.google.common.collect.ImmutableList;
1919
import org.opensearch.action.ActionRequest;
2020
import org.opensearch.neuralsearch.settings.NeuralSearchSettingsAccessor;
21+
import org.opensearch.neuralsearch.stats.events.EventStatsManager;
22+
import org.opensearch.neuralsearch.stats.state.StateStatsManager;
2123
import org.opensearch.transport.client.Client;
2224
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
2325
import org.opensearch.cluster.node.DiscoveryNodes;
@@ -125,7 +127,7 @@ public Collection<Object> createComponents(
125127
PipelineServiceUtil.instance().initialize(clusterService);
126128
NeuralSearchSettingsAccessor.instance().initialize(clusterService, environment.settings());
127129

128-
return List.of(clientAccessor);
130+
return List.of(clientAccessor, EventStatsManager.instance(), StateStatsManager.instance());
129131
}
130132

131133
@Override

src/main/java/org/opensearch/neuralsearch/stats/events/EventStatName.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
*/
1818
@Getter
1919
public enum EventStatName implements StatName {
20-
TEXT_EMBEDDING_PROCESSOR_EXECUTIONS("text_embedding_executions", "processors.ingest", EventStatType.TIMESTAMPED_COUNTER),
21-
22-
// TODO : NEURAL QUERY COUNTER NOT YET IMPLEMENTED
23-
NEURAL_QUERY_COUNT("neural_query_count", "query", EventStatType.TIMESTAMPED_COUNTER);
20+
TEXT_EMBEDDING_PROCESSOR_EXECUTIONS("text_embedding_executions", "processors.ingest", EventStatType.TIMESTAMPED_COUNTER);
2421

2522
private final String name;
2623
private final String path;

src/main/java/org/opensearch/neuralsearch/transport/NeuralStatsResponse.java

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.opensearch.neuralsearch.transport;
66

7+
import lombok.Getter;
78
import org.opensearch.action.FailedNodeException;
89
import org.opensearch.action.support.nodes.BaseNodesResponse;
910
import org.opensearch.cluster.ClusterName;
@@ -22,6 +23,7 @@
2223
/**
2324
* NeuralStatsResponse consists of the aggregated responses from the nodes
2425
*/
26+
@Getter
2527
public class NeuralStatsResponse extends BaseNodesResponse<NeuralStatsNodeResponse> implements ToXContentObject {
2628

2729
private static final String NODES_KEY = "nodes";
@@ -116,6 +118,7 @@ private Map<String, Object> formatStats(Map<String, StatSnapshot<?>> rawStats) {
116118

117119
private Map<String, Object> getFlattenedStats(Map<String, StatSnapshot<?>> rawStats) {
118120
if (includeMetadata) {
121+
// Safe downcast to object
119122
return (Map<String, Object>) (Map) rawStats;
120123
}
121124
return rawStats.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getValue()));

src/main/java/org/opensearch/neuralsearch/transport/NeuralStatsTransportAction.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ public NeuralStatsTransportAction(
5454
ThreadPool threadPool,
5555
ClusterService clusterService,
5656
TransportService transportService,
57-
ActionFilters actionFilters
57+
ActionFilters actionFilters,
58+
EventStatsManager eventStatsManager,
59+
StateStatsManager stateStatsManager
5860
) {
5961
super(
6062
NeuralStatsAction.NAME,
@@ -67,8 +69,8 @@ public NeuralStatsTransportAction(
6769
ThreadPool.Names.MANAGEMENT,
6870
NeuralStatsNodeResponse.class
6971
);
70-
this.eventStatsManager = EventStatsManager.instance();
71-
this.stateStatsManager = StateStatsManager.instance();
72+
this.eventStatsManager = eventStatsManager;
73+
this.stateStatsManager = stateStatsManager;
7274
}
7375

7476
@Override

src/test/java/org/opensearch/neuralsearch/rest/RestNeuralStatsHandlerIT.java

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public void test_textEmbedding() throws Exception {
9090
updateClusterSettings("plugins.neural_search.stats_enabled", false);
9191
updateClusterSettings("plugins.neural_search.stats_enabled", true);
9292

93+
// State stats should persist, event stats should be reset
9394
response = executeNeuralStatRequest(new ArrayList<>(), new ArrayList<>());
9495
responseBody = EntityUtils.toString(response.getEntity());
9596
stats = parseStatsResponse(responseBody);
@@ -135,6 +136,7 @@ public void test_includeMetadata() throws Exception {
135136
Object clusterVersionStatMetadata = getNestedValue(stats, StateStatName.CLUSTER_VERSION.getFullPath());
136137

137138
// Path value should be JSON object (convertible to map)
139+
// If metadata wasn't included, path value would be the raw value
138140
assertTrue(getNestedValue(stats, StateStatName.CLUSTER_VERSION.getFullPath()) instanceof Map);
139141

140142
String statType = ((Map<String, String>) clusterVersionStatMetadata).get(StatSnapshot.STAT_TYPE_FIELD);

src/test/java/org/opensearch/neuralsearch/stats/NeuralStatsInputTests.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515

1616
import java.io.IOException;
1717
import java.util.Arrays;
18+
import java.util.Collections;
1819
import java.util.EnumSet;
1920
import java.util.HashSet;
21+
import java.util.Map;
2022
import java.util.Set;
2123

2224
import static org.mockito.ArgumentMatchers.any;
2325
import static org.mockito.Mockito.mock;
2426
import static org.mockito.Mockito.times;
2527
import static org.mockito.Mockito.verify;
2628
import static org.mockito.Mockito.when;
29+
import static org.opensearch.neuralsearch.util.TestUtils.xContentBuilderToMap;
2730

2831
public class NeuralStatsInputTests extends OpenSearchTestCase {
2932
private static final String NODE_ID_1 = "node1";
@@ -127,13 +130,13 @@ public void test_toXContent() throws IOException {
127130

128131
XContentBuilder builder = XContentFactory.jsonBuilder();
129132
input.toXContent(builder, ToXContent.EMPTY_PARAMS);
130-
String jsonString = builder.toString();
133+
Map<String, Object> responseMap = xContentBuilderToMap(builder);
131134

132-
assertTrue(jsonString.contains(String.format("\"node_ids\":[\"%s\"]", NODE_ID_1)));
133-
assertTrue(jsonString.contains(String.format("\"event_stats\":[\"%s\"]", EVENT_STAT.getName())));
134-
assertTrue(jsonString.contains(String.format("\"state_stats\":[\"%s\"]", STATE_STAT.getName())));
135-
assertTrue(jsonString.contains("\"include_metadata\":true"));
136-
assertTrue(jsonString.contains("\"flat_keys\":true"));
135+
assertEquals(Collections.singletonList(NODE_ID_1), responseMap.get("node_ids"));
136+
assertEquals(Collections.singletonList(EVENT_STAT.getName()), responseMap.get("event_stats"));
137+
assertEquals(Collections.singletonList(STATE_STAT.getName()), responseMap.get("state_stats"));
138+
assertEquals(true, responseMap.get("include_metadata"));
139+
assertEquals(true, responseMap.get("flat_keys"));
137140
}
138141

139142
public void test_writeToHandlesEmptyCollections() throws IOException {

src/test/java/org/opensearch/neuralsearch/stats/events/EventStatsManagerTests.java

-3
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,14 @@ public void test_getEventStatSnapshotsReturnsEmptyMap() {
9696
public void test_reset() {
9797
// Create multiple mock stats
9898
TimestampedEventStat mockStat1 = mock(TimestampedEventStat.class);
99-
TimestampedEventStat mockStat2 = mock(TimestampedEventStat.class);
10099

101100
// Add mock stats to manager
102101
eventStatsManager.getStats().clear();
103102
eventStatsManager.getStats().put(STAT_NAME, mockStat1);
104-
eventStatsManager.getStats().put(EventStatName.NEURAL_QUERY_COUNT, mockStat2);
105103

106104
eventStatsManager.reset();
107105

108106
verify(mockStat1, times(1)).reset();
109-
verify(mockStat2, times(1)).reset();
110107
}
111108

112109
public void test_singletonInstanceCreation() {

src/test/java/org/opensearch/neuralsearch/stats/events/TimestampedEventStatSnapshotTests.java

+8-11
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
import java.io.IOException;
1414
import java.util.Arrays;
1515
import java.util.Collections;
16+
import java.util.Map;
1617

1718
import static org.mockito.Mockito.mock;
1819
import static org.mockito.Mockito.times;
1920
import static org.mockito.Mockito.verify;
2021
import static org.mockito.Mockito.when;
22+
import static org.opensearch.neuralsearch.util.TestUtils.xContentBuilderToMap;
2123

2224
public class TimestampedEventStatSnapshotTests extends OpenSearchTestCase {
2325
private static final EventStatName STAT_NAME = EventStatName.TEXT_EMBEDDING_PROCESSOR_EXECUTIONS;
@@ -79,7 +81,7 @@ public void test_aggregateEventStatSnapshotsReturnsNull() {
7981

8082
public void test_aggregateEventStatDataThrowsException() {
8183
TimestampedEventStatSnapshot snapshot1 = new TimestampedEventStatSnapshot(STAT_NAME, 100L, 50L, 10L);
82-
TimestampedEventStatSnapshot snapshot2 = new TimestampedEventStatSnapshot(EventStatName.NEURAL_QUERY_COUNT, 200L, 100L, 5L);
84+
TimestampedEventStatSnapshot snapshot2 = new TimestampedEventStatSnapshot(null, 200L, 100L, 5L);
8385

8486
assertThrows(
8587
IllegalArgumentException.class,
@@ -89,20 +91,15 @@ public void test_aggregateEventStatDataThrowsException() {
8991

9092
public void test_toXContent() throws IOException {
9193
XContentBuilder builder = JsonXContent.contentBuilder();
92-
93-
// Create a real snapshot with known values
9494
TimestampedEventStatSnapshot snapshot = new TimestampedEventStatSnapshot(STAT_NAME, 100L, 50L, 10L);
9595

96-
// Convert to XContent
9796
snapshot.toXContent(builder, null);
9897

99-
// Convert to string for assertion
100-
String json = builder.toString();
98+
Map<String, Object> responseMap = xContentBuilderToMap(builder);
10199

102-
// Verify the JSON structure contains all expected fields with correct values
103-
assertTrue(json.contains("\"value\":100"));
104-
assertTrue(json.contains("\"trailing_interval_value\":50"));
105-
assertTrue(json.contains("\"minutes_since_last_event\":10"));
106-
assertTrue(json.contains("\"stat_type\""));
100+
assertEquals(100, responseMap.get("value"));
101+
assertEquals(50, responseMap.get("trailing_interval_value"));
102+
assertEquals(10, responseMap.get("minutes_since_last_event"));
103+
assertEquals(STAT_NAME.getStatType().getName(), responseMap.get("stat_type"));
107104
}
108105
}

src/test/java/org/opensearch/neuralsearch/stats/state/CountableStateStatSnapshotTests.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import org.opensearch.test.OpenSearchTestCase;
1212

1313
import java.io.IOException;
14+
import java.util.Map;
15+
16+
import static org.opensearch.neuralsearch.util.TestUtils.xContentBuilderToMap;
1417

1518
public class CountableStateStatSnapshotTests extends OpenSearchTestCase {
1619
private static final StateStatName STAT_NAME = StateStatName.TEXT_EMBEDDING_PROCESSORS;
@@ -26,17 +29,14 @@ public void test_increment() {
2629

2730
public void test_toXContent() throws IOException {
2831
CountableStateStatSnapshot snapshot = new CountableStateStatSnapshot(STAT_NAME);
29-
snapshot.incrementBy(42L);
32+
snapshot.incrementBy(8675309L);
3033

3134
XContentBuilder builder = JsonXContent.contentBuilder();
3235
snapshot.toXContent(builder, ToXContent.EMPTY_PARAMS);
33-
String jsonStr = builder.toString();
3436

35-
// Verify JSON
36-
String expectedValueJson = String.format("\"%s\":42", StatSnapshot.VALUE_FIELD);
37-
String expectedTypeJson = String.format("\"%s\":\"%s\"", StatSnapshot.STAT_TYPE_FIELD, STAT_NAME.getStatType().getName());
37+
Map<String, Object> responseMap = xContentBuilderToMap(builder);
3838

39-
assertTrue(jsonStr.contains(expectedValueJson));
40-
assertTrue(jsonStr.contains(expectedTypeJson));
39+
assertEquals(8675309, responseMap.get(StatSnapshot.VALUE_FIELD));
40+
assertEquals(STAT_NAME.getStatType().getName(), responseMap.get(StatSnapshot.STAT_TYPE_FIELD));
4141
}
4242
}

src/test/java/org/opensearch/neuralsearch/stats/state/SettableStateStatSnapshotTests.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import org.opensearch.test.OpenSearchTestCase;
1212

1313
import java.io.IOException;
14+
import java.util.Map;
15+
16+
import static org.opensearch.neuralsearch.util.TestUtils.xContentBuilderToMap;
1417

1518
public class SettableStateStatSnapshotTests extends OpenSearchTestCase {
1619

@@ -35,17 +38,12 @@ public void test_setValueUpdates() {
3538

3639
public void test_toXContent() throws IOException {
3740
SettableStateStatSnapshot<String> snapshot = new SettableStateStatSnapshot<>(STAT_NAME, SETTABLE_VALUE);
38-
3941
XContentBuilder builder = JsonXContent.contentBuilder();
40-
4142
snapshot.toXContent(builder, ToXContent.EMPTY_PARAMS);
42-
String json = builder.toString();
4343

44-
// Verify the JSON structure
45-
String expectedValueJson = String.format("\"%s\":\"%s\"", StatSnapshot.VALUE_FIELD, SETTABLE_VALUE);
46-
String expectedTypeJson = String.format("\"%s\":\"%s\"", StatSnapshot.STAT_TYPE_FIELD, STAT_NAME.getStatType().getName());
44+
Map<String, Object> responseMap = xContentBuilderToMap(builder);
4745

48-
assertTrue(json.contains(expectedValueJson));
49-
assertTrue(json.contains(expectedTypeJson));
46+
assertEquals(SETTABLE_VALUE, responseMap.get(StatSnapshot.VALUE_FIELD));
47+
assertEquals(STAT_NAME.getStatType().getName(), responseMap.get(StatSnapshot.STAT_TYPE_FIELD));
5048
}
5149
}

0 commit comments

Comments
 (0)