Skip to content

Commit

Permalink
REST layer UT's for QueryRcaRequestHandler (#436)
Browse files Browse the repository at this point in the history
* Initial tests set up.

Signed-off-by: Filip Drobnjakovic <[email protected]>

* Muted RCA test.

Signed-off-by: Filip Drobnjakovic <[email protected]>

* Expand muted nodes update with config file.

Signed-off-by: Filip Drobnjakovic <[email protected]>

---------

Signed-off-by: Filip Drobnjakovic <[email protected]>
  • Loading branch information
Tjofil authored Jul 11, 2023
1 parent cc70891 commit 6f780f1
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ private void readAndUpdateMutedComponentsDuringStart() {
}
}

private boolean updateMutedComponents() {
@VisibleForTesting
public boolean updateMutedComponents() {
try {
Set<String> allNodes =
ConnectedComponent.getNodesForAllComponents(this.connectedComponents);
Expand Down Expand Up @@ -547,6 +548,16 @@ public void setDbProvider(Queryable dbProvider) throws InterruptedException {
this.dbProvider = dbProvider;
}

@VisibleForTesting
public void setRcaConf(RcaConf rcaConf) {
this.rcaConf = rcaConf;
}

@VisibleForTesting
public void setConnectedComponents(List<ConnectedComponent> connectedComponents) {
this.connectedComponents = connectedComponents;
}

@VisibleForTesting
public List<ConnectedComponent> getConnectedComponents() {
return connectedComponents;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.performanceanalyzer.rest;


import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.util.Collections;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.opensearch.performanceanalyzer.AppContext;
import org.opensearch.performanceanalyzer.PerformanceAnalyzerApp;
import org.opensearch.performanceanalyzer.commons.metrics.AllMetrics;
import org.opensearch.performanceanalyzer.rca.RcaController;
import org.opensearch.performanceanalyzer.rca.framework.core.ConnectedComponent;
import org.opensearch.performanceanalyzer.rca.framework.core.RcaConf;
import org.opensearch.performanceanalyzer.rca.framework.core.Stats;
import org.opensearch.performanceanalyzer.rca.store.rca.hotshard.HotShardClusterRca;
import org.opensearch.performanceanalyzer.rca.store.rca.temperature.NodeTemperatureRca;
import org.opensearch.performanceanalyzer.reader.ClusterDetailsEventProcessor;

public class QueryRcaRequestHandlerTest {
private QueryRcaRequestHandler handler;
private AppContext appContext;
private RcaController rcaController;
private static final String queryPrefix =
"http://localhost:9600/_plugins/_performanceanalyzer/rca";
private static final String mutedConfPath =
"./src/test/resources/rca/rca_query_muted_test.conf";
private static final String nonMutedConfPath = "./src/test/resources/rca/rca_query_test.conf";

private void setClusterManagerContext(boolean isClusterManager) {
ClusterDetailsEventProcessor clusterDetailsEventProcessor =
new ClusterDetailsEventProcessor();
clusterDetailsEventProcessor.setNodesDetails(
Collections.singletonList(
new ClusterDetailsEventProcessor.NodeDetails(
isClusterManager
? AllMetrics.NodeRole.ELECTED_CLUSTER_MANAGER
: AllMetrics.NodeRole.DATA,
"test_node",
"127.0.0.1",
isClusterManager)));
appContext.setClusterDetailsEventProcessor(clusterDetailsEventProcessor);
}

private void setConfPath(String rcaConfPath) {
rcaController.setRcaConf(new RcaConf(rcaConfPath));
rcaController.updateMutedComponents();
}

private HttpExchange sendQuery(String query, String requestMethod, OutputStream os)
throws Exception {
HttpExchange exchange = Mockito.mock(HttpExchange.class);
Mockito.when(exchange.getResponseBody()).thenReturn(os != null ? os : System.out);
Mockito.when(exchange.getRequestMethod()).thenReturn(requestMethod);
Headers responseHeaders = Mockito.mock(Headers.class);
Mockito.when(exchange.getResponseHeaders()).thenReturn(responseHeaders);
Mockito.when(exchange.getRequestURI()).thenReturn(new URI(query));
handler.handle(exchange);
return exchange;
}

@Before
public void setUp() {
/* Prepares RcaController for with nodes and config files for testing */
appContext = new AppContext();
rcaController = new RcaController();
ConnectedComponent connectedComponent = new ConnectedComponent(1);
connectedComponent.addLeafNode(new HotShardClusterRca(0, null));
connectedComponent.addLeafNode(new NodeTemperatureRca(null, null, null));
rcaController.setConnectedComponents(Collections.singletonList(connectedComponent));
connectedComponent.getAllNodes(); // Initializes node names
Stats.getInstance().getConnectedComponents(); // Initializes muted graph nodes structure
setConfPath(nonMutedConfPath);
PerformanceAnalyzerApp.setRcaController(rcaController);
handler = new QueryRcaRequestHandler(appContext);
setClusterManagerContext(false);
}

@After
public void reset() {
Stats.getInstance().getConnectedComponents();
PerformanceAnalyzerApp.setRcaController(null);
}

@Test
public void testInvalidNodeRole() throws Exception {
HttpExchange exchange = sendQuery(queryPrefix + "?name=HotShardClusterRca", "GET", null);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_BAD_REQUEST),
ArgumentMatchers.anyLong());
}

@Test
public void testValidNodeRole() throws Exception {
setClusterManagerContext(true);
HttpExchange exchange = sendQuery(queryPrefix + "?name=HotShardClusterRca", "GET", null);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_OK), ArgumentMatchers.anyLong());
}

@Test
public void testBadRequestMethod() throws Exception {
HttpExchange exchange = sendQuery(queryPrefix + "?name=HotShardClusterRca", "PUT", null);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_NOT_FOUND),
ArgumentMatchers.anyLong());
}

@Test
public void testMutedLocalTemperatureRCA() throws Exception {
setConfPath(mutedConfPath);
Assert.assertTrue(Stats.getInstance().getMutedGraphNodes().contains("NodeTemperatureRca"));
OutputStream exchangeOutputStream = new ByteArrayOutputStream();
HttpExchange exchange =
sendQuery(
queryPrefix + "?name=NodeTemperatureRca&local=true",
"GET",
exchangeOutputStream);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_BAD_REQUEST),
ArgumentMatchers.anyLong());

Assert.assertTrue(exchangeOutputStream.toString().contains("muted"));
}

@Test
public void testInvalidParams() throws Exception {
setClusterManagerContext(true);
OutputStream exchangeOutputStream = new ByteArrayOutputStream();
HttpExchange exchange =
sendQuery(queryPrefix + "?name=NonExistingClusterRCA", "GET", exchangeOutputStream);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_BAD_REQUEST),
ArgumentMatchers.anyLong());

Assert.assertTrue(exchangeOutputStream.toString().contains("Invalid RCA"));
}

@Test
public void testMutedClusterRCA() throws Exception {
setClusterManagerContext(true);
setConfPath(mutedConfPath);
Assert.assertTrue(Stats.getInstance().getMutedGraphNodes().contains("NodeTemperatureRca"));
OutputStream exchangeOutputStream = new ByteArrayOutputStream();
HttpExchange exchange =
sendQuery(queryPrefix + "?name=HotShardClusterRca", "GET", exchangeOutputStream);
Mockito.verify(exchange)
.sendResponseHeaders(
ArgumentMatchers.eq(HttpURLConnection.HTTP_OK), ArgumentMatchers.anyLong());

Assert.assertEquals("{}", exchangeOutputStream.toString());
}
}
27 changes: 27 additions & 0 deletions src/test/resources/rca/rca_query_muted_test.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"analysis-graph-implementor" : "org.opensearch.performanceanalyzer.rca.store.AnalysisGraphTest",
"rca-store-location" : "s3://sifi-store/rcas/",
"threshold-store-location" : "s3://sifi-store/thresholds/",
"new-rca-check-minutes" : 60,
"new-threshold-check-minutes" : 30,
"network-queue-length" : 200,
"max-flow-units-per-vertex-buffer" : 200,
"tags" : {
"locus" : "data-node",
"disk" : "ssd",
"region" : "use1",
"instance-type" : "i3.8xl",
"domain" : "rca-test-cluster"
},
"remote-peers" : [ "ip1", "ip2", "ip3" ],
"datastore" : {
"type" : "sqlite",
"location-dir" : "/tmp",
"filename" : "rca.sqlite",
"storage-file-retention-count" : 5,
"rotation-period-seconds" : 21600
},
"muted-rcas" : [ "HotShardClusterRca" , "NodeTemperatureRca"],
"muted-deciders" : [ ],
"muted-actions" : [ ]
}
27 changes: 27 additions & 0 deletions src/test/resources/rca/rca_query_test.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"analysis-graph-implementor" : "org.opensearch.performanceanalyzer.rca.store.AnalysisGraphTest",
"rca-store-location" : "s3://sifi-store/rcas/",
"threshold-store-location" : "s3://sifi-store/thresholds/",
"new-rca-check-minutes" : 60,
"new-threshold-check-minutes" : 30,
"network-queue-length" : 200,
"max-flow-units-per-vertex-buffer" : 200,
"tags" : {
"locus" : "data-node",
"disk" : "ssd",
"region" : "use1",
"instance-type" : "i3.8xl",
"domain" : "rca-test-cluster"
},
"remote-peers" : [ "ip1", "ip2", "ip3" ],
"datastore" : {
"type" : "sqlite",
"location-dir" : "/tmp",
"filename" : "rca.sqlite",
"storage-file-retention-count" : 5,
"rotation-period-seconds" : 21600
},
"muted-rcas" : [ ],
"muted-deciders" : [ ],
"muted-actions" : [ ]
}

0 comments on commit 6f780f1

Please sign in to comment.