diff options
Diffstat (limited to 'clustercontroller-core')
2 files changed, 131 insertions, 0 deletions
diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MetricReporterTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MetricReporterTest.java new file mode 100644 index 00000000000..adc804c805d --- /dev/null +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MetricReporterTest.java @@ -0,0 +1,60 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.clustercontroller.core; + +import com.yahoo.vdslib.state.ClusterState; +import com.yahoo.vespa.clustercontroller.core.matchers.HasMetricContext; +import com.yahoo.vespa.clustercontroller.utils.util.MetricReporter; +import org.junit.Test; + +import java.util.Map; + +import static com.yahoo.vespa.clustercontroller.core.matchers.HasMetricContext.hasMetricContext; +import static com.yahoo.vespa.clustercontroller.core.matchers.HasMetricContext.withDimension; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class MetricReporterTest { + + private static class Fixture { + final MetricReporter mockReporter = mock(MetricReporter.class); + final MetricUpdater metricUpdater = new MetricUpdater(mockReporter, 0); + final ClusterFixture clusterFixture = ClusterFixture.forFlatCluster(10); + + Fixture() { + when(mockReporter.createContext(any())).then(invocation -> + new HasMetricContext.MockContext((Map<String, ?>)invocation.getArguments()[0])); + } + } + + private static HasMetricContext.Dimension[] withNodeTypeDimension(String type) { + // Dimensions that are always present + HasMetricContext.Dimension controllerDim = withDimension("controller-index", "0"); + HasMetricContext.Dimension clusterDim = withDimension("cluster", "foo"); + // Node type-specific dimension + HasMetricContext.Dimension nodeType = withDimension("node-type", type); + return new HasMetricContext.Dimension[] { controllerDim, clusterDim, nodeType }; + } + + @Test + public void metrics_are_emitted_for_different_node_state_counts() { + Fixture f = new Fixture(); + f.metricUpdater.updateClusterStateMetrics(f.clusterFixture.cluster(), + ClusterState.stateFromString("distributor:10 .1.s:d storage:9 .1.s:d .2.s:m .4.s:d")); + + verify(f.mockReporter).set(eq("cluster-controller.up.count"), eq(9), + argThat(hasMetricContext(withNodeTypeDimension("distributor")))); + verify(f.mockReporter).set(eq("cluster-controller.up.count"), eq(6), + argThat(hasMetricContext(withNodeTypeDimension("storage")))); + verify(f.mockReporter).set(eq("cluster-controller.down.count"), eq(1), + argThat(hasMetricContext(withNodeTypeDimension("distributor")))); + verify(f.mockReporter).set(eq("cluster-controller.down.count"), eq(3), + argThat(hasMetricContext(withNodeTypeDimension("storage")))); + verify(f.mockReporter).set(eq("cluster-controller.maintenance.count"), eq(1), + argThat(hasMetricContext(withNodeTypeDimension("storage")))); + } + +} diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/matchers/HasMetricContext.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/matchers/HasMetricContext.java new file mode 100644 index 00000000000..dcc9055f0d1 --- /dev/null +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/matchers/HasMetricContext.java @@ -0,0 +1,71 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.clustercontroller.core.matchers; + +import com.yahoo.vespa.clustercontroller.utils.util.MetricReporter; +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.mockito.ArgumentMatcher; + +import java.util.Map; +import java.util.TreeMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class HasMetricContext extends ArgumentMatcher<MetricReporter.Context> { + + private final Map<String, String> dimensions; + + public HasMetricContext(Map<String, String> dimensions) { + this.dimensions = new TreeMap<>(dimensions); + } + + @Override + public boolean matches(Object o) { + if (!(o instanceof MockContext)) { + return false; + } + return dimensions.equals(((MockContext)o).dimensions); + } + + @Override + public void describeTo(Description description) { + description.appendText(String.format("Context with dimensions %s", dimensions.toString())); + } + + @Override + public void describeMismatch(Object item, Description description) { + description.appendText(String.format("Context dimensions are %s", item.toString())); + } + + public static class Dimension { + final String name; + final String value; + + public Dimension(String name, String value) { + this.name = name; + this.value = value; + } + } + + public static class MockContext implements MetricReporter.Context { + final TreeMap<String, ?> dimensions; + + public MockContext(Map<String, ?> dimensions) { + this.dimensions = new TreeMap<>(dimensions); + } + + @Override + public String toString() { + return dimensions.toString(); + } + } + + public static Dimension withDimension(String name, String value) { + return new Dimension(name, value); + } + + @Factory + public static HasMetricContext hasMetricContext(Dimension... dimensions) { + return new HasMetricContext(Stream.of(dimensions).collect(Collectors.toMap(dim -> dim.name, dim -> dim.value))); + } +} |