blob: 340e72d0caa31ba4a6d23fad610fcff901c6b93d [file] [log] [blame]
/*
* 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.server.appmaster.model.history
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.apache.hadoop.yarn.api.records.Container
import org.apache.hadoop.yarn.api.records.Priority
import org.apache.hadoop.yarn.api.records.Resource
import org.apache.hadoop.yarn.client.api.AMRMClient
import org.apache.slider.api.ResourceKeys
import org.apache.slider.providers.ProviderRole
import org.apache.slider.server.appmaster.model.mock.BaseMockAppStateTest
import org.apache.slider.server.appmaster.model.mock.MockContainer
import org.apache.slider.server.appmaster.model.mock.MockFactory
import org.apache.slider.server.appmaster.model.mock.MockNodeId
import org.apache.slider.server.appmaster.state.*
import org.junit.Before
import org.junit.Test
/**
* Test container events at the role history level -one below
* the App State
*/
@Slf4j
@CompileStatic
class TestRoleHistoryContainerEvents extends BaseMockAppStateTest {
@Override
String getTestName() {
return "TestRoleHistoryContainerEvents"
}
NodeInstance age1Active4 = nodeInstance(1, 4, 0, 0)
NodeInstance age2Active2 = nodeInstance(2, 2, 0, 1)
NodeInstance age3Active0 = nodeInstance(3, 0, 0, 0)
NodeInstance age4Active1 = nodeInstance(4, 1, 0, 0)
NodeInstance age2Active0 = nodeInstance(2, 0, 0, 0)
NodeInstance empty = new NodeInstance("empty", MockFactory.ROLE_COUNT)
String roleName = "test"
List<NodeInstance> nodes = [age2Active2, age2Active0, age4Active1, age1Active4, age3Active0]
RoleHistory roleHistory = new RoleHistory(MockFactory.ROLES)
Resource resource
@Before
public void setupRH() {
roleHistory.onStart(fs, historyPath)
roleHistory.insert(nodes)
roleHistory.buildAvailableNodeLists();
resource = Resource.newInstance(ResourceKeys.DEF_YARN_CORES,
ResourceKeys.DEF_YARN_MEMORY);
}
@Test
public void testFindAndCreate() throws Throwable {
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
List<String> nodes = request.getNodes()
assert nodes != null
assert nodes.size() == 1
String hostname = nodes[0]
assert hostname == age3Active0.hostname
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.getPriority()
roleHistory.onContainerAssigned(container);
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert roleEntry.starting == 1
assert !roleEntry.available
RoleInstance ri = new RoleInstance(container);
//start it
roleHistory.onContainerStartSubmitted(container, ri)
//later, declare that it started
roleHistory.onContainerStarted(container)
assert roleEntry.starting == 0
assert !roleEntry.available
assert roleEntry.active == 1
assert roleEntry.live == 1
}
@Test
public void testCreateAndRelease() throws Throwable {
int role = 1
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
//verify it is empty
assert roleHistory.listActiveNodes(role).empty
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
List<String> nodes = request.nodes
assert nodes == null
//pick an idle host
String hostname = age3Active0.hostname;
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.priority
roleHistory.onContainerAssigned(container);
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert roleEntry.starting == 1
assert !roleEntry.available
RoleInstance ri = new RoleInstance(container);
//start it
roleHistory.onContainerStartSubmitted(container, ri)
//later, declare that it started
roleHistory.onContainerStarted(container)
assert roleEntry.starting == 0
assert !roleEntry.available
assert roleEntry.active == 1
assert roleEntry.live == 1
// now pick that instance to destroy
List<NodeInstance> activeNodes = roleHistory.listActiveNodes(role)
assert activeNodes.size() == 1
NodeInstance target = activeNodes[0]
assert target == allocated
roleHistory.onContainerReleaseSubmitted(container);
assert roleEntry.releasing == 1
assert roleEntry.live == 1
assert roleEntry.active == 0
// release completed
roleHistory.onReleaseCompleted(container, true)
assert roleEntry.releasing == 0
assert roleEntry.live == 0
assert roleEntry.active == 0
// verify it is empty
assert roleHistory.listActiveNodes(role).empty
// ask for a container and expect to get the recently released one
AMRMClient.ContainerRequest request2 =
roleHistory.requestNode(roleStatus, resource);
List<String> nodes2 = request2.nodes
assert nodes2 != null
String hostname2 = nodes2[0]
//pick an idle host
assert hostname2 == age3Active0.hostname;
}
@Test
public void testStartWithoutWarning() throws Throwable {
int role = 0
//pick an idle host
String hostname = age3Active0.hostname;
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = ContainerPriority.createPriority(0, false)
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
RoleInstance ri = new RoleInstance(container);
//tell RH that it started
roleHistory.onContainerStarted(container)
assert roleEntry.starting == 0
assert !roleEntry.available
assert roleEntry.active == 1
assert roleEntry.live == 1
}
@Test
public void testStartFailed() throws Throwable {
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
String hostname = request.getNodes()[0]
assert hostname == age3Active0.hostname
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.getPriority()
roleHistory.onContainerAssigned(container);
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert roleEntry.starting == 1
assert !roleEntry.available
RoleInstance ri = new RoleInstance(container);
//start it
roleHistory.onContainerStartSubmitted(container, ri)
//later, declare that it failed on startup
assert !roleHistory.onNodeManagerContainerStartFailed(container)
assert roleEntry.starting == 0
assert roleEntry.startFailed == 1
assert roleEntry.failed == 1
assert roleEntry.available
assert roleEntry.active == 0
assert roleEntry.live == 0
}
@Test
public void testStartFailedWithoutWarning() throws Throwable {
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
String hostname = request.getNodes()[0]
assert hostname == age3Active0.hostname
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.getPriority()
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert !roleHistory.onNodeManagerContainerStartFailed(container)
assert roleEntry.starting == 0
assert roleEntry.startFailed == 1
assert roleEntry.failed == 1
assert roleEntry.available
assert roleEntry.active == 0
assert roleEntry.live == 0
}
@Test
public void testContainerFailed() throws Throwable {
describe("fail a container without declaring it as starting")
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
String hostname = request.getNodes()[0]
assert hostname == age3Active0.hostname
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.getPriority()
roleHistory.onContainerAssigned(container);
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert roleEntry.starting == 1
assert !roleEntry.available
RoleInstance ri = new RoleInstance(container);
//start it
roleHistory.onContainerStartSubmitted(container, ri)
roleHistory.onContainerStarted(container)
//later, declare that it failed
roleHistory.onFailedContainer(container, false)
assert roleEntry.starting == 0
assert roleEntry.available
assert roleEntry.active == 0
assert roleEntry.live == 0
}
@Test
public void testContainerFailedWithoutWarning() throws Throwable {
describe( "fail a container without declaring it as starting")
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
String hostname = request.getNodes()[0]
assert hostname == age3Active0.hostname
//build a container
MockContainer container = factory.newContainer()
container.nodeId = new MockNodeId(hostname, 0)
container.priority = request.getPriority()
NodeMap nodemap = roleHistory.cloneNodemap();
NodeInstance allocated = nodemap.get(hostname)
NodeEntry roleEntry = allocated.get(role)
assert roleEntry.available
roleHistory.onFailedContainer(container, false)
assert roleEntry.starting == 0
assert roleEntry.failed == 1
assert roleEntry.available
assert roleEntry.active == 0
assert roleEntry.live == 0
}
@Test
public void testAllocationListPrep() throws Throwable {
describe("test prepareAllocationList")
int role = 0
ProviderRole provRole = new ProviderRole(roleName, role)
RoleStatus roleStatus = new RoleStatus(provRole)
AMRMClient.ContainerRequest request =
roleHistory.requestNode(roleStatus, resource);
String hostname = request.getNodes()[0]
assert hostname == age3Active0.hostname
MockContainer container1 = factory.newContainer()
container1.nodeId = new MockNodeId(hostname, 0)
container1.priority = Priority.newInstance(0);
MockContainer container2 = factory.newContainer()
container2.nodeId = new MockNodeId(hostname, 0)
container2.priority = Priority.newInstance(1);
// put containers in List with role == 1 first
List<Container> containers = [ (Container) container2, (Container) container1 ]
List<Container> sortedContainers = roleHistory.prepareAllocationList(containers)
// verify that the first container has role == 0 after sorting
MockContainer c1 = (MockContainer) sortedContainers[0]
assert c1.priority.getPriority() == 0
MockContainer c2 = (MockContainer) sortedContainers[1]
assert c2.priority.getPriority() == 1
}
}