use of io.kubernetes.client.openapi.models.V1ContainerBuilder in project heron by twitter.
the class V1ControllerTest method testConfigureContainerEnvVars.
@Test
public void testConfigureContainerEnvVars() {
final List<V1EnvVar> heronEnvVars = Collections.unmodifiableList(V1Controller.getExecutorEnvVars());
final V1EnvVar additionEnvVar = new V1EnvVar().name("env-variable-to-be-kept").valueFrom(new V1EnvVarSource().fieldRef(new V1ObjectFieldSelector().fieldPath("env-variable-was-kept")));
final List<V1EnvVar> inputEnvVars = Arrays.asList(new V1EnvVar().name(KubernetesConstants.ENV_HOST).valueFrom(new V1EnvVarSource().fieldRef(new V1ObjectFieldSelector().fieldPath("env-host-to-be-replaced"))), new V1EnvVar().name(KubernetesConstants.ENV_POD_NAME).valueFrom(new V1EnvVarSource().fieldRef(new V1ObjectFieldSelector().fieldPath("pod-name-to-be-replaced"))), additionEnvVar);
// Null env vars. This is the default case.
V1Container containerWithNullEnvVars = new V1ContainerBuilder().build();
v1ControllerWithPodTemplate.configureContainerEnvVars(containerWithNullEnvVars);
Assert.assertTrue("ENV_HOST & ENV_POD_NAME in container with null Env Vars should match", CollectionUtils.containsAll(containerWithNullEnvVars.getEnv(), heronEnvVars));
// Empty env vars.
V1Container containerWithEmptyEnvVars = new V1ContainerBuilder().withEnv(new LinkedList<>()).build();
v1ControllerWithPodTemplate.configureContainerEnvVars(containerWithEmptyEnvVars);
Assert.assertTrue("ENV_HOST & ENV_POD_NAME in container with empty Env Vars should match", CollectionUtils.containsAll(containerWithEmptyEnvVars.getEnv(), heronEnvVars));
// Env Var overriding.
final List<V1EnvVar> expectedOverriding = new LinkedList<>(heronEnvVars);
expectedOverriding.add(additionEnvVar);
V1Container containerWithEnvVars = new V1ContainerBuilder().withEnv(inputEnvVars).build();
v1ControllerWithPodTemplate.configureContainerEnvVars(containerWithEnvVars);
Assert.assertTrue("ENV_HOST & ENV_POD_NAME in container with Env Vars should be overridden", CollectionUtils.containsAll(containerWithEnvVars.getEnv(), expectedOverriding));
}
use of io.kubernetes.client.openapi.models.V1ContainerBuilder in project heron by twitter.
the class V1ControllerTest method testConfigureContainerPorts.
@Test
public void testConfigureContainerPorts() {
final String portNamekept = "random-port-to-be-kept";
final int portNumberkept = 1111;
final int numInstances = 3;
final List<V1ContainerPort> expectedPortsBase = Collections.unmodifiableList(V1Controller.getExecutorPorts());
final List<V1ContainerPort> debugPorts = Collections.unmodifiableList(V1Controller.getDebuggingPorts(numInstances));
final List<V1ContainerPort> inputPortsBase = Collections.unmodifiableList(Arrays.asList(new V1ContainerPort().name("server-port-to-replace").containerPort(KubernetesConstants.SERVER_PORT), new V1ContainerPort().name("shell-port-to-replace").containerPort(KubernetesConstants.SHELL_PORT), new V1ContainerPort().name(portNamekept).containerPort(portNumberkept)));
// Null ports. This is the default case.
final V1Container inputContainerWithNullPorts = new V1ContainerBuilder().build();
v1ControllerWithPodTemplate.configureContainerPorts(false, 0, inputContainerWithNullPorts);
Assert.assertTrue("Server and/or shell PORTS for container with null ports list", CollectionUtils.containsAll(inputContainerWithNullPorts.getPorts(), expectedPortsBase));
// Empty ports.
final V1Container inputContainerWithEmptyPorts = new V1ContainerBuilder().withPorts(new LinkedList<>()).build();
v1ControllerWithPodTemplate.configureContainerPorts(false, 0, inputContainerWithEmptyPorts);
Assert.assertTrue("Server and/or shell PORTS for container with empty ports list", CollectionUtils.containsAll(inputContainerWithEmptyPorts.getPorts(), expectedPortsBase));
// Port overriding.
final List<V1ContainerPort> inputPorts = new LinkedList<>(inputPortsBase);
final V1Container inputContainerWithPorts = new V1ContainerBuilder().withPorts(inputPorts).build();
final List<V1ContainerPort> expectedPortsOverriding = new LinkedList<>(expectedPortsBase);
expectedPortsOverriding.add(new V1ContainerPort().name(portNamekept).containerPort(portNumberkept));
v1ControllerWithPodTemplate.configureContainerPorts(false, 0, inputContainerWithPorts);
Assert.assertTrue("Server and/or shell PORTS for container should be overwritten.", CollectionUtils.containsAll(inputContainerWithPorts.getPorts(), expectedPortsOverriding));
// Port overriding with debug ports.
final List<V1ContainerPort> inputPortsWithDebug = new LinkedList<>(debugPorts);
inputPortsWithDebug.addAll(inputPortsBase);
final V1Container inputContainerWithDebug = new V1ContainerBuilder().withPorts(inputPortsWithDebug).build();
final List<V1ContainerPort> expectedPortsDebug = new LinkedList<>(expectedPortsBase);
expectedPortsDebug.add(new V1ContainerPort().name(portNamekept).containerPort(portNumberkept));
expectedPortsDebug.addAll(debugPorts);
v1ControllerWithPodTemplate.configureContainerPorts(true, numInstances, inputContainerWithDebug);
Assert.assertTrue("Server and/or shell with debug PORTS for container should be overwritten.", CollectionUtils.containsAll(inputContainerWithDebug.getPorts(), expectedPortsDebug));
}
use of io.kubernetes.client.openapi.models.V1ContainerBuilder in project heron by twitter.
the class V1ControllerTest method testConfigureContainerResources.
@Test
public void testConfigureContainerResources() {
final boolean isExecutor = true;
final Resource resourceDefault = new Resource(9, ByteAmount.fromMegabytes(19000), ByteAmount.fromMegabytes(99000));
final Resource resourceCustom = new Resource(4, ByteAmount.fromMegabytes(34000), ByteAmount.fromMegabytes(400000));
final Quantity defaultRAM = Quantity.fromString(KubernetesUtils.Megabytes(resourceDefault.getRam()));
final Quantity defaultCPU = Quantity.fromString(Double.toString(KubernetesUtils.roundDecimal(resourceDefault.getCpu(), 3)));
final Quantity customRAM = Quantity.fromString(KubernetesUtils.Megabytes(resourceCustom.getRam()));
final Quantity customCPU = Quantity.fromString(Double.toString(KubernetesUtils.roundDecimal(resourceCustom.getCpu(), 3)));
final Quantity customDisk = Quantity.fromString(KubernetesUtils.Megabytes(resourceCustom.getDisk()));
final Config configNoLimit = Config.newBuilder().put(KubernetesContext.KUBERNETES_RESOURCE_REQUEST_MODE, "NOT_SET").build();
final Config configWithLimit = Config.newBuilder().put(KubernetesContext.KUBERNETES_RESOURCE_REQUEST_MODE, "EQUAL_TO_LIMIT").build();
final V1ResourceRequirements expectDefaultRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, defaultRAM).putLimitsItem(KubernetesConstants.CPU, defaultCPU);
final V1ResourceRequirements expectCustomRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, defaultRAM).putLimitsItem(KubernetesConstants.CPU, defaultCPU).putLimitsItem("disk", customDisk);
final V1ResourceRequirements customRequirements = new V1ResourceRequirements().putLimitsItem(KubernetesConstants.MEMORY, customRAM).putLimitsItem(KubernetesConstants.CPU, customCPU).putLimitsItem("disk", customDisk);
// Default. Null resources.
V1Container containerNull = new V1ContainerBuilder().build();
v1ControllerWithPodTemplate.configureContainerResources(containerNull, configNoLimit, resourceDefault, isExecutor);
Assert.assertTrue("Default LIMITS should be set in container with null LIMITS", containerNull.getResources().getLimits().entrySet().containsAll(expectDefaultRequirements.getLimits().entrySet()));
// Empty resources.
V1Container containerEmpty = new V1ContainerBuilder().withNewResources().endResources().build();
v1ControllerWithPodTemplate.configureContainerResources(containerEmpty, configNoLimit, resourceDefault, isExecutor);
Assert.assertTrue("Default LIMITS should be set in container with empty LIMITS", containerNull.getResources().getLimits().entrySet().containsAll(expectDefaultRequirements.getLimits().entrySet()));
// Custom resources.
V1Container containerCustom = new V1ContainerBuilder().withResources(customRequirements).build();
v1ControllerWithPodTemplate.configureContainerResources(containerCustom, configNoLimit, resourceDefault, isExecutor);
Assert.assertTrue("Custom LIMITS should be set in container with custom LIMITS", containerCustom.getResources().getLimits().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
// Custom resources with request.
V1Container containerRequests = new V1ContainerBuilder().withResources(customRequirements).build();
v1ControllerWithPodTemplate.configureContainerResources(containerRequests, configWithLimit, resourceDefault, isExecutor);
Assert.assertTrue("Custom LIMITS should be set in container with custom LIMITS and REQUEST", containerRequests.getResources().getLimits().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
Assert.assertTrue("Custom REQUEST should be set in container with custom LIMITS and REQUEST", containerRequests.getResources().getRequests().entrySet().containsAll(expectCustomRequirements.getLimits().entrySet()));
}
use of io.kubernetes.client.openapi.models.V1ContainerBuilder in project heron by twitter.
the class V1ControllerTest method testConfigurePodWithVolumesAndMountsFromCLI.
@Test
public void testConfigurePodWithVolumesAndMountsFromCLI() {
final String volumeNameClashing = "clashing-volume";
final String volumeMountNameClashing = "original-volume-mount";
V1Volume baseVolume = new V1VolumeBuilder().withName(volumeNameClashing).withNewPersistentVolumeClaim().withClaimName("Original Base Claim Name").endPersistentVolumeClaim().build();
V1VolumeMount baseVolumeMount = new V1VolumeMountBuilder().withName(volumeMountNameClashing).withMountPath("/original/mount/path").build();
V1Volume clashingVolume = new V1VolumeBuilder().withName(volumeNameClashing).withNewPersistentVolumeClaim().withClaimName("Clashing Claim Replaced").endPersistentVolumeClaim().build();
V1VolumeMount clashingVolumeMount = new V1VolumeMountBuilder().withName(volumeMountNameClashing).withMountPath("/clashing/mount/path").build();
V1Volume secondaryVolume = new V1VolumeBuilder().withName("secondary-volume").withNewPersistentVolumeClaim().withClaimName("Original Secondary Claim Name").endPersistentVolumeClaim().build();
V1VolumeMount secondaryVolumeMount = new V1VolumeMountBuilder().withName("secondary-volume-mount").withMountPath("/secondary/mount/path").build();
// Test case container.
// Input: [0] Pod Spec to modify, [1] Heron container to modify, [2] List of Volumes
// [3] List of Volume Mounts.
// Output: The expected <V1PodSpec> and <V1Container>.
final List<TestTuple<Object[], Pair<V1PodSpec, V1Container>>> testCases = new LinkedList<>();
// No Persistent Volume Claim.
final V1PodSpec podSpecEmptyCase = new V1PodSpecBuilder().withVolumes(baseVolume).build();
final V1Container executorEmptyCase = new V1ContainerBuilder().withVolumeMounts(baseVolumeMount).build();
final V1PodSpec expectedEmptyPodSpec = new V1PodSpecBuilder().withVolumes(baseVolume).build();
final V1Container expectedEmptyExecutor = new V1ContainerBuilder().withVolumeMounts(baseVolumeMount).build();
testCases.add(new TestTuple<>("Empty", new Object[] { podSpecEmptyCase, executorEmptyCase, new LinkedList<>(), new LinkedList<>() }, new Pair<>(expectedEmptyPodSpec, expectedEmptyExecutor)));
// Non-clashing Persistent Volume Claim.
final V1PodSpec podSpecNoClashCase = new V1PodSpecBuilder().withVolumes(baseVolume).build();
final V1Container executorNoClashCase = new V1ContainerBuilder().withVolumeMounts(baseVolumeMount).build();
final V1PodSpec expectedNoClashPodSpec = new V1PodSpecBuilder().addToVolumes(baseVolume).addToVolumes(secondaryVolume).build();
final V1Container expectedNoClashExecutor = new V1ContainerBuilder().addToVolumeMounts(baseVolumeMount).addToVolumeMounts(secondaryVolumeMount).build();
testCases.add(new TestTuple<>("No Clash", new Object[] { podSpecNoClashCase, executorNoClashCase, Collections.singletonList(secondaryVolume), Collections.singletonList(secondaryVolumeMount) }, new Pair<>(expectedNoClashPodSpec, expectedNoClashExecutor)));
// Clashing Persistent Volume Claim.
final V1PodSpec podSpecClashCase = new V1PodSpecBuilder().withVolumes(baseVolume).build();
final V1Container executorClashCase = new V1ContainerBuilder().withVolumeMounts(baseVolumeMount).build();
final V1PodSpec expectedClashPodSpec = new V1PodSpecBuilder().addToVolumes(clashingVolume).addToVolumes(secondaryVolume).build();
final V1Container expectedClashExecutor = new V1ContainerBuilder().addToVolumeMounts(clashingVolumeMount).addToVolumeMounts(secondaryVolumeMount).build();
testCases.add(new TestTuple<>("Clashing", new Object[] { podSpecClashCase, executorClashCase, Arrays.asList(clashingVolume, secondaryVolume), Arrays.asList(clashingVolumeMount, secondaryVolumeMount) }, new Pair<>(expectedClashPodSpec, expectedClashExecutor)));
// Testing loop.
for (TestTuple<Object[], Pair<V1PodSpec, V1Container>> testCase : testCases) {
v1ControllerWithPodTemplate.configurePodWithVolumesAndMountsFromCLI((V1PodSpec) testCase.input[0], (V1Container) testCase.input[1], (List<V1Volume>) testCase.input[2], (List<V1VolumeMount>) testCase.input[3]);
Assert.assertEquals("Pod Specs match " + testCase.description, testCase.input[0], testCase.expected.first);
Assert.assertEquals("Executors match " + testCase.description, testCase.input[1], testCase.expected.second);
}
}
use of io.kubernetes.client.openapi.models.V1ContainerBuilder in project heron by twitter.
the class V1ControllerTest method testConfigureContainerResourcesCLI.
@Test
public void testConfigureContainerResourcesCLI() {
final boolean isExecutor = true;
final String customLimitMEMStr = "120Gi";
final String customLimitCPUStr = "5";
final String customRequestMEMStr = "100Mi";
final String customRequestCPUStr = "4";
final Resource resources = new Resource(6, ByteAmount.fromMegabytes(34000), ByteAmount.fromGigabytes(400));
final Quantity customLimitMEM = Quantity.fromString(customLimitMEMStr);
final Quantity customLimitCPU = Quantity.fromString(customLimitCPUStr);
final Quantity customRequestMEM = Quantity.fromString(customRequestMEMStr);
final Quantity customRequestCPU = Quantity.fromString(customRequestCPUStr);
final Config config = Config.newBuilder().put(String.format(KubernetesContext.KUBERNETES_RESOURCE_LIMITS_PREFIX + KubernetesConstants.CPU, KubernetesConstants.EXECUTOR_NAME), customLimitCPUStr).put(String.format(KubernetesContext.KUBERNETES_RESOURCE_LIMITS_PREFIX + KubernetesConstants.MEMORY, KubernetesConstants.EXECUTOR_NAME), customLimitMEMStr).put(String.format(KubernetesContext.KUBERNETES_RESOURCE_REQUESTS_PREFIX + KubernetesConstants.CPU, KubernetesConstants.EXECUTOR_NAME), customRequestCPUStr).put(String.format(KubernetesContext.KUBERNETES_RESOURCE_REQUESTS_PREFIX + KubernetesConstants.MEMORY, KubernetesConstants.EXECUTOR_NAME), customRequestMEMStr).put(KubernetesContext.KUBERNETES_RESOURCE_REQUEST_MODE, "EQUAL_TO_LIMIT").build();
final V1Container expected = new V1ContainerBuilder().withNewResources().addToLimits(KubernetesConstants.CPU, customLimitCPU).addToLimits(KubernetesConstants.MEMORY, customLimitMEM).addToRequests(KubernetesConstants.CPU, customRequestCPU).addToRequests(KubernetesConstants.MEMORY, customRequestMEM).endResources().build();
final V1Container actual = new V1Container();
v1ControllerWithPodTemplate.configureContainerResources(actual, config, resources, isExecutor);
Assert.assertEquals("Container Resources are set from CLI.", expected, actual);
}
Aggregations