com.vmware.photon.controller.deployer.xenon.DeployerServiceGroupTest.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.photon.controller.deployer.xenon.DeployerServiceGroupTest.java

Source

/*
 * 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.xenon;

import com.vmware.photon.controller.clustermanager.ClusterManagerFactory;
import com.vmware.photon.controller.common.clients.AgentControlClientFactory;
import com.vmware.photon.controller.common.clients.HostClientFactory;
import com.vmware.photon.controller.common.config.BadConfigException;
import com.vmware.photon.controller.common.config.ConfigBuilder;
import com.vmware.photon.controller.common.thrift.ServerSet;
import com.vmware.photon.controller.common.xenon.CloudStoreHelper;
import com.vmware.photon.controller.common.xenon.MultiHostEnvironment;
import com.vmware.photon.controller.common.xenon.ServiceHostUtils;
import com.vmware.photon.controller.common.xenon.host.PhotonControllerXenonHost;
import com.vmware.photon.controller.common.xenon.host.XenonConfig;
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.ZookeeperClientFactory;
import com.vmware.photon.controller.deployer.healthcheck.HealthCheckHelperFactory;
import com.vmware.photon.controller.deployer.helpers.TestHelper;
import com.vmware.photon.controller.deployer.helpers.xenon.DeployerTestConfig;
import com.vmware.photon.controller.nsxclient.NsxClientFactory;
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.common.util.concurrent.MoreExecutors;
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.Mockito.mock;

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.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * This class implements tests for the {@link DeployerServiceGroup} class.
 */
public class DeployerServiceGroupTest {

    private static File storageDir;

    private static final String configFilePath = "/config.yml";

    private PhotonControllerXenonHost host;
    private DeployerServiceGroup deployerServiceGroup;

    private Collection<String> serviceSelfLinks;
    private DeployerTestConfig deployerTestConfig;
    private ServerSet cloudStoreServerSet;
    private CloudStoreHelper cloudStoreHelper;
    private AgentControlClientFactory agentControlClientFactory;
    private HostClientFactory hostClientFactory;
    private HttpFileServiceClientFactory httpFileServiceClientFactory;
    private ListeningExecutorService listeningExecutorService;
    private ApiClientFactory apiClientFactory;
    private DockerProvisionerFactory dockerProvisionerFactory;
    private AuthHelperFactory authHelperFactory;
    private HealthCheckHelperFactory healthCheckHelperFactory;
    private ServiceConfiguratorFactory serviceConfiguratorFactory;
    private ZookeeperClientFactory zookeeperClientFactory;
    private HostManagementVmAddressValidatorFactory hostManagementVmAddressValidatorFactory;
    private ClusterManagerFactory clusterManagerFactory;
    private NsxClientFactory nsxClientFactory;

    private void waitForServicesStartup(PhotonControllerXenonHost host)
            throws TimeoutException, InterruptedException, NoSuchFieldException, IllegalAccessException {

        serviceSelfLinks = ServiceHostUtils.getServiceSelfLinks(
                DeployerServiceGroup.FACTORY_SERVICE_FIELD_NAME_SELF_LINK, DeployerServiceGroup.FACTORY_SERVICES);
        serviceSelfLinks.add(DeployerServiceGroup.UPLOAD_VIB_WORK_QUEUE_SELF_LINK);

        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 {
            deployerTestConfig = ConfigBuilder.build(DeployerTestConfig.class,
                    DeployerServiceGroupTest.class.getResource(configFilePath).getPath());
            TestHelper.setContainersConfig(deployerTestConfig);

            listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
            cloudStoreServerSet = mock(ServerSet.class);
            cloudStoreHelper = new CloudStoreHelper(cloudStoreServerSet);
            agentControlClientFactory = mock(AgentControlClientFactory.class);
            hostClientFactory = mock(HostClientFactory.class);
            httpFileServiceClientFactory = mock(HttpFileServiceClientFactory.class);
            apiClientFactory = mock(ApiClientFactory.class);
            dockerProvisionerFactory = mock(DockerProvisionerFactory.class);
            authHelperFactory = mock(AuthHelperFactory.class);
            healthCheckHelperFactory = mock(HealthCheckHelperFactory.class);
            serviceConfiguratorFactory = mock(ServiceConfiguratorFactory.class);
            zookeeperClientFactory = mock(ZookeeperClientFactory.class);
            hostManagementVmAddressValidatorFactory = mock(HostManagementVmAddressValidatorFactory.class);
            clusterManagerFactory = mock(ClusterManagerFactory.class);
            nsxClientFactory = mock(NsxClientFactory.class);

            storageDir = new File(deployerTestConfig.getXenonConfig().getStoragePath());
            FileUtils.deleteDirectory(storageDir);

        }

        @BeforeMethod
        public void setUp() throws Throwable {
            host = new PhotonControllerXenonHost(deployerTestConfig.getXenonConfig(), hostClientFactory,
                    agentControlClientFactory, nsxClientFactory, cloudStoreHelper);

            deployerServiceGroup = new DeployerServiceGroup(deployerTestConfig.getDeployerContext(),
                    dockerProvisionerFactory, apiClientFactory, deployerTestConfig.getContainersConfig(),
                    listeningExecutorService, httpFileServiceClientFactory, authHelperFactory,
                    healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host.registerDeployer(deployerServiceGroup);
        }

        @AfterMethod
        public void tearDown() throws Exception {
            FileUtils.deleteDirectory(storageDir);
        }

        @Test
        public void testStoragePathExists() throws IOException {
            // make sure folder exists
            storageDir.mkdirs();

            assertThat(storageDir.exists(), is(true));
            assertThat(host, is(notNullValue()));
        }

        @Test
        public void testStoragePathDoesNotExist() throws Throwable {
            // make sure folder does not exist
            FileUtils.deleteDirectory(storageDir);
            assertThat(storageDir.exists(), is(false));

            // Check that host creates storage directory
            host = new PhotonControllerXenonHost(deployerTestConfig.getXenonConfig(), hostClientFactory,
                    agentControlClientFactory, nsxClientFactory, cloudStoreHelper);

            deployerServiceGroup = new DeployerServiceGroup(deployerTestConfig.getDeployerContext(),
                    dockerProvisionerFactory, apiClientFactory, deployerTestConfig.getContainersConfig(),
                    listeningExecutorService, httpFileServiceClientFactory, authHelperFactory,
                    healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host.registerDeployer(deployerServiceGroup);

            assertThat(storageDir.exists(), is(true));
            assertThat(host, is(notNullValue()));
        }

        @Test
        public void testParams() {
            assertThat(host.getPort(), is(18000));
            Path storagePath = Paths.get(storageDir.getPath()).resolve(Integer.toString(18000));
            assertThat(host.getStorageSandbox().getPath(), is(storagePath.toString()));
        }
    }

    /**
     * Tests for the start method.
     */
    public class StartTest {

        @BeforeClass
        private void setUpClass() throws IOException, BadConfigException {
            deployerTestConfig = ConfigBuilder.build(DeployerTestConfig.class,
                    DeployerServiceGroupTest.class.getResource(configFilePath).getPath());
            TestHelper.setContainersConfig(deployerTestConfig);

            listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
            cloudStoreServerSet = mock(ServerSet.class);
            cloudStoreHelper = new CloudStoreHelper(cloudStoreServerSet);
            agentControlClientFactory = mock(AgentControlClientFactory.class);
            hostClientFactory = mock(HostClientFactory.class);
            httpFileServiceClientFactory = mock(HttpFileServiceClientFactory.class);
            apiClientFactory = mock(ApiClientFactory.class);
            dockerProvisionerFactory = mock(DockerProvisionerFactory.class);
            authHelperFactory = mock(AuthHelperFactory.class);
            healthCheckHelperFactory = mock(HealthCheckHelperFactory.class);
            serviceConfiguratorFactory = mock(ServiceConfiguratorFactory.class);
            zookeeperClientFactory = mock(ZookeeperClientFactory.class);
            hostManagementVmAddressValidatorFactory = mock(HostManagementVmAddressValidatorFactory.class);
            clusterManagerFactory = mock(ClusterManagerFactory.class);
            nsxClientFactory = mock(NsxClientFactory.class);

            storageDir = new File(deployerTestConfig.getXenonConfig().getStoragePath());
            FileUtils.deleteDirectory(storageDir);
        }

        @BeforeMethod
        private void setUp() throws Throwable {
            host = new PhotonControllerXenonHost(deployerTestConfig.getXenonConfig(), hostClientFactory,
                    agentControlClientFactory, nsxClientFactory, cloudStoreHelper);

            deployerServiceGroup = new DeployerServiceGroup(deployerTestConfig.getDeployerContext(),
                    dockerProvisionerFactory, apiClientFactory, deployerTestConfig.getContainersConfig(),
                    listeningExecutorService, httpFileServiceClientFactory, authHelperFactory,
                    healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host.registerDeployer(deployerServiceGroup);
        }

        @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, BadConfigException {
            deployerTestConfig = ConfigBuilder.build(DeployerTestConfig.class,
                    DeployerServiceGroupTest.class.getResource(configFilePath).getPath());
            TestHelper.setContainersConfig(deployerTestConfig);

            listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
            cloudStoreServerSet = mock(ServerSet.class);
            cloudStoreHelper = new CloudStoreHelper(cloudStoreServerSet);
            agentControlClientFactory = mock(AgentControlClientFactory.class);
            hostClientFactory = mock(HostClientFactory.class);
            httpFileServiceClientFactory = mock(HttpFileServiceClientFactory.class);
            apiClientFactory = mock(ApiClientFactory.class);
            dockerProvisionerFactory = mock(DockerProvisionerFactory.class);
            authHelperFactory = mock(AuthHelperFactory.class);
            healthCheckHelperFactory = mock(HealthCheckHelperFactory.class);
            serviceConfiguratorFactory = mock(ServiceConfiguratorFactory.class);
            zookeeperClientFactory = mock(ZookeeperClientFactory.class);
            hostManagementVmAddressValidatorFactory = mock(HostManagementVmAddressValidatorFactory.class);
            clusterManagerFactory = mock(ClusterManagerFactory.class);
            nsxClientFactory = mock(NsxClientFactory.class);

            storageDir = new File(deployerTestConfig.getXenonConfig().getStoragePath());
            FileUtils.deleteDirectory(storageDir);
        }

        @BeforeMethod
        private void setUp() throws Throwable {
            host = new PhotonControllerXenonHost(deployerTestConfig.getXenonConfig(), hostClientFactory,
                    agentControlClientFactory, nsxClientFactory, cloudStoreHelper);

            deployerServiceGroup = new DeployerServiceGroup(deployerTestConfig.getDeployerContext(),
                    dockerProvisionerFactory, apiClientFactory, deployerTestConfig.getContainersConfig(),
                    listeningExecutorService, httpFileServiceClientFactory, authHelperFactory,
                    healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host.registerDeployer(deployerServiceGroup);
        }

        @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 {
            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/xenon/18002/");
        private final long maintenanceInterval = TimeUnit.MILLISECONDS.toMicros(500);
        private PhotonControllerXenonHost host2;

        @BeforeClass
        private void setUpClass() throws Throwable {
            listeningExecutorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
            cloudStoreServerSet = mock(ServerSet.class);
            cloudStoreHelper = new CloudStoreHelper(cloudStoreServerSet);
            agentControlClientFactory = mock(AgentControlClientFactory.class);
            hostClientFactory = mock(HostClientFactory.class);
            httpFileServiceClientFactory = mock(HttpFileServiceClientFactory.class);
            apiClientFactory = mock(ApiClientFactory.class);
            dockerProvisionerFactory = mock(DockerProvisionerFactory.class);
            authHelperFactory = mock(AuthHelperFactory.class);
            healthCheckHelperFactory = mock(HealthCheckHelperFactory.class);
            serviceConfiguratorFactory = mock(ServiceConfiguratorFactory.class);
            zookeeperClientFactory = mock(ZookeeperClientFactory.class);
            hostManagementVmAddressValidatorFactory = mock(HostManagementVmAddressValidatorFactory.class);
            clusterManagerFactory = mock(ClusterManagerFactory.class);
            nsxClientFactory = mock(NsxClientFactory.class);

            deployerTestConfig = ConfigBuilder.build(DeployerTestConfig.class,
                    DeployerServiceGroupTest.class.getResource(configFilePath).getPath());
            TestHelper.setContainersConfig(deployerTestConfig);
            storageDir = new File(deployerTestConfig.getXenonConfig().getStoragePath());
            FileUtils.deleteDirectory(storageDir);
        }

        @BeforeMethod
        private void setUp() throws Throwable {
            XenonConfig xenonConfig = new XenonConfig();
            xenonConfig.setBindAddress("0.0.0.0");
            xenonConfig.setPort(18000);
            xenonConfig.setStoragePath(storageDir.getAbsolutePath());

            host = new PhotonControllerXenonHost(xenonConfig, hostClientFactory, agentControlClientFactory,
                    nsxClientFactory, cloudStoreHelper);

            deployerServiceGroup = new DeployerServiceGroup(null, dockerProvisionerFactory, apiClientFactory, null,
                    listeningExecutorService, httpFileServiceClientFactory, authHelperFactory,
                    healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host.registerDeployer(deployerServiceGroup);

            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 PhotonControllerXenonHost(xenonConfig2, hostClientFactory, agentControlClientFactory,
                    nsxClientFactory, cloudStoreHelper);

            DeployerServiceGroup deployerServiceGroup2 = new DeployerServiceGroup(null, dockerProvisionerFactory,
                    apiClientFactory, null, listeningExecutorService, httpFileServiceClientFactory,
                    authHelperFactory, healthCheckHelperFactory, serviceConfiguratorFactory, zookeeperClientFactory,
                    hostManagementVmAddressValidatorFactory, clusterManagerFactory);

            host2.registerDeployer(deployerServiceGroup2);

            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 PhotonControllerXenonHost[] { host, host2 },
                    ServiceUriPaths.DEFAULT_NODE_GROUP, ServiceHostUtils.DEFAULT_NODE_GROUP_CONVERGENCE_MAX_RETRIES,
                    MultiHostEnvironment.TEST_NODE_GROUP_CONVERGENCE_SLEEP);
        }
    }
}