aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--document/src/test/java/com/yahoo/document/DocumentTypeManagerTestCase.java50
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/JobControl.java15
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java20
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/JobsResponse.java43
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java55
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java (renamed from node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MockDeployer.java)10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java11
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/OrchestratorMock.java64
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ServiceMonitorStub.java91
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/TestHostLivenessTracker.java31
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java152
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodeStateSerializerTest.java19
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/maintenance.json10
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/root.json3
-rw-r--r--testutil/pom.xml5
-rw-r--r--testutil/src/main/java/com/yahoo/test/ManualClock.java2
-rw-r--r--vespalog/src/main/java/com/yahoo/log/VespaFormatter.java35
-rw-r--r--zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java2
25 files changed, 407 insertions, 226 deletions
diff --git a/document/src/test/java/com/yahoo/document/DocumentTypeManagerTestCase.java b/document/src/test/java/com/yahoo/document/DocumentTypeManagerTestCase.java
index 4363a704ad7..e6c020e6688 100644
--- a/document/src/test/java/com/yahoo/document/DocumentTypeManagerTestCase.java
+++ b/document/src/test/java/com/yahoo/document/DocumentTypeManagerTestCase.java
@@ -10,15 +10,11 @@ import org.junit.Test;
import java.util.Iterator;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
@@ -125,7 +121,7 @@ public class DocumentTypeManagerTestCase {
@Test
public void testReverseMapOrder() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.map.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.map.cfg");
assertNotNull(manager.getDataType(1000));
assertNotNull(manager.getDataType(1001));
@@ -134,7 +130,7 @@ public class DocumentTypeManagerTestCase {
@SuppressWarnings("deprecation")
@Test
public void testConfigure() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.cfg");
Iterator typeIt = manager.documentTypeIterator();
DocumentType type = null;
@@ -215,7 +211,7 @@ public class DocumentTypeManagerTestCase {
@Test
public void testConfigureUpdate() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.cfg");
DocumentType banana = manager.getDocumentType(new DataTypeName("banana"));
DocumentType customtypes = manager.getDocumentType(new DataTypeName("customtypes"));
@@ -234,7 +230,7 @@ public class DocumentTypeManagerTestCase {
@Test
public void testConfigureWithAnnotations() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationtypes1.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationtypes1.cfg");
/*
annotation banana {
@@ -294,7 +290,7 @@ public class DocumentTypeManagerTestCase {
@Test
public void testConfigureWithAnnotationsWithInheritance() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationtypes2.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationtypes2.cfg");
/*
annotation fruit {
@@ -419,7 +415,7 @@ search annotationsimplicitstruct {
}
*/
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.structsanyorder.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.structsanyorder.cfg");
StructDataType foo = (StructDataType) manager.getDataType("foo");
assertNotNull(foo);
@@ -442,7 +438,7 @@ search annotationsimplicitstruct {
@Test
public void testSombrero1() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.sombrero1.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.sombrero1.cfg");
{
StringFieldValue sfv = new StringFieldValue("ballooooo");
@@ -482,7 +478,7 @@ search annotationsimplicitstruct {
*/
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationspolymorphy.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.annotationspolymorphy.cfg");
AnnotationType suuper = manager.getAnnotationTypeRegistry().getType("super");
AnnotationType sub = manager.getAnnotationTypeRegistry().getType("sub");
@@ -509,23 +505,23 @@ search annotationsimplicitstruct {
private static void assertReferenceTypePresentInManager(DocumentTypeManager manager, int refTypeId,
String refTargetTypeName) {
- final DataType type = manager.getDataType(refTypeId);
- assertThat(type, instanceOf(ReferenceDataType.class));
- final ReferenceDataType refType = (ReferenceDataType) type;
+ DataType type = manager.getDataType(refTypeId);
+ assertTrue(type instanceof ReferenceDataType);
+ ReferenceDataType refType = (ReferenceDataType) type;
- final DocumentType targetDocType = manager.getDocumentType(refTargetTypeName);
- assertThat(refType.getTargetType(), sameInstance(targetDocType));
+ DocumentType targetDocType = manager.getDocumentType(refTargetTypeName);
+ assertTrue(refType.getTargetType() == targetDocType);
}
private static DocumentTypeManager createConfiguredManager(String configFilePath) {
- final DocumentTypeManager manager = new DocumentTypeManager();
+ DocumentTypeManager manager = new DocumentTypeManager();
DocumentTypeManagerConfigurer.configure(manager, configFilePath);
return manager;
}
@Test
public void multiple_reference_types_are_mapped_to_correct_document_target_types() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.multiplereferences.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.multiplereferences.cfg");
assertReferenceTypePresentInManager(manager, 12345678, "referenced_type");
assertReferenceTypePresentInManager(manager, 87654321, "referenced_type2");
@@ -533,23 +529,23 @@ search annotationsimplicitstruct {
@Test
public void can_have_reference_type_pointing_to_own_document_type() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.selfreference.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.selfreference.cfg");
assertReferenceTypePresentInManager(manager, 12345678, "type_with_ref");
}
@Test
public void reference_field_has_correct_reference_type() {
- final DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.singlereference.cfg");
+ DocumentTypeManager manager = createConfiguredManager("file:src/test/document/documentmanager.singlereference.cfg");
- final DocumentType docType = manager.getDocumentType("type_with_ref");
- final Field field = docType.getField("my_ref_field");
+ DocumentType docType = manager.getDocumentType("type_with_ref");
+ Field field = docType.getField("my_ref_field");
- assertThat(field.getDataType(), instanceOf(ReferenceDataType.class));
- final ReferenceDataType fieldRefType = (ReferenceDataType) field.getDataType();
+ assertTrue(field.getDataType() instanceof ReferenceDataType);
+ ReferenceDataType fieldRefType = (ReferenceDataType) field.getDataType();
- final DocumentType targetDocType = manager.getDocumentType("referenced_type");
- assertThat(fieldRefType.getTargetType(), sameInstance(targetDocType));
+ DocumentType targetDocType = manager.getDocumentType("referenced_type");
+ assertTrue(fieldRefType.getTargetType() == targetDocType);
}
// TODO test reference to own doc type
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/JobControl.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/JobControl.java
index 93c626c8b81..197c173e639 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/JobControl.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/JobControl.java
@@ -35,21 +35,24 @@ public class JobControl {
* Each job is represented by its simple (omitting package) class name.
*/
public Set<String> jobs() { return new HashSet<>(startedJobs); }
+
+ /** Returns a snapshot containing the currently inactive jobs in this */
+ public Set<String> inactiveJobs() { return db.readInactiveJobs(); }
/** Returns true if this job is not currently deactivated */
public boolean isActive(String jobSimpleClassName) {
- return ! db.readDeactivatedJobs().contains(jobSimpleClassName);
+ return ! db.readInactiveJobs().contains(jobSimpleClassName);
}
/** Set a job active or inactive */
public void setActive(String jobSimpleClassName, boolean active) {
- try (CuratorMutex lock = db.lockDeactivatedJobs()) {
- Set<String> deactivatedJobs = db.readDeactivatedJobs();
+ try (CuratorMutex lock = db.lockInactiveJobs()) {
+ Set<String> inactiveJobs = db.readInactiveJobs();
if (active)
- deactivatedJobs.remove(jobSimpleClassName);
+ inactiveJobs.remove(jobSimpleClassName);
else
- deactivatedJobs.add(jobSimpleClassName);
- db.writeDeactivatedJobs(deactivatedJobs);
+ inactiveJobs.add(jobSimpleClassName);
+ db.writeInactiveJobs(inactiveJobs);
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
index 970dbde9cc8..95466d1d4b1 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java
@@ -83,6 +83,8 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
metricsReporter.deconstruct();
}
+ public JobControl jobControl() { return jobControl; }
+
private static Optional<Duration> durationFromEnv(String envVariable) {
return Optional.ofNullable(System.getenv(envPrefix + envVariable)).map(Long::parseLong).map(Duration::ofSeconds);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
index 08d56c9cb42..544772ecb8f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
@@ -68,7 +68,7 @@ public class CuratorDatabaseClient {
curatorDatabase.create(root);
for (Node.State state : Node.State.values())
curatorDatabase.create(toPath(state));
- curatorDatabase.create(deactivatedJobsPath());
+ curatorDatabase.create(inactiveJobsPath());
}
/**
@@ -308,26 +308,26 @@ public class CuratorDatabaseClient {
return root.append("defaultFlavor").append(applicationId.serializedForm());
}
- public Set<String> readDeactivatedJobs() {
- return curatorDatabase.getData(deactivatedJobsPath())
+ public Set<String> readInactiveJobs() {
+ return curatorDatabase.getData(inactiveJobsPath())
.map(data -> stringSetSerializer.fromJson(data))
.orElse(Collections.emptySet());
}
- public void writeDeactivatedJobs(Set<String> deactivatedJobs) {
+ public void writeInactiveJobs(Set<String> inactiveJobs) {
NestedTransaction transaction = new NestedTransaction();
CuratorTransaction curatorTransaction = curatorDatabase.newCuratorTransactionIn(transaction);
- curatorTransaction.add(CuratorOperations.setData(deactivatedJobsPath().getAbsolute(),
- stringSetSerializer.toJson(deactivatedJobs)));
+ curatorTransaction.add(CuratorOperations.setData(inactiveJobsPath().getAbsolute(),
+ stringSetSerializer.toJson(inactiveJobs)));
transaction.commit();
}
- public CuratorMutex lockDeactivatedJobs() {
- return lock(deactivatedJobsPath(), defaultLockTimeout);
+ public CuratorMutex lockInactiveJobs() {
+ return lock(inactiveJobsPath(), defaultLockTimeout);
}
- private Path deactivatedJobsPath() {
- return root.append("deactivatedJobs");
+ private Path inactiveJobsPath() {
+ return root.append("inactiveJobs");
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/JobsResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/JobsResponse.java
new file mode 100644
index 00000000000..aa1f1438fb7
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/JobsResponse.java
@@ -0,0 +1,43 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.provision.restapi.v2;
+
+import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.JsonFormat;
+import com.yahoo.slime.Slime;
+import com.yahoo.vespa.hosted.provision.maintenance.JobControl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+
+/** A response containing maintenance job status */
+public class JobsResponse extends HttpResponse {
+
+ private final JobControl jobControl;
+
+ public JobsResponse(JobControl jobControl) {
+ super(200);
+ this.jobControl = jobControl;
+ }
+
+ @Override
+ public void render(OutputStream stream) throws IOException {
+ Slime slime = new Slime();
+ Cursor root = slime.setObject();
+
+ Cursor jobArray = root.setArray("jobs");
+ for (String jobName : jobControl.jobs())
+ jobArray.addObject().setString("name", jobName);
+
+ Cursor inactiveArray = root.setArray("inactive");
+ for (String jobName : jobControl.inactiveJobs())
+ inactiveArray.addString(jobName);
+
+ new JsonFormat(true).encode(stream, slime);
+ }
+
+ @Override
+ public String getContentType() { return "application/json"; }
+
+}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
index c126a1f29ec..1498ff10a81 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
@@ -16,6 +16,7 @@ import com.yahoo.vespa.hosted.provision.NoSuchNodeException;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.config.provision.NodeFlavors;
+import com.yahoo.vespa.hosted.provision.maintenance.NodeRepositoryMaintenance;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.filter.ApplicationFilter;
import com.yahoo.vespa.hosted.provision.node.filter.NodeFilter;
@@ -48,13 +49,16 @@ import static com.yahoo.vespa.config.SlimeUtils.optionalString;
public class NodesApiHandler extends LoggingRequestHandler {
private final NodeRepository nodeRepository;
+ private final NodeRepositoryMaintenance maintenance;
private final NodeFlavors nodeFlavors;
private static final String nodeTypeKey = "type";
- public NodesApiHandler(Executor executor, AccessLog accessLog, NodeRepository nodeRepository, NodeFlavors flavors) {
+ public NodesApiHandler(Executor executor, AccessLog accessLog, NodeRepository nodeRepository,
+ NodeRepositoryMaintenance maintenance, NodeFlavors flavors) {
super(executor, accessLog);
this.nodeRepository = nodeRepository;
+ this.maintenance = maintenance;
this.nodeFlavors = flavors;
}
@@ -84,13 +88,14 @@ public class NodesApiHandler extends LoggingRequestHandler {
private HttpResponse handleGET(HttpRequest request) {
String path = request.getUri().getPath();
- if (path.equals( "/nodes/v2/")) return ResourcesResponse.fromStrings(request.getUri(), "state", "node", "command");
+ if (path.equals( "/nodes/v2/")) return ResourcesResponse.fromStrings(request.getUri(), "state", "node", "command", "maintenance");
if (path.equals( "/nodes/v2/node/")) return new NodesResponse(ResponseType.nodeList, request, nodeRepository);
if (path.startsWith("/nodes/v2/node/")) return new NodesResponse(ResponseType.singleNode, request, nodeRepository);
if (path.equals( "/nodes/v2/state/")) return new NodesResponse(ResponseType.stateList, request, nodeRepository);
if (path.startsWith("/nodes/v2/state/")) return new NodesResponse(ResponseType.nodesInStateList, request, nodeRepository);
if (path.startsWith("/nodes/v2/acl/")) return new NodeAclResponse(request, nodeRepository);
if (path.equals( "/nodes/v2/command/")) return ResourcesResponse.fromStrings(request.getUri(), "restart", "reboot");
+ if (path.equals( "/nodes/v2/maintenance/")) return new JobsResponse(maintenance.jobControl());
throw new NotFoundException("Nothing at path '" + path + "'");
}
@@ -132,21 +137,34 @@ public class NodesApiHandler extends LoggingRequestHandler {
}
private HttpResponse handlePOST(HttpRequest request) {
- switch (request.getUri().getPath()) {
- case "/nodes/v2/command/restart" :
- int restartCount = nodeRepository.restart(toNodeFilter(request)).size();
- return new MessageResponse("Scheduled restart of " + restartCount + " matching nodes");
- case "/nodes/v2/command/reboot" :
- int rebootCount = nodeRepository.reboot(toNodeFilter(request)).size();
- return new MessageResponse("Scheduled reboot of " + rebootCount + " matching nodes");
- case "/nodes/v2/node" :
- int addedNodes = addNodes(request.getData());
- return new MessageResponse("Added " + addedNodes + " nodes to the provisioned state");
- default:
- throw new NotFoundException("Nothing at path '" + request.getUri().getPath() + "'");
+ String path = request.getUri().getPath();
+ if (path.equals("/nodes/v2/command/restart")) {
+ int restartCount = nodeRepository.restart(toNodeFilter(request)).size();
+ return new MessageResponse("Scheduled restart of " + restartCount + " matching nodes");
+ }
+ else if (path.equals("/nodes/v2/command/reboot")) {
+ int rebootCount = nodeRepository.reboot(toNodeFilter(request)).size();
+ return new MessageResponse("Scheduled reboot of " + rebootCount + " matching nodes");
+ }
+ else if (path.equals("/nodes/v2/node")) {
+ int addedNodes = addNodes(request.getData());
+ return new MessageResponse("Added " + addedNodes + " nodes to the provisioned state");
+ }
+ else if (path.startsWith("/nodes/v2/maintenance/inactive/")) {
+ return setActive(lastElement(path), false);
+ }
+ else {
+ throw new NotFoundException("Nothing at path '" + request.getUri().getPath() + "'");
}
}
+ private MessageResponse setActive(String jobName, boolean active) {
+ if ( ! maintenance.jobControl().jobs().contains(jobName))
+ throw new NotFoundException("No job named '" + jobName + "'");
+ maintenance.jobControl().setActive(jobName, active);
+ return new MessageResponse((active ? "Re-activated" : "Deactivated" ) + " job '" + jobName + "'");
+ }
+
private HttpResponse handleDELETE(HttpRequest request) {
String path = request.getUri().getPath();
if (path.startsWith("/nodes/v2/node/")) {
@@ -156,8 +174,13 @@ public class NodesApiHandler extends LoggingRequestHandler {
else
throw new NotFoundException("No node in the provisioned, parked or failed state with hostname " + hostname);
}
-
- throw new NotFoundException("Nothing at path '" + request.getUri().getPath() + "'");
+ else if (path.startsWith("/nodes/v2/maintenance/inactive/")) {
+ setActive(lastElement(path), true);
+ return new MessageResponse("Reactivated job '" + lastElement(path) + "'");
+ }
+ else {
+ throw new NotFoundException("Nothing at path '" + request.getUri().getPath() + "'");
+ }
}
private Node nodeFromRequest(HttpRequest request) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java
index 1239069c1a0..d383e90d184 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ContainerConfig.java
@@ -12,8 +12,15 @@ public class ContainerConfig {
public static final String servicesXmlV2(int port) {
return
"<jdisc version='1.0'>" +
+ " <component id='com.yahoo.test.ManualClock'/>" +
+ " <component id='com.yahoo.vespa.curator.mock.MockCurator'/>" +
+ " <component id='com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock'/>" +
+ " <component id='com.yahoo.vespa.hosted.provision.testutils.MockDeployer'/>" +
+ " <component id='com.yahoo.vespa.hosted.provision.testutils.TestHostLivenessTracker'/>" +
+ " <component id='com.yahoo.vespa.hosted.provision.testutils.ServiceMonitorStub'/>" +
" <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeFlavors'/>" +
" <component id='com.yahoo.vespa.hosted.provision.testutils.MockNodeRepository'/>" +
+ " <component id='com.yahoo.vespa.hosted.provision.maintenance.NodeRepositoryMaintenance'/>" +
" <handler id='com.yahoo.vespa.hosted.provision.restapi.v2.NodesApiHandler'>" +
" <binding>http://*/nodes/v2/*</binding>" +
" </handler>" +
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MockDeployer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java
index 377cb2e4443..e46797240f2 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MockDeployer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockDeployer.java
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.provision.maintenance;
+package com.yahoo.vespa.hosted.provision.testutils;
+import com.google.inject.Inject;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
@@ -12,6 +13,7 @@ import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import java.time.Duration;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -27,6 +29,12 @@ public class MockDeployer implements Deployer {
/** The number of redeployments done to this */
public int redeployments = 0;
+ @Inject
+ @SuppressWarnings("unused")
+ public MockDeployer() {
+ this(null, Collections.emptyMap());
+ }
+
/**
* Create a mock deployer which contains a substitute for an application repository, fullfilled to
* be able to call provision with the right parameters.
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index a8490076d5b..adfccd1f874 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -43,19 +43,14 @@ public class MockNodeRepository extends NodeRepository {
* Constructor
* @param flavors flavors to have in node repo
*/
- public MockNodeRepository(NodeFlavors flavors) throws Exception {
- super(flavors, mockCurator(), Clock.fixed(Instant.ofEpochMilli(123), ZoneId.of("Z")), Zone.defaultZone(),
+ public MockNodeRepository(MockCurator curator, NodeFlavors flavors) throws Exception {
+ super(flavors, curator, Clock.fixed(Instant.ofEpochMilli(123), ZoneId.of("Z")), Zone.defaultZone(),
new MockNameResolver().mockAnyLookup());
this.flavors = flavors;
+ curator.setConnectionSpec("cfg1:1234,cfg2:1234,cfg3:1234");
populate();
}
- private static Curator mockCurator() {
- MockCurator mockCurator = new MockCurator();
- mockCurator.setConnectionSpec("cfg1:1234,cfg2:1234,cfg3:1234");
- return mockCurator;
- }
-
private void populate() {
NodeRepositoryProvisioner provisioner = new NodeRepositoryProvisioner(this, flavors, Zone.defaultZone());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/OrchestratorMock.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/OrchestratorMock.java
new file mode 100644
index 00000000000..3de5278cd41
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/OrchestratorMock.java
@@ -0,0 +1,64 @@
+package com.yahoo.vespa.hosted.provision.testutils;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.orchestrator.ApplicationIdNotFoundException;
+import com.yahoo.vespa.orchestrator.ApplicationStateChangeDeniedException;
+import com.yahoo.vespa.orchestrator.BatchHostNameNotFoundException;
+import com.yahoo.vespa.orchestrator.BatchInternalErrorException;
+import com.yahoo.vespa.orchestrator.HostNameNotFoundException;
+import com.yahoo.vespa.orchestrator.Orchestrator;
+import com.yahoo.vespa.orchestrator.policy.BatchHostStateChangeDeniedException;
+import com.yahoo.vespa.orchestrator.policy.HostStateChangeDeniedException;
+import com.yahoo.vespa.orchestrator.status.ApplicationInstanceStatus;
+import com.yahoo.vespa.orchestrator.status.HostStatus;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author bratseth
+ */
+public class OrchestratorMock implements Orchestrator {
+
+ Set<ApplicationId> suspendedApplications = new HashSet<>();
+
+ @Override
+ public HostStatus getNodeStatus(HostName hostName) throws HostNameNotFoundException {
+ return null;
+ }
+
+ @Override
+ public void resume(HostName hostName) throws HostStateChangeDeniedException, HostNameNotFoundException {}
+
+ @Override
+ public void suspend(HostName hostName) throws HostStateChangeDeniedException, HostNameNotFoundException {}
+
+ @Override
+ public ApplicationInstanceStatus getApplicationInstanceStatus(ApplicationId appId) throws ApplicationIdNotFoundException {
+ return suspendedApplications.contains(appId)
+ ? ApplicationInstanceStatus.ALLOWED_TO_BE_DOWN : ApplicationInstanceStatus.NO_REMARKS;
+ }
+
+ @Override
+ public Set<ApplicationId> getAllSuspendedApplications() {
+ return null;
+ }
+
+ @Override
+ public void resume(ApplicationId appId) throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException {
+ suspendedApplications.remove(appId);
+ }
+
+ @Override
+ public void suspend(ApplicationId appId) throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException {
+ suspendedApplications.add(appId);
+ }
+
+ @Override
+ public void suspendAll(HostName parentHostname, List<HostName> hostNames) throws BatchInternalErrorException, BatchHostStateChangeDeniedException, BatchHostNameNotFoundException {
+ throw new RuntimeException("Not implemented");
+ }
+
+}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ServiceMonitorStub.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ServiceMonitorStub.java
new file mode 100644
index 00000000000..983f81be126
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/ServiceMonitorStub.java
@@ -0,0 +1,91 @@
+package com.yahoo.vespa.hosted.provision.testutils;
+
+import com.google.inject.Inject;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.vespa.applicationmodel.ApplicationInstance;
+import com.yahoo.vespa.applicationmodel.ApplicationInstanceId;
+import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
+import com.yahoo.vespa.applicationmodel.ClusterId;
+import com.yahoo.vespa.applicationmodel.ConfigId;
+import com.yahoo.vespa.applicationmodel.HostName;
+import com.yahoo.vespa.applicationmodel.ServiceCluster;
+import com.yahoo.vespa.applicationmodel.ServiceInstance;
+import com.yahoo.vespa.applicationmodel.ServiceType;
+import com.yahoo.vespa.applicationmodel.TenantId;
+import com.yahoo.vespa.hosted.provision.Node;
+import com.yahoo.vespa.hosted.provision.NodeRepository;
+import com.yahoo.vespa.service.monitor.ServiceMonitor;
+import com.yahoo.vespa.service.monitor.ServiceMonitorStatus;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author bratseth
+ */
+public class ServiceMonitorStub implements ServiceMonitor {
+
+ private final Map<ApplicationId, MockDeployer.ApplicationContext> apps;
+ private final NodeRepository nodeRepository;
+
+ private Set<String> downHosts = new HashSet<>();
+ private boolean statusIsKnown = true;
+
+ /** Create a service monitor where all nodes are initially up */
+ @Inject
+ @SuppressWarnings("unused")
+ public ServiceMonitorStub(NodeRepository nodeRepository) {
+ this(Collections.emptyMap(), nodeRepository);
+ }
+
+ /** Create a service monitor where all nodes are initially up */
+ public ServiceMonitorStub(Map<ApplicationId, MockDeployer.ApplicationContext> apps, NodeRepository nodeRepository) {
+ this.apps = apps;
+ this.nodeRepository = nodeRepository;
+ }
+
+ public void setHostDown(String hostname) {
+ downHosts.add(hostname);
+ }
+
+ public void setHostUp(String hostname) {
+ downHosts.remove(hostname);
+ }
+
+ public void setStatusIsKnown(boolean statusIsKnown) {
+ this.statusIsKnown = statusIsKnown;
+ }
+
+ private ServiceMonitorStatus getHostStatus(String hostname) {
+ if (!statusIsKnown) return ServiceMonitorStatus.NOT_CHECKED;
+ if (downHosts.contains(hostname)) return ServiceMonitorStatus.DOWN;
+ return ServiceMonitorStatus.UP;
+ }
+
+ @Override
+ public Map<ApplicationInstanceReference, ApplicationInstance<ServiceMonitorStatus>> queryStatusOfAllApplicationInstances() {
+ // Convert apps information to the response payload to return
+ Map<ApplicationInstanceReference, ApplicationInstance<ServiceMonitorStatus>> status = new HashMap<>();
+ for (Map.Entry<ApplicationId, MockDeployer.ApplicationContext> app : apps.entrySet()) {
+ Set<ServiceInstance<ServiceMonitorStatus>> serviceInstances = new HashSet<>();
+ for (Node node : nodeRepository.getNodes(app.getValue().id(), Node.State.active)) {
+ serviceInstances.add(new ServiceInstance<>(new ConfigId("configid"),
+ new HostName(node.hostname()),
+ getHostStatus(node.hostname())));
+ }
+ Set<ServiceCluster<ServiceMonitorStatus>> serviceClusters = new HashSet<>();
+ serviceClusters.add(new ServiceCluster<>(new ClusterId(app.getValue().cluster().id().value()),
+ new ServiceType("serviceType"),
+ serviceInstances));
+ TenantId tenantId = new TenantId(app.getKey().tenant().value());
+ ApplicationInstanceId applicationInstanceId = new ApplicationInstanceId(app.getKey().application().value());
+ status.put(new ApplicationInstanceReference(tenantId, applicationInstanceId),
+ new ApplicationInstance<>(tenantId, applicationInstanceId, serviceClusters));
+ }
+ return status;
+ }
+
+}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/TestHostLivenessTracker.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/TestHostLivenessTracker.java
new file mode 100644
index 00000000000..e0ad7238f4a
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/TestHostLivenessTracker.java
@@ -0,0 +1,31 @@
+package com.yahoo.vespa.hosted.provision.testutils;
+
+import com.yahoo.config.provision.HostLivenessTracker;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/** This is a fully functional implementation */
+public class TestHostLivenessTracker implements HostLivenessTracker {
+
+ private final Clock clock;
+ private final Map<String, Instant> lastRequestFromHost = new HashMap<>();
+
+ public TestHostLivenessTracker(Clock clock) {
+ this.clock = clock;
+ }
+
+ @Override
+ public void receivedRequestFrom(String hostname) {
+ lastRequestFromHost.put(hostname, clock.instant());
+ }
+
+ @Override
+ public Optional<Instant> lastRequestFrom(String hostname) {
+ return Optional.ofNullable(lastRequestFromHost.get(hostname));
+ }
+
+}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
index a07deff3543..47055af075e 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveAndFailedExpirerTest.java
@@ -16,6 +16,7 @@ import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.node.History;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import org.junit.Test;
import java.time.Duration;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
index 4e51138eceb..378c1bf554b 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
@@ -7,7 +7,6 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
-import com.yahoo.config.provision.HostLivenessTracker;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
@@ -17,16 +16,6 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.test.ManualClock;
import com.yahoo.transaction.NestedTransaction;
-import com.yahoo.vespa.applicationmodel.ApplicationInstance;
-import com.yahoo.vespa.applicationmodel.ApplicationInstanceId;
-import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
-import com.yahoo.vespa.applicationmodel.ClusterId;
-import com.yahoo.vespa.applicationmodel.ConfigId;
-import com.yahoo.vespa.applicationmodel.HostName;
-import com.yahoo.vespa.applicationmodel.ServiceCluster;
-import com.yahoo.vespa.applicationmodel.ServiceInstance;
-import com.yahoo.vespa.applicationmodel.ServiceType;
-import com.yahoo.vespa.applicationmodel.TenantId;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.curator.mock.MockCurator;
import com.yahoo.vespa.curator.transaction.CuratorTransaction;
@@ -34,23 +23,14 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.FlavorConfigBuilder;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
-import com.yahoo.vespa.orchestrator.ApplicationIdNotFoundException;
-import com.yahoo.vespa.orchestrator.ApplicationStateChangeDeniedException;
-import com.yahoo.vespa.orchestrator.BatchHostNameNotFoundException;
-import com.yahoo.vespa.orchestrator.BatchInternalErrorException;
-import com.yahoo.vespa.orchestrator.HostNameNotFoundException;
+import com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock;
+import com.yahoo.vespa.hosted.provision.testutils.ServiceMonitorStub;
+import com.yahoo.vespa.hosted.provision.testutils.TestHostLivenessTracker;
import com.yahoo.vespa.orchestrator.Orchestrator;
-import com.yahoo.vespa.orchestrator.policy.BatchHostStateChangeDeniedException;
-import com.yahoo.vespa.orchestrator.policy.HostStateChangeDeniedException;
-import com.yahoo.vespa.orchestrator.status.ApplicationInstanceStatus;
-import com.yahoo.vespa.orchestrator.status.HostStatus;
-import com.yahoo.vespa.service.monitor.ServiceMonitor;
-import com.yahoo.vespa.service.monitor.ServiceMonitorStatus;
-
-import java.time.Clock;
+
import java.time.Duration;
-import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -59,7 +39,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Set;
import static org.junit.Assert.assertEquals;
@@ -265,125 +244,4 @@ public class NodeFailTester {
return highestIndex;
}
- /** This is a fully functional implementation */
- private static class TestHostLivenessTracker implements HostLivenessTracker {
-
- private final Clock clock;
- private final Map<String, Instant> lastRequestFromHost = new HashMap<>();
-
- public TestHostLivenessTracker(Clock clock) {
- this.clock = clock;
- }
-
- @Override
- public void receivedRequestFrom(String hostname) {
- lastRequestFromHost.put(hostname, clock.instant());
- }
-
- @Override
- public Optional<Instant> lastRequestFrom(String hostname) {
- return Optional.ofNullable(lastRequestFromHost.get(hostname));
- }
-
- }
-
- public static class ServiceMonitorStub implements ServiceMonitor {
-
- private final Map<ApplicationId, MockDeployer.ApplicationContext> apps;
- private final NodeRepository nodeRepository;
-
- private Set<String> downHosts = new HashSet<>();
- private boolean statusIsKnown = true;
-
- /** Create a service monitor where all nodes are initially up */
- public ServiceMonitorStub(Map<ApplicationId, MockDeployer.ApplicationContext> apps, NodeRepository nodeRepository) {
- this.apps = apps;
- this.nodeRepository = nodeRepository;
- }
-
- public void setHostDown(String hostname) {
- downHosts.add(hostname);
- }
-
- public void setHostUp(String hostname) {
- downHosts.remove(hostname);
- }
-
- public void setStatusIsKnown(boolean statusIsKnown) {
- this.statusIsKnown = statusIsKnown;
- }
-
- private ServiceMonitorStatus getHostStatus(String hostname) {
- if ( ! statusIsKnown) return ServiceMonitorStatus.NOT_CHECKED;
- if (downHosts.contains(hostname)) return ServiceMonitorStatus.DOWN;
- return ServiceMonitorStatus.UP;
- }
-
- @Override
- public Map<ApplicationInstanceReference, ApplicationInstance<ServiceMonitorStatus>> queryStatusOfAllApplicationInstances() {
- // Convert apps information to the response payload to return
- Map<ApplicationInstanceReference, ApplicationInstance<ServiceMonitorStatus>> status = new HashMap<>();
- for (Map.Entry<ApplicationId, MockDeployer.ApplicationContext> app : apps.entrySet()) {
- Set<ServiceInstance<ServiceMonitorStatus>> serviceInstances = new HashSet<>();
- for (Node node : nodeRepository.getNodes(app.getValue().id(), Node.State.active)) {
- serviceInstances.add(new ServiceInstance<>(new ConfigId("configid"),
- new HostName(node.hostname()),
- getHostStatus(node.hostname())));
- }
- Set<ServiceCluster<ServiceMonitorStatus>> serviceClusters = new HashSet<>();
- serviceClusters.add(new ServiceCluster<>(new ClusterId(app.getValue().cluster().id().value()),
- new ServiceType("serviceType"),
- serviceInstances));
- TenantId tenantId = new TenantId(app.getKey().tenant().value());
- ApplicationInstanceId applicationInstanceId = new ApplicationInstanceId(app.getKey().application().value());
- status.put(new ApplicationInstanceReference(tenantId, applicationInstanceId),
- new ApplicationInstance<>(tenantId, applicationInstanceId, serviceClusters));
- }
- return status;
- }
-
- }
-
- class OrchestratorMock implements Orchestrator {
-
- Set<ApplicationId> suspendedApplications = new HashSet<>();
-
- @Override
- public HostStatus getNodeStatus(HostName hostName) throws HostNameNotFoundException {
- return null;
- }
-
- @Override
- public void resume(HostName hostName) throws HostStateChangeDeniedException, HostNameNotFoundException {}
-
- @Override
- public void suspend(HostName hostName) throws HostStateChangeDeniedException, HostNameNotFoundException {}
-
- @Override
- public ApplicationInstanceStatus getApplicationInstanceStatus(ApplicationId appId) throws ApplicationIdNotFoundException {
- return suspendedApplications.contains(appId)
- ? ApplicationInstanceStatus.ALLOWED_TO_BE_DOWN : ApplicationInstanceStatus.NO_REMARKS;
- }
-
- @Override
- public Set<ApplicationId> getAllSuspendedApplications() {
- return null;
- }
-
- @Override
- public void resume(ApplicationId appId) throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException {
- suspendedApplications.remove(appId);
- }
-
- @Override
- public void suspend(ApplicationId appId) throws ApplicationStateChangeDeniedException, ApplicationIdNotFoundException {
- suspendedApplications.add(appId);
- }
-
- @Override
- public void suspendAll(HostName parentHostname, List<HostName> hostNames) throws BatchInternalErrorException, BatchHostStateChangeDeniedException, BatchHostNameNotFoundException {
- throw new RuntimeException("Not implemented");
- }
- }
-
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
index 5ce876bf12c..91ce0a8ef59 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainerTest.java
@@ -25,6 +25,7 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.FlavorConfigBuilder;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
import org.junit.Test;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
index 844571acce5..69ef4744001 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainerTest.java
@@ -27,6 +27,7 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.FlavorConfigBuilder;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
import org.junit.Before;
import org.junit.Test;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
index 085f711058b..f034490b3f7 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/RetiredExpirerTest.java
@@ -23,6 +23,7 @@ import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.vespa.hosted.provision.provisioning.NodeRepositoryProvisioner;
import com.yahoo.vespa.hosted.provision.testutils.FlavorConfigBuilder;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.testutils.MockNameResolver;
import org.junit.Test;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
index b4f17cc003c..6ef0e6ab01f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
@@ -11,7 +11,7 @@ import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.maintenance.JobControl;
-import com.yahoo.vespa.hosted.provision.maintenance.MockDeployer;
+import com.yahoo.vespa.hosted.provision.testutils.MockDeployer;
import com.yahoo.vespa.hosted.provision.maintenance.RetiredExpirer;
import org.junit.Ignore;
import org.junit.Test;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodeStateSerializerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodeStateSerializerTest.java
index c4f96b0709a..de7a9bac878 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodeStateSerializerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodeStateSerializerTest.java
@@ -8,38 +8,39 @@ import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* @author bakksjo
*/
public class NodeStateSerializerTest {
+
@Test
public void allStatesHaveASerializedForm() {
for (Node.State nodeState : Node.State.values()) {
- assertThat(NodeStateSerializer.wireNameOf(nodeState), is(notNullValue()));
+ assertNotNull(NodeStateSerializer.wireNameOf(nodeState));
}
}
@Test
public void wireNamesDoNotOverlap() {
- final Set<String> wireNames = new HashSet<>();
+ Set<String> wireNames = new HashSet<>();
for (Node.State nodeState : Node.State.values()) {
wireNames.add(NodeStateSerializer.wireNameOf(nodeState));
}
- assertThat(wireNames.size(), is(Node.State.values().length));
+ assertEquals(Node.State.values().length, wireNames.size());
}
@Test
public void serializationAndDeserializationIsSymmetric() {
for (Node.State nodeState : Node.State.values()) {
- final String serialized = NodeStateSerializer.wireNameOf(nodeState);
- final Node.State deserialized = NodeStateSerializer.fromWireName(serialized)
+ String serialized = NodeStateSerializer.wireNameOf(nodeState);
+ Node.State deserialized = NodeStateSerializer.fromWireName(serialized)
.orElseThrow(() -> new RuntimeException(
"Cannot deserialize '" + serialized + "', serialized form of " + nodeState.name()));
- assertThat(deserialized, is(nodeState));
+ assertEquals(nodeState, deserialized);
}
}
+
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/maintenance.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/maintenance.json
new file mode 100644
index 00000000000..3ee004d1e29
--- /dev/null
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/maintenance.json
@@ -0,0 +1,10 @@
+{
+ "jobs": [
+ {
+ "name" : "Job1"
+ }
+ ],
+ "inactive" : [
+
+ ]
+} \ No newline at end of file
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/root.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/root.json
index 9648c059af6..4224718ab06 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/root.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/root.json
@@ -8,6 +8,9 @@
},
{
"url": "http://localhost:8080/nodes/v2/command/"
+ },
+ {
+ "url": "http://localhost:8080/nodes/v2/maintenance/"
}
]
} \ No newline at end of file
diff --git a/testutil/pom.xml b/testutil/pom.xml
index bd46d2e4c16..8d132737852 100644
--- a/testutil/pom.xml
+++ b/testutil/pom.xml
@@ -20,6 +20,11 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>inject</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<scope>compile</scope>
diff --git a/testutil/src/main/java/com/yahoo/test/ManualClock.java b/testutil/src/main/java/com/yahoo/test/ManualClock.java
index 1ffc7aa77da..e3ed647e03b 100644
--- a/testutil/src/main/java/com/yahoo/test/ManualClock.java
+++ b/testutil/src/main/java/com/yahoo/test/ManualClock.java
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.test;
+import com.google.inject.Inject;
import java.time.Clock;
import java.time.Instant;
import java.time.LocalDateTime;
@@ -14,6 +15,7 @@ public class ManualClock extends Clock {
private Instant currentTime = Instant.now();
+ @Inject
public ManualClock() {}
public ManualClock(String utcIsoTime) {
diff --git a/vespalog/src/main/java/com/yahoo/log/VespaFormatter.java b/vespalog/src/main/java/com/yahoo/log/VespaFormatter.java
index ee0f6e90b7c..b6a63c52321 100644
--- a/vespalog/src/main/java/com/yahoo/log/VespaFormatter.java
+++ b/vespalog/src/main/java/com/yahoo/log/VespaFormatter.java
@@ -137,7 +137,8 @@ public class VespaFormatter extends SimpleFormatter {
private void appendException(Throwable throwable, StringBuilder builder) {
if (throwable == null)
return;
-
+//throwable.printStackTrace();
+if (1==1) return;
String escapedStackTrace = VespaFormat.escape(stackTrace(throwable));
builder.append("\\n").append("exception=").append("\\n").append(escapedStackTrace);
}
@@ -169,4 +170,36 @@ public class VespaFormatter extends SimpleFormatter {
public String getServiceName () {
return serviceName;
}
+
+
+ public static String toMessageString(Throwable t) {
+ StringBuilder b = new StringBuilder();
+ String lastMessage = null;
+ String message;
+ for (; t != null; t = t.getCause()) {
+ message = getMessage(t);
+ if (message == null) continue;
+ if (message.equals(lastMessage)) continue;
+ if (b.length() > 0) {
+ b.append(": ");
+ }
+ b.append(message);
+ lastMessage = message;
+ }
+ return b.toString();
+ }
+
+ /** Returns a useful message from *this* exception, or null if there is nothing useful to return */
+ private static String getMessage(Throwable t) {
+ String message = t.getMessage();
+ if (t.getCause() == null) {
+ if (message == null) return t.getClass().getSimpleName();
+ } else {
+ if (message == null) return null;
+ //if (message.equals(t.getCause().getClass().getName() + ": " + t.getCause().getMessage())) return null;
+ }
+ return message;
+ }
+
+
}
diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java
index 4615eb4e34a..2e70d1d736b 100644
--- a/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java
+++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java
@@ -1,6 +1,7 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.curator.mock;
+import com.google.inject.Inject;
import com.yahoo.collections.Pair;
import com.yahoo.path.Path;
import static com.yahoo.vespa.curator.mock.MemoryFileSystem.Node;
@@ -115,6 +116,7 @@ public class MockCurator extends Curator {
private final CuratorFramework curatorFramework;
/** Creates a mock curator with stable ordering */
+ @Inject
public MockCurator() {
this(true);
}