Skip to content

Commit

Permalink
add some unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
m-nagarajan committed Nov 25, 2024
1 parent 8a53e26 commit f746f2d
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.linkedin.venice.stats.metrics;

import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.linkedin.venice.stats.VeniceOpenTelemetryMetricsRepository;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.LongCounter;
import io.tehuti.metrics.MeasurableStat;
import io.tehuti.metrics.Sensor;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,29 +438,29 @@ public void recordThrottledRequest(HttpResponseStatus responseStatus) {
}

public void recordErrorRetryCount() {
recordRetryTriggeredSensorOtel(MetricNamesInTehuti.ERROR_RETRY, RequestRetryType.ERROR_RETRY);
recordRetryTriggeredSensorOtel(RequestRetryType.ERROR_RETRY);
}

public void recordRetryTriggeredSensorOtel(String tetutiMetricName, RequestRetryType retryType) {
public void recordRetryTriggeredSensorOtel(RequestRetryType retryType) {
Attributes dimensions = null;
if (emitOpenTelemetryMetrics) {
dimensions = Attributes.builder()
.putAll(commonMetricDimensions)
.put(getDimensionName(VENICE_REQUEST_RETRY_TYPE), retryType.getRetryType())
.build();
}
retryCountMetric.record(tetutiMetricName, 1, dimensions);
retryCountMetric.record(MetricNamesInTehuti.ERROR_RETRY, 1, dimensions);
}

public void recordAbortedRetrySensorOtel(String tetutiMetricName, RequestRetryAbortReason abortReason) {
public void recordAbortedRetrySensorOtel(String tehutiMetricName, RequestRetryAbortReason abortReason) {
Attributes dimensions = null;
if (emitOpenTelemetryMetrics) {
dimensions = Attributes.builder()
.putAll(commonMetricDimensions)
.put(getDimensionName(VENICE_REQUEST_RETRY_ABORT_REASON), abortReason.getAbortReason())
.build();
}
abortedRetryCountMetric.record(tetutiMetricName, 1, dimensions);
abortedRetryCountMetric.record(tehutiMetricName, 1, dimensions);
}

public void recordBadRequest(HttpResponseStatus responseStatus) {
Expand Down Expand Up @@ -494,7 +494,7 @@ public void recordLatencyMetric(
if (emitOpenTelemetryMetrics) {
dimensions = Attributes.builder()
.putAll(commonMetricDimensions)
// only add HTTP_RESPONSE_STATUS_CODE_CATEGORY to reduce the cardinality for histogram
// Don't add HTTP_RESPONSE_STATUS_CODE to reduce the cardinality for histogram
.put(
getDimensionName(HTTP_RESPONSE_STATUS_CODE_CATEGORY),
getVeniceHttpResponseStatusCodeCategory(responseStatus))
Expand All @@ -505,7 +505,7 @@ public void recordLatencyMetric(
}

public void recordRequestMetric(
String tetutiMetricName,
String tehutiMetricName,
HttpResponseStatus responseStatus,
VeniceResponseStatusCategory veniceResponseStatusCategory) {
Attributes dimensions = null;
Expand All @@ -519,7 +519,7 @@ public void recordRequestMetric(
.put(getDimensionName(HTTP_RESPONSE_STATUS_CODE), responseStatus.codeAsText().toString())
.build();
}
requestMetric.record(tetutiMetricName, 1, dimensions);
requestMetric.record(tehutiMetricName, 1, dimensions);
}

public void recordResponseWaitingTime(double waitingTime) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package com.linkedin.venice.router.stats;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;

import com.linkedin.venice.router.RouterServer;
import com.linkedin.venice.stats.dimensions.VeniceMetricsDimensions;
import com.linkedin.venice.stats.metrics.MetricEntity;
import com.linkedin.venice.stats.metrics.MetricType;
import com.linkedin.venice.stats.metrics.MetricUnit;
import com.linkedin.venice.utils.Utils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.testng.annotations.Test;


public class RouterMetricEntityTest {
@Test
public void testRouterMetricEntities() {
Map<RouterMetricEntity, MetricEntity> expectedMetrics = new HashMap<>();

expectedMetrics.put(
RouterMetricEntity.INCOMING_CALL_COUNT,
new MetricEntity(
"incoming_call_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of all incoming requests",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD)));
expectedMetrics.put(
RouterMetricEntity.CALL_COUNT,
new MetricEntity(
"call_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of all requests with response details",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD,
VeniceMetricsDimensions.HTTP_RESPONSE_STATUS_CODE,
VeniceMetricsDimensions.HTTP_RESPONSE_STATUS_CODE_CATEGORY,
VeniceMetricsDimensions.VENICE_RESPONSE_STATUS_CODE_CATEGORY)));
expectedMetrics.put(
RouterMetricEntity.CALL_TIME,
new MetricEntity(
"call_time",
MetricType.HISTOGRAM,
MetricUnit.MILLISECOND,
"Latency based on all responses",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD,
VeniceMetricsDimensions.HTTP_RESPONSE_STATUS_CODE_CATEGORY,
VeniceMetricsDimensions.VENICE_RESPONSE_STATUS_CODE_CATEGORY)));
expectedMetrics.put(
RouterMetricEntity.CALL_KEY_COUNT,
new MetricEntity(
"call_key_count",
MetricType.MIN_MAX_COUNT_SUM_AGGREGATIONS,
MetricUnit.NUMBER,
"Count of keys in multi key requests",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD,
VeniceMetricsDimensions.VENICE_REQUEST_VALIDATION_OUTCOME)));
expectedMetrics.put(
RouterMetricEntity.RETRY_COUNT,
new MetricEntity(
"retry_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of retries triggered",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD,
VeniceMetricsDimensions.VENICE_REQUEST_RETRY_TYPE)));
expectedMetrics.put(
RouterMetricEntity.ALLOWED_RETRY_COUNT,
new MetricEntity(
"allowed_retry_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of allowed retry requests",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD)));
expectedMetrics.put(
RouterMetricEntity.DISALLOWED_RETRY_COUNT,
new MetricEntity(
"disallowed_retry_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of disallowed retry requests",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD)));
expectedMetrics.put(
RouterMetricEntity.RETRY_DELAY,
new MetricEntity(
"retry_delay",
MetricType.MIN_MAX_COUNT_SUM_AGGREGATIONS,
MetricUnit.MILLISECOND,
"Retry delay time",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD)));
expectedMetrics.put(
RouterMetricEntity.ABORTED_RETRY_COUNT,
new MetricEntity(
"aborted_retry_count",
MetricType.COUNTER,
MetricUnit.NUMBER,
"Count of aborted retry requests",
Utils.setOf(
VeniceMetricsDimensions.VENICE_STORE_NAME,
VeniceMetricsDimensions.VENICE_CLUSTER_NAME,
VeniceMetricsDimensions.VENICE_REQUEST_METHOD,
VeniceMetricsDimensions.VENICE_REQUEST_RETRY_ABORT_REASON)));

for (RouterMetricEntity metric: RouterMetricEntity.values()) {
MetricEntity actual = metric.getMetricEntity();
MetricEntity expected = expectedMetrics.get(metric);

assertNotNull(expected, "No expected definition for " + metric.name());
assertNotNull(actual.getMetricName(), "Metric name should not be null for " + metric.name());
assertEquals(actual.getMetricName(), expected.getMetricName(), "Unexpected metric name for " + metric.name());
assertNotNull(actual.getMetricType(), "Metric type should not be null for " + metric.name());
assertEquals(actual.getMetricType(), expected.getMetricType(), "Unexpected metric type for " + metric.name());
assertNotNull(actual.getUnit(), "Metric unit should not be null for " + metric.name());
assertEquals(actual.getUnit(), expected.getUnit(), "Unexpected metric unit for " + metric.name());
assertNotNull(actual.getDescription(), "Metric description should not be null for " + metric.name());
assertEquals(
actual.getDescription(),
expected.getDescription(),
"Unexpected metric description for " + metric.name());
assertNotNull(actual.getDimensionsList(), "Metric dimensions should not be null for " + metric.name());
assertEquals(
actual.getDimensionsList(),
expected.getDimensionsList(),
"Unexpected metric dimensions for " + metric.name());
}

// Convert expectedMetrics to a Collection for comparison
Collection<MetricEntity> expectedMetricEntities = expectedMetrics.values();

// Assert size
assertEquals(
RouterServer.ROUTER_SERVICE_METRIC_ENTITIES.size(),
expectedMetricEntities.size(),
"Unexpected size of ROUTER_SERVICE_METRIC_ENTITIES");

// Assert contents
for (MetricEntity actual: RouterServer.ROUTER_SERVICE_METRIC_ENTITIES) {
boolean found = false;
for (MetricEntity expected: expectedMetricEntities) {
if (metricEntitiesEqual(actual, expected)) {
found = true;
break;
}
}
assertTrue(found, "Unexpected MetricEntity found: " + actual.getMetricName());
}
}

private boolean metricEntitiesEqual(MetricEntity actual, MetricEntity expected) {
return Objects.equals(actual.getMetricName(), expected.getMetricName())
&& actual.getMetricType() == expected.getMetricType() && actual.getUnit() == expected.getUnit()
&& Objects.equals(actual.getDescription(), expected.getDescription())
&& Objects.equals(actual.getDimensionsList(), expected.getDimensionsList());
}
}

0 comments on commit f746f2d

Please sign in to comment.