org.apache.ambari.server.api.services.AmbariMetaInfoTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ambari.server.api.services.AmbariMetaInfoTest.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.ambari.server.api.services;

import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
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.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;

import junit.framework.Assert;

import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.metadata.AgentAlertDefinitions;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.MetainfoEntity;
import org.apache.ambari.server.stack.StackManager;
import org.apache.ambari.server.state.AutoDeployInfo;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ComponentInfo;
import org.apache.ambari.server.state.CustomCommandDefinition;
import org.apache.ambari.server.state.DependencyInfo;
import org.apache.ambari.server.state.OperatingSystemInfo;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.apache.ambari.server.state.alert.MetricSource;
import org.apache.ambari.server.state.alert.PortSource;
import org.apache.ambari.server.state.alert.Reporting;
import org.apache.ambari.server.state.alert.Source;
import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.ambari.server.state.stack.OsFamily;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.util.Modules;

public class AmbariMetaInfoTest {

    private static final String STACK_NAME_HDP = "HDP";
    private static final String STACK_NAME_XYZ = "XYZ";
    private static final String STACK_VERSION_HDP = "0.1";
    private static final String EXT_STACK_NAME = "2.0.6";
    private static final String STACK_VERSION_HDP_02 = "0.2";
    private static final String STACK_MINIMAL_VERSION_HDP = "0.0";
    private static String SERVICE_NAME_HDFS = "HDFS";
    private static String SERVICE_NAME_MAPRED2 = "MAPREDUCE2";
    private static String SERVICE_COMPONENT_NAME = "NAMENODE";
    private static final String OS_TYPE = "centos5";
    private static final String HDP_REPO_NAME = "HDP";
    private static final String HDP_REPO_ID = "HDP-2.1.1";
    private static final String HDP_UTILS_REPO_NAME = "HDP-UTILS";
    private static final String REPO_ID = "HDP-UTILS-1.1.0.15";
    private static final String PROPERTY_NAME = "hbase.regionserver.msginterval";
    private static final String SHARED_PROPERTY_NAME = "content";

    private static final String NON_EXT_VALUE = "XXX";

    private static final int REPOS_CNT = 3;
    private static final int PROPERTIES_CNT = 62;
    private static final int OS_CNT = 4;

    private AmbariMetaInfo metaInfo = null;
    private final static Logger LOG = LoggerFactory.getLogger(AmbariMetaInfoTest.class);
    private static final String FILE_NAME = "hbase-site.xml";
    private static final String HADOOP_ENV_FILE_NAME = "hadoop-env.xml";
    private static final String HDFS_LOG4J_FILE_NAME = "hdfs-log4j.xml";

    //private Injector injector;

    //todo: add fail() for cases where an exception is expected such as getService, getComponent ...

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();

    @Before
    public void before() throws Exception {
        File stacks = new File("src/test/resources/stacks");
        File version = new File("src/test/resources/version");
        if (System.getProperty("os.name").contains("Windows")) {
            stacks = new File(ClassLoader.getSystemClassLoader().getResource("stacks").getPath());
            version = new File(new File(ClassLoader.getSystemClassLoader().getResource("").getPath()).getParent(),
                    "version");
        }
        metaInfo = createAmbariMetaInfo(stacks, version, true);
    }

    public class MockModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(ActionMetadata.class);
        }
    }

    @Test
    public void getRestartRequiredServicesNames() throws AmbariException {
        Set<String> res = metaInfo.getRestartRequiredServicesNames(STACK_NAME_HDP, "2.0.7");
        assertEquals(1, res.size());
    }

    @Test
    public void getComponentsByService() throws AmbariException {
        List<ComponentInfo> components = metaInfo.getComponentsByService(STACK_NAME_HDP, STACK_VERSION_HDP,
                SERVICE_NAME_HDFS);
        assertNotNull(components);
        assertTrue(components.size() > 0);
    }

    @Test
    public void getRepository() throws AmbariException {
        Map<String, List<RepositoryInfo>> repository = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP);
        assertNotNull(repository);
        assertFalse(repository.get("centos5").isEmpty());
        assertFalse(repository.get("centos6").isEmpty());
    }

    @Test
    public void testGetRepositoryDefault() throws Exception {
        // Scenario: user has internet and does nothing to repos via api
        // use the latest
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true);
        // The current stack already has (HDP, 2.1.1, redhat6) with valid latest
        // url
        ambariMetaInfo.init();

        waitForAllReposToBeResolved(ambariMetaInfo);

        List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(STACK_NAME_HDP, "2.1.1", "redhat6");
        assertNotNull(redhat6Repo);
        for (RepositoryInfo ri : redhat6Repo) {
            if (STACK_NAME_HDP.equals(ri.getRepoName())) {
                assertFalse(ri.getBaseUrl().equals(ri.getDefaultBaseUrl()));
                assertEquals(ri.getBaseUrl(), ri.getLatestBaseUrl());
            }
        }
    }

    @Test
    public void testGetRepositoryNoInternetDefault() throws Exception {
        // Scenario: user has no internet and does nothing to repos via api
        // use the default
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        AmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true);
        // The current stack already has (HDP, 2.1.1, redhat6).

        // Deleting the json file referenced by the latestBaseUrl to simulate No
        // Internet.
        File latestUrlFile = new File(buildDir, "ambari-metaInfo/HDP/2.1.1/repos/hdp.json");
        if (System.getProperty("os.name").contains("Windows")) {
            latestUrlFile.deleteOnExit();
        } else {
            FileUtils.deleteQuietly(latestUrlFile);
            assertTrue(!latestUrlFile.exists());
        }
        ambariMetaInfo.init();

        List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(STACK_NAME_HDP, "2.1.1", "redhat6");
        assertNotNull(redhat6Repo);
        for (RepositoryInfo ri : redhat6Repo) {
            if (STACK_NAME_HDP.equals(ri.getRepoName())) {
                // baseUrl should be same as defaultBaseUrl since No Internet to load the
                // latestBaseUrl from the json file.
                assertEquals(ri.getBaseUrl(), ri.getDefaultBaseUrl());
            }
        }
    }

    @Test
    public void testGetRepositoryUpdatedBaseUrl() throws Exception {
        // Scenario: user has internet and but calls to set repos via api
        // use whatever they set
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        TestAmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true);
        // The current stack already has (HDP, 2.1.1, redhat6)

        // Updating the baseUrl
        String newBaseUrl = "http://myprivate-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0";
        ambariMetaInfo.updateRepoBaseURL(STACK_NAME_HDP, "2.1.1", "redhat6", HDP_REPO_ID, newBaseUrl);
        RepositoryInfo repoInfo = ambariMetaInfo.getRepository(STACK_NAME_HDP, "2.1.1", "redhat6", HDP_REPO_ID);
        assertEquals(newBaseUrl, repoInfo.getBaseUrl());
        String prevBaseUrl = repoInfo.getDefaultBaseUrl();

        // mock expectations
        MetainfoDAO metainfoDAO = ambariMetaInfo.metaInfoDAO;
        reset(metainfoDAO);
        MetainfoEntity entity = createNiceMock(MetainfoEntity.class);
        expect(metainfoDAO.findByKey("repo:/HDP/2.1.1/redhat6/HDP-2.1.1:baseurl")).andReturn(entity).atLeastOnce();
        expect(entity.getMetainfoValue()).andReturn(newBaseUrl).atLeastOnce();
        replay(metainfoDAO, entity);

        ambariMetaInfo.init();

        waitForAllReposToBeResolved(ambariMetaInfo);

        List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(STACK_NAME_HDP, "2.1.1", "redhat6");
        assertNotNull(redhat6Repo);
        for (RepositoryInfo ri : redhat6Repo) {
            if (HDP_REPO_NAME.equals(ri.getRepoName())) {
                assertEquals(newBaseUrl, ri.getBaseUrl());
                // defaultBaseUrl and baseUrl should not be same, since it is updated.
                assertFalse(ri.getBaseUrl().equals(ri.getDefaultBaseUrl()));
            }
        }

        Capture<MetainfoEntity> c = new Capture<MetainfoEntity>();

        metainfoDAO = ambariMetaInfo.metaInfoDAO;
        reset(metainfoDAO);
        reset(entity);
        expect(metainfoDAO.findByKey("repo:/HDP/2.1.1/redhat6/HDP-2.1.1:baseurl")).andReturn(entity).atLeastOnce();
        expect(metainfoDAO.merge(EasyMock.capture(c))).andReturn(entity).atLeastOnce();
        replay(metainfoDAO, entity);

        // Reset the database with the original baseUrl
        ambariMetaInfo.updateRepoBaseURL(STACK_NAME_HDP, "2.1.1", "redhat6", HDP_REPO_ID, prevBaseUrl);

        assertEquals(prevBaseUrl, c.getValue().getMetainfoValue());
        assertTrue(repoInfo.isBaseUrlFromSaved());

    }

    @Test
    public void testGetRepositoryUpdatedUtilsBaseUrl() throws Exception {
        // Scenario: user has internet and but calls to set repos via api
        // use whatever they set
        String stackVersion = "0.2";
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        TestAmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true);

        // Updating the baseUrl
        String newBaseUrl = "http://myprivate-repo-1.hortonworks.com/HDP-Utils/centos6/2.x/updates/2.0.6.0";
        ambariMetaInfo.updateRepoBaseURL(STACK_NAME_HDP, stackVersion, "redhat6", REPO_ID, newBaseUrl);
        RepositoryInfo repoInfo = ambariMetaInfo.getRepository(STACK_NAME_HDP, stackVersion, "redhat6", REPO_ID);
        assertEquals(newBaseUrl, repoInfo.getBaseUrl());
        String prevBaseUrl = repoInfo.getDefaultBaseUrl();

        // mock expectations
        MetainfoDAO metainfoDAO = ambariMetaInfo.metaInfoDAO;
        reset(metainfoDAO);
        MetainfoEntity entity = createNiceMock(MetainfoEntity.class);
        expect(metainfoDAO.findByKey("repo:/HDP/0.2/redhat6/HDP-UTILS-1.1.0.15:baseurl")).andReturn(entity)
                .atLeastOnce();
        expect(entity.getMetainfoValue()).andReturn(newBaseUrl).atLeastOnce();
        replay(metainfoDAO, entity);

        ambariMetaInfo.init();

        List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(STACK_NAME_HDP, stackVersion, "redhat6");
        assertNotNull(redhat6Repo);
        for (RepositoryInfo ri : redhat6Repo) {
            if (HDP_UTILS_REPO_NAME.equals(ri.getRepoName())) {
                assertEquals(newBaseUrl, ri.getBaseUrl());
                // defaultBaseUrl and baseUrl should not be same, since it is updated.
                assertFalse(ri.getBaseUrl().equals(ri.getDefaultBaseUrl()));
            }
        }

        // Reset the database with the original baseUrl
        ambariMetaInfo.updateRepoBaseURL(STACK_NAME_HDP, stackVersion, "redhat6", REPO_ID, prevBaseUrl);
    }

    @Test
    public void testGetRepositoryNoInternetUpdatedBaseUrl() throws Exception {
        // Scenario: user has no internet and but calls to set repos via api
        // use whatever they set
        String newBaseUrl = "http://myprivate-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0";
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        TestAmbariMetaInfo ambariMetaInfo = setupTempAmbariMetaInfo(buildDir, true);
        // The current stack already has (HDP, 2.1.1, redhat6).

        // Deleting the json file referenced by the latestBaseUrl to simulate No
        // Internet.
        File latestUrlFile = new File(buildDir, "ambari-metaInfo/HDP/2.1.1/repos/hdp.json");
        if (System.getProperty("os.name").contains("Windows")) {
            latestUrlFile.deleteOnExit();
        } else {
            FileUtils.deleteQuietly(latestUrlFile);
            assertTrue(!latestUrlFile.exists());
        }

        // Update baseUrl
        ambariMetaInfo.updateRepoBaseURL("HDP", "2.1.1", "redhat6", "HDP-2.1.1", newBaseUrl);
        RepositoryInfo repoInfo = ambariMetaInfo.getRepository(STACK_NAME_HDP, "2.1.1", "redhat6",
                STACK_NAME_HDP + "-2.1.1");
        assertEquals(newBaseUrl, repoInfo.getBaseUrl());
        String prevBaseUrl = repoInfo.getDefaultBaseUrl();

        // mock expectations
        MetainfoDAO metainfoDAO = ambariMetaInfo.metaInfoDAO;
        reset(metainfoDAO);
        MetainfoEntity entity = createNiceMock(MetainfoEntity.class);
        expect(metainfoDAO.findByKey("repo:/HDP/2.1.1/redhat6/HDP-2.1.1:baseurl")).andReturn(entity).atLeastOnce();
        expect(entity.getMetainfoValue()).andReturn(newBaseUrl).atLeastOnce();
        replay(metainfoDAO, entity);

        ambariMetaInfo.init();

        waitForAllReposToBeResolved(ambariMetaInfo);

        List<RepositoryInfo> redhat6Repo = ambariMetaInfo.getRepositories(STACK_NAME_HDP, "2.1.1", "redhat6");
        assertNotNull(redhat6Repo);
        for (RepositoryInfo ri : redhat6Repo) {
            if (STACK_NAME_HDP.equals(ri.getRepoName())) {
                // baseUrl should point to the updated baseUrl
                assertEquals(newBaseUrl, ri.getBaseUrl());
                assertFalse(ri.getDefaultBaseUrl().equals(ri.getBaseUrl()));
            }
        }

        // Reset the database with the original baseUrl
        ambariMetaInfo.updateRepoBaseURL(STACK_NAME_HDP, "2.1.1", "redhat6", STACK_NAME_HDP + "-2.1.1",
                prevBaseUrl);
    }

    @Test
    public void isSupportedStack() throws AmbariException {
        boolean supportedStack = metaInfo.isSupportedStack(STACK_NAME_HDP, STACK_VERSION_HDP);
        assertTrue(supportedStack);

        boolean notSupportedStack = metaInfo.isSupportedStack(NON_EXT_VALUE, NON_EXT_VALUE);
        assertFalse(notSupportedStack);
    }

    @Test
    public void isValidService() throws AmbariException {
        boolean valid = metaInfo.isValidService(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS);
        assertTrue(valid);

        boolean invalid = metaInfo.isValidService(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE);
        assertFalse(invalid);
    }

    @Test
    public void testServiceNameUsingComponentName() throws AmbariException {
        String serviceName = metaInfo.getComponentToService(STACK_NAME_HDP, STACK_VERSION_HDP, "NAMENODE");
        assertEquals("HDFS", serviceName);
    }

    /**
     * Method: Map<String, ServiceInfo> getServices(String stackName, String
     * version, String serviceName)
     * @throws AmbariException
     */
    @Test
    public void getServices() throws AmbariException {
        Map<String, ServiceInfo> services = metaInfo.getServices(STACK_NAME_HDP, STACK_VERSION_HDP);
        LOG.info("Getting all the services ");
        for (Map.Entry<String, ServiceInfo> entry : services.entrySet()) {
            LOG.info("Service Name " + entry.getKey() + " values " + entry.getValue());
        }
        assertTrue(services.containsKey("HDFS"));
        assertTrue(services.containsKey("MAPREDUCE"));
        assertNotNull(services);
        assertFalse(services.keySet().size() == 0);
    }

    /**
     * Method: getServiceInfo(String stackName, String version, String
     * serviceName)
     */
    @Test
    public void getServiceInfo() throws Exception {
        ServiceInfo si = metaInfo.getService(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS);
        assertNotNull(si);
    }

    @Test
    public void testConfigDependencies() throws Exception {
        ServiceInfo serviceInfo = metaInfo.getService(STACK_NAME_HDP, EXT_STACK_NAME, SERVICE_NAME_MAPRED2);
        assertNotNull(serviceInfo);
        assertTrue(!serviceInfo.getConfigDependencies().isEmpty());
    }

    @Test
    public void testGetRepos() throws Exception {
        Map<String, List<RepositoryInfo>> repos = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP);
        Set<String> centos5Cnt = new HashSet<String>();
        Set<String> centos6Cnt = new HashSet<String>();
        Set<String> redhat6cnt = new HashSet<String>();
        Set<String> redhat5cnt = new HashSet<String>();

        for (List<RepositoryInfo> vals : repos.values()) {
            for (RepositoryInfo repo : vals) {
                LOG.debug("Dumping repo info : " + repo.toString());
                if (repo.getOsType().equals("centos5")) {
                    centos5Cnt.add(repo.getRepoId());
                } else if (repo.getOsType().equals("centos6")) {
                    centos6Cnt.add(repo.getRepoId());
                } else if (repo.getOsType().equals("redhat6")) {
                    redhat6cnt.add(repo.getRepoId());
                } else if (repo.getOsType().equals("redhat5")) {
                    redhat5cnt.add(repo.getRepoId());
                } else {
                    fail("Found invalid os " + repo.getOsType());
                }

                if (repo.getRepoId().equals("epel")) {
                    assertFalse(repo.getMirrorsList().isEmpty());
                    assertNull(repo.getBaseUrl());
                } else {
                    assertNull(repo.getMirrorsList());
                    assertFalse(repo.getBaseUrl().isEmpty());
                }
            }
        }

        assertEquals(3, centos5Cnt.size());
        assertEquals(3, redhat6cnt.size());
        assertEquals(3, redhat5cnt.size());
        assertEquals(3, centos6Cnt.size());
    }

    @Test
    /**
     * Make sure global mapping is avaliable when global.xml is
     * in the path.
     * @throws Exception
     */
    public void testGlobalMapping() throws Exception {
        ServiceInfo sinfo = metaInfo.getService("HDP", "0.2", "HDFS");
        List<PropertyInfo> pinfo = sinfo.getProperties();
        /** check all the config knobs and make sure the global one is there **/
        boolean checkforglobal = false;

        for (PropertyInfo pinfol : pinfo) {
            if ("global.xml".equals(pinfol.getFilename())) {
                checkforglobal = true;
            }
        }
        Assert.assertTrue(checkforglobal);
        sinfo = metaInfo.getService("HDP", "0.2", "MAPREDUCE");
        boolean checkforhadoopheapsize = false;
        pinfo = sinfo.getProperties();
        for (PropertyInfo pinfol : pinfo) {
            if ("global.xml".equals(pinfol.getFilename())) {
                if ("hadoop_heapsize".equals(pinfol.getName())) {
                    checkforhadoopheapsize = true;
                }
            }
        }
        Assert.assertTrue(checkforhadoopheapsize);
    }

    @Test
    public void testMetaInfoFileFilter() throws Exception {
        String buildDir = tmpFolder.getRoot().getAbsolutePath();
        File stackRoot = new File("src/test/resources/stacks");
        File version = new File("src/test/resources/version");
        if (System.getProperty("os.name").contains("Windows")) {
            stackRoot = new File(ClassLoader.getSystemClassLoader().getResource("stacks").getPath());
            version = new File(new File(ClassLoader.getSystemClassLoader().getResource("").getPath()).getParent(),
                    "version");
        }
        File stackRootTmp = new File(buildDir + "/ambari-metaInfo");
        stackRootTmp.mkdir();
        FileUtils.copyDirectory(stackRoot, stackRootTmp);
        AmbariMetaInfo ambariMetaInfo = createAmbariMetaInfo(stackRootTmp, version, true);
        //todo
        //ambariMetaInfo.injector = injector;
        File f1, f2, f3;
        f1 = new File(stackRootTmp.getAbsolutePath() + "/001.svn");
        f1.createNewFile();
        f2 = new File(stackRootTmp.getAbsolutePath() + "/abcd.svn/001.svn");
        f2.mkdirs();
        f2.createNewFile();
        f3 = new File(stackRootTmp.getAbsolutePath() + "/.svn");
        if (!f3.exists()) {
            f3.createNewFile();
        }
        ambariMetaInfo.init();
        // Tests the stack is loaded as expected
        getServices();
        getComponentsByService();
        // Check .svn is not part of the stack but abcd.svn is
        Assert.assertNotNull(ambariMetaInfo.getStack("abcd.svn", "001.svn"));

        Assert.assertFalse(ambariMetaInfo.isSupportedStack(".svn", ""));
        Assert.assertFalse(ambariMetaInfo.isSupportedStack(".svn", ""));
    }

    @Test
    public void testGetComponent() throws Exception {
        ComponentInfo component = metaInfo.getComponent(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS,
                SERVICE_COMPONENT_NAME);
        Assert.assertEquals(component.getName(), SERVICE_COMPONENT_NAME);

        try {
            metaInfo.getComponent(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }

    }

    @Test
    public void testGetRepositories() throws Exception {
        List<RepositoryInfo> repositories = metaInfo.getRepositories(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE);
        Assert.assertEquals(repositories.size(), REPOS_CNT);
    }

    @Test
    public void testGetRepository() throws Exception {
        RepositoryInfo repository = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, REPO_ID);
        Assert.assertEquals(repository.getRepoId(), REPO_ID);

        try {
            metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }
    }

    @Test
    public void testGetService() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS);
        Assert.assertEquals(service.getName(), SERVICE_NAME_HDFS);
        try {
            metaInfo.getService(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }

    }

    @Test
    public void testGetStacks() {
        Collection<StackInfo> stacks = metaInfo.getStacks();
        //todo: complete test
    }

    @Test
    public void testGetStackInfo() throws Exception {
        StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, STACK_VERSION_HDP);
        Assert.assertEquals(stackInfo.getName(), STACK_NAME_HDP);
        Assert.assertEquals(stackInfo.getVersion(), STACK_VERSION_HDP);
        Assert.assertEquals(stackInfo.getMinUpgradeVersion(), STACK_MINIMAL_VERSION_HDP);
        try {
            metaInfo.getStack(STACK_NAME_HDP, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }
    }

    @Test
    public void testGetStackParentVersions() throws Exception {
        List<String> parents = metaInfo.getStackParentVersions(STACK_NAME_HDP, "2.0.8");
        Assert.assertEquals(3, parents.size());
        Assert.assertEquals("2.0.7", parents.get(0));
        Assert.assertEquals("2.0.6", parents.get(1));
        Assert.assertEquals("2.0.5", parents.get(2));
    }

    @Test
    public void testGetProperties() throws Exception {
        Set<PropertyInfo> properties = metaInfo.getServiceProperties(STACK_NAME_HDP, STACK_VERSION_HDP,
                SERVICE_NAME_HDFS);
        Assert.assertEquals(properties.size(), PROPERTIES_CNT);
    }

    @Test
    public void testGetPropertiesNoName() throws Exception {
        Set<PropertyInfo> properties = metaInfo.getPropertiesByName(STACK_NAME_HDP, STACK_VERSION_HDP,
                SERVICE_NAME_HDFS, PROPERTY_NAME);
        Assert.assertEquals(1, properties.size());
        for (PropertyInfo propertyInfo : properties) {
            Assert.assertEquals(PROPERTY_NAME, propertyInfo.getName());
            Assert.assertEquals(FILE_NAME, propertyInfo.getFilename());
        }

        try {
            metaInfo.getPropertiesByName(STACK_NAME_HDP, STACK_VERSION_HDP, SERVICE_NAME_HDFS, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }

    }

    @Test
    public void testGetPropertiesSharedName() throws Exception {
        Set<PropertyInfo> properties = metaInfo.getPropertiesByName(STACK_NAME_HDP, STACK_VERSION_HDP_02,
                SERVICE_NAME_HDFS, SHARED_PROPERTY_NAME);
        Assert.assertEquals(2, properties.size());
        for (PropertyInfo propertyInfo : properties) {
            Assert.assertEquals(SHARED_PROPERTY_NAME, propertyInfo.getName());
            Assert.assertTrue(propertyInfo.getFilename().equals(HADOOP_ENV_FILE_NAME)
                    || propertyInfo.getFilename().equals(HDFS_LOG4J_FILE_NAME));
        }
    }

    @Test
    public void testGetOperatingSystems() throws Exception {
        Set<OperatingSystemInfo> operatingSystems = metaInfo.getOperatingSystems(STACK_NAME_HDP, STACK_VERSION_HDP);
        Assert.assertEquals(OS_CNT, operatingSystems.size());
    }

    @Test
    public void testGetOperatingSystem() throws Exception {
        OperatingSystemInfo operatingSystem = metaInfo.getOperatingSystem(STACK_NAME_HDP, STACK_VERSION_HDP,
                OS_TYPE);
        Assert.assertEquals(operatingSystem.getOsType(), OS_TYPE);

        try {
            metaInfo.getOperatingSystem(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE);
        } catch (StackAccessException e) {
        }
    }

    @Test
    public void isOsSupported() throws Exception {
        Assert.assertTrue(metaInfo.isOsSupported("redhat5"));
        Assert.assertTrue(metaInfo.isOsSupported("centos5"));
        Assert.assertTrue(metaInfo.isOsSupported("oraclelinux5"));
        Assert.assertTrue(metaInfo.isOsSupported("redhat6"));
        Assert.assertTrue(metaInfo.isOsSupported("centos6"));
        Assert.assertTrue(metaInfo.isOsSupported("oraclelinux6"));
        Assert.assertTrue(metaInfo.isOsSupported("suse11"));
        Assert.assertTrue(metaInfo.isOsSupported("sles11"));
        Assert.assertTrue(metaInfo.isOsSupported("ubuntu12"));
        Assert.assertTrue(metaInfo.isOsSupported("win2008server6"));
        Assert.assertTrue(metaInfo.isOsSupported("win2008serverr26"));
        Assert.assertTrue(metaInfo.isOsSupported("win2012server6"));
        Assert.assertTrue(metaInfo.isOsSupported("win2012serverr26"));
    }

    @Test
    public void testExtendedStackDefinition() throws Exception {
        StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, EXT_STACK_NAME);
        Assert.assertTrue(stackInfo != null);
        Collection<ServiceInfo> serviceInfos = stackInfo.getServices();
        Assert.assertFalse(serviceInfos.isEmpty());
        Assert.assertTrue(serviceInfos.size() > 1);
        ServiceInfo deletedService = null;
        ServiceInfo redefinedService = null;
        for (ServiceInfo serviceInfo : serviceInfos) {
            if (serviceInfo.getName().equals("SQOOP")) {
                deletedService = serviceInfo;
            }
            if (serviceInfo.getName().equals("YARN")) {
                redefinedService = serviceInfo;
            }
        }
        Assert.assertNull("SQOOP is a deleted service, should not be a part of " + "the extended stack.",
                deletedService);
        Assert.assertNotNull(redefinedService);
        // Components
        Assert.assertEquals("YARN service is expected to be defined with 3 active" + " components.", 3,
                redefinedService.getComponents().size());
        Assert.assertEquals("TEZ is expected to be a part of extended stack " + "definition", "TEZ",
                redefinedService.getClientComponent().getName());
        Assert.assertFalse("YARN CLIENT is a deleted component.",
                redefinedService.getClientComponent().getName().equals("YARN_CLIENT"));
        // Properties
        Assert.assertNotNull(redefinedService.getProperties());
        Assert.assertTrue(redefinedService.getProperties().size() > 4);
        PropertyInfo deleteProperty1 = null;
        PropertyInfo deleteProperty2 = null;
        PropertyInfo redefinedProperty1 = null;
        PropertyInfo redefinedProperty2 = null;
        PropertyInfo redefinedProperty3 = null;
        PropertyInfo inheritedProperty = null;
        PropertyInfo newProperty = null;
        PropertyInfo originalProperty = null;

        for (PropertyInfo propertyInfo : redefinedService.getProperties()) {
            if (propertyInfo.getName().equals("yarn.resourcemanager.resource-tracker.address")) {
                deleteProperty1 = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.resourcemanager.scheduler.address")) {
                deleteProperty2 = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.resourcemanager.address")) {
                redefinedProperty1 = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.resourcemanager.admin.address")) {
                redefinedProperty2 = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.nodemanager.health-checker.interval-ms")) {
                redefinedProperty3 = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.nodemanager.address")) {
                inheritedProperty = propertyInfo;
            } else if (propertyInfo.getName().equals("new-yarn-property")) {
                newProperty = propertyInfo;
            } else if (propertyInfo.getName().equals("yarn.nodemanager.aux-services")) {
                originalProperty = propertyInfo;
            }
        }

        Assert.assertNull(deleteProperty1);
        Assert.assertNull(deleteProperty2);
        Assert.assertNotNull(redefinedProperty1);
        Assert.assertNotNull(redefinedProperty2);
        Assert.assertNotNull("yarn.nodemanager.address expected to be inherited " + "from parent",
                inheritedProperty);
        Assert.assertEquals("localhost:100009", redefinedProperty1.getValue());
        // Parent property value will result in property being present in the child stack
        Assert.assertNotNull(redefinedProperty3);
        Assert.assertEquals("135000", redefinedProperty3.getValue());
        // Child can override parent property to empty value
        Assert.assertEquals("", redefinedProperty2.getValue());
        // New property
        Assert.assertNotNull(newProperty);
        Assert.assertEquals("some-value", newProperty.getValue());
        Assert.assertEquals("some description.", newProperty.getDescription());
        Assert.assertEquals("yarn-site.xml", newProperty.getFilename());
        // Original property
        Assert.assertNotNull(originalProperty);
        Assert.assertEquals("mapreduce.shuffle", originalProperty.getValue());
        Assert.assertEquals("Auxilliary services of NodeManager", originalProperty.getDescription());
        Assert.assertEquals(6, redefinedService.getConfigDependencies().size());
        Assert.assertEquals(7, redefinedService.getConfigDependenciesWithComponents().size());
    }

    @Test
    public void testPropertyCount() throws Exception {
        Set<PropertyInfo> properties = metaInfo.getServiceProperties(STACK_NAME_HDP, STACK_VERSION_HDP_02,
                SERVICE_NAME_HDFS);
        // 3 empty properties
        Assert.assertEquals(103, properties.size());
    }

    @Test
    public void testBadStack() throws Exception {
        File stackRoot = new File("src/test/resources/bad-stacks");
        File version = new File("src/test/resources/version");
        if (System.getProperty("os.name").contains("Windows")) {
            stackRoot = new File(ClassLoader.getSystemClassLoader().getResource("bad-stacks").getPath());
            version = new File(new File(ClassLoader.getSystemClassLoader().getResource("").getPath()).getParent(),
                    "version");
        }
        LOG.info("Stacks file " + stackRoot.getAbsolutePath());

        TestAmbariMetaInfo ambariMetaInfo = createAmbariMetaInfo(stackRoot, version, true);
        Assert.assertEquals(1, ambariMetaInfo.getStackManager().getStacks().size());
        Assert.assertEquals(false, ambariMetaInfo.getStackManager().getStack("HDP", "0.1").isValid());
        Assert.assertEquals(2, ambariMetaInfo.getStackManager().getStack("HDP", "0.1").getErrors().size());

    }

    @Test
    public void testMetricsJson() throws Exception {
        ServiceInfo svc = metaInfo.getService(STACK_NAME_HDP, "2.0.5", "HDFS");
        Assert.assertNotNull(svc);
        Assert.assertNotNull(svc.getMetricsFile());

        svc = metaInfo.getService(STACK_NAME_HDP, "2.0.6", "HDFS");
        Assert.assertNotNull(svc);
        Assert.assertNotNull(svc.getMetricsFile());

        List<MetricDefinition> list = metaInfo.getMetrics(STACK_NAME_HDP, "2.0.5", "HDFS", "NAMENODE", "Component");
        Assert.assertNotNull(list);

        list = metaInfo.getMetrics(STACK_NAME_HDP, "2.0.5", "HDFS", "DATANODE", "Component");
        Assert.assertNull(list);

        List<MetricDefinition> list0 = metaInfo.getMetrics(STACK_NAME_HDP, "2.0.5", "HDFS", "DATANODE",
                "Component");
        Assert.assertNull(list0);
        Assert.assertTrue("Expecting subsequent calls to use a cached value for the definition", list == list0);

        // not explicitly defined, uses 2.0.5
        list = metaInfo.getMetrics(STACK_NAME_HDP, "2.0.6", "HDFS", "DATANODE", "Component");
        Assert.assertNull(list);
    }

    @Test
    public void testKerberosJson() throws Exception {
        ServiceInfo svc;

        svc = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertNotNull(svc);

        File kerberosDescriptorFile1 = svc.getKerberosDescriptorFile();
        Assert.assertNotNull(kerberosDescriptorFile1);
        Assert.assertTrue(kerberosDescriptorFile1.exists());

        svc = metaInfo.getService(STACK_NAME_HDP, "2.1.1", "HDFS");
        Assert.assertNotNull(svc);

        File kerberosDescriptorFile2 = svc.getKerberosDescriptorFile();
        Assert.assertNotNull(kerberosDescriptorFile1);
        Assert.assertTrue(kerberosDescriptorFile1.exists());

        Assert.assertEquals(kerberosDescriptorFile1, kerberosDescriptorFile2);

        svc = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HDFS");
        Assert.assertNotNull(svc);

        File kerberosDescriptorFile3 = svc.getKerberosDescriptorFile();
        Assert.assertNull(kerberosDescriptorFile3);
    }

    @Test
    public void testGanglia134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "GANGLIA");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(2, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("GANGLIA_SERVER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("GANGLIA_MONITOR")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertTrue(component.getAutoDeploy().isEnabled());
                // cardinality
                Assert.assertEquals("ALL", component.getCardinality());
            }
        }
    }

    @Test
    public void testHBase134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HBASE");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(3, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("HBASE_MASTER")) {
                // dependencies
                List<DependencyInfo> dependencyList = component.getDependencies();
                Assert.assertEquals(2, dependencyList.size());
                for (DependencyInfo dependency : dependencyList) {
                    if (dependency.getName().equals("HDFS/HDFS_CLIENT")) {
                        Assert.assertEquals("host", dependency.getScope());
                        Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
                    } else if (dependency.getName().equals("ZOOKEEPER/ZOOKEEPER_SERVER")) {
                        Assert.assertEquals("cluster", dependency.getScope());
                        AutoDeployInfo autoDeploy = dependency.getAutoDeploy();
                        Assert.assertEquals(true, autoDeploy.isEnabled());
                        Assert.assertEquals("HBASE/HBASE_MASTER", autoDeploy.getCoLocate());
                    } else {
                        Assert.fail("Unexpected dependency");
                    }
                }
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("HBASE_REGIONSERVER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1+", component.getCardinality());
            }
            if (name.equals("HBASE_CLIENT")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testHDFS134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HDFS");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(4, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("NAMENODE")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("DATANODE")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1+", component.getCardinality());
            }
            if (name.equals("SECONDARY_NAMENODE")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("HDFS_CLIENT")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testHive134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HIVE");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(4, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("HIVE_METASTORE")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                AutoDeployInfo autoDeploy = component.getAutoDeploy();
                Assert.assertTrue(autoDeploy.isEnabled());
                Assert.assertEquals("HIVE/HIVE_SERVER", autoDeploy.getCoLocate());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("HIVE_SERVER")) {
                // dependencies
                List<DependencyInfo> dependencyList = component.getDependencies();
                Assert.assertEquals(1, dependencyList.size());
                DependencyInfo dependency = dependencyList.get(0);
                Assert.assertEquals("ZOOKEEPER/ZOOKEEPER_SERVER", dependency.getName());
                Assert.assertEquals("cluster", dependency.getScope());
                AutoDeployInfo autoDeploy = dependency.getAutoDeploy();
                Assert.assertTrue(autoDeploy.isEnabled());
                Assert.assertEquals("HIVE/HIVE_SERVER", autoDeploy.getCoLocate());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("MYSQL_SERVER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                AutoDeployInfo autoDeploy = component.getAutoDeploy();
                Assert.assertTrue(autoDeploy.isEnabled());
                Assert.assertEquals("HIVE/HIVE_SERVER", autoDeploy.getCoLocate());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("HIVE_CLIENT")) {
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testHue134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HUE");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(1, componentList.size());
        ComponentInfo component = componentList.get(0);
        Assert.assertEquals("HUE_SERVER", component.getName());
        // dependencies
        Assert.assertEquals(0, component.getDependencies().size());
        // component auto deploy
        Assert.assertNull(component.getAutoDeploy());
        // cardinality
        Assert.assertEquals("1", component.getCardinality());
    }

    @Test
    public void testMapReduce134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "MAPREDUCE");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(4, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("JOBTRACKER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("TASKTRACKER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1+", component.getCardinality());
            }
            if (name.equals("HISTORYSERVER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                AutoDeployInfo autoDeploy = component.getAutoDeploy();
                Assert.assertTrue(autoDeploy.isEnabled());
                Assert.assertEquals("MAPREDUCE/JOBTRACKER", autoDeploy.getCoLocate());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("MAPREDUCE_CLIENT")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testOozie134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "OOZIE");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(2, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("OOZIE_SERVER")) {
                // dependencies
                List<DependencyInfo> dependencyList = component.getDependencies();
                Assert.assertEquals(2, dependencyList.size());
                for (DependencyInfo dependency : dependencyList) {
                    if (dependency.getName().equals("HDFS/HDFS_CLIENT")) {
                        Assert.assertEquals("host", dependency.getScope());
                        Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
                    } else if (dependency.getName().equals("MAPREDUCE/MAPREDUCE_CLIENT")) {
                        Assert.assertEquals("host", dependency.getScope());
                        Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
                    } else {
                        Assert.fail("Unexpected dependency");
                    }
                }
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("OOZIE_CLIENT")) {
                // dependencies
                List<DependencyInfo> dependencyList = component.getDependencies();
                Assert.assertEquals(2, dependencyList.size());
                for (DependencyInfo dependency : dependencyList) {
                    if (dependency.getName().equals("HDFS/HDFS_CLIENT")) {
                        Assert.assertEquals("host", dependency.getScope());
                        Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
                    } else if (dependency.getName().equals("MAPREDUCE/MAPREDUCE_CLIENT")) {
                        Assert.assertEquals("host", dependency.getScope());
                        Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
                    } else {
                        Assert.fail("Unexpected dependency");
                    }
                }
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testPig134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "PIG");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(1, componentList.size());
        ComponentInfo component = componentList.get(0);
        Assert.assertEquals("PIG", component.getName());
        // dependencies
        Assert.assertEquals(0, component.getDependencies().size());
        // component auto deploy
        Assert.assertNull(component.getAutoDeploy());
        // cardinality
        Assert.assertEquals("0+", component.getCardinality());
    }

    @Test
    public void testSqoop134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "SQOOP");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(1, componentList.size());
        ComponentInfo component = componentList.get(0);
        Assert.assertEquals("SQOOP", component.getName());
        // dependencies
        List<DependencyInfo> dependencyList = component.getDependencies();
        Assert.assertEquals(2, dependencyList.size());
        for (DependencyInfo dependency : dependencyList) {
            if (dependency.getName().equals("HDFS/HDFS_CLIENT")) {
                Assert.assertEquals("host", dependency.getScope());
                Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
            } else if (dependency.getName().equals("MAPREDUCE/MAPREDUCE_CLIENT")) {
                Assert.assertEquals("host", dependency.getScope());
                Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
            } else {
                Assert.fail("Unexpected dependency");
            }
        }
        // component auto deploy
        Assert.assertNull(component.getAutoDeploy());
        // cardinality
        Assert.assertEquals("0+", component.getCardinality());
    }

    @Test
    public void testWebHCat134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "WEBHCAT");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(1, componentList.size());
        ComponentInfo component = componentList.get(0);
        Assert.assertEquals("WEBHCAT_SERVER", component.getName());
        // dependencies
        List<DependencyInfo> dependencyList = component.getDependencies();
        Assert.assertEquals(4, dependencyList.size());
        for (DependencyInfo dependency : dependencyList) {
            if (dependency.getName().equals("HDFS/HDFS_CLIENT")) {
                Assert.assertEquals("host", dependency.getScope());
                Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
            } else if (dependency.getName().equals("MAPREDUCE/MAPREDUCE_CLIENT")) {
                Assert.assertEquals("host", dependency.getScope());
                Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
            } else if (dependency.getName().equals("ZOOKEEPER/ZOOKEEPER_SERVER")) {
                Assert.assertEquals("cluster", dependency.getScope());
                AutoDeployInfo autoDeploy = dependency.getAutoDeploy();
                Assert.assertEquals(true, autoDeploy.isEnabled());
                Assert.assertEquals("WEBHCAT/WEBHCAT_SERVER", autoDeploy.getCoLocate());
            } else if (dependency.getName().equals("ZOOKEEPER/ZOOKEEPER_CLIENT")) {
                Assert.assertEquals("host", dependency.getScope());
                Assert.assertEquals(true, dependency.getAutoDeploy().isEnabled());
            } else {
                Assert.fail("Unexpected dependency");
            }
        }
        // component auto deploy
        Assert.assertNull(component.getAutoDeploy());
        // cardinality
        Assert.assertEquals("1", component.getCardinality());
    }

    @Test
    public void testZooKeeper134Dependencies() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "ZOOKEEPER");
        List<ComponentInfo> componentList = service.getComponents();
        Assert.assertEquals(2, componentList.size());
        for (ComponentInfo component : componentList) {
            String name = component.getName();
            if (name.equals("ZOOKEEPER_SERVER")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("1", component.getCardinality());
            }
            if (name.equals("ZOOKEEPER_CLIENT")) {
                // dependencies
                Assert.assertEquals(0, component.getDependencies().size());
                // component auto deploy
                Assert.assertNull(component.getAutoDeploy());
                // cardinality
                Assert.assertEquals("0+", component.getCardinality());
            }
        }
    }

    @Test
    public void testHooksDirInheritance() throws Exception {
        String hookAssertionTemplate = "HDP/%s/hooks";
        if (System.getProperty("os.name").contains("Windows")) {
            hookAssertionTemplate = "HDP\\%s\\hooks";
        }
        // Test hook dir determination in parent
        StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.6");
        Assert.assertEquals(String.format(hookAssertionTemplate, "2.0.6"), stackInfo.getStackHooksFolder());
        // Test hook dir inheritance
        stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.7");
        Assert.assertEquals(String.format(hookAssertionTemplate, "2.0.6"), stackInfo.getStackHooksFolder());
        // Test hook dir override
        stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.8");
        Assert.assertEquals(String.format(hookAssertionTemplate, "2.0.8"), stackInfo.getStackHooksFolder());
    }

    @Test
    public void testServicePackageDirInheritance() throws Exception {
        String assertionTemplate07 = StringUtils
                .join(new String[] { "stacks", "HDP", "2.0.7", "services", "%s", "package" }, File.separator);
        String assertionTemplate08 = StringUtils
                .join(new String[] { "stacks", "HDP", "2.0.8", "services", "%s", "package" }, File.separator);
        // Test service package dir determination in parent
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HBASE");
        Assert.assertEquals(String.format(assertionTemplate07, "HBASE"), service.getServicePackageFolder());

        service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HDFS");
        Assert.assertEquals(String.format(assertionTemplate07, "HDFS"), service.getServicePackageFolder());
        // Test service package dir inheritance
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HBASE");
        Assert.assertEquals(String.format(assertionTemplate07, "HBASE"), service.getServicePackageFolder());
        // Test service package dir override
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertEquals(String.format(assertionTemplate08, "HDFS"), service.getServicePackageFolder());
    }

    @Test
    public void testServiceCommandScriptInheritance() throws Exception {
        // Test command script determination in parent
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HDFS");
        Assert.assertEquals("scripts/service_check_1.py", service.getCommandScript().getScript());
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HBASE");
        Assert.assertEquals("scripts/service_check.py", service.getCommandScript().getScript());
        // Test command script inheritance
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HBASE");
        Assert.assertEquals("scripts/service_check.py", service.getCommandScript().getScript());
        // Test command script override
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertEquals("scripts/service_check_2.py", service.getCommandScript().getScript());
    }

    @Test
    public void testComponentCommandScriptInheritance() throws Exception {
        // Test command script determination in parent
        ComponentInfo component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.7", "HDFS", "HDFS_CLIENT");
        Assert.assertEquals("scripts/hdfs_client.py", component.getCommandScript().getScript());
        component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.7", "HBASE", "HBASE_MASTER");
        Assert.assertEquals("scripts/hbase_master.py", component.getCommandScript().getScript());
        // Test command script inheritance
        component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.8", "HBASE", "HBASE_MASTER");
        Assert.assertEquals("scripts/hbase_master.py", component.getCommandScript().getScript());
        // Test command script override
        component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.8", "HDFS", "HDFS_CLIENT");
        Assert.assertEquals("scripts/hdfs_client_overridden.py", component.getCommandScript().getScript());
    }

    @Test
    public void testServiceCustomCommandScriptInheritance() throws Exception {
        // Test custom command script determination in parent
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HDFS");

        CustomCommandDefinition ccd = findCustomCommand("RESTART", service);
        Assert.assertEquals("scripts/restart_parent.py", ccd.getCommandScript().getScript());

        ccd = findCustomCommand("YET_ANOTHER_PARENT_SRV_COMMAND", service);
        Assert.assertEquals("scripts/yet_another_parent_srv_command.py", ccd.getCommandScript().getScript());

        Assert.assertEquals(2, service.getCustomCommands().size());

        // Test custom command script inheritance
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertEquals(3, service.getCustomCommands().size());

        ccd = findCustomCommand("YET_ANOTHER_PARENT_SRV_COMMAND", service);
        Assert.assertEquals("scripts/yet_another_parent_srv_command.py", ccd.getCommandScript().getScript());

        // Test custom command script override
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");

        ccd = findCustomCommand("RESTART", service);
        Assert.assertEquals("scripts/restart_child.py", ccd.getCommandScript().getScript());

        ccd = findCustomCommand("YET_ANOTHER_CHILD_SRV_COMMAND", service);
        Assert.assertEquals("scripts/yet_another_child_srv_command.py", ccd.getCommandScript().getScript());
    }

    @Test
    public void testChildCustomCommandScriptInheritance() throws Exception {
        // Test custom command script determination in parent
        ComponentInfo component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.7", "HDFS", "NAMENODE");

        CustomCommandDefinition ccd = findCustomCommand("DECOMMISSION", component);
        Assert.assertEquals("scripts/namenode_dec.py", ccd.getCommandScript().getScript());

        ccd = findCustomCommand("YET_ANOTHER_PARENT_COMMAND", component);
        Assert.assertEquals("scripts/yet_another_parent_command.py", ccd.getCommandScript().getScript());

        ccd = findCustomCommand("REBALANCEHDFS", component);
        Assert.assertEquals("scripts/namenode.py", ccd.getCommandScript().getScript());
        Assert.assertTrue(ccd.isBackground());

        Assert.assertEquals(3, component.getCustomCommands().size());

        // Test custom command script inheritance
        component = metaInfo.getComponent(STACK_NAME_HDP, "2.0.8", "HDFS", "NAMENODE");
        Assert.assertEquals(4, component.getCustomCommands().size());

        ccd = findCustomCommand("YET_ANOTHER_PARENT_COMMAND", component);
        Assert.assertEquals("scripts/yet_another_parent_command.py", ccd.getCommandScript().getScript());

        // Test custom command script override
        ccd = findCustomCommand("DECOMMISSION", component);
        Assert.assertEquals("scripts/namenode_dec_overr.py", ccd.getCommandScript().getScript());

        ccd = findCustomCommand("YET_ANOTHER_CHILD_COMMAND", component);
        Assert.assertEquals("scripts/yet_another_child_command.py", ccd.getCommandScript().getScript());
    }

    @Test
    public void testServiceOsSpecificsInheritance() throws Exception {
        // Test command script determination in parent
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HDFS");
        Assert.assertEquals("parent-package-def",
                service.getOsSpecifics().get("any").getPackages().get(0).getName());
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "HBASE");
        Assert.assertEquals(2, service.getOsSpecifics().keySet().size());
        // Test command script inheritance
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HBASE");
        Assert.assertEquals(2, service.getOsSpecifics().keySet().size());
        // Test command script override
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertEquals("child-package-def",
                service.getOsSpecifics().get("any").getPackages().get(0).getName());
    }

    @Test
    public void testServiceSchemaVersionInheritance() throws Exception {
        // Check parent
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "SQOOP");
        Assert.assertEquals("2.0", service.getSchemaVersion());
        // Test child service metainfo after merge
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "SQOOP");
        Assert.assertEquals("2.0", service.getSchemaVersion());
    }

    private CustomCommandDefinition findCustomCommand(String ccName, ServiceInfo service) {
        for (CustomCommandDefinition ccd : service.getCustomCommands()) {
            if (ccd.getName().equals(ccName)) {
                return ccd;
            }
        }
        return null;
    }

    private CustomCommandDefinition findCustomCommand(String ccName, ComponentInfo component) {
        for (CustomCommandDefinition ccd : component.getCustomCommands()) {
            if (ccd.getName().equals(ccName)) {
                return ccd;
            }
        }
        return null;
    }

    @Test
    public void testCustomConfigDir() throws Exception {

        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.7", "MAPREDUCE2");

        // assert that the property was found in a differently-named directory
        // cannot check the dirname itself since extended stacks won't carry over
        // the name

        boolean found = false;
        for (PropertyInfo pi : service.getProperties()) {
            if (pi.getName().equals("mr2-prop")) {
                Assert.assertEquals("some-mr2-value", pi.getValue());
                found = true;
            }
        }

        Assert.assertTrue(found);
    }

    @Test
    public void testLatestRepo() throws Exception {
        // ensure that all of the latest repo retrieval tasks have completed
        StackManager sm = metaInfo.getStackManager();
        int maxWait = 45000;
        int waitTime = 0;
        while (waitTime < maxWait && !sm.haveAllRepoUrlsBeenResolved()) {
            Thread.sleep(5);
            waitTime += 5;
        }

        if (waitTime >= maxWait) {
            fail("Latest Repo tasks did not complete");
        }

        for (RepositoryInfo ri : metaInfo.getRepositories("HDP", "2.1.1", "centos6")) {
            Assert.assertEquals("Expected the base url to be set properly",
                    "http://s3.amazonaws.com/dev.hortonworks.com/HDP/centos6/2.x/BUILDS/2.1.1.0-118",
                    ri.getLatestBaseUrl());
            Assert.assertEquals("Expected the default URL to be the same as in the xml file",
                    "http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0", ri.getDefaultBaseUrl());
        }

        for (RepositoryInfo ri : metaInfo.getRepositories("HDP", "2.1.1", "suse11")) {
            Assert.assertEquals("Expected hdp.json to be stripped from the url",
                    "http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11/2.x/BUILDS/2.1.1.0-118",
                    ri.getLatestBaseUrl());
        }

        for (RepositoryInfo ri : metaInfo.getRepositories("HDP", "2.1.1", "sles11")) {
            Assert.assertEquals("http://s3.amazonaws.com/dev.hortonworks.com/HDP/suse11/2.x/BUILDS/2.1.1.0-118",
                    ri.getLatestBaseUrl());
        }
    }

    @Test
    public void testGetComponentDependency() throws AmbariException {
        DependencyInfo dependency = metaInfo.getComponentDependency("HDP", "1.3.4", "HIVE", "HIVE_SERVER",
                "ZOOKEEPER_SERVER");
        assertEquals("ZOOKEEPER/ZOOKEEPER_SERVER", dependency.getName());
        assertEquals("ZOOKEEPER_SERVER", dependency.getComponentName());
        assertEquals("ZOOKEEPER", dependency.getServiceName());
        assertEquals("cluster", dependency.getScope());
    }

    @Test
    public void testGetComponentDependencies() throws AmbariException {
        List<DependencyInfo> dependencies = metaInfo.getComponentDependencies("HDP", "1.3.4", "HBASE",
                "HBASE_MASTER");
        assertEquals(2, dependencies.size());

        DependencyInfo dependency = dependencies.get(0);
        assertEquals("HDFS/HDFS_CLIENT", dependency.getName());
        assertEquals("HDFS_CLIENT", dependency.getComponentName());
        assertEquals("HDFS", dependency.getServiceName());
        assertEquals("host", dependency.getScope());

        dependency = dependencies.get(1);
        assertEquals("ZOOKEEPER/ZOOKEEPER_SERVER", dependency.getName());
        assertEquals("ZOOKEEPER_SERVER", dependency.getComponentName());
        assertEquals("ZOOKEEPER", dependency.getServiceName());
        assertEquals("cluster", dependency.getScope());
    }

    @Test
    public void testPasswordPropertyAttribute() throws Exception {
        ServiceInfo service = metaInfo.getService(STACK_NAME_HDP, "2.0.1", "HIVE");
        List<PropertyInfo> propertyInfoList = service.getProperties();
        Assert.assertNotNull(propertyInfoList);
        PropertyInfo passwordProperty = null;
        for (PropertyInfo propertyInfo : propertyInfoList) {
            if (propertyInfo.isRequireInput()
                    && propertyInfo.getPropertyTypes().contains(PropertyInfo.PropertyType.PASSWORD)) {
                passwordProperty = propertyInfo;
            } else {
                Assert.assertTrue(propertyInfo.getPropertyTypes().isEmpty());
            }
        }
        Assert.assertNotNull(passwordProperty);
        Assert.assertEquals("javax.jdo.option.ConnectionPassword", passwordProperty.getName());
    }

    @Test
    public void testAlertsJson() throws Exception {
        ServiceInfo svc = metaInfo.getService(STACK_NAME_HDP, "2.0.5", "HDFS");
        Assert.assertNotNull(svc);
        Assert.assertNotNull(svc.getAlertsFile());

        svc = metaInfo.getService(STACK_NAME_HDP, "2.0.6", "HDFS");
        Assert.assertNotNull(svc);
        Assert.assertNotNull(svc.getAlertsFile());

        svc = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HDFS");
        Assert.assertNotNull(svc);
        Assert.assertNull(svc.getAlertsFile());

        Set<AlertDefinition> set = metaInfo.getAlertDefinitions(STACK_NAME_HDP, "2.0.5", "HDFS");
        Assert.assertNotNull(set);
        Assert.assertTrue(set.size() > 0);

        // find two different definitions and test each one
        AlertDefinition nameNodeProcess = null;
        AlertDefinition nameNodeCpu = null;
        AlertDefinition datanodeStorage = null;
        AlertDefinition ignoreHost = null;

        Iterator<AlertDefinition> iterator = set.iterator();
        while (iterator.hasNext()) {
            AlertDefinition definition = iterator.next();
            if (definition.getName().equals("namenode_process")) {
                nameNodeProcess = definition;
            }

            if (definition.getName().equals("namenode_cpu")) {
                nameNodeCpu = definition;
            }

            if (definition.getName().equals("datanode_storage")) {
                datanodeStorage = definition;
            }

            if (definition.getName().equals("hdfs_ignore_host_test")) {
                ignoreHost = definition;
            }
        }

        assertNotNull(nameNodeProcess);
        assertNotNull(nameNodeCpu);
        assertNotNull(ignoreHost);

        assertEquals("NameNode Host CPU Utilization", nameNodeCpu.getLabel());

        // test namenode_process
        assertFalse(nameNodeProcess.isHostIgnored());
        assertEquals("A description of namenode_process", nameNodeProcess.getDescription());
        Source source = nameNodeProcess.getSource();
        assertNotNull(source);
        assertNotNull(((PortSource) source).getPort());
        Reporting reporting = source.getReporting();
        assertNotNull(reporting);
        assertNotNull(reporting.getOk());
        assertNotNull(reporting.getOk().getText());
        assertNull(reporting.getOk().getValue());
        assertNotNull(reporting.getCritical());
        assertNotNull(reporting.getCritical().getText());
        assertNull(reporting.getCritical().getValue());
        assertNull(reporting.getWarning());

        // test namenode_cpu
        assertFalse(nameNodeCpu.isHostIgnored());
        assertEquals("A description of namenode_cpu", nameNodeCpu.getDescription());
        source = nameNodeCpu.getSource();
        assertNotNull(source);
        reporting = source.getReporting();
        assertNotNull(reporting);
        assertNotNull(reporting.getOk());
        assertNotNull(reporting.getOk().getText());
        assertNull(reporting.getOk().getValue());
        assertNotNull(reporting.getCritical());
        assertNotNull(reporting.getCritical().getText());
        assertNotNull(reporting.getCritical().getValue());
        assertNotNull(reporting.getWarning());
        assertNotNull(reporting.getWarning().getText());
        assertNotNull(reporting.getWarning().getValue());

        // test a metric alert
        assertNotNull(datanodeStorage);
        assertEquals("A description of datanode_storage", datanodeStorage.getDescription());
        assertFalse(datanodeStorage.isHostIgnored());
        MetricSource metricSource = (MetricSource) datanodeStorage.getSource();
        assertNotNull(metricSource.getUri());
        assertNotNull(metricSource.getUri().getHttpsProperty());
        assertNotNull(metricSource.getUri().getHttpsPropertyValue());
        assertNotNull(metricSource.getUri().getHttpsUri());
        assertNotNull(metricSource.getUri().getHttpUri());
        assertEquals(12345, metricSource.getUri().getDefaultPort());

        // ignore host
        assertTrue(ignoreHost.isHostIgnored());
    }

    //todo: refactor test to use mocks instead of injector
    /**
     * Tests merging stack-based with existing definitions works
     *
     * @throws Exception
     */
    @Test
    public void testAlertDefinitionMerging() throws Exception {
        Injector injector = Guice
                .createInjector(Modules.override(new InMemoryDefaultTestModule()).with(new MockModule()));

        injector.getInstance(GuiceJpaInitializer.class);
        injector.getInstance(EntityManager.class);
        injector.getInstance(OrmTestHelper.class).createCluster();

        metaInfo.alertDefinitionDao = injector.getInstance(AlertDefinitionDAO.class);
        Class<?> c = metaInfo.getClass().getSuperclass();
        Field f = c.getDeclaredField("agentAlertDefinitions");
        f.setAccessible(true);
        f.set(metaInfo, injector.getInstance(AgentAlertDefinitions.class));

        Clusters clusters = injector.getInstance(Clusters.class);
        Cluster cluster = clusters.getClusterById(1);
        cluster.setDesiredStackVersion(new StackId(STACK_NAME_HDP, "2.0.6"));

        cluster.addService("HDFS");

        metaInfo.reconcileAlertDefinitions(clusters);

        AlertDefinitionDAO dao = injector.getInstance(AlertDefinitionDAO.class);
        List<AlertDefinitionEntity> definitions = dao.findAll();
        assertEquals(7, definitions.size());

        // figure out how many of these alerts were merged into from the
        // non-stack alerts.json
        int hostAlertCount = 0;
        for (AlertDefinitionEntity definition : definitions) {
            if (definition.getServiceName().equals("AMBARI")
                    && definition.getComponentName().equals("AMBARI_AGENT")) {
                hostAlertCount++;
            }
        }

        assertEquals(1, hostAlertCount);
        assertEquals(6, definitions.size() - hostAlertCount);

        for (AlertDefinitionEntity definition : definitions) {
            definition.setScheduleInterval(28);
            dao.merge(definition);
        }

        metaInfo.reconcileAlertDefinitions(clusters);

        definitions = dao.findAll();
        assertEquals(7, definitions.size());

        for (AlertDefinitionEntity definition : definitions) {
            assertEquals(28, definition.getScheduleInterval().intValue());
        }
    }

    @Test
    public void testKerberosDescriptor() throws Exception {
        ServiceInfo service;

        // Test that kerberos descriptor file is not available when not supplied in service definition
        service = metaInfo.getService(STACK_NAME_HDP, "2.1.1", "PIG");
        Assert.assertNotNull(service);
        Assert.assertNull(service.getKerberosDescriptorFile());

        // Test that kerberos descriptor file is available when supplied in service definition
        service = metaInfo.getService(STACK_NAME_HDP, "2.0.8", "HDFS");
        Assert.assertNotNull(service);
        Assert.assertNotNull(service.getKerberosDescriptorFile());

        // Test that kerberos descriptor file is available from inherited stack version
        service = metaInfo.getService(STACK_NAME_HDP, "2.1.1", "HDFS");
        Assert.assertNotNull(service);
        Assert.assertNotNull(service.getKerberosDescriptorFile());

        // Test that kerberos.json file can be parsed into mapped data
        Map<?, ?> kerberosDescriptorData = new Gson().fromJson(new FileReader(service.getKerberosDescriptorFile()),
                Map.class);

        Assert.assertNotNull(kerberosDescriptorData);
        Assert.assertEquals(1, kerberosDescriptorData.size());
    }

    @Test
    public void testGetKerberosDescriptor() throws AmbariException {
        KerberosDescriptor descriptor = metaInfo.getKerberosDescriptor(STACK_NAME_HDP, "2.0.8");

        Assert.assertNotNull(descriptor);
        Assert.assertNotNull(descriptor.getProperties());
        Assert.assertEquals(2, descriptor.getProperties().size());

        Assert.assertNotNull(descriptor.getIdentities());
        Assert.assertEquals(1, descriptor.getIdentities().size());
        Assert.assertEquals("spnego", descriptor.getIdentities().get(0).getName());

        Assert.assertNotNull(descriptor.getConfigurations());
        Assert.assertEquals(1, descriptor.getConfigurations().size());
        Assert.assertNotNull(descriptor.getConfigurations().get("core-site"));
        Assert.assertNotNull(descriptor.getConfiguration("core-site"));

        Assert.assertNotNull(descriptor.getServices());
        Assert.assertEquals(1, descriptor.getServices().size());
        Assert.assertNotNull(descriptor.getServices().get("HDFS"));
        Assert.assertNotNull(descriptor.getService("HDFS"));
    }

    private TestAmbariMetaInfo setupTempAmbariMetaInfo(String buildDir, boolean replayMocks) throws Exception {
        File stackRootTmp = new File(buildDir + "/ambari-metaInfo");
        File stackRoot = new File("src/test/resources/stacks");
        File version = new File("src/test/resources/version");

        if (System.getProperty("os.name").contains("Windows")) {
            stackRoot = new File(ClassLoader.getSystemClassLoader().getResource("stacks").getPath());
            version = new File(new File(ClassLoader.getSystemClassLoader().getResource("").getPath()).getParent(),
                    "version");
        }

        stackRootTmp.mkdir();
        FileUtils.copyDirectory(stackRoot, stackRootTmp);
        TestAmbariMetaInfo ambariMetaInfo = createAmbariMetaInfo(stackRootTmp, version, replayMocks);

        return ambariMetaInfo;
    }

    private TestAmbariMetaInfo createAmbariMetaInfo(File stackRoot, File versionFile, boolean replayMocks)
            throws Exception {
        TestAmbariMetaInfo metaInfo = new TestAmbariMetaInfo(stackRoot, versionFile);
        if (replayMocks) {
            metaInfo.replayAllMocks();

            try {
                metaInfo.init();
            } catch (Exception e) {
                LOG.info("Error in initializing ", e);
                throw e;
            }
            waitForAllReposToBeResolved(metaInfo);
        }

        return metaInfo;
    }

    private void waitForAllReposToBeResolved(AmbariMetaInfo metaInfo) throws Exception {
        int maxWait = 45000;
        int waitTime = 0;
        StackManager sm = metaInfo.getStackManager();
        while (waitTime < maxWait && !sm.haveAllRepoUrlsBeenResolved()) {
            Thread.sleep(5);
            waitTime += 5;
        }

        if (waitTime >= maxWait) {
            fail("Latest Repo tasks did not complete");
        }
    }

    private static class TestAmbariMetaInfo extends AmbariMetaInfo {

        MetainfoDAO metaInfoDAO;
        AlertDefinitionDAO alertDefinitionDAO;
        AlertDefinitionFactory alertDefinitionFactory;
        OsFamily osFamily;

        public TestAmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception {
            super(stackRoot, null, serverVersionFile);
            // MetainfoDAO
            metaInfoDAO = createNiceMock(MetainfoDAO.class);
            Class<?> c = getClass().getSuperclass();
            Field f = c.getDeclaredField("metaInfoDAO");
            f.setAccessible(true);
            f.set(this, metaInfoDAO);

            // ActionMetadata
            ActionMetadata actionMetadata = new ActionMetadata();
            f = c.getDeclaredField("actionMetadata");
            f.setAccessible(true);
            f.set(this, actionMetadata);

            //AlertDefinitionDAO
            alertDefinitionDAO = createNiceMock(AlertDefinitionDAO.class);
            f = c.getDeclaredField("alertDefinitionDao");
            f.setAccessible(true);
            f.set(this, alertDefinitionDAO);

            //AlertDefinitionFactory
            //alertDefinitionFactory = createNiceMock(AlertDefinitionFactory.class);
            alertDefinitionFactory = new AlertDefinitionFactory();
            f = c.getDeclaredField("alertDefinitionFactory");
            f.setAccessible(true);
            f.set(this, alertDefinitionFactory);

            //AmbariEventPublisher
            AmbariEventPublisher ambariEventPublisher = new AmbariEventPublisher();
            f = c.getDeclaredField("eventPublisher");
            f.setAccessible(true);
            f.set(this, ambariEventPublisher);

            //KerberosDescriptorFactory
            KerberosDescriptorFactory kerberosDescriptorFactory = new KerberosDescriptorFactory();
            f = c.getDeclaredField("kerberosDescriptorFactory");
            f.setAccessible(true);
            f.set(this, kerberosDescriptorFactory);

            //KerberosServiceDescriptorFactory
            KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory = new KerberosServiceDescriptorFactory();
            f = c.getDeclaredField("kerberosServiceDescriptorFactory");
            f.setAccessible(true);
            f.set(this, kerberosServiceDescriptorFactory);

            //OSFamily
            Configuration config = createNiceMock(Configuration.class);
            if (System.getProperty("os.name").contains("Windows")) {
                expect(config.getSharedResourcesDirPath())
                        .andReturn(ClassLoader.getSystemClassLoader().getResource("").getPath()).anyTimes();
            } else {
                expect(config.getSharedResourcesDirPath()).andReturn("./src/test/resources").anyTimes();
            }
            replay(config);
            osFamily = new OsFamily(config);
            f = c.getDeclaredField("os_family");
            f.setAccessible(true);
            f.set(this, osFamily);
        }

        public void replayAllMocks() {
            replay(metaInfoDAO, alertDefinitionDAO);
        }
    }
}