diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2018-02-16 08:51:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-16 08:51:06 +0100 |
commit | 5d9b3466e7bfa41e1a7855576d1bb32d83f5b9e0 (patch) | |
tree | 485795d732fe441738a5c50c6f16fddf31e8ba1e /node-admin/src/test/java | |
parent | 61c5c820c167cd26d9544380af755ed46d267f7b (diff) | |
parent | 1da246219d581219b7d558cbcc3740baf224161a (diff) |
Merge pull request #5050 from vespa-engine/freva/update-config-server-certificate
Update config server certificate in node-admin
Diffstat (limited to 'node-admin/src/test/java')
10 files changed, 221 insertions, 62 deletions
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/ConfigServerHttpRequestExecutorTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerApiImplTest.java index 175d3a9a051..f39a64d2dee 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/ConfigServerHttpRequestExecutorTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerApiImplTest.java @@ -1,5 +1,5 @@ // 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.util; +package com.yahoo.vespa.hosted.node.admin.configserver; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -34,7 +34,7 @@ import static org.mockito.Mockito.when; * * @author dybis */ -public class ConfigServerHttpRequestExecutorTest { +public class ConfigServerApiImplTest { @JsonIgnoreProperties(ignoreUnknown = true) public static class TestPojo { @@ -49,7 +49,7 @@ public class ConfigServerHttpRequestExecutorTest { private final List<URI> configServers = Arrays.asList(URI.create(uri1), URI.create(uri2)); private final StringBuilder mockLog = new StringBuilder(); - private ConfigServerHttpRequestExecutor executor; + private ConfigServerApiImpl executor; private int mockReturnCode = 200; @Before @@ -72,7 +72,7 @@ public class ConfigServerHttpRequestExecutorTest { return response; }); - executor = new ConfigServerHttpRequestExecutor(configServers, httpMock); + executor = new ConfigServerApiImpl(configServers, httpMock); } @Test diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherTest.java new file mode 100644 index 00000000000..f9f8b230154 --- /dev/null +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/certificate/ConfigServerKeyStoreRefresherTest.java @@ -0,0 +1,162 @@ +// Copyright 2018 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.configserver.certificate; + +import com.yahoo.test.ManualClock; +import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi; +import com.yahoo.vespa.hosted.node.admin.util.KeyStoreOptions; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.cert.X509Certificate; +import java.time.Duration; +import java.util.Date; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +/** + * @author freva + */ +public class ConfigServerKeyStoreRefresherTest { + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + private final ManualClock clock = new ManualClock(); + private final String commonName = "CertificateRefresherTest"; + private final Duration certificateExpiration = Duration.ofDays(6); + private final ConfigServerApi configServerApi = mock(ConfigServerApi.class); + private final Runnable keyStoreUpdatedCallback = mock(Runnable.class); + private final ScheduledExecutorService executor = mock(ScheduledExecutorService.class); + private KeyStoreOptions keyStoreOptions; + + @Before + public void setup() { + keyStoreOptions = new KeyStoreOptions( + tempFolder.getRoot().toPath().resolve("some/path/keystore.p12"), new char[0], "PKCS12", null); + } + + @Test + public void manually_trigger_certificate_refresh() throws Exception { + X509Certificate firstCertificate = mockConfigServerCertificateSigning(1); + + ConfigServerKeyStoreRefresher keyStoreRefresher = new ConfigServerKeyStoreRefresher( + keyStoreOptions, keyStoreUpdatedCallback, configServerApi, executor, clock, commonName); + + // No keystore previously existed, so a new one should be written + assertTrue(keyStoreRefresher.refreshKeyStoreIfNeeded()); + assertEquals(firstCertificate, keyStoreRefresher.getConfigServerCertificate()); + + // Calling it again before a third of certificate lifetime has passed has no effect + assertFalse(keyStoreRefresher.refreshKeyStoreIfNeeded()); + assertEquals(firstCertificate, keyStoreRefresher.getConfigServerCertificate()); + + // After a third of the expiration time passes, we should refresh the certificate + clock.advance(certificateExpiration.dividedBy(3).plusSeconds(1)); + X509Certificate secondCertificate = mockConfigServerCertificateSigning(2); + assertTrue(keyStoreRefresher.refreshKeyStoreIfNeeded()); + assertEquals(secondCertificate, keyStoreRefresher.getConfigServerCertificate()); + + verify(configServerApi, times(2)) + .post(eq(ConfigServerKeyStoreRefresher.CONFIG_SERVER_CERTIFICATE_SIGNING_PATH), any(), any()); + + // We're just triggering refresh manually, so callback and executor should not have been touched + verifyZeroInteractions(keyStoreUpdatedCallback); + verifyZeroInteractions(executor); + } + + @Test + public void certificate_refresh_schedule_test() throws Exception { + ConfigServerKeyStoreRefresher keyStoreRefresher = new ConfigServerKeyStoreRefresher( + keyStoreOptions, keyStoreUpdatedCallback, configServerApi, executor, clock, commonName); + + // No keystore exist, so refresh once + mockConfigServerCertificateSigning(1); + assertTrue(keyStoreRefresher.refreshKeyStoreIfNeeded()); + + // Start automatic refreshment, since keystore was just written, next check should be in 1/3rd of + // certificate lifetime, which is in 2 days. + keyStoreRefresher.start(); + Duration nextExpectedExecution = Duration.ofDays(2); + verify(executor, times(1)).schedule(any(Runnable.class), eq(nextExpectedExecution.getSeconds()), eq(TimeUnit.SECONDS)); + + // First automatic refreshment goes without any problems + clock.advance(nextExpectedExecution); + mockConfigServerCertificateSigning(2); + keyStoreRefresher.refresh(); + verify(executor, times(2)).schedule(any(Runnable.class), eq(nextExpectedExecution.getSeconds()), eq(TimeUnit.SECONDS)); + verify(keyStoreUpdatedCallback).run(); + + // We fail to refresh the certificate, wait minimum amount of time and try again + clock.advance(nextExpectedExecution); + mockConfigServerCertificateSigningFailure(new RuntimeException()); + keyStoreRefresher.refresh(); + nextExpectedExecution = Duration.ofSeconds(ConfigServerKeyStoreRefresher.MINIMUM_SECONDS_BETWEEN_REFRESH_RETRY); + verify(executor, times(1)).schedule(any(Runnable.class), eq(nextExpectedExecution.getSeconds()), eq(TimeUnit.SECONDS)); + + clock.advance(nextExpectedExecution); + keyStoreRefresher.refresh(); + verify(executor, times(2)).schedule(any(Runnable.class), eq(nextExpectedExecution.getSeconds()), eq(TimeUnit.SECONDS)); + verifyNoMoreInteractions(keyStoreUpdatedCallback); // Callback not called after the last 2 failures + + clock.advance(nextExpectedExecution); + mockConfigServerCertificateSigning(3); + keyStoreRefresher.refresh(); + nextExpectedExecution = Duration.ofDays(2); + verify(executor, times(3)).schedule(any(Runnable.class), eq(nextExpectedExecution.getSeconds()), eq(TimeUnit.SECONDS)); + verify(keyStoreUpdatedCallback, times(2)).run(); + } + + private X509Certificate mockConfigServerCertificateSigning(int serial) throws Exception { + X509Certificate certificate = makeCertificate(serial); + + when(configServerApi.post(eq(ConfigServerKeyStoreRefresher.CONFIG_SERVER_CERTIFICATE_SIGNING_PATH), any(), any())) + .thenReturn(new CertificateSerializedPayload(certificate)); + return certificate; + } + + private void mockConfigServerCertificateSigningFailure(Exception exception) throws Exception { + when(configServerApi.post(eq(ConfigServerKeyStoreRefresher.CONFIG_SERVER_CERTIFICATE_SIGNING_PATH), any(), any())) + .thenThrow(exception); + } + + private X509Certificate makeCertificate(int serial) throws Exception { + try { + KeyPair keyPair = ConfigServerKeyStoreRefresher.generateKeyPair(); + X500Name subject = new X500Name("CN=" + commonName); + Date notBefore = Date.from(clock.instant()); + Date notAfter = Date.from(clock.instant().plus(certificateExpiration)); + + JcaX509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(subject, + BigInteger.valueOf(serial), notBefore, notAfter, subject, keyPair.getPublic()); + ContentSigner sigGen = new JcaContentSignerBuilder(ConfigServerKeyStoreRefresher.SIGNER_ALGORITHM) + .build(keyPair.getPrivate()); + return new JcaX509CertificateConverter() + .setProvider(new BouncyCastleProvider()) + .getCertificate(certGen.build(sigGen)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +}
\ No newline at end of file diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/noderepository/NodeRepositoryImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepositoryImplTest.java index 949b4ccdf78..85e101714e8 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/noderepository/NodeRepositoryImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeRepositoryImplTest.java @@ -1,13 +1,13 @@ // 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.noderepository; +package com.yahoo.vespa.hosted.node.admin.configserver.noderepository; import com.yahoo.application.Networking; import com.yahoo.application.container.JDisc; import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; import com.yahoo.vespa.hosted.dockerapi.DockerImage; +import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApiImpl; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAttributes; -import com.yahoo.vespa.hosted.node.admin.util.ConfigServerHttpRequestExecutor; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.testutils.ContainerConfig; @@ -36,7 +36,7 @@ import static org.junit.Assert.fail; */ public class NodeRepositoryImplTest { private JDisc container; - private ConfigServerHttpRequestExecutor requestExecutor; + private ConfigServerApiImpl configServerApi; private int findRandomOpenPort() throws IOException { @@ -63,8 +63,7 @@ public class NodeRepositoryImplTest { try { final int port = findRandomOpenPort(); container = JDisc.fromServicesXml(ContainerConfig.servicesXmlV2(port), Networking.enable); - requestExecutor = ConfigServerHttpRequestExecutor.create( - Collections.singleton(URI.create("http://127.0.0.1:" + port)), Optional.empty(), Optional.empty(), Optional.empty()); + configServerApi = new ConfigServerApiImpl(Collections.singleton(URI.create("http://127.0.0.1:" + port))); return; } catch (RuntimeException e) { lastException = e; @@ -75,7 +74,7 @@ public class NodeRepositoryImplTest { private void waitForJdiscContainerToServe() throws InterruptedException { Instant start = Instant.now(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); while (Instant.now().minusSeconds(120).isBefore(start)) { try { nodeRepositoryApi.getContainersToRun("foobar"); @@ -95,9 +94,9 @@ public class NodeRepositoryImplTest { } @Test - public void testGetContainersToRunApi() throws IOException, InterruptedException { + public void testGetContainersToRunApi() throws InterruptedException { waitForJdiscContainerToServe(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); String dockerHostHostname = "dockerhost1.yahoo.com"; final List<ContainerNodeSpec> containersToRun = nodeRepositoryApi.getContainersToRun(dockerHostHostname); @@ -116,7 +115,7 @@ public class NodeRepositoryImplTest { @Test public void testGetContainer() throws InterruptedException, IOException { waitForJdiscContainerToServe(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); String hostname = "host4.yahoo.com"; Optional<ContainerNodeSpec> nodeSpec = nodeRepositoryApi.getContainerNodeSpec(hostname); assertThat(nodeSpec.isPresent(), is(true)); @@ -126,7 +125,7 @@ public class NodeRepositoryImplTest { @Test public void testGetContainerForNonExistingNode() throws InterruptedException, IOException { waitForJdiscContainerToServe(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); String hostname = "host-that-does-not-exist"; Optional<ContainerNodeSpec> nodeSpec = nodeRepositoryApi.getContainerNodeSpec(hostname); assertFalse(nodeSpec.isPresent()); @@ -135,7 +134,7 @@ public class NodeRepositoryImplTest { @Test public void testUpdateNodeAttributes() throws InterruptedException, IOException { waitForJdiscContainerToServe(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); String hostname = "host4.yahoo.com"; nodeRepositoryApi.updateNodeAttributes( hostname, @@ -148,7 +147,7 @@ public class NodeRepositoryImplTest { @Test(expected = RuntimeException.class) public void testUpdateNodeAttributesWithBadValue() throws InterruptedException, IOException { waitForJdiscContainerToServe(); - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); String hostname = "host4.yahoo.com"; nodeRepositoryApi.updateNodeAttributes( hostname, @@ -160,7 +159,7 @@ public class NodeRepositoryImplTest { @Test public void testMarkAsReady() throws InterruptedException, IOException { - NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(requestExecutor); + NodeRepository nodeRepositoryApi = new NodeRepositoryImpl(configServerApi); waitForJdiscContainerToServe(); nodeRepositoryApi.markAsDirty("host5.yahoo.com"); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/orchestrator/OrchestratorImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/orchestrator/OrchestratorImplTest.java index 779a0a6a376..2d355c93c09 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/orchestrator/OrchestratorImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/configserver/orchestrator/OrchestratorImplTest.java @@ -1,8 +1,8 @@ // 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.orchestrator; +package com.yahoo.vespa.hosted.node.admin.configserver.orchestrator; -import com.yahoo.vespa.hosted.node.admin.util.ConfigServerHttpRequestExecutor; -import com.yahoo.vespa.hosted.node.admin.util.HttpException; +import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApiImpl; +import com.yahoo.vespa.hosted.node.admin.configserver.HttpException; import com.yahoo.vespa.orchestrator.restapi.wire.BatchHostSuspendRequest; import com.yahoo.vespa.orchestrator.restapi.wire.BatchOperationResult; import com.yahoo.vespa.orchestrator.restapi.wire.HostStateChangeDenialReason; @@ -23,12 +23,12 @@ import static org.mockito.Mockito.when; public class OrchestratorImplTest { private static final String hostName = "host123.yahoo.com"; - private final ConfigServerHttpRequestExecutor requestExecutor = mock(ConfigServerHttpRequestExecutor.class); - private final OrchestratorImpl orchestrator = new OrchestratorImpl(requestExecutor); + private final ConfigServerApiImpl configServerApi = mock(ConfigServerApiImpl.class); + private final OrchestratorImpl orchestrator = new OrchestratorImpl(configServerApi); @Test public void testSuspendCall() { - when(requestExecutor.put( + when(configServerApi.put( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_API + "/" + hostName+ "/suspended", Optional.empty(), UpdateHostResponse.class @@ -39,7 +39,7 @@ public class OrchestratorImplTest { @Test(expected=OrchestratorException.class) public void testSuspendCallWithFailureReason() { - when(requestExecutor.put( + when(configServerApi.put( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_API + "/" + hostName+ "/suspended", Optional.empty(), UpdateHostResponse.class @@ -50,7 +50,7 @@ public class OrchestratorImplTest { @Test(expected=OrchestratorNotFoundException.class) public void testSuspendCallWithNotFound() { - when(requestExecutor.put( + when(configServerApi.put( any(String.class), any(), any() @@ -61,7 +61,7 @@ public class OrchestratorImplTest { @Test(expected=RuntimeException.class) public void testSuspendCallWithSomeOtherException() { - when(requestExecutor.put( + when(configServerApi.put( any(String.class), any(), any() @@ -73,7 +73,7 @@ public class OrchestratorImplTest { @Test public void testResumeCall() { - when(requestExecutor.delete( + when(configServerApi.delete( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_API + "/" + hostName+ "/suspended", UpdateHostResponse.class )).thenReturn(new UpdateHostResponse(hostName, null)); @@ -83,7 +83,7 @@ public class OrchestratorImplTest { @Test(expected=OrchestratorException.class) public void testResumeCallWithFailureReason() { - when(requestExecutor.delete( + when(configServerApi.delete( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_API + "/" + hostName+ "/suspended", UpdateHostResponse.class )).thenReturn(new UpdateHostResponse(hostName, new HostStateChangeDenialReason("hostname", "fail"))); @@ -93,7 +93,7 @@ public class OrchestratorImplTest { @Test(expected=OrchestratorNotFoundException.class) public void testResumeCallWithNotFound() { - when(requestExecutor.delete( + when(configServerApi.delete( any(String.class), any() )).thenThrow(new HttpException.NotFoundException("Not Found")); @@ -103,7 +103,7 @@ public class OrchestratorImplTest { @Test(expected=RuntimeException.class) public void testResumeCallWithSomeOtherException() { - when(requestExecutor.put( + when(configServerApi.put( any(String.class), any(), any() @@ -118,7 +118,7 @@ public class OrchestratorImplTest { String parentHostName = "host1.test.yahoo.com"; List<String> hostNames = Arrays.asList("a1.host1.test.yahoo.com", "a2.host1.test.yahoo.com"); - when(requestExecutor.put( + when(configServerApi.put( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_SUSPENSION_API, Optional.of(new BatchHostSuspendRequest(parentHostName, hostNames)), BatchOperationResult.class @@ -133,7 +133,7 @@ public class OrchestratorImplTest { List<String> hostNames = Arrays.asList("a1.host1.test.yahoo.com", "a2.host1.test.yahoo.com"); String failureReason = "Failed to suspend"; - when(requestExecutor.put( + when(configServerApi.put( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_SUSPENSION_API, Optional.of(new BatchHostSuspendRequest(parentHostName, hostNames)), BatchOperationResult.class @@ -148,7 +148,7 @@ public class OrchestratorImplTest { List<String> hostNames = Arrays.asList("a1.host1.test.yahoo.com", "a2.host1.test.yahoo.com"); String exceptionMessage = "Exception: Something crashed!"; - when(requestExecutor.put( + when(configServerApi.put( OrchestratorImpl.ORCHESTRATOR_PATH_PREFIX_HOST_SUSPENSION_API, Optional.of(new BatchHostSuspendRequest(parentHostName, hostNames)), BatchOperationResult.class diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java index 2d2a622f8f0..8557da75ee9 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java @@ -4,10 +4,9 @@ package com.yahoo.vespa.hosted.node.admin.integrationTests; import com.yahoo.vespa.hosted.node.admin.ContainerAclSpec; import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAttributes; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; import com.yahoo.vespa.hosted.provision.Node; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -32,7 +31,7 @@ public class NodeRepoMock implements NodeRepository { } @Override - public List<ContainerNodeSpec> getContainersToRun(String dockerHostHostname) throws IOException { + public List<ContainerNodeSpec> getContainersToRun(String dockerHostHostname) { synchronized (monitor) { return new ArrayList<>(containerNodeSpecsByHostname.values()); } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/OrchestratorMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/OrchestratorMock.java index dc285bb27ce..469022cec56 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/OrchestratorMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/OrchestratorMock.java @@ -1,7 +1,7 @@ // 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.integrationTests; -import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.Orchestrator; import java.util.List; diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RunInContainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RunInContainerTest.java index e4b6558e8e1..3a163c94caa 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RunInContainerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RunInContainerTest.java @@ -18,9 +18,9 @@ import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminImpl; import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminStateUpdaterImpl; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgent; import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentImpl; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; -import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; -import com.yahoo.vespa.hosted.node.admin.orchestrator.OrchestratorException; +import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.Orchestrator; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.OrchestratorException; import com.yahoo.vespa.hosted.node.admin.provider.NodeAdminStateUpdater; import com.yahoo.vespa.hosted.node.admin.component.Environment; import com.yahoo.vespa.hosted.provision.Node; diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java index a699377b4c3..d50f869617a 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java @@ -6,7 +6,7 @@ import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.dockerapi.DockerImage; import com.yahoo.vespa.hosted.node.admin.ContainerAclSpec; import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; import org.junit.Before; import org.junit.Test; import org.mockito.verification.VerificationMode; diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminStateUpdaterImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminStateUpdaterImplTest.java index 1ab24fe8f9a..c9985247018 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminStateUpdaterImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminStateUpdaterImplTest.java @@ -4,14 +4,13 @@ package com.yahoo.vespa.hosted.node.admin.nodeadmin; import com.yahoo.test.ManualClock; import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; -import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; -import com.yahoo.vespa.hosted.node.admin.orchestrator.OrchestratorException; +import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.Orchestrator; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.OrchestratorException; import com.yahoo.vespa.hosted.node.admin.provider.NodeAdminStateUpdater; import com.yahoo.vespa.hosted.provision.Node; import org.junit.Test; -import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -53,7 +52,7 @@ public class NodeAdminStateUpdaterImplTest { @Test - public void testStateConvergence() throws IOException { + public void testStateConvergence() { mockNodeRepo(4); List<String> activeHostnames = nodeRepository.getContainersToRun(parentHostname).stream() .map(node -> node.hostname) @@ -155,7 +154,7 @@ public class NodeAdminStateUpdaterImplTest { } @Test - public void half_transition_revert() throws IOException { + public void half_transition_revert() { mockNodeRepo(3); // Initially everything is frozen to force convergence @@ -182,7 +181,7 @@ public class NodeAdminStateUpdaterImplTest { verify(nodeAdmin, times(2)).setFrozen(eq(false)); // Make sure that we unfreeze! } - private void mockNodeRepo(int numberOfNodes) throws IOException { + private void mockNodeRepo(int numberOfNodes) { List<ContainerNodeSpec> containersToRun = IntStream.range(0, numberOfNodes) .mapToObj(i -> new ContainerNodeSpec.Builder() .hostname("host" + i + ".test.yahoo.com") diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java index f1852fda8a3..fb9303ea382 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java @@ -15,8 +15,8 @@ import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; -import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; +import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.Orchestrator; import com.yahoo.vespa.hosted.node.admin.component.Environment; import com.yahoo.vespa.hosted.node.admin.util.InetAddressResolver; import com.yahoo.vespa.hosted.node.admin.component.PathResolver; @@ -95,7 +95,7 @@ public class NodeAgentImplTest { @Test - public void upToDateContainerIsUntouched() throws Exception { + public void upToDateContainerIsUntouched() { final long restartGeneration = 1; final long rebootGeneration = 0; final ContainerNodeSpec nodeSpec = nodeSpecBuilder @@ -135,7 +135,7 @@ public class NodeAgentImplTest { } @Test - public void verifyRemoveOldFilesIfDiskFull() throws Exception { + public void verifyRemoveOldFilesIfDiskFull() { final long restartGeneration = 1; final long rebootGeneration = 0; final ContainerNodeSpec nodeSpec = nodeSpecBuilder @@ -199,7 +199,7 @@ public class NodeAgentImplTest { } @Test - public void containerIsNotStoppedIfNewImageMustBePulled() throws Exception { + public void containerIsNotStoppedIfNewImageMustBePulled() { final DockerImage newDockerImage = new DockerImage("new-image"); final long wantedRestartGeneration = 2; final long currentRestartGeneration = 1; @@ -230,7 +230,7 @@ public class NodeAgentImplTest { } @Test - public void containerIsRestartedIfFlavorChanged() throws Exception { + public void containerIsRestartedIfFlavorChanged() { final long wantedRestartGeneration = 1; final long currentRestartGeneration = 1; ContainerNodeSpec.Builder specBuilder = nodeSpecBuilder @@ -268,7 +268,7 @@ public class NodeAgentImplTest { } @Test - public void noRestartIfOrchestratorSuspendFails() throws Exception { + public void noRestartIfOrchestratorSuspendFails() { final long wantedRestartGeneration = 2; final long currentRestartGeneration = 1; final ContainerNodeSpec nodeSpec = nodeSpecBuilder @@ -294,7 +294,7 @@ public class NodeAgentImplTest { } @Test - public void failedNodeRunningContainerShouldStillBeRunning() throws Exception { + public void failedNodeRunningContainerShouldStillBeRunning() { final long restartGeneration = 1; final long rebootGeneration = 0; final ContainerNodeSpec nodeSpec = nodeSpecBuilder @@ -324,7 +324,7 @@ public class NodeAgentImplTest { } @Test - public void readyNodeLeadsToNoAction() throws Exception { + public void readyNodeLeadsToNoAction() { final long restartGeneration = 1; final long rebootGeneration = 0; final ContainerNodeSpec nodeSpec = nodeSpecBuilder @@ -356,7 +356,7 @@ public class NodeAgentImplTest { } @Test - public void inactiveNodeRunningContainerShouldStillBeRunning() throws Exception { + public void inactiveNodeRunningContainerShouldStillBeRunning() { final long restartGeneration = 1; final long rebootGeneration = 0; @@ -390,7 +390,7 @@ public class NodeAgentImplTest { } @Test - public void reservedNodeDoesNotUpdateNodeRepoWithVersion() throws Exception { + public void reservedNodeDoesNotUpdateNodeRepoWithVersion() { final long restartGeneration = 1; final long rebootGeneration = 0; @@ -462,7 +462,7 @@ public class NodeAgentImplTest { } @Test - public void provisionedNodeIsMarkedAsDirty() throws Exception { + public void provisionedNodeIsMarkedAsDirty() { final ContainerNodeSpec nodeSpec = nodeSpecBuilder .wantedDockerImage(dockerImage) .nodeState(Node.State.provisioned) @@ -497,7 +497,7 @@ public class NodeAgentImplTest { } @Test - public void resumeProgramRunsUntilSuccess() throws Exception { + public void resumeProgramRunsUntilSuccess() { final long restartGeneration = 1; final ContainerNodeSpec nodeSpec = nodeSpecBuilder .wantedDockerImage(dockerImage) @@ -626,7 +626,7 @@ public class NodeAgentImplTest { } @Test - public void testGetRelevantMetricsForReadyNode() throws Exception { + public void testGetRelevantMetricsForReadyNode() { final ContainerNodeSpec nodeSpec = nodeSpecBuilder .nodeState(Node.State.ready) .build(); |