SLIDER-280. Add unit and functional tests for agents discovering AM after 
restart (Gour Saha via smohanty)


Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/a509561f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/a509561f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/a509561f

Branch: refs/heads/feature/SLIDER-149_Support_a_YARN_service_registry
Commit: a509561f0c710e61f1f7612e14bc6c70176d29f9
Parents: fa7130d
Author: Sumit Mohanty <smoha...@hortonworks.com>
Authored: Wed Aug 20 15:07:21 2014 -0700
Committer: Sumit Mohanty <smoha...@hortonworks.com>
Committed: Thu Sep 11 10:40:00 2014 -0700

----------------------------------------------------------------------
 .../web/rest/agent/ExecutionCommand.java        |  16 ++
 .../appmaster/web/rest/agent/StatusCommand.java |  13 ++
 .../agent/TestAgentProviderService.java         | 214 +++++++++++++++++++
 3 files changed, 243 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/a509561f/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
index c184e63..94aa29f 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/ExecutionCommand.java
@@ -179,4 +179,20 @@ public class ExecutionCommand {
   public void setComponentName(String componentName) {
     this.componentName = componentName;
   }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("ExecutionCommand [commandType=").append(commandType)
+        .append(", clusterName=").append(clusterName).append(", taskId=")
+        .append(taskId).append(", commandId=").append(commandId)
+        .append(", hostname=").append(hostname).append(", role=").append(role)
+        .append(", hostLevelParams=").append(hostLevelParams)
+        .append(", roleParams=").append(roleParams).append(", roleCommand=")
+        .append(roleCommand).append(", configurations=").append(configurations)
+        .append(", commandParams=").append(commandParams)
+        .append(", serviceName=").append(serviceName)
+        .append(", componentName=").append(componentName).append("]");
+    return builder.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/a509561f/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/StatusCommand.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/StatusCommand.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/StatusCommand.java
index 0610cac..52fb8dd 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/StatusCommand.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/agent/StatusCommand.java
@@ -125,4 +125,17 @@ public class StatusCommand {
   public void setRoleCommand(String roleCommand) {
     this.roleCommand = roleCommand;
   }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("StatusCommand [agentCommandType=").append(agentCommandType)
+        .append(", clusterName=").append(clusterName).append(", serviceName=")
+        .append(serviceName).append(", componentName=").append(componentName)
+        .append(", configurations=").append(configurations)
+        .append(", commandParams=").append(commandParams)
+        .append(", hostLevelParams=").append(hostLevelParams)
+        .append(", roleCommand=").append(roleCommand).append("]");
+    return builder.toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/a509561f/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
 
b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
index 3711e12..48a5f18 100644
--- 
a/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
+++ 
b/slider-core/src/test/java/org/apache/slider/providers/agent/TestAgentProviderService.java
@@ -28,6 +28,7 @@ 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;
@@ -41,6 +42,7 @@ 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.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;
@@ -58,6 +60,7 @@ 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;
@@ -381,6 +384,217 @@ public class TestAgentProviderService {
     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);
+    AgentProviderService aps = new AgentProviderService();
+    AgentProviderService mockAps = Mockito.spy(aps);
+
+    doReturn(access).when(mockAps).getAmState();
+    doReturn("scripts/hbase_master.py").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();
+
+    Configuration conf = new Configuration();
+    conf.set(SliderXmlConfKeys.REGISTRY_PATH,
+        SliderXmlConfKeys.DEFAULT_REGISTRY_PATH);
+
+    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"));
+      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.setHostname("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.setHostname("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 = new AgentProviderService();

Reply via email to