blob: 94aaf21fa422822993ffa1259735f538b077cd8f [file] [log] [blame]
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.metricsreportercloudwatch;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import com.google.common.base.Splitter;
import com.google.common.base.Stopwatch;
import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.acceptance.config.GerritConfig;
import com.google.gerrit.metrics.Counter0;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.MetricMaker;
import com.google.inject.Inject;
import java.time.Duration;
import java.util.Enumeration;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.Test;
@UseLocalDisk
@TestPlugin(
name = "metrics-reporter-cloudwatch",
sysModule = "com.googlesource.gerrit.plugins.metricsreportercloudwatch.GerritCloudwatchModule")
public class MetricsReporterCloudwatchIT extends LightweightPluginDaemonTest {
private static final String GERRIT_INSTANCE_ID = "testInstanceId";
private static final String TEST_METRIC_NAME = "test/metric/name";
private static final long TEST_METRIC_INCREMENT = 1234567L;
private static final String TEST_JVM_METRIC_NAME = "jvm.uptime";
private static final String TEST_TIMEOUT = "10";
private static final Duration TEST_TIMEOUT_DURATION =
Duration.ofSeconds(Integer.valueOf(TEST_TIMEOUT));
@Inject private MetricMaker metricMaker;
private Counter0 testCounterMetric;
@Override
public void setUpTestPlugin() throws Exception {
System.setProperty("aws.region", "us-west-1");
testCounterMetric = metricMaker.newCounter(TEST_METRIC_NAME, new Description("test metric"));
super.setUpTestPlugin();
}
@Test
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
public void shouldCloudwatchReporterBeStartedInDryRun() throws Exception {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
waitUntil(() -> dryRunMetricsOutput.metricsStream().anyMatch(l -> l.contains("DRY RUN")));
}
@Test
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
public void shouldReportMetricValueToCloudwatch() throws Exception {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
testCounterMetric.incrementBy(TEST_METRIC_INCREMENT);
waitUntil(
() ->
dryRunMetricsOutput
.metricsStream()
.filter(l -> l.contains("MetricName=" + TEST_METRIC_NAME))
.anyMatch(l -> l.contains("Value=" + TEST_METRIC_INCREMENT)));
}
@Test
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
@GerritConfig(
name = "plugin.metrics-reporter-cloudwatch.excludeMetrics",
value = TEST_METRIC_NAME)
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
public void shouldExcludeMetrics() {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
assertThrows(
InterruptedException.class,
() -> {
waitUntil(
() ->
dryRunMetricsOutput
.metricsStream()
.anyMatch(l -> l.contains("MetricName=" + TEST_METRIC_NAME)));
});
}
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.jvmMetrics", value = "true")
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
public void shouldReportJVMMetricsToCloudwatch() throws Exception {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
waitUntil(
() ->
dryRunMetricsOutput
.metricsStream()
.anyMatch(l -> l.contains("MetricName=" + TEST_JVM_METRIC_NAME)));
}
@Test
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
public void shouldNotReportJVMMetricsToCloudwatchByDefault() throws Exception {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
assertThrows(
InterruptedException.class,
() -> {
waitUntil(
() ->
dryRunMetricsOutput
.metricsStream()
.anyMatch(l -> l.contains("MetricName=" + TEST_JVM_METRIC_NAME)));
});
}
@Test
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.dryrun", value = "true")
@GerritConfig(name = "plugin.metrics-reporter-cloudwatch.rate", value = TEST_TIMEOUT)
@GerritConfig(name = "gerrit.instanceId", value = GERRIT_INSTANCE_ID)
public void shouldAddInstanceIdDimensionWhenAvailable() throws Exception {
InMemoryLoggerAppender dryRunMetricsOutput = newInMemoryLogger();
waitUntil(
() ->
dryRunMetricsOutput
.metricsStream()
.anyMatch(
l ->
l.contains(
String.format("Name=InstanceId, Value=%s", GERRIT_INSTANCE_ID))));
}
private static InMemoryLoggerAppender newInMemoryLogger() {
InMemoryLoggerAppender dryRunMetricsOutput = new InMemoryLoggerAppender();
for (Enumeration<?> logger = LogManager.getCurrentLoggers(); logger.hasMoreElements(); ) {
Logger log = (Logger) logger.nextElement();
if (log.getName().contains("CloudWatchReporter")) {
log.addAppender(dryRunMetricsOutput);
log.setLevel(Level.DEBUG);
}
}
return dryRunMetricsOutput;
}
private static void waitUntil(Supplier<Boolean> waitCondition) throws InterruptedException {
Stopwatch stopwatch = Stopwatch.createStarted();
while (!waitCondition.get()) {
if (stopwatch.elapsed().compareTo(TEST_TIMEOUT_DURATION) > 0) {
throw new InterruptedException();
}
MILLISECONDS.sleep(50);
}
}
static class InMemoryLoggerAppender extends AppenderSkeleton {
private final Splitter metricsDatumSplitter = Splitter.on("MetricDatum");
private CopyOnWriteArrayList<String> logLines = new CopyOnWriteArrayList<>();
@Override
public void close() {}
@Override
public boolean requiresLayout() {
return false;
}
@Override
protected void append(LoggingEvent event) {
String logMessage = event.getMessage().toString();
logLines.add(logMessage);
}
public Stream<String> metricsStream() {
return logLines.stream().flatMap(metricsDatumSplitter::splitToStream);
}
}
}