// Copyright 2016 Twitter. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.twitter.heron.scheduler.mesos.framework;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.mesos.Protos;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import com.twitter.heron.scheduler.utils.SchedulerUtils;
import com.twitter.heron.spi.common.Config;
import com.twitter.heron.spi.common.Key;
public class LaunchableTaskTest {
private static final String TOPOLOGY_NAME = "testTopology";
private static final String ROLE = "role";
private static final long NUM_CONTAINER = 2;
private static final String TOPOLOGY_PACKAGE_URI = "topologyPackageURI";
private static final String CORE_PACKAGE_URI = "corePackageURI";
private Config config;
private Config runtime;
@Before
public void before() throws Exception {
config = Mockito.mock(Config.class);
Mockito.when(config.getStringValue(Key.TOPOLOGY_NAME)).thenReturn(TOPOLOGY_NAME);
Mockito.when(config.getStringValue(Key.ROLE)).thenReturn(ROLE);
Mockito.when(config.getStringValue(Key.CORE_PACKAGE_URI)).thenReturn(CORE_PACKAGE_URI);
runtime = Mockito.mock(Config.class);
Mockito.when(runtime.getLongValue(Key.NUM_CONTAINERS)).thenReturn(NUM_CONTAINER);
Properties properties = new Properties();
properties.put(Key.TOPOLOGY_PACKAGE_URI.value(), TOPOLOGY_PACKAGE_URI);
Mockito.when(runtime.get(Key.SCHEDULER_PROPERTIES)).thenReturn(properties);
}
@After
public void after() throws Exception {
}
/**
* Unit test for constructMesosTaskInfo()
*/
@Test
public void testConstructMesosTaskInfo() throws Exception {
// Create a valid offer
final double CPU = 0.5;
final double MEM = 1.6;
final double DISK = 2.7;
Protos.Offer.Builder builder =
Protos.Offer.newBuilder()
.setId(Protos.OfferID.newBuilder().setValue("id"))
.setFrameworkId(Protos.FrameworkID.newBuilder().setValue("framework-id"))
.setHostname("hostname")
.setSlaveId(Protos.SlaveID.newBuilder().setValue("slave-id"));
Protos.Resource cpu =
Protos.Resource.newBuilder()
.setType(Protos.Value.Type.SCALAR)
.setName(TaskResources.CPUS_RESOURCE_NAME)
.setScalar(
Protos.Value.Scalar.newBuilder().setValue(CPU))
.build();
Protos.Resource mem =
Protos.Resource.newBuilder()
.setType(Protos.Value.Type.SCALAR)
.setName(TaskResources.MEM_RESOURCE_NAME)
.setScalar(
Protos.Value.Scalar.newBuilder().setValue(MEM))
.build();
Protos.Resource disk =
Protos.Resource.newBuilder()
.setType(Protos.Value.Type.SCALAR)
.setName(TaskResources.DISK_RESOURCE_NAME)
.setScalar(
Protos.Value.Scalar.newBuilder().setValue(DISK))
.build();
builder.addResources(cpu).addResources(mem).addResources(disk);
Protos.Offer offer = builder.build();
// Create a BaseContainer
final int containerIndex = 0;
BaseContainer container = new BaseContainer();
container.name = TaskUtils.getTaskNameForContainerIndex(containerIndex);
container.runAsUser = ROLE;
container.description = String.format("Container %d for topology %s",
containerIndex, TOPOLOGY_NAME);
container.cpu = CPU;
container.diskInMB = DISK;
container.memInMB = MEM;
container.ports = SchedulerUtils.PORTS_REQUIRED_FOR_EXECUTOR;
container.shell = true;
container.retries = Integer.MAX_VALUE;
container.dependencies = new ArrayList<>();
String topologyPath = TOPOLOGY_PACKAGE_URI;
String heronCoreReleasePath = CORE_PACKAGE_URI;
container.dependencies.add(topologyPath);
container.dependencies.add(heronCoreReleasePath);
// List of free ports
List<Integer> freePorts = new ArrayList<>();
for (int i = 0; i < SchedulerUtils.PORTS_REQUIRED_FOR_EXECUTOR; i++) {
freePorts.add(i);
}
// Instantiate the LaunchableTask
final String taskName = TaskUtils.getTaskNameForContainerIndex(containerIndex);
final String taskId = TaskUtils.getTaskId(taskName, 0);
LaunchableTask launchableTask =
Mockito.spy(new LaunchableTask(taskId, container, offer, freePorts));
final String executorCmd = "executor_command";
Mockito.doReturn(executorCmd).when(launchableTask).executorCommand(
config, runtime, containerIndex);
Protos.TaskInfo taskInfo = launchableTask.constructMesosTaskInfo(config, runtime);
Assert.assertTrue(taskInfo.isInitialized());
Assert.assertEquals("slave-id", taskInfo.getSlaveId().getValue());
int resourceCount = 0;
for (Protos.Resource r : taskInfo.getResourcesList()) {
Assert.assertEquals("*", r.getRole());
if (r.getName().equals(TaskResources.CPUS_RESOURCE_NAME)) {
Assert.assertEquals(Protos.Value.Type.SCALAR, r.getType());
Assert.assertEquals(CPU, r.getScalar().getValue(), 0.01);
resourceCount++;
}
if (r.getName().equals(TaskResources.MEM_RESOURCE_NAME)) {
Assert.assertEquals(Protos.Value.Type.SCALAR, r.getType());
Assert.assertEquals(MEM, r.getScalar().getValue(), 0.01);
resourceCount++;
}
if (r.getName().equals(TaskResources.DISK_RESOURCE_NAME)) {
Assert.assertEquals(Protos.Value.Type.SCALAR, r.getType());
Assert.assertEquals(DISK, r.getScalar().getValue(), 0.01);
resourceCount++;
}
if (r.getName().equals(TaskResources.PORT_RESOURCE_NAME)) {
Assert.assertEquals(Protos.Value.Type.RANGES, r.getType());
Assert.assertEquals(0, r.getRanges().getRange(0).getBegin());
Assert.assertEquals(freePorts.size() - 1, r.getRanges().getRange(0).getEnd());
resourceCount++;
}
}
Assert.assertEquals(4, resourceCount);
Protos.CommandInfo commandInfo = taskInfo.getCommand();
Assert.assertEquals(executorCmd, commandInfo.getValue());
Assert.assertEquals(ROLE, commandInfo.getUser());
Assert.assertEquals(2, commandInfo.getUrisCount());
Assert.assertEquals(TOPOLOGY_PACKAGE_URI, commandInfo.getUris(0).getValue());
Assert.assertTrue(commandInfo.getUris(0).getExtract());
Assert.assertEquals(CORE_PACKAGE_URI, commandInfo.getUris(1).getValue());
Assert.assertTrue(commandInfo.getUris(1).getExtract());
// Test join
String[] s = {"A", "B", "C"};
String joined = launchableTask.join(s, "--");
Assert.assertEquals("A--B--C", joined);
}
}