org.apache.slider.providers.agent.TestAgentProviderService.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.slider.providers.agent.TestAgentProviderService.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.slider.providers.agent;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FilterFileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.registry.client.api.RegistryConstants;
import org.apache.hadoop.registry.client.api.RegistryOperations;
import org.apache.hadoop.registry.client.types.ServiceRecord;
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.LocalResource;
import org.apache.hadoop.yarn.api.records.LocalResourceType;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.slider.api.ClusterDescription;
import org.apache.slider.api.ClusterDescriptionKeys;
import org.apache.slider.api.ClusterNode;
import org.apache.slider.api.InternalKeys;
import org.apache.slider.api.OptionKeys;
import org.apache.slider.common.SliderKeys;
import org.apache.slider.common.SliderXmlConfKeys;
import org.apache.slider.common.tools.SliderFileSystem;
import org.apache.slider.core.conf.AggregateConf;
import org.apache.slider.core.conf.ConfTree;
import org.apache.slider.core.conf.ConfTreeOperations;
import org.apache.slider.core.conf.MapOperations;
import org.apache.slider.core.exceptions.SliderException;
import org.apache.slider.core.launch.ContainerLauncher;
import org.apache.slider.core.registry.docstore.ExportEntry;
import org.apache.slider.core.registry.docstore.PublishedExports;
import org.apache.slider.core.registry.docstore.PublishedExportsSet;
import org.apache.slider.providers.ProviderRole;
import org.apache.slider.providers.agent.application.metadata.Application;
import org.apache.slider.providers.agent.application.metadata.CommandOrder;
import org.apache.slider.providers.agent.application.metadata.CommandScript;
import org.apache.slider.providers.agent.application.metadata.Component;
import org.apache.slider.providers.agent.application.metadata.ComponentExport;
import org.apache.slider.providers.agent.application.metadata.ConfigFile;
import org.apache.slider.providers.agent.application.metadata.DefaultConfig;
import org.apache.slider.providers.agent.application.metadata.Export;
import org.apache.slider.providers.agent.application.metadata.ExportGroup;
import org.apache.slider.providers.agent.application.metadata.Metainfo;
import org.apache.slider.providers.agent.application.metadata.MetainfoParser;
import org.apache.slider.providers.agent.application.metadata.PropertyInfo;
import org.apache.slider.server.appmaster.model.mock.MockRegistryOperations;
import org.apache.slider.server.appmaster.model.mock.MockApplicationAttemptId;
import org.apache.slider.server.appmaster.model.mock.MockApplicationId;
import org.apache.slider.server.appmaster.model.mock.MockContainerId;
import org.apache.slider.server.appmaster.model.mock.MockFileSystem;
import org.apache.slider.server.appmaster.model.mock.MockNodeId;
import org.apache.slider.server.appmaster.state.ProviderAppState;
import org.apache.slider.server.appmaster.state.StateAccessForProviders;
import org.apache.slider.server.appmaster.web.rest.agent.AgentCommandType;
import org.apache.slider.server.appmaster.web.rest.agent.CommandReport;
import org.apache.slider.server.appmaster.web.rest.agent.ComponentStatus;
import org.apache.slider.server.appmaster.web.rest.agent.ExecutionCommand;
import org.apache.slider.server.appmaster.web.rest.agent.HeartBeat;
import org.apache.slider.server.appmaster.web.rest.agent.HeartBeatResponse;
import org.apache.slider.server.appmaster.web.rest.agent.Register;
import org.apache.slider.server.appmaster.web.rest.agent.RegistrationResponse;
import org.apache.slider.server.appmaster.web.rest.agent.RegistrationStatus;
import org.apache.slider.server.services.yarnregistry.YarnRegistryViewForProviders;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyCollection;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;

public class TestAgentProviderService {
    protected static final Logger log = LoggerFactory.getLogger(TestAgentProviderService.class);
    private static final String metainfo_1_str = "<metainfo>\n" + "  <schemaVersion>2.0</schemaVersion>\n"
            + "  <application>\n" + "      <name>HBASE</name>\n" + "      <comment>\n" + "        Apache HBase\n"
            + "      </comment>\n" + "      <version>0.96.0.2.1.1</version>\n" + "      <type>YARN-APP</type>\n"
            + "      <minHadoopVersion>2.1.0</minHadoopVersion>\n"
            + "      <exportedConfigs>hbase-site,global</exportedConfigs>\n" + "      <exportGroups>\n"
            + "        <exportGroup>\n" + "          <name>QuickLinks</name>\n" + "          <exports>\n"
            + "            <export>\n" + "              <name>JMX_Endpoint</name>\n"
            + "              <value>http://${HBASE_MASTER_HOST}:${site.hbase-site.hbase.master.info.port}/jmx</value>\n"
            + "            </export>\n" + "            <export>\n" + "              <name>Master_Status</name>\n"
            + "              <value>http://${HBASE_MASTER_HOST}:${site.hbase-site.hbase.master.info.port}/master-status</value>\n"
            + "            </export>\n" + "            <export>\n" + "              <name>Comp_Endpoint</name>\n"
            + "              <value>http://${HBASE_REGIONSERVER_HOST}:${site.global.listen_port}</value>\n"
            + "            </export>\n" + "          </exports>\n" + "        </exportGroup>\n"
            + "      </exportGroups>\n" + "      <commandOrders>\n" + "        <commandOrder>\n"
            + "          <command>HBASE_REGIONSERVER-START</command>\n"
            + "          <requires>HBASE_MASTER-STARTED</requires>\n" + "        </commandOrder>\n"
            + "        <commandOrder>\n" + "          <command>A-START</command>\n"
            + "          <requires>B-STARTED</requires>\n" + "        </commandOrder>\n"
            + "      </commandOrders>\n" + "      <components>\n" + "        <component>\n"
            + "          <name>HBASE_REST</name>\n" + "          <category>MASTER</category>\n"
            + "          <commandScript>\n" + "            <script>scripts/hbase_rest.py</script>\n"
            + "            <scriptType>PYTHON</scriptType>\n" + "            <timeout>600</timeout>\n"
            + "          </commandScript>\n" + "        </component>\n" + "        <component>\n"
            + "          <name>HBASE_MASTER</name>\n" + "          <category>MASTER</category>\n"
            + "          <publishConfig>true</publishConfig>\n"
            + "          <autoStartOnFailure>true</autoStartOnFailure>\n"
            + "          <appExports>QuickLinks-JMX_Endpoint,QuickLinks-Master_Status</appExports>\n"
            + "          <compExports>QuickLinks-Comp_Endpoint</compExports>\n"
            + "          <minInstanceCount>1</minInstanceCount>\n"
            + "          <maxInstanceCount>2</maxInstanceCount>\n" + "          <commandScript>\n"
            + "            <script>scripts/hbase_master.py</script>\n"
            + "            <scriptType>PYTHON</scriptType>\n" + "            <timeout>600</timeout>\n"
            + "          </commandScript>\n" + "        </component>\n" + "        <component>\n"
            + "          <name>HBASE_REGIONSERVER</name>\n" + "          <category>SLAVE</category>\n"
            + "          <minInstanceCount>1</minInstanceCount>\n"
            + "          <autoStartOnFailure>Falsee</autoStartOnFailure>\n" + "          <commandScript>\n"
            + "            <script>scripts/hbase_regionserver.py</script>\n"
            + "            <scriptType>PYTHON</scriptType>\n" + "          </commandScript>\n"
            + "          <compExports>QuickLinks-Comp_Endpoint</compExports>\n" + "          <componentExports>\n"
            + "            <componentExport>\n" + "              <name>PropertyA</name>\n"
            + "              <value>${THIS_HOST}:${site.global.listen_port}</value>\n"
            + "            </componentExport>\n" + "            <componentExport>\n"
            + "              <name>PropertyB</name>\n" + "              <value>AConstant</value>\n"
            + "            </componentExport>\n" + "          </componentExports>\n" + "        </component>\n"
            + "      </components>\n" + "      <osSpecifics>\n" + "        <osSpecific>\n"
            + "          <osType>any</osType>\n" + "          <packages>\n" + "            <package>\n"
            + "              <type>tarball</type>\n"
            + "              <name>files/hbase-0.96.1-hadoop2-bin.tar.gz</name>\n" + "            </package>\n"
            + "          </packages>\n" + "        </osSpecific>\n" + "      </osSpecifics>\n"
            + "      <configFiles>\n" + "        <configFile>\n" + "          <type>xml</type>\n"
            + "          <fileName>hbase-site.xml</fileName>\n"
            + "          <dictionaryName>hbase-site</dictionaryName>\n" + "        </configFile>\n"
            + "        <configFile>\n" + "          <type>env</type>\n"
            + "          <fileName>hbase-env.sh</fileName>\n"
            + "          <dictionaryName>hbase-env</dictionaryName>\n" + "        </configFile>\n"
            + "      </configFiles>\n" + "  </application>\n" + "</metainfo>";
    private static final String metainfo_2_str = "<metainfo>\n" + "  <schemaVersion>2.0</schemaVersion>\n"
            + "  <application>\n" + "      <name>HBASE</name>\n" + "      <comment>\n" + "        Apache HBase\n"
            + "      </comment>\n" + "      <version>0.96.0.2.1.1</version>\n" + "      <type>YARN-APP</type>\n"
            + "      <minHadoopVersion>2.1.0</minHadoopVersion>\n" + "      <components>\n"
            + "        <component>\n" + "          <name>HBASE_MASTER</name>\n"
            + "          <category>MASTER</category>\n" + "          <publishConfig>true</publishConfig>\n"
            + "          <minInstanceCount>1</minInstanceCount>\n"
            + "          <maxInstanceCount>2</maxInstanceCount>\n" + "          <commandScript>\n"
            + "            <script>scripts/hbase_master.py</script>\n"
            + "            <scriptType>PYTHON</scriptType>\n" + "            <timeout>600</timeout>\n"
            + "          </commandScript>\n" + "        </component>\n" + "        <component>\n"
            + "          <name>HBASE_REGIONSERVER</name>\n" + "          <category>SLAVE</category>\n"
            + "          <minInstanceCount>1</minInstanceCount>\n" + "          <commandScript>\n"
            + "            <script>scripts/hbase_regionserver.py</script>\n"
            + "            <scriptType>PYTHON</scriptType>\n" + "          </commandScript>\n"
            + "        </component>\n" + "      </components>\n" + "  </application>\n" + "</metainfo>";

    @Test
    public void testRegistration() throws IOException {

        ConfTree tree = new ConfTree();
        tree.global.put(InternalKeys.INTERNAL_APPLICATION_IMAGE_PATH, ".");

        AgentProviderService aps = createAgentProviderService(new Configuration());
        ContainerLaunchContext ctx = createNiceMock(ContainerLaunchContext.class);
        AggregateConf instanceDefinition = new AggregateConf();

        instanceDefinition.setInternal(tree);
        instanceDefinition.setAppConf(tree);
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.APP_DEF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_CONF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_VERSION, ".");

        Container container = createNiceMock(Container.class);
        String role = "HBASE_MASTER";
        SliderFileSystem sliderFileSystem = createNiceMock(SliderFileSystem.class);
        ContainerLauncher launcher = createNiceMock(ContainerLauncher.class);
        Path generatedConfPath = new Path(".", "test");
        MapOperations resourceComponent = new MapOperations();
        MapOperations appComponent = new MapOperations();
        Path containerTmpDirPath = new Path(".", "test");
        FileSystem mockFs = createNiceMock(FileSystem.class);
        expect(mockFs.exists(anyObject(Path.class))).andReturn(true);
        expect(sliderFileSystem.getFileSystem()).andReturn(mockFs).anyTimes();
        expect(sliderFileSystem.createAmResource(anyObject(Path.class), anyObject(LocalResourceType.class)))
                .andReturn(createNiceMock(LocalResource.class)).anyTimes();
        expect(container.getId()).andReturn(new MockContainerId(1)).anyTimes();
        expect(container.getNodeId()).andReturn(new MockNodeId("localhost")).anyTimes();
        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);

        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(access).when(mockAps).getAmState();
        CommandScript cs = new CommandScript();
        cs.setScript("scripts/hbase_master.py");
        doReturn(cs).when(mockAps).getScriptPathFromMetainfo(anyString());
        Metainfo metainfo = new Metainfo();
        metainfo.setApplication(new Application());
        doReturn(metainfo).when(mockAps).getApplicationMetainfo(any(SliderFileSystem.class), anyString());

        Configuration conf = new Configuration();
        conf.set(RegistryConstants.KEY_REGISTRY_ZK_ROOT, RegistryConstants.DEFAULT_ZK_REGISTRY_ROOT);

        try {
            doReturn(true).when(mockAps).isMaster(anyString());
            doNothing().when(mockAps).addInstallCommand(eq("HBASE_MASTER"), eq("mockcontainer_1"),
                    any(HeartBeatResponse.class), eq("scripts/hbase_master.py"), eq(600L));
            doReturn(conf).when(mockAps).getConfig();
        } catch (SliderException e) {
        }

        doNothing().when(mockAps).processAllocatedPorts(anyString(), anyString(), anyString(), anyMap());

        doNothing().when(mockAps).publishFolderPaths(anyMap(), anyString(), anyString(), anyString());
        expect(access.isApplicationLive()).andReturn(true).anyTimes();
        ClusterDescription desc = new ClusterDescription();
        desc.setOption(OptionKeys.ZOOKEEPER_QUORUM, "host1:2181");
        desc.setInfo(OptionKeys.APPLICATION_NAME, "HBASE");
        expect(access.getClusterStatus()).andReturn(desc).anyTimes();

        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getOrAddComponent("HBASE_MASTER").put(AgentKeys.WAIT_HEARTBEAT, "0");
        treeOps.set(OptionKeys.APPLICATION_NAME, "HBASE");
        expect(access.getInstanceDefinitionSnapshot()).andReturn(aggConf);
        expect(access.getInternalsSnapshot()).andReturn(treeOps).anyTimes();
        replay(access, ctx, container, sliderFileSystem, mockFs);

        try {
            mockAps.buildContainerLaunchContext(launcher, instanceDefinition, container, role, sliderFileSystem,
                    generatedConfPath, resourceComponent, appComponent, containerTmpDirPath);
            // JDK7
        } catch (IOException he) {
            log.warn("{}", he, he);
        } catch (SliderException he) {
            log.warn("{}", he, he);
        }

        Register reg = new Register();
        reg.setResponseId(0);
        reg.setLabel("mockcontainer_1___HBASE_MASTER");
        Map<String, String> ports = new HashMap<String, String>();
        ports.put("a", "100");
        reg.setAllocatedPorts(ports);
        Map<String, String> folders = new HashMap<String, String>();
        folders.put("F1", "F2");
        reg.setLogFolders(folders);
        RegistrationResponse resp = mockAps.handleRegistration(reg);
        Assert.assertEquals(0, resp.getResponseId());
        Assert.assertEquals(RegistrationStatus.OK, resp.getResponseStatus());

        Mockito.verify(mockAps, Mockito.times(1)).processAllocatedPorts(anyString(), anyString(), anyString(),
                anyMap());

        Mockito.verify(mockAps, Mockito.times(1)).publishFolderPaths(anyMap(), anyString(), anyString(),
                anyString());

        HeartBeat hb = new HeartBeat();
        hb.setResponseId(1);
        hb.setHostname("mockcontainer_1___HBASE_MASTER");
        HeartBeatResponse hbr = mockAps.handleHeartBeat(hb);
        Assert.assertEquals(2, hbr.getResponseId());
    }

    private AggregateConf prepareConfForAgentStateTests() {
        ConfTree tree = new ConfTree();
        tree.global.put(InternalKeys.INTERNAL_APPLICATION_IMAGE_PATH, ".");

        AggregateConf instanceDefinition = new AggregateConf();
        instanceDefinition.setInternal(tree);
        instanceDefinition.setAppConf(tree);
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.APP_DEF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_CONF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_VERSION, ".");
        return instanceDefinition;
    }

    private AgentProviderService prepareProviderServiceForAgentStateTests() throws IOException {
        ContainerLaunchContext ctx = createNiceMock(ContainerLaunchContext.class);
        Container container = createNiceMock(Container.class);
        String role = "HBASE_MASTER";
        SliderFileSystem sliderFileSystem = createNiceMock(SliderFileSystem.class);
        FileSystem mockFs = new MockFileSystem();
        expect(sliderFileSystem.getFileSystem()).andReturn(new FilterFileSystem(mockFs)).anyTimes();
        expect(sliderFileSystem.createAmResource(anyObject(Path.class), anyObject(LocalResourceType.class)))
                .andReturn(createNiceMock(LocalResource.class)).anyTimes();
        expect(container.getId()).andReturn(new MockContainerId(1)).anyTimes();
        expect(container.getNodeId()).andReturn(new MockNodeId("localhost")).anyTimes();
        expect(container.getPriority()).andReturn(Priority.newInstance(1));

        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        Configuration conf = new Configuration();

        AgentProviderService aps = createAgentProviderService(conf);
        AgentProviderService mockAps = Mockito.spy(aps);

        doReturn(access).when(mockAps).getAmState();
        CommandScript cs = new CommandScript();
        cs.setScript("scripts/hbase_master.py");
        doReturn(cs).when(mockAps).getScriptPathFromMetainfo(anyString());
        Metainfo metainfo = new Metainfo();
        Application application = new Application();
        metainfo.setApplication(application);
        doReturn(metainfo).when(mockAps).getApplicationMetainfo(any(SliderFileSystem.class), anyString());
        doReturn(metainfo).when(mockAps).getMetainfo();

        try {
            doReturn(true).when(mockAps).isMaster(anyString());
            doNothing().when(mockAps).addInstallCommand(eq("HBASE_MASTER"), eq("mockcontainer_1"),
                    any(HeartBeatResponse.class), eq("scripts/hbase_master.py"), eq(600L));
            doReturn(conf).when(mockAps).getConfig();
        } catch (SliderException e) {
        }

        doNothing().when(mockAps).processAllocatedPorts(anyString(), anyString(), anyString(), anyMap());
        expect(access.isApplicationLive()).andReturn(true).anyTimes();
        ClusterDescription desc = new ClusterDescription();
        desc.setOption(OptionKeys.ZOOKEEPER_QUORUM, "host1:2181");
        desc.setInfo(OptionKeys.APPLICATION_NAME, "HBASE");
        expect(access.getClusterStatus()).andReturn(desc).anyTimes();

        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getOrAddComponent("HBASE_MASTER").put(AgentKeys.WAIT_HEARTBEAT, "0");
        treeOps.set(OptionKeys.APPLICATION_NAME, "HBASE");
        treeOps.set("java_home", "/usr/jdk7/");
        treeOps.set("site.fs.defaultFS", "hdfs://c6409.ambari.apache.org:8020");
        treeOps.set(InternalKeys.INTERNAL_DATA_DIR_PATH,
                "hdfs://c6409.ambari.apache.org:8020/user/yarn/.slider/cluster/cl1/data");
        expect(access.getInstanceDefinitionSnapshot()).andReturn(aggConf);
        expect(access.getInternalsSnapshot()).andReturn(treeOps).anyTimes();
        expect(access.getAppConfSnapshot()).andReturn(treeOps).anyTimes();
        replay(access, ctx, container, sliderFileSystem);

        List<Container> containers = new ArrayList<Container>();
        containers.add(container);
        Map<Integer, ProviderRole> providerRoleMap = new HashMap<Integer, ProviderRole>();
        ProviderRole providerRole = new ProviderRole(role, 1);
        providerRoleMap.put(1, providerRole);
        mockAps.rebuildContainerDetails(containers, "mockcontainer_1", providerRoleMap);
        return mockAps;
    }

    @Test
    public void testAgentStateStarted() throws IOException, SliderException {
        AggregateConf instanceDefinition = prepareConfForAgentStateTests();
        AgentProviderService mockAps = prepareProviderServiceForAgentStateTests();
        Register reg = new Register();
        reg.setResponseId(0);
        reg.setLabel("mockcontainer_1___HBASE_MASTER");
        Map<String, String> ports = new HashMap<String, String>();
        ports.put("a", "100");
        reg.setAllocatedPorts(ports);

        // Simulating agent in STARTED state
        reg.setActualState(State.STARTED);

        mockAps.initializeApplicationConfiguration(instanceDefinition, null);

        RegistrationResponse resp = mockAps.handleRegistration(reg);
        Assert.assertEquals(0, resp.getResponseId());
        Assert.assertEquals(RegistrationStatus.OK, resp.getResponseStatus());

        Mockito.verify(mockAps, Mockito.times(1)).processAllocatedPorts(anyString(), anyString(), anyString(),
                anyMap());

        HeartBeat hb = new HeartBeat();
        hb.setResponseId(1);
        hb.setHostname("mockcontainer_1___HBASE_MASTER");
        HeartBeatResponse hbr = mockAps.handleHeartBeat(hb);
        Assert.assertEquals(2, hbr.getResponseId());
        Assert.assertNotNull("Status command from AM cannot be null when agent's actualState "
                + "is set to STARTED during registration", hbr.getStatusCommands());
        Assert.assertTrue("Status command from AM cannot be empty when agent's actualState "
                + "is set to STARTED during registration", hbr.getStatusCommands().size() > 0);
        Assert.assertEquals(
                "AM should directly send a STATUS request if agent's actualState is "
                        + "set to STARTED during registration",
                AgentCommandType.STATUS_COMMAND, hbr.getStatusCommands().get(0).getCommandType());
        Assert.assertEquals(
                "AM should directly request for CONFIG if agent's actualState is "
                        + "set to STARTED during registration",
                "GET_CONFIG", hbr.getStatusCommands().get(0).getRoleCommand());
        Assert.assertFalse("AM cannot ask agent to restart", hbr.isRestartAgent());
    }

    @Test
    public void testAgentStateInstalled() throws IOException, SliderException {
        AggregateConf instanceDefinition = prepareConfForAgentStateTests();
        AgentProviderService mockAps = prepareProviderServiceForAgentStateTests();

        Metainfo metainfo = new Metainfo();
        Application application = new Application();
        CommandOrder cmdOrder = new CommandOrder();
        cmdOrder.setCommand("HBASE_MASTER-START");
        cmdOrder.setRequires("HBASE_MASTER-INSTALLED");
        application.addCommandOrder(cmdOrder);
        metainfo.setApplication(application);
        doReturn(metainfo).when(mockAps).getApplicationMetainfo(any(SliderFileSystem.class), anyString());
        doReturn(metainfo).when(mockAps).getMetainfo();
        doNothing().when(mockAps).addRoleRelatedTokens(anyMap());

        Register reg = new Register();
        reg.setResponseId(0);
        reg.setLabel("mockcontainer_1___HBASE_MASTER");
        Map<String, String> ports = new HashMap<String, String>();
        ports.put("a", "100");
        reg.setAllocatedPorts(ports);

        // Simulating agent in INSTALLED state
        reg.setActualState(State.INSTALLED);

        mockAps.initializeApplicationConfiguration(instanceDefinition, null);

        RegistrationResponse resp = mockAps.handleRegistration(reg);
        Assert.assertEquals(0, resp.getResponseId());
        Assert.assertEquals(RegistrationStatus.OK, resp.getResponseStatus());

        Mockito.verify(mockAps, Mockito.times(1)).processAllocatedPorts(anyString(), anyString(), anyString(),
                anyMap());

        HeartBeat hb = new HeartBeat();
        hb.setResponseId(1);
        hb.setHostname("mockcontainer_1___HBASE_MASTER");
        HeartBeatResponse hbr = mockAps.handleHeartBeat(hb);
        Assert.assertEquals(2, hbr.getResponseId());
        Assert.assertNotNull("Execution command from AM cannot be null when agent's actualState "
                + "is set to INSTALLED during registration", hbr.getExecutionCommands());
        Assert.assertTrue("Execution command from AM cannot be empty when agent's actualState "
                + "is set to INSTALLED during registration", hbr.getExecutionCommands().size() > 0);
        Assert.assertEquals(
                "AM should send an EXECUTION command if agent's actualState is "
                        + "set to INSTALLED during registration",
                AgentCommandType.EXECUTION_COMMAND, hbr.getExecutionCommands().get(0).getCommandType());
        Assert.assertEquals(
                "AM should request for START if agent's actualState is " + "set to INSTALLED during registration",
                "START", hbr.getExecutionCommands().get(0).getRoleCommand());
        Assert.assertFalse("AM cannot ask agent to restart", hbr.isRestartAgent());
    }

    @Test
    public void testRoleHostMapping() throws Exception {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        StateAccessForProviders appState = new ProviderAppState("undefined", null) {
            @Override
            public ClusterDescription getClusterStatus() {
                ClusterDescription cd = new ClusterDescription();
                cd.status = new HashMap<String, Object>();
                Map<String, Map<String, ClusterNode>> roleMap = new HashMap<String, Map<String, ClusterNode>>();
                ClusterNode cn1 = new ClusterNode(new MockContainerId(1));
                cn1.host = "FIRST_HOST";
                Map<String, ClusterNode> map1 = new HashMap<String, ClusterNode>();
                map1.put("FIRST_CONTAINER", cn1);
                ClusterNode cn2 = new ClusterNode(new MockContainerId(2));
                cn2.host = "SECOND_HOST";
                Map<String, ClusterNode> map2 = new HashMap<String, ClusterNode>();
                map2.put("SECOND_CONTAINER", cn2);
                ClusterNode cn3 = new ClusterNode(new MockContainerId(3));
                cn3.host = "THIRD_HOST";
                map2.put("THIRD_CONTAINER", cn3);

                roleMap.put("FIRST_ROLE", map1);
                roleMap.put("SECOND_ROLE", map2);

                cd.status.put(ClusterDescriptionKeys.KEY_CLUSTER_LIVE, roleMap);

                return cd;
            }

            @Override
            public boolean isApplicationLive() {
                return true;
            }

            @Override
            public void refreshClusterStatus() {
                // do nothing
            }
        };

        aps.setAmState(appState);
        Map<String, String> tokens = new HashMap<String, String>();
        aps.addRoleRelatedTokens(tokens);
        Assert.assertEquals(2, tokens.size());
        Assert.assertEquals("FIRST_HOST", tokens.get("${FIRST_ROLE_HOST}"));
        Assert.assertEquals("THIRD_HOST,SECOND_HOST", tokens.get("${SECOND_ROLE_HOST}"));
        aps.close();
    }

    @Test
    public void testComponentSpecificPublishes() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        AgentProviderService aps = createAgentProviderService(new Configuration());
        AgentProviderService mockAps = Mockito.spy(aps);
        doNothing().when(mockAps).publishApplicationInstanceData(anyString(), anyString(), anyCollection());
        doReturn(metainfo).when(mockAps).getMetainfo();

        Map<String, String> ports = new HashMap<String, String>();
        ports.put("global.listen_port", "10010");
        mockAps.processAndPublishComponentSpecificData(ports, "cid1", "host1", "HBASE_REGIONSERVER");
        ArgumentCaptor<Collection> entriesCaptor = ArgumentCaptor.forClass(Collection.class);
        ArgumentCaptor<String> publishNameCaptor = ArgumentCaptor.forClass(String.class);
        Mockito.verify(mockAps, Mockito.times(1)).publishApplicationInstanceData(anyString(),
                publishNameCaptor.capture(), entriesCaptor.capture());
        assert entriesCaptor.getAllValues().size() == 1;
        for (Collection coll : entriesCaptor.getAllValues()) {
            Set<Map.Entry<String, String>> entrySet = (Set<Map.Entry<String, String>>) coll;
            for (Map.Entry entry : entrySet) {
                log.info("{}:{}", entry.getKey(), entry.getValue().toString());
                if (entry.getKey().equals("PropertyA")) {
                    assert entry.getValue().toString().equals("host1:10010");
                }
            }
        }
        assert publishNameCaptor.getAllValues().size() == 1;
        for (String coll : publishNameCaptor.getAllValues()) {
            assert coll.equals("ComponentInstanceData");
        }
    }

    @Test
    public void testComponentSpecificPublishes2() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        AgentProviderService aps = createAgentProviderService(new Configuration());
        AgentProviderService mockAps = Mockito.spy(aps);
        doNothing().when(mockAps).publishApplicationInstanceData(anyString(), anyString(), anyCollection());
        doReturn(metainfo).when(mockAps).getMetainfo();
        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        doReturn(access).when(mockAps).getAmState();
        PublishedExportsSet pubExpSet = new PublishedExportsSet();
        expect(access.getPublishedExportsSet()).andReturn(pubExpSet).anyTimes();
        replay(access);

        Map<String, String> ports = new HashMap<String, String>();
        ports.put("global.listen_port", "10010");
        mockAps.processAndPublishComponentSpecificExports(ports, "mockcontainer_1", "host1", "HBASE_REGIONSERVER");
        ArgumentCaptor<Collection> entriesCaptor = ArgumentCaptor.forClass(Collection.class);
        ArgumentCaptor<String> publishNameCaptor = ArgumentCaptor.forClass(String.class);
        Mockito.verify(mockAps, Mockito.times(1)).publishApplicationInstanceData(anyString(),
                publishNameCaptor.capture(), entriesCaptor.capture());

        PublishedExports pubExports = pubExpSet.get("QuickLinks".toLowerCase());
        Assert.assertEquals(1, pubExports.entries.size());
        Assert.assertEquals("QuickLinks", pubExports.description);
        List<ExportEntry> expEntries = pubExports.entries.get("Comp_Endpoint");
        Assert.assertEquals(1, expEntries.size());
        Assert.assertEquals("mockcontainer_1", expEntries.get(0).getContainerId());
        Assert.assertEquals("component", expEntries.get(0).getLevel());
        Assert.assertEquals("1", expEntries.get(0).getTag());
        Assert.assertEquals("http://host1:10010", expEntries.get(0).getValue());
        Assert.assertNotNull(expEntries.get(0).getUpdatedTime());
        Assert.assertNull(expEntries.get(0).getValidUntil());

        assert entriesCaptor.getAllValues().size() == 1;
        for (Collection coll : entriesCaptor.getAllValues()) {
            Set<Map.Entry<String, String>> entrySet = (Set<Map.Entry<String, String>>) coll;
            for (Map.Entry entry : entrySet) {
                log.info("{}:{}", entry.getKey(), entry.getValue().toString());
                if (entry.getKey().equals("Comp_Endpoint")) {
                    assert entry.getValue().toString().equals("http://host1:10010");
                }
            }
        }
        assert publishNameCaptor.getAllValues().size() == 1;
        for (String coll : publishNameCaptor.getAllValues()) {
            assert coll.equals("QuickLinks");
        }

        mockAps.notifyContainerCompleted(new MockContainerId(1));
        pubExports = pubExpSet.get("QuickLinks".toLowerCase());
        Assert.assertEquals(1, pubExports.entries.size());
        Assert.assertEquals("QuickLinks", pubExports.description);
        expEntries = pubExports.entries.get("Comp_Endpoint");
        Assert.assertEquals(0, expEntries.size());

        mockAps.notifyContainerCompleted(new MockContainerId(1));
        mockAps.notifyContainerCompleted(new MockContainerId(2));

        mockAps.processAndPublishComponentSpecificExports(ports, "mockcontainer_1", "host1", "HBASE_REGIONSERVER");
        mockAps.processAndPublishComponentSpecificExports(ports, "mockcontainer_2", "host1", "HBASE_REGIONSERVER");
        pubExports = pubExpSet.get("QuickLinks".toLowerCase());
        Assert.assertEquals(1, pubExports.entries.size());
        Assert.assertEquals("QuickLinks", pubExports.description);
        expEntries = pubExports.entries.get("Comp_Endpoint");
        Assert.assertEquals(2, expEntries.size());

        mockAps.notifyContainerCompleted(new MockContainerId(2));
        expEntries = pubExports.entries.get("Comp_Endpoint");
        Assert.assertEquals(1, expEntries.size());
    }

    @Test
    public void testProcessConfig() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        Assert.assertNotNull(metainfo.getApplication());
        AgentProviderService aps = createAgentProviderService(new Configuration());
        HeartBeat hb = new HeartBeat();
        ComponentStatus status = new ComponentStatus();
        status.setClusterName("test");
        status.setComponentName("HBASE_MASTER");
        status.setRoleCommand("GET_CONFIG");
        Map<String, String> hbaseSite = new HashMap<String, String>();
        hbaseSite.put("hbase.master.info.port", "60012");
        hbaseSite.put("c", "d");
        Map<String, Map<String, String>> configs = new HashMap<String, Map<String, String>>();
        configs.put("hbase-site", hbaseSite);
        configs.put("global", hbaseSite);
        status.setConfigs(configs);
        hb.setComponentStatus(new ArrayList<ComponentStatus>(Arrays.asList(status)));

        Map<String, Map<String, ClusterNode>> roleClusterNodeMap = new HashMap<String, Map<String, ClusterNode>>();
        Map<String, ClusterNode> container = new HashMap<String, ClusterNode>();
        ClusterNode cn1 = new ClusterNode(new MockContainerId(1));
        cn1.host = "HOST1";
        container.put("cid1", cn1);
        roleClusterNodeMap.put("HBASE_MASTER", container);

        ComponentInstanceState componentStatus = new ComponentInstanceState("HBASE_MASTER", new MockContainerId(1),
                "cid");
        AgentProviderService mockAps = Mockito.spy(aps);
        doNothing().when(mockAps).publishApplicationInstanceData(anyString(), anyString(), anyCollection());
        doReturn(metainfo).when(mockAps).getMetainfo();
        doReturn(roleClusterNodeMap).when(mockAps).getRoleClusterNodeMapping();
        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        doReturn(access).when(mockAps).getAmState();
        PublishedExportsSet pubExpSet = new PublishedExportsSet();
        expect(access.getPublishedExportsSet()).andReturn(pubExpSet).anyTimes();
        replay(access);

        mockAps.publishConfigAndExportGroups(hb, componentStatus, "HBASE_MASTER");
        Assert.assertTrue(componentStatus.getConfigReported());
        ArgumentCaptor<Collection> entriesCaptor = ArgumentCaptor.forClass(Collection.class);
        Mockito.verify(mockAps, Mockito.times(3)).publishApplicationInstanceData(anyString(), anyString(),
                entriesCaptor.capture());
        Assert.assertEquals(3, entriesCaptor.getAllValues().size());
        for (Collection coll : entriesCaptor.getAllValues()) {
            Set<Map.Entry<String, String>> entrySet = (Set<Map.Entry<String, String>>) coll;
            for (Map.Entry entry : entrySet) {
                log.info("{}:{}", entry.getKey(), entry.getValue().toString());
                if (entry.getKey().equals("JMX_Endpoint")) {
                    assert entry.getValue().toString().equals("http://HOST1:60012/jmx");
                }
            }
        }

        Map<String, List<ExportEntry>> exports = mockAps.getCurrentExports("QuickLinks");
        Assert.assertEquals(2, exports.size());
        Assert.assertEquals(exports.get("JMX_Endpoint").get(0).getValue(), "http://HOST1:60012/jmx");

        mockAps.publishConfigAndExportGroups(hb, componentStatus, "HBASE_REST");
        Mockito.verify(mockAps, Mockito.times(3)).publishApplicationInstanceData(anyString(), anyString(),
                entriesCaptor.capture());
        PublishedExports pubExports = pubExpSet.get("QuickLinks".toLowerCase());
        Assert.assertEquals(2, pubExports.entries.size());
        Assert.assertEquals("QuickLinks", pubExports.description);
        List<ExportEntry> expEntries = pubExports.entries.get("JMX_Endpoint");
        Assert.assertEquals(1, expEntries.size());
        Assert.assertEquals(null, expEntries.get(0).getContainerId());
        Assert.assertEquals("application", expEntries.get(0).getLevel());
        Assert.assertEquals(null, expEntries.get(0).getTag());
        Assert.assertEquals("http://HOST1:60012/jmx", expEntries.get(0).getValue());
        Assert.assertNull(expEntries.get(0).getValidUntil());

        expEntries = pubExports.entries.get("Master_Status");
        Assert.assertEquals(1, expEntries.size());
        expEntries = pubExports.entries.get("JMX_Endpoint");
        Assert.assertEquals("http://HOST1:60012/jmx", expEntries.get(0).getValue());
    }

    @Test
    public void testMetainfoParsing() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        Assert.assertNotNull(metainfo.getApplication());
        Application application = metainfo.getApplication();
        log.info("Service: " + application.toString());
        Assert.assertEquals(application.getName(), "HBASE");
        Assert.assertEquals(application.getExportedConfigs(), "hbase-site,global");
        Assert.assertEquals(application.getComponents().size(), 3);
        List<Component> components = application.getComponents();
        int found = 0;
        for (Component component : components) {
            if (component.getName().equals("HBASE_MASTER")) {
                Assert.assertEquals(component.getAutoStartOnFailure(), "true");
                Assert.assertEquals(component.getRequiresAutoRestart(), Boolean.TRUE);
                Assert.assertEquals(component.getMinInstanceCount(), "1");
                Assert.assertEquals(component.getMaxInstanceCount(), "2");
                Assert.assertEquals(component.getCommandScript().getScript(), "scripts/hbase_master.py");
                Assert.assertEquals(component.getCategory(), "MASTER");
                Assert.assertEquals(component.getComponentExports().size(), 0);
                Assert.assertEquals(component.getAppExports(), "QuickLinks-JMX_Endpoint,QuickLinks-Master_Status");
                Assert.assertEquals(component.getCompExports(), "QuickLinks-Comp_Endpoint");
                found++;
            }
            if (component.getName().equals("HBASE_REGIONSERVER")) {
                Assert.assertEquals(component.getAutoStartOnFailure(), "Falsee");
                Assert.assertEquals(component.getRequiresAutoRestart(), Boolean.FALSE);
                Assert.assertEquals(component.getMinInstanceCount(), "1");
                Assert.assertNull(component.getMaxInstanceCount());
                Assert.assertEquals(component.getCommandScript().getScript(), "scripts/hbase_regionserver.py");
                Assert.assertEquals(component.getCategory(), "SLAVE");
                Assert.assertEquals(component.getComponentExports().size(), 2);
                List<ComponentExport> es = component.getComponentExports();
                ComponentExport e = es.get(0);
                Assert.assertEquals(e.getName(), "PropertyA");
                Assert.assertEquals(e.getValue(), "${THIS_HOST}:${site.global.listen_port}");
                e = es.get(1);
                Assert.assertEquals(e.getName(), "PropertyB");
                Assert.assertEquals(e.getValue(), "AConstant");
                found++;
            }
        }
        Assert.assertEquals(found, 2);

        Assert.assertEquals(application.getExportGroups().size(), 1);
        List<ExportGroup> egs = application.getExportGroups();
        ExportGroup eg = egs.get(0);
        Assert.assertEquals(eg.getName(), "QuickLinks");
        Assert.assertEquals(eg.getExports().size(), 3);

        found = 0;
        for (Export export : eg.getExports()) {
            if (export.getName().equals("JMX_Endpoint")) {
                found++;
                Assert.assertEquals(export.getValue(),
                        "http://${HBASE_MASTER_HOST}:${site.hbase-site.hbase.master.info.port}/jmx");
            }
            if (export.getName().equals("Master_Status")) {
                found++;
                Assert.assertEquals(export.getValue(),
                        "http://${HBASE_MASTER_HOST}:${site.hbase-site.hbase.master.info.port}/master-status");
            }
        }
        Assert.assertEquals(found, 2);

        List<CommandOrder> cmdOrders = application.getCommandOrder();
        Assert.assertEquals(cmdOrders.size(), 2);
        found = 0;
        for (CommandOrder co : application.getCommandOrder()) {
            if (co.getCommand().equals("HBASE_REGIONSERVER-START")) {
                Assert.assertTrue(co.getRequires().equals("HBASE_MASTER-STARTED"));
                found++;
            }
            if (co.getCommand().equals("A-START")) {
                Assert.assertEquals(co.getRequires(), "B-STARTED");
                found++;
            }
        }
        Assert.assertEquals(found, 2);

        List<ConfigFile> configFiles = application.getConfigFiles();
        Assert.assertEquals(configFiles.size(), 2);
        found = 0;
        for (ConfigFile configFile : configFiles) {
            if (configFile.getDictionaryName().equals("hbase-site")) {
                Assert.assertEquals("hbase-site.xml", configFile.getFileName());
                Assert.assertEquals("xml", configFile.getType());
                found++;
            }
            if (configFile.getDictionaryName().equals("hbase-env")) {
                Assert.assertEquals("hbase-env.sh", configFile.getFileName());
                Assert.assertEquals("env", configFile.getType());
                found++;
            }
        }
        Assert.assertEquals("Two config dependencies must be found.", found, 2);

        AgentProviderService aps = createAgentProviderService(new Configuration());
        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(metainfo).when(mockAps).getMetainfo();
        CommandScript script = mockAps.getScriptPathFromMetainfo("HBASE_MASTER");
        Assert.assertEquals(script.getScript(), "scripts/hbase_master.py");

        String metainfo_1_str_bad = "<metainfo>\n" + "  <schemaVersion>2.0</schemaVersion>\n" + "  <services>\n"
                + "    <service>\n" + "      <name>HBASE</name>\n" + "      <comment>\n" + "        Apache HBase\n"
                + "      </comment>\n";

        metainfo_1 = new ByteArrayInputStream(metainfo_1_str_bad.getBytes());
        metainfo = new MetainfoParser().parse(metainfo_1);
        Assert.assertNull(metainfo);
    }

    @Test
    public void testMetaInfoRelatedOperations() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        InputStream metainfo_2 = new ByteArrayInputStream(metainfo_2_str.getBytes());
        Metainfo metainfo2 = new MetainfoParser().parse(metainfo_2);
        String role_hm = "HBASE_MASTER";
        String role_hrs = "HBASE_REGIONSERVER";

        AgentProviderService aps1 = createAgentProviderService(new Configuration());
        AgentProviderService mockAps = Mockito.spy(aps1);
        doReturn(metainfo).when(mockAps).getMetainfo();

        AgentProviderService mockAps2 = Mockito.spy(aps1);
        doReturn(metainfo2).when(mockAps2).getMetainfo();

        Assert.assertTrue(mockAps.isMaster(role_hm));
        Assert.assertFalse(mockAps.isMaster(role_hrs));
        Assert.assertTrue(mockAps.canPublishConfig(role_hm));
        Assert.assertFalse(mockAps.canPublishConfig(role_hrs));
        Assert.assertTrue(mockAps.canAnyMasterPublishConfig());

        Assert.assertTrue(mockAps2.isMaster(role_hm));
        Assert.assertFalse(mockAps2.isMaster(role_hrs));
        Assert.assertTrue(mockAps2.canPublishConfig(role_hm));
        Assert.assertFalse(mockAps2.canPublishConfig(role_hrs));
        Assert.assertTrue(mockAps2.canAnyMasterPublishConfig());
    }

    @Test
    public void testOrchestratedAppStart() throws IOException {
        // App has two components HBASE_MASTER and HBASE_REGIONSERVER
        // Start of HBASE_RS depends on the start of HBASE_MASTER
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        ConfTree tree = new ConfTree();
        tree.global.put(InternalKeys.INTERNAL_APPLICATION_IMAGE_PATH, ".");

        Configuration conf = new Configuration();
        AgentProviderService aps = createAgentProviderService(conf);
        YarnRegistryViewForProviders registryViewForProviders = aps.getYarnRegistry();
        assertNotNull(registryViewForProviders);

        ContainerLaunchContext ctx = createNiceMock(ContainerLaunchContext.class);
        AggregateConf instanceDefinition = new AggregateConf();

        instanceDefinition.setInternal(tree);
        instanceDefinition.setAppConf(tree);
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.APP_DEF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_CONF, ".");
        instanceDefinition.getAppConfOperations().getGlobalOptions().put(AgentKeys.AGENT_VERSION, ".");

        Container container = createNiceMock(Container.class);
        String role_hm = "HBASE_MASTER";
        String role_hrs = "HBASE_REGIONSERVER";
        SliderFileSystem sliderFileSystem = createNiceMock(SliderFileSystem.class);
        ContainerLauncher launcher = createNiceMock(ContainerLauncher.class);
        ContainerLauncher launcher2 = createNiceMock(ContainerLauncher.class);
        Path generatedConfPath = new Path(".", "test");
        MapOperations resourceComponent = new MapOperations();
        MapOperations appComponent = new MapOperations();
        Path containerTmpDirPath = new Path(".", "test");
        FilterFileSystem mockFs = createNiceMock(FilterFileSystem.class);
        expect(sliderFileSystem.getFileSystem()).andReturn(mockFs).anyTimes();
        expect(mockFs.exists(anyObject(Path.class))).andReturn(true);
        expect(sliderFileSystem.createAmResource(anyObject(Path.class), anyObject(LocalResourceType.class)))
                .andReturn(createNiceMock(LocalResource.class)).anyTimes();
        expect(container.getId()).andReturn(new MockContainerId(1)).anyTimes();
        expect(container.getNodeId()).andReturn(new MockNodeId("localhost")).anyTimes();
        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);

        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(access).when(mockAps).getAmState();
        doReturn(metainfo).when(mockAps).getApplicationMetainfo(any(SliderFileSystem.class), anyString());
        doReturn(new HashMap<String, DefaultConfig>()).when(mockAps)
                .initializeDefaultConfigs(any(SliderFileSystem.class), anyString(), any(Metainfo.class));

        try {
            doReturn(true).when(mockAps).isMaster(anyString());
            doNothing().when(mockAps).addInstallCommand(anyString(), anyString(), any(HeartBeatResponse.class),
                    anyString(), Mockito.anyLong());
            doNothing().when(mockAps).addStartCommand(anyString(), anyString(), any(HeartBeatResponse.class),
                    anyString(), Mockito.anyLong(), Matchers.anyBoolean());
            doNothing().when(mockAps).addGetConfigCommand(anyString(), anyString(), any(HeartBeatResponse.class));
            doNothing().when(mockAps).publishFolderPaths(anyMap(), anyString(), anyString(), anyString());
            doReturn(conf).when(mockAps).getConfig();
        } catch (SliderException e) {
        }

        PublishedExportsSet pubExpSet = new PublishedExportsSet();
        expect(access.isApplicationLive()).andReturn(true).anyTimes();
        expect(access.getPublishedExportsSet()).andReturn(pubExpSet).anyTimes();
        ClusterDescription desc = new ClusterDescription();
        desc.setOption(OptionKeys.ZOOKEEPER_QUORUM, "host1:2181");
        desc.setInfo(OptionKeys.APPLICATION_NAME, "HBASE");
        expect(access.getClusterStatus()).andReturn(desc).anyTimes();

        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getOrAddComponent("HBASE_MASTER").put(AgentKeys.WAIT_HEARTBEAT, "0");
        treeOps.getOrAddComponent("HBASE_REGIONSERVER").put(AgentKeys.WAIT_HEARTBEAT, "0");
        treeOps.set(OptionKeys.APPLICATION_NAME, "HBASE");
        expect(access.getInstanceDefinitionSnapshot()).andReturn(aggConf).anyTimes();
        expect(access.getInternalsSnapshot()).andReturn(treeOps).anyTimes();
        doNothing().when(mockAps).publishApplicationInstanceData(anyString(), anyString(), anyCollection());
        replay(access, ctx, container, sliderFileSystem, mockFs);

        // build two containers
        try {
            mockAps.buildContainerLaunchContext(launcher, instanceDefinition, container, role_hm, sliderFileSystem,
                    generatedConfPath, resourceComponent, appComponent, containerTmpDirPath);

            mockAps.buildContainerLaunchContext(launcher2, instanceDefinition, container, role_hrs,
                    sliderFileSystem, generatedConfPath, resourceComponent, appComponent, containerTmpDirPath);

            // Both containers register
            Register reg = new Register();
            reg.setResponseId(0);
            reg.setLabel("mockcontainer_1___HBASE_MASTER");
            RegistrationResponse resp = mockAps.handleRegistration(reg);
            Assert.assertEquals(0, resp.getResponseId());
            Assert.assertEquals(RegistrationStatus.OK, resp.getResponseStatus());

            reg = new Register();
            reg.setResponseId(0);
            reg.setLabel("mockcontainer_1___HBASE_REGIONSERVER");
            resp = mockAps.handleRegistration(reg);
            Assert.assertEquals(0, resp.getResponseId());
            Assert.assertEquals(RegistrationStatus.OK, resp.getResponseStatus());

            // Both issue install command
            HeartBeat hb = new HeartBeat();
            hb.setResponseId(1);
            hb.setHostname("mockcontainer_1___HBASE_MASTER");
            HeartBeatResponse hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(2, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(1)).addInstallCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong());

            hb = new HeartBeat();
            hb.setResponseId(1);
            hb.setHostname("mockcontainer_1___HBASE_REGIONSERVER");
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(2, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(2)).addInstallCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong());
            // RS succeeds install but does not start
            hb = new HeartBeat();
            hb.setResponseId(2);
            hb.setHostname("mockcontainer_1___HBASE_REGIONSERVER");
            CommandReport cr = new CommandReport();
            cr.setRole("HBASE_REGIONSERVER");
            cr.setRoleCommand("INSTALL");
            cr.setStatus("COMPLETED");
            cr.setFolders(new HashMap<String, String>() {
                {
                    put("a", "b");
                }
            });
            hb.setReports(Arrays.asList(cr));
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(3, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(0)).addStartCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong(), Matchers.anyBoolean());
            // RS still does not start
            hb = new HeartBeat();
            hb.setResponseId(3);
            hb.setHostname("mockcontainer_1___HBASE_REGIONSERVER");
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(4, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(0)).addStartCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong(), Matchers.anyBoolean());

            // MASTER succeeds install and issues start
            hb = new HeartBeat();
            hb.setResponseId(2);
            hb.setHostname("mockcontainer_1___HBASE_MASTER");
            hb.setFqdn("host1");
            cr = new CommandReport();
            cr.setRole("HBASE_MASTER");
            cr.setRoleCommand("INSTALL");
            cr.setStatus("COMPLETED");
            Map<String, String> ap = new HashMap<String, String>();
            ap.put("a.port", "10233");
            cr.setAllocatedPorts(ap);
            hb.setReports(Arrays.asList(cr));
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(3, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(1)).addStartCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong(), Matchers.anyBoolean());
            Map<String, String> allocatedPorts = mockAps.getAllocatedPorts();
            Assert.assertTrue(allocatedPorts != null);
            Assert.assertTrue(allocatedPorts.size() == 1);
            Assert.assertTrue(allocatedPorts.containsKey("a.port"));

            // RS still does not start
            hb = new HeartBeat();
            hb.setResponseId(4);
            hb.setHostname("mockcontainer_1___HBASE_REGIONSERVER");
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(5, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(1)).addStartCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong(), Matchers.anyBoolean());
            // MASTER succeeds start
            hb = new HeartBeat();
            hb.setResponseId(3);
            hb.setHostname("mockcontainer_1___HBASE_MASTER");
            cr = new CommandReport();
            cr.setRole("HBASE_MASTER");
            cr.setRoleCommand("START");
            cr.setStatus("COMPLETED");
            hb.setReports(Arrays.asList(cr));
            mockAps.handleHeartBeat(hb);
            Mockito.verify(mockAps, Mockito.times(1)).addGetConfigCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class));

            // RS starts now
            hb = new HeartBeat();
            hb.setResponseId(5);
            hb.setHostname("mockcontainer_1___HBASE_REGIONSERVER");
            hbr = mockAps.handleHeartBeat(hb);
            Assert.assertEquals(6, hbr.getResponseId());
            Mockito.verify(mockAps, Mockito.times(2)).addStartCommand(anyString(), anyString(),
                    any(HeartBeatResponse.class), anyString(), Mockito.anyLong(), Matchers.anyBoolean());
            // JDK7 
        } catch (SliderException he) {
            log.warn(he.getMessage());
        } catch (IOException he) {
            log.warn(he.getMessage());
        }

        Mockito.verify(mockAps, Mockito.times(1)).publishFolderPaths(anyMap(), anyString(), anyString(),
                anyString());
    }

    protected AgentProviderService createAgentProviderService(Configuration conf) throws IOException {
        AgentProviderService aps = new AgentProviderService();
        YarnRegistryViewForProviders registryViewForProviders = createYarnRegistryViewForProviders(conf);
        aps.bindToYarnRegistry(registryViewForProviders);
        return aps;
    }

    protected YarnRegistryViewForProviders createYarnRegistryViewForProviders(Configuration conf)
            throws IOException {
        conf.set(SliderXmlConfKeys.REGISTRY_PATH, SliderXmlConfKeys.DEFAULT_REGISTRY_PATH);

        RegistryOperations registryOperations = new MockRegistryOperations();
        registryOperations.init(conf);
        YarnRegistryViewForProviders registryViewForProviders = new YarnRegistryViewForProviders(registryOperations,
                "hbase", SliderKeys.APP_TYPE, "hbase1", new MockApplicationAttemptId(new MockApplicationId(1), 1));
        registryViewForProviders.registerSelf(new ServiceRecord(), true);
        return registryViewForProviders;
    }

    @Test
    public void testPublishFolderPaths() throws IOException {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(access).when(mockAps).getAmState();
        PublishedExportsSet pubExpSet = new PublishedExportsSet();
        expect(access.getPublishedExportsSet()).andReturn(pubExpSet).anyTimes();
        replay(access);

        Map<String, String> folders = new HashMap<String, String>();
        folders.put("AGENT_LOG_ROOT", "aFolder");
        folders.put("AGENT_WORK_ROOT", "folderB");
        mockAps.publishFolderPaths(folders, "cid", "role", "fqdn");

        PublishedExports exports = pubExpSet.get("container_log_dirs");
        Assert.assertEquals(1, exports.entries.size());
        List<ExportEntry> expEntries = exports.entries.get("role");
        Assert.assertEquals(1, expEntries.size());
        Assert.assertEquals("cid", expEntries.get(0).getContainerId());
        Assert.assertEquals("component", expEntries.get(0).getLevel());
        Assert.assertEquals("role", expEntries.get(0).getTag());
        Assert.assertEquals("fqdn:aFolder", expEntries.get(0).getValue());
        Assert.assertNull(expEntries.get(0).getValidUntil());
        Assert.assertEquals(null, expEntries.get(0).getValidUntil());

        exports = pubExpSet.get("container_work_dirs");
        Assert.assertEquals(1, exports.entries.size());
        expEntries = exports.entries.get("role");
        Assert.assertEquals(1, expEntries.size());
        Assert.assertEquals("cid", expEntries.get(0).getContainerId());
        Assert.assertEquals("component", expEntries.get(0).getLevel());
        Assert.assertEquals("role", expEntries.get(0).getTag());
        Assert.assertEquals("fqdn:folderB", expEntries.get(0).getValue());
        Assert.assertNull(expEntries.get(0).getValidUntil());
        Assert.assertEquals(null, expEntries.get(0).getValidUntil());
    }

    @Test
    public void testNotifyContainerCompleted() throws IOException {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        AgentProviderService mockAps = Mockito.spy(aps);
        doNothing().when(mockAps).publishApplicationInstanceData(anyString(), anyString(), anyCollection());

        ContainerId cid = new MockContainerId(1);
        String id = cid.toString();
        ContainerId cid2 = new MockContainerId(2);
        mockAps.getAllocatedPorts().put("a", "100");
        mockAps.getAllocatedPorts(id).put("a", "100");
        mockAps.getAllocatedPorts(id).put("b", "101");
        mockAps.getAllocatedPorts("cid2").put("c", "102");

        mockAps.getComponentInstanceData().put("cid2", new HashMap<String, String>());
        mockAps.getComponentInstanceData().put(id, new HashMap<String, String>());

        mockAps.getComponentStatuses().put("cid2_HM", new ComponentInstanceState("HM", cid2, "aid"));
        mockAps.getComponentStatuses().put(id + "_HM", new ComponentInstanceState("HM", cid, "aid"));

        Assert.assertNotNull(mockAps.getComponentInstanceData().get(id));
        Assert.assertNotNull(mockAps.getComponentInstanceData().get("cid2"));

        Assert.assertNotNull(mockAps.getComponentStatuses().get(id + "_HM"));
        Assert.assertNotNull(mockAps.getComponentStatuses().get("cid2_HM"));

        Assert.assertEquals(mockAps.getAllocatedPorts().size(), 1);
        Assert.assertEquals(mockAps.getAllocatedPorts(id).size(), 2);
        Assert.assertEquals(mockAps.getAllocatedPorts("cid2").size(), 1);

        // Make the call
        mockAps.notifyContainerCompleted(new MockContainerId(1));

        Assert.assertEquals(mockAps.getAllocatedPorts().size(), 0);
        Assert.assertEquals(mockAps.getAllocatedPorts(id).size(), 0);
        Assert.assertEquals(mockAps.getAllocatedPorts("cid2").size(), 1);

        Assert.assertNull(mockAps.getComponentInstanceData().get(id));
        Assert.assertNotNull(mockAps.getComponentInstanceData().get("cid2"));

        Assert.assertNull(mockAps.getComponentStatuses().get(id + "_HM"));
        Assert.assertNotNull(mockAps.getComponentStatuses().get("cid2_HM"));
    }

    @Test
    public void testAddInstallCommand() throws Exception {
        InputStream metainfo_1 = new ByteArrayInputStream(metainfo_1_str.getBytes());
        Metainfo metainfo = new MetainfoParser().parse(metainfo_1);
        AgentProviderService aps = createAgentProviderService(new Configuration());
        HeartBeatResponse hbr = new HeartBeatResponse();

        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(access).when(mockAps).getAmState();

        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getGlobalOptions().put(AgentKeys.JAVA_HOME, "java_home");
        treeOps.set(OptionKeys.APPLICATION_NAME, "HBASE");
        treeOps.set("site.fs.defaultFS", "hdfs://HOST1:8020/");
        treeOps.set("internal.data.dir.path", "hdfs://HOST1:8020/database");
        treeOps.set(OptionKeys.ZOOKEEPER_HOSTS, "HOST1");

        expect(access.getAppConfSnapshot()).andReturn(treeOps).anyTimes();
        expect(access.getInternalsSnapshot()).andReturn(treeOps).anyTimes();
        expect(access.isApplicationLive()).andReturn(true).anyTimes();

        doReturn("HOST1").when(mockAps).getClusterInfoPropertyValue(anyString());
        doReturn(metainfo).when(mockAps).getMetainfo();
        doReturn(new HashMap<String, DefaultConfig>()).when(mockAps).getDefaultConfigs();

        Map<String, Map<String, ClusterNode>> roleClusterNodeMap = new HashMap<String, Map<String, ClusterNode>>();
        Map<String, ClusterNode> container = new HashMap<String, ClusterNode>();
        ClusterNode cn1 = new ClusterNode(new MockContainerId(1));
        cn1.host = "HOST1";
        container.put("cid1", cn1);
        roleClusterNodeMap.put("HBASE_MASTER", container);
        doReturn(roleClusterNodeMap).when(mockAps).getRoleClusterNodeMapping();

        replay(access);

        mockAps.addInstallCommand("HBASE_MASTER", "cid1", hbr, "", 0);
        ExecutionCommand cmd = hbr.getExecutionCommands().get(0);
        String pkgs = cmd.getHostLevelParams().get(AgentKeys.PACKAGE_LIST);
        Assert.assertEquals("[{\"type\":\"tarball\",\"name\":\"files/hbase-0.96.1-hadoop2-bin.tar.gz\"}]", pkgs);
        Assert.assertEquals("java_home", cmd.getHostLevelParams().get(AgentKeys.JAVA_HOME));
        Assert.assertEquals("cid1", cmd.getHostLevelParams().get("container_id"));
        Assert.assertEquals(Command.INSTALL.toString(), cmd.getRoleCommand());
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_log_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_pid_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_install_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_input_conf_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_container_id"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("pid_file"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_root"));
    }

    @Test
    public void testAddStartCommand() throws Exception {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        HeartBeatResponse hbr = new HeartBeatResponse();

        StateAccessForProviders access = createNiceMock(StateAccessForProviders.class);
        AgentProviderService mockAps = Mockito.spy(aps);
        doReturn(access).when(mockAps).getAmState();

        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getGlobalOptions().put(AgentKeys.JAVA_HOME, "java_home");
        treeOps.set(OptionKeys.APPLICATION_NAME, "HBASE");
        treeOps.set("site.fs.defaultFS", "hdfs://HOST1:8020/");
        treeOps.set("internal.data.dir.path", "hdfs://HOST1:8020/database");
        treeOps.set(OptionKeys.ZOOKEEPER_HOSTS, "HOST1");
        treeOps.getGlobalOptions().put("site.hbase-site.a.port", "${HBASE_MASTER.ALLOCATED_PORT}");
        treeOps.getGlobalOptions().put("site.hbase-site.b.port", "${HBASE_MASTER.ALLOCATED_PORT}");
        treeOps.getGlobalOptions().put("site.hbase-site.random.port",
                "${HBASE_MASTER.ALLOCATED_PORT}{PER_CONTAINER}");
        treeOps.getGlobalOptions().put("site.hbase-site.random2.port", "${HBASE_MASTER.ALLOCATED_PORT}");

        Map<String, DefaultConfig> defaultConfigMap = new HashMap<String, DefaultConfig>();
        DefaultConfig defaultConfig = new DefaultConfig();
        PropertyInfo propertyInfo1 = new PropertyInfo();
        propertyInfo1.setName("defaultA");
        propertyInfo1.setValue("Avalue");
        defaultConfig.addPropertyInfo(propertyInfo1);
        propertyInfo1 = new PropertyInfo();
        propertyInfo1.setName("defaultB");
        propertyInfo1.setValue("");
        defaultConfig.addPropertyInfo(propertyInfo1);
        defaultConfigMap.put("hbase-site", defaultConfig);

        expect(access.getAppConfSnapshot()).andReturn(treeOps).anyTimes();
        expect(access.getInternalsSnapshot()).andReturn(treeOps).anyTimes();
        expect(access.isApplicationLive()).andReturn(true).anyTimes();

        doReturn("HOST1").when(mockAps).getClusterInfoPropertyValue(anyString());
        doReturn(defaultConfigMap).when(mockAps).getDefaultConfigs();
        List<String> configurations = new ArrayList<String>();
        configurations.add("hbase-site");
        configurations.add("global");
        List<String> sysConfigurations = new ArrayList<String>();
        configurations.add("core-site");
        doReturn(configurations).when(mockAps).getApplicationConfigurationTypes();
        doReturn(sysConfigurations).when(mockAps).getSystemConfigurationsRequested(any(ConfTreeOperations.class));

        Map<String, Map<String, ClusterNode>> roleClusterNodeMap = new HashMap<String, Map<String, ClusterNode>>();
        Map<String, ClusterNode> container = new HashMap<String, ClusterNode>();
        ClusterNode cn1 = new ClusterNode(new MockContainerId(1));
        cn1.host = "HOST1";
        container.put("cid1", cn1);
        roleClusterNodeMap.put("HBASE_MASTER", container);
        doReturn(roleClusterNodeMap).when(mockAps).getRoleClusterNodeMapping();
        Map<String, String> allocatedPorts = new HashMap<String, String>();
        allocatedPorts.put("hbase-site.a.port", "10023");
        allocatedPorts.put("hbase-site.b.port", "10024");
        doReturn(allocatedPorts).when(mockAps).getAllocatedPorts();
        Map<String, String> allocatedPorts2 = new HashMap<String, String>();
        allocatedPorts2.put("hbase-site.random.port", "10025");
        doReturn(allocatedPorts2).when(mockAps).getAllocatedPorts(anyString());

        replay(access);

        mockAps.addStartCommand("HBASE_MASTER", "cid1", hbr, "", 0, Boolean.FALSE);
        Assert.assertTrue(hbr.getExecutionCommands().get(0).getConfigurations().containsKey("hbase-site"));
        Assert.assertTrue(hbr.getExecutionCommands().get(0).getConfigurations().containsKey("core-site"));
        Map<String, String> hbaseSiteConf = hbr.getExecutionCommands().get(0).getConfigurations().get("hbase-site");
        Assert.assertTrue(hbaseSiteConf.containsKey("a.port"));
        Assert.assertEquals("10023", hbaseSiteConf.get("a.port"));
        Assert.assertEquals("10024", hbaseSiteConf.get("b.port"));
        Assert.assertEquals("10025", hbaseSiteConf.get("random.port"));
        assertEquals("${HBASE_MASTER.ALLOCATED_PORT}", hbaseSiteConf.get("random2.port"));
        ExecutionCommand cmd = hbr.getExecutionCommands().get(0);
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_log_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_pid_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_install_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_input_conf_dir"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_container_id"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("pid_file"));
        Assert.assertTrue(cmd.getConfigurations().get("global").containsKey("app_root"));
        Assert.assertTrue(cmd.getConfigurations().get("hbase-site").containsKey("defaultA"));
        Assert.assertFalse(cmd.getConfigurations().get("hbase-site").containsKey("defaultB"));
    }

    @Test
    public void testParameterParsing() throws IOException {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        AggregateConf aggConf = new AggregateConf();
        ConfTreeOperations treeOps = aggConf.getAppConfOperations();
        treeOps.getGlobalOptions().put(AgentKeys.SYSTEM_CONFIGS, "core-site,yarn-site, core-site ");
        List<String> configs = aps.getSystemConfigurationsRequested(treeOps);
        Assert.assertEquals(2, configs.size());
        Assert.assertTrue(configs.contains("core-site"));
        Assert.assertFalse(configs.contains("bore-site"));
    }

    @Test
    public void testDereferenceAllConfig() throws IOException {
        AgentProviderService aps = createAgentProviderService(new Configuration());
        Map<String, Map<String, String>> allConfigs = new HashMap<String, Map<String, String>>();
        Map<String, String> cfg1 = new HashMap<String, String>();
        cfg1.put("a1", "${@//site/cfg-2/A1}");
        cfg1.put("b1", "22");
        cfg1.put("c1", "33");
        cfg1.put("d1", "${@//site/cfg1/c1}AA");
        Map<String, String> cfg2 = new HashMap<String, String>();
        cfg2.put("A1", "11");
        cfg2.put("B1", "${@//site/cfg-2/A1},${@//site/cfg-2/A1},AA,${@//site/cfg1/c1}");
        cfg2.put("C1", "DD${@//site/cfg1/c1}");
        cfg2.put("D1", "${14}");

        allConfigs.put("cfg1", cfg1);
        allConfigs.put("cfg-2", cfg2);
        aps.dereferenceAllConfigs(allConfigs);
        Assert.assertEquals("11", cfg1.get("a1"));
        Assert.assertEquals("22", cfg1.get("b1"));
        Assert.assertEquals("33", cfg1.get("c1"));
        Assert.assertEquals("33AA", cfg1.get("d1"));

        Assert.assertEquals("11", cfg2.get("A1"));
        Assert.assertEquals("11,11,AA,33", cfg2.get("B1"));
        Assert.assertEquals("DD33", cfg2.get("C1"));
        Assert.assertEquals("${14}", cfg2.get("D1"));
    }

}