Java tutorial
/* * Copyright 2015 VMware, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, without warranties or * conditions of any kind, EITHER EXPRESS OR IMPLIED. See the License for the * specific language governing permissions and limitations under the License. */ package com.vmware.photon.controller.deployer.dcp; import com.vmware.photon.controller.clustermanager.ClusterManagerFactory; import com.vmware.photon.controller.common.config.BadConfigException; import com.vmware.photon.controller.common.config.ConfigBuilder; import com.vmware.photon.controller.common.xenon.MultiHostEnvironment; import com.vmware.photon.controller.common.xenon.ServiceHostUtils; import com.vmware.photon.controller.common.xenon.host.XenonConfig; import com.vmware.photon.controller.deployer.DeployerConfig; import com.vmware.photon.controller.deployer.DeployerConfigTest; import com.vmware.photon.controller.deployer.configuration.ServiceConfiguratorFactory; import com.vmware.photon.controller.deployer.deployengine.ApiClientFactory; import com.vmware.photon.controller.deployer.deployengine.AuthHelperFactory; import com.vmware.photon.controller.deployer.deployengine.DockerProvisionerFactory; import com.vmware.photon.controller.deployer.deployengine.HostManagementVmAddressValidatorFactory; import com.vmware.photon.controller.deployer.deployengine.HttpFileServiceClientFactory; import com.vmware.photon.controller.deployer.deployengine.NsxClientFactory; import com.vmware.photon.controller.deployer.deployengine.ZookeeperClientFactory; import com.vmware.photon.controller.deployer.healthcheck.HealthCheckHelperFactory; import com.vmware.photon.controller.deployer.helpers.TestHelper; import com.vmware.xenon.common.Operation; import com.vmware.xenon.services.common.LuceneDocumentIndexService; import com.vmware.xenon.services.common.ServiceUriPaths; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Injector; import org.apache.commons.io.FileUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * This class implements tests for the {@link DeployerXenonServiceHost} class. */ public class DeployerXenonServiceHostTest { private static File storageDir; private static final String configFilePath = "/config.yml"; private Injector injector; private DeployerXenonServiceHost host; private Collection<String> serviceSelfLinks; private void waitForServicesStartup(DeployerXenonServiceHost host) throws TimeoutException, InterruptedException, NoSuchFieldException, IllegalAccessException { serviceSelfLinks = ServiceHostUtils.getServiceSelfLinks( DeployerXenonServiceHost.FACTORY_SERVICE_FIELD_NAME_SELF_LINK, DeployerXenonServiceHost.FACTORY_SERVICES); serviceSelfLinks.add(DeployerXenonServiceHost.UPLOAD_VIB_SCHEDULER_SERVICE); final CountDownLatch latch = new CountDownLatch(serviceSelfLinks.size()); Operation.CompletionHandler handler = new Operation.CompletionHandler() { @Override public void handle(Operation completedOp, Throwable failure) { latch.countDown(); } }; String[] links = new String[serviceSelfLinks.size()]; host.registerForServiceAvailability(handler, serviceSelfLinks.toArray(links)); if (!latch.await(10, TimeUnit.SECONDS)) { throw new TimeoutException(); } } /** * Dummy test case to make Intellij recognize this as a test class. */ @Test private void dummy() { } /** * Tests for the constructors. */ public class InitializationTest { @BeforeClass public void setUpClass() throws IOException, BadConfigException { DeployerConfig config = ConfigBuilder.build(DeployerConfig.class, DeployerConfigTest.class.getResource(configFilePath).getPath()); storageDir = new File(config.getXenonConfig().getStoragePath()); FileUtils.deleteDirectory(storageDir); } @BeforeMethod public void setUp() throws Exception { injector = TestHelper.createInjector(configFilePath); } @AfterMethod public void tearDown() throws Exception { FileUtils.deleteDirectory(storageDir); } @Test public void testStoragePathExists() throws IOException { // make sure folder exists storageDir.mkdirs(); DeployerXenonServiceHost host = injector.getInstance(DeployerXenonServiceHost.class); assertThat(storageDir.exists(), is(true)); assertThat(host, is(notNullValue())); } @Test public void testStoragePathDoesNotExist() throws Exception { // make sure folder does not exist FileUtils.deleteDirectory(storageDir); DeployerXenonServiceHost host = injector.getInstance(DeployerXenonServiceHost.class); assertThat(storageDir.exists(), is(true)); assertThat(host, is(notNullValue())); } @Test public void testParams() { DeployerXenonServiceHost host = injector.getInstance(DeployerXenonServiceHost.class); assertThat(host.getPort(), is(18001)); Path storagePath = Paths.get(storageDir.getPath()).resolve(Integer.toString(18001)); assertThat(host.getStorageSandbox().getPath(), is(storagePath.toString())); } } /** * Tests for the start method. */ public class StartTest { @BeforeClass private void setUpClass() throws IOException { FileUtils.deleteDirectory(storageDir); } @BeforeMethod private void setUp() throws Throwable { injector = TestHelper.createInjector(configFilePath); host = injector.getInstance(DeployerXenonServiceHost.class); } @AfterMethod private void tearDown() throws Throwable { if (host != null) { host.stop(); } FileUtils.deleteDirectory(storageDir); } @Test public void testStart() throws Throwable { host.start(); try { waitForServicesStartup(host); } catch (TimeoutException e) { // N.B. This exception is swallowed so that the asserts below will // identify the service which failed to start. } assertThat(host.checkServiceAvailable(ServiceUriPaths.DEFAULT_NODE_GROUP), is(true)); assertThat(host.checkServiceAvailable(LuceneDocumentIndexService.SELF_LINK), is(true)); assertThat(host.checkServiceAvailable(ServiceUriPaths.CORE_LOCAL_QUERY_TASKS), is(true)); for (String serviceLink : serviceSelfLinks) { assertThat(String.format("Failed to start service: %s", serviceLink), host.checkServiceAvailable(serviceLink), is(true)); } } } /** * Tests for the isReady method. */ public class IsReadyTest { @BeforeClass private void setUpClass() throws IOException { FileUtils.deleteDirectory(storageDir); } @BeforeMethod private void setUp() throws Throwable { injector = TestHelper.createInjector(configFilePath); host = injector.getInstance(DeployerXenonServiceHost.class); //host.start(); //waitForServicesStartup(host); } @AfterMethod private void tearDown() throws Throwable { if (host != null) { host.stop(); } FileUtils.deleteDirectory(storageDir); } @Test public void testAllReady() throws Throwable { startHost(); assertThat(host.isReady(), is(true)); } @Test public void testNotReady() throws Throwable { doReturn(false).when(host).checkServiceAvailable(anyString()); // need to start the host after mocking it otherwise we can run into the issue detailed here // https://code.google.com/p/mockito/issues/detail?id=203 startHost(); assertThat(host.isReady(), is(false)); } private void startHost() throws Throwable { host.start(); waitForServicesStartup(host); } } /** * Tests for joining node group. */ public class JoinNodeGroupTest { private final File storageDir2 = new File("/tmp/dcp/18002/"); private final long maintenanceInterval = TimeUnit.MILLISECONDS.toMicros(500); private DeployerXenonServiceHost host2; @BeforeClass private void setUpClass() throws IOException { FileUtils.deleteDirectory(storageDir); } @BeforeMethod private void setUp() throws Throwable { injector = TestHelper.createInjector(configFilePath); XenonConfig xenonConfig = new XenonConfig(); xenonConfig.setBindAddress("0.0.0.0"); xenonConfig.setPort(18001); xenonConfig.setStoragePath(storageDir.getAbsolutePath()); host = new DeployerXenonServiceHost(xenonConfig, null, /*cloudStoreServers*/ injector.getInstance(DeployerContext.class), null /* containersConfig */, () -> null, () -> null, injector.getInstance(HttpFileServiceClientFactory.class), injector.getInstance(ListeningExecutorService.class), injector.getInstance(ApiClientFactory.class), injector.getInstance(DockerProvisionerFactory.class), injector.getInstance(AuthHelperFactory.class), injector.getInstance(HealthCheckHelperFactory.class), injector.getInstance(ServiceConfiguratorFactory.class), injector.getInstance(ZookeeperClientFactory.class), injector.getInstance(HostManagementVmAddressValidatorFactory.class), injector.getInstance(ClusterManagerFactory.class), injector.getInstance(NsxClientFactory.class)); host.setMaintenanceIntervalMicros(maintenanceInterval); host.start(); waitForServicesStartup(host); XenonConfig xenonConfig2 = new XenonConfig(); xenonConfig2.setBindAddress("0.0.0.0"); xenonConfig2.setPort(18002); xenonConfig2.setStoragePath(storageDir2.getAbsolutePath()); host2 = new DeployerXenonServiceHost(xenonConfig2, null, /*cloudStoreServers*/ injector.getInstance(DeployerContext.class), null /* containersConfig */, () -> null, () -> null, injector.getInstance(HttpFileServiceClientFactory.class), injector.getInstance(ListeningExecutorService.class), injector.getInstance(ApiClientFactory.class), injector.getInstance(DockerProvisionerFactory.class), injector.getInstance(AuthHelperFactory.class), injector.getInstance(HealthCheckHelperFactory.class), injector.getInstance(ServiceConfiguratorFactory.class), injector.getInstance(ZookeeperClientFactory.class), injector.getInstance(HostManagementVmAddressValidatorFactory.class), injector.getInstance(ClusterManagerFactory.class), injector.getInstance(NsxClientFactory.class)); host2.setMaintenanceIntervalMicros(maintenanceInterval); host2.start(); waitForServicesStartup(host2); } @AfterMethod private void tearDown() throws Throwable { if (host != null) { host.stop(); } FileUtils.deleteDirectory(storageDir); if (host2 != null) { host2.stop(); } FileUtils.deleteDirectory(storageDir2); } @Test public void testJoinNodeGroup() throws Throwable { ServiceHostUtils.joinNodeGroup(host2, host.getUri().getHost(), host.getPort()); ServiceHostUtils.waitForNodeGroupConvergence(new DeployerXenonServiceHost[] { host, host2 }, ServiceUriPaths.DEFAULT_NODE_GROUP, ServiceHostUtils.DEFAULT_NODE_GROUP_CONVERGENCE_MAX_RETRIES, MultiHostEnvironment.TEST_NODE_GROUP_CONVERGENCE_SLEEP); } } }