summaryrefslogtreecommitdiffstats
path: root/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java')
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java85
1 files changed, 84 insertions, 1 deletions
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
index 7722354a633..d9cce7f80a0 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
@@ -1,12 +1,20 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.maintenance;
+import com.yahoo.collections.Pair;
+import com.yahoo.config.provision.NodeType;
+import com.yahoo.metrics.simple.MetricReceiver;
import com.yahoo.system.ProcessExecuter;
+import com.yahoo.test.ManualClock;
+import com.yahoo.vespa.hosted.dockerapi.ContainerName;
+import com.yahoo.vespa.hosted.dockerapi.metrics.MetricReceiverWrapper;
+import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec;
import com.yahoo.vespa.hosted.node.admin.config.ConfigServerConfig;
import com.yahoo.vespa.hosted.node.admin.docker.DockerNetworking;
import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations;
import com.yahoo.vespa.hosted.node.admin.component.Environment;
import com.yahoo.vespa.hosted.node.admin.component.PathResolver;
+import com.yahoo.vespa.hosted.provision.Node;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -14,15 +22,21 @@ import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
+import java.time.Duration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
/**
* @author dybis
*/
public class StorageMaintainerTest {
+ private final ManualClock clock = new ManualClock();
private final Environment environment = new Environment.Builder()
.configServerConfig(new ConfigServerConfig(new ConfigServerConfig.Builder()))
.region("us-east-1")
@@ -36,7 +50,7 @@ public class StorageMaintainerTest {
private final DockerOperations docker = mock(DockerOperations.class);
private final ProcessExecuter processExecuter = mock(ProcessExecuter.class);
private final StorageMaintainer storageMaintainer = new StorageMaintainer(docker, processExecuter,
- environment, null);
+ new MetricReceiverWrapper(MetricReceiver.nullImplementation), environment, clock);
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@@ -57,7 +71,76 @@ public class StorageMaintainerTest {
assertEquals(0L, usedBytes);
}
+ @Test
+ public void testMaintenanceThrottlingAfterSuccessfulMaintenance() {
+ String hostname = "node-123.us-north-3.test.yahoo.com";
+ ContainerName containerName = ContainerName.fromHostname(hostname);
+ NodeSpec node = new NodeSpec.Builder()
+ .hostname(hostname)
+ .state(Node.State.ready)
+ .nodeType(NodeType.tenant)
+ .flavor("docker")
+ .minCpuCores(1)
+ .minMainMemoryAvailableGb(1)
+ .minDiskAvailableGb(1)
+ .build();
+
+ try {
+ when(processExecuter.exec(any(String[].class))).thenReturn(new Pair<>(0, ""));
+ } catch (IOException ignored) { }
+ storageMaintainer.removeOldFilesFromNode(containerName);
+ verifyProcessExecuterCalled(1);
+ // Will not actually run maintenance job until an hour passes
+ storageMaintainer.removeOldFilesFromNode(containerName);
+ verifyProcessExecuterCalled(1);
+
+ clock.advance(Duration.ofMinutes(61));
+ storageMaintainer.removeOldFilesFromNode(containerName);
+ verifyProcessExecuterCalled(2);
+
+ // Coredump handling is unthrottled
+ storageMaintainer.handleCoreDumpsForContainer(containerName, node);
+ verifyProcessExecuterCalled(3);
+
+ storageMaintainer.handleCoreDumpsForContainer(containerName, node);
+ verifyProcessExecuterCalled(4);
+
+ // cleanupNodeStorage is unthrottled and it should reset previous times
+ storageMaintainer.cleanupNodeStorage(containerName, node);
+ verifyProcessExecuterCalled(5);
+ storageMaintainer.cleanupNodeStorage(containerName, node);
+ verifyProcessExecuterCalled(6);
+ }
+
+ @Test
+ public void testMaintenanceThrottlingAfterFailedMaintenance() {
+ String hostname = "node-123.us-north-3.test.yahoo.com";
+ ContainerName containerName = ContainerName.fromHostname(hostname);
+
+ try {
+ when(processExecuter.exec(any(String[].class)))
+ .thenThrow(new RuntimeException("Something went wrong"))
+ .thenReturn(new Pair<>(0, ""));
+ } catch (IOException ignored) { }
+
+ try {
+ storageMaintainer.removeOldFilesFromNode(containerName);
+ fail("Maintenance job should've failed!");
+ } catch (RuntimeException ignored) { }
+ verifyProcessExecuterCalled(1);
+
+ // Maintenance job failed, we should be able to immediately re-run it
+ storageMaintainer.removeOldFilesFromNode(containerName);
+ verifyProcessExecuterCalled(2);
+ }
+
private static void writeNBytesToFile(File file, int nBytes) throws IOException {
Files.write(file.toPath(), new byte[nBytes]);
}
+
+ private void verifyProcessExecuterCalled(int times) {
+ try {
+ verify(processExecuter, times(times)).exec(any(String[].class));
+ } catch (IOException ignored) { }
+ }
}