Search in sources :

Example 1 with TestTuple

use of org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple in project heron by twitter.

the class KubernetesContextTest method testGetVolumeConfigsErrors.

@Test
public void testGetVolumeConfigsErrors() {
    final String prefix = KubernetesContext.KUBERNETES_VOLUME_CLAIM_PREFIX;
    final String volumeNameValid = "volume-name-valid";
    final String volumeNameInvalid = "volume-Name-Invalid";
    final String passingValue = "should-pass";
    final String failureValue = "Should-Fail";
    final String generalFailureMessage = "Invalid Volume configuration";
    final String keyPattern = String.format(KubernetesContext.KUBERNETES_VOLUME_CLAIM_PREFIX + "%%s.%%s", KubernetesConstants.EXECUTOR_NAME);
    final List<TestTuple<Config, String>> testCases = new LinkedList<>();
    // Invalid option key test.
    final Config configInvalidOption = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "claimName"), passingValue).put(String.format(keyPattern, volumeNameValid, "storageClassName"), passingValue).put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "accessModes"), passingValue).put(String.format(keyPattern, volumeNameValid, "volumeMode"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "server"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).put(String.format(keyPattern, volumeNameValid, "type"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), passingValue).put(String.format(keyPattern, volumeNameValid, "NonExistentKey"), failureValue).build();
    testCases.add(new TestTuple<>("Invalid option key should trigger exception", configInvalidOption, generalFailureMessage));
    // Invalid Volume Name.
    final Config configInvalidVolumeName = Config.newBuilder().put(String.format(keyPattern, volumeNameInvalid, "path"), failureValue).build();
    testCases.add(new TestTuple<>("Invalid Volume Name should trigger exception", configInvalidVolumeName, "lowercase RFC-1123"));
    // Required Path.
    final Config configRequiredPath = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "claimName"), passingValue).put(String.format(keyPattern, volumeNameValid, "storageClassName"), passingValue).put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "accessModes"), passingValue).put(String.format(keyPattern, volumeNameValid, "volumeMode"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "server"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).put(String.format(keyPattern, volumeNameValid, "type"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), passingValue).build();
    testCases.add(new TestTuple<>("Missing path should trigger exception", configRequiredPath, "All Volumes require a 'path'."));
    // Disabled.
    final Config configDisabled = Config.newBuilder().put(KubernetesContext.KUBERNETES_VOLUME_FROM_CLI_DISABLED, "true").put(String.format(keyPattern, volumeNameValid, "claimName"), passingValue).put(String.format(keyPattern, volumeNameValid, "storageClassName"), passingValue).put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "accessModes"), passingValue).put(String.format(keyPattern, volumeNameValid, "volumeMode"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "server"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).put(String.format(keyPattern, volumeNameValid, "type"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), passingValue).build();
    testCases.add(new TestTuple<>("Disabled functionality should trigger exception", configDisabled, "Configuring Volumes from the CLI is disabled."));
    // Testing loop.
    for (TestTuple<Config, String> testCase : testCases) {
        String message = "";
        try {
            KubernetesContext.getVolumeConfigs(testCase.input, prefix, true);
        } catch (TopologySubmissionException e) {
            message = e.getMessage();
        }
        Assert.assertTrue(testCase.description, message.contains(testCase.expected));
    }
}
Also used : TopologySubmissionException(org.apache.heron.scheduler.TopologySubmissionException) TestTuple(org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple) Config(org.apache.heron.spi.common.Config) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Example 2 with TestTuple

use of org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple in project heron by twitter.

the class V1ControllerTest method testLoadPodFromTemplateValidConfigMap.

@Test
public void testLoadPodFromTemplateValidConfigMap() {
    final String expected = "        containers: [class V1Container {\n" + "            args: null\n" + "            command: null\n" + "            env: null\n" + "            envFrom: null\n" + "            image: apache/heron:latest\n" + "            imagePullPolicy: null\n" + "            lifecycle: null\n" + "            livenessProbe: null\n" + "            name: heron-tracker\n" + "            ports: [class V1ContainerPort {\n" + "                containerPort: 8888\n" + "                hostIP: null\n" + "                hostPort: null\n" + "                name: api-port\n" + "                protocol: null\n" + "            }]\n" + "            readinessProbe: null\n" + "            resources: class V1ResourceRequirements {\n" + "                limits: {cpu=Quantity{number=0.400, format=DECIMAL_SI}, " + "memory=Quantity{number=512000000, format=DECIMAL_SI}}\n" + "                requests: {cpu=Quantity{number=0.100, format=DECIMAL_SI}, " + "memory=Quantity{number=200000000, format=DECIMAL_SI}}\n" + "            }\n" + "            securityContext: null\n" + "            startupProbe: null\n" + "            stdin: null\n" + "            stdinOnce: null\n" + "            terminationMessagePath: null\n" + "            terminationMessagePolicy: null\n" + "            tty: null\n" + "            volumeDevices: null\n" + "            volumeMounts: null\n" + "            workingDir: null\n" + "        }]";
    // ConfigMap with valid Pod Template.
    final V1ConfigMap configMapValidPod = new V1ConfigMapBuilder().withNewMetadata().withName(CONFIGMAP_NAME).endMetadata().addToData(POD_TEMPLATE_NAME, POD_TEMPLATE_VALID).build();
    // Test case container.
    // Input: ConfigMap to setup mock V1Controller, Boolean flag for executor/manager switch.
    // Output: The expected Pod template as a string.
    final List<TestTuple<Pair<V1ConfigMap, Boolean>, String>> testCases = new LinkedList<>();
    testCases.add(new TestTuple<>("Executor valid Pod Template", new Pair<>(configMapValidPod, true), expected));
    testCases.add(new TestTuple<>("Manager valid Pod Template", new Pair<>(configMapValidPod, false), expected));
    // Test loop.
    for (TestTuple<Pair<V1ConfigMap, Boolean>, String> testCase : testCases) {
        doReturn(testCase.input.first).when(v1ControllerWithPodTemplate).getConfigMap(anyString());
        V1PodTemplateSpec podTemplateSpec = v1ControllerWithPodTemplate.loadPodFromTemplate(true);
        Assert.assertTrue(podTemplateSpec.toString().contains(testCase.expected));
    }
}
Also used : V1ConfigMapBuilder(io.kubernetes.client.openapi.models.V1ConfigMapBuilder) TestTuple(org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple) Matchers.anyString(org.mockito.Matchers.anyString) V1PodTemplateSpec(io.kubernetes.client.openapi.models.V1PodTemplateSpec) V1ConfigMap(io.kubernetes.client.openapi.models.V1ConfigMap) LinkedList(java.util.LinkedList) Pair(org.apache.heron.common.basics.Pair) Test(org.junit.Test)

Example 3 with TestTuple

use of org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple in project heron by twitter.

the class V1ControllerTest method testLoadPodFromTemplateNoTargetConfigMap.

@Test
public void testLoadPodFromTemplateNoTargetConfigMap() {
    final List<TestTuple<Boolean, String>> testCases = new LinkedList<>();
    testCases.add(new TestTuple<>("Executor no target ConfigMap", true, "Failed to locate Pod Template"));
    testCases.add(new TestTuple<>("Manager no target ConfigMap", false, "Failed to locate Pod Template"));
    final V1ConfigMap configMapNoTargetData = new V1ConfigMapBuilder().withNewMetadata().withName(CONFIGMAP_NAME).endMetadata().addToData("Dummy Key", "Dummy Value").build();
    for (TestTuple<Boolean, String> testCase : testCases) {
        doReturn(configMapNoTargetData).when(v1ControllerWithPodTemplate).getConfigMap(anyString());
        String message = "";
        try {
            v1ControllerWithPodTemplate.loadPodFromTemplate(testCase.input);
        } catch (TopologySubmissionException e) {
            message = e.getMessage();
        }
        Assert.assertTrue(testCase.description, message.contains(testCase.expected));
    }
}
Also used : V1ConfigMapBuilder(io.kubernetes.client.openapi.models.V1ConfigMapBuilder) TopologySubmissionException(org.apache.heron.scheduler.TopologySubmissionException) TestTuple(org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple) Matchers.anyString(org.mockito.Matchers.anyString) LinkedList(java.util.LinkedList) V1ConfigMap(io.kubernetes.client.openapi.models.V1ConfigMap) Test(org.junit.Test)

Example 4 with TestTuple

use of org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple in project heron by twitter.

the class V1ControllerTest method testCreatePersistentVolumeClaimVolumesAndMounts.

@Test
public void testCreatePersistentVolumeClaimVolumesAndMounts() {
    final String volumeNameOne = "VolumeNameONE";
    final String volumeNameTwo = "VolumeNameTWO";
    final String claimNameOne = "claim-name-one";
    final String claimNameTwo = "OnDemand";
    final String mountPathOne = "/mount/path/ONE";
    final String mountPathTwo = "/mount/path/TWO";
    final String mountSubPathTwo = "/mount/sub/path/TWO";
    Map<String, Map<VolumeConfigKeys, String>> mapOfOpts = ImmutableMap.of(volumeNameOne, ImmutableMap.of(VolumeConfigKeys.claimName, claimNameOne, VolumeConfigKeys.path, mountPathOne), volumeNameTwo, ImmutableMap.of(VolumeConfigKeys.claimName, claimNameTwo, VolumeConfigKeys.path, mountPathTwo, VolumeConfigKeys.subPath, mountSubPathTwo));
    final V1Volume volumeOne = new V1VolumeBuilder().withName(volumeNameOne).withNewPersistentVolumeClaim().withClaimName(claimNameOne).endPersistentVolumeClaim().build();
    final V1Volume volumeTwo = new V1VolumeBuilder().withName(volumeNameTwo).withNewPersistentVolumeClaim().withClaimName(claimNameTwo).endPersistentVolumeClaim().build();
    final V1VolumeMount volumeMountOne = new V1VolumeMountBuilder().withName(volumeNameOne).withMountPath(mountPathOne).build();
    final V1VolumeMount volumeMountTwo = new V1VolumeMountBuilder().withName(volumeNameTwo).withMountPath(mountPathTwo).withSubPath(mountSubPathTwo).build();
    // Test case container.
    // Input: Map of Volume configurations.
    // Output: The expected lists of Volumes and Volume Mounts.
    final List<TestTuple<Map<String, Map<VolumeConfigKeys, String>>, Pair<List<V1Volume>, List<V1VolumeMount>>>> testCases = new LinkedList<>();
    // Default case: No PVC provided.
    testCases.add(new TestTuple<>("Generated an empty list of Volumes", new HashMap<>(), new Pair<>(new LinkedList<>(), new LinkedList<>())));
    // PVC Provided.
    final Pair<List<V1Volume>, List<V1VolumeMount>> expectedFull = new Pair<>(new LinkedList<>(Arrays.asList(volumeOne, volumeTwo)), new LinkedList<>(Arrays.asList(volumeMountOne, volumeMountTwo)));
    testCases.add(new TestTuple<>("Generated a list of Volumes", mapOfOpts, new Pair<>(expectedFull.first, expectedFull.second)));
    // Testing loop.
    for (TestTuple<Map<String, Map<VolumeConfigKeys, String>>, Pair<List<V1Volume>, List<V1VolumeMount>>> testCase : testCases) {
        List<V1Volume> actualVolume = new LinkedList<>();
        List<V1VolumeMount> actualVolumeMount = new LinkedList<>();
        v1ControllerPodTemplate.createVolumeAndMountsPersistentVolumeClaimCLI(testCase.input, actualVolume, actualVolumeMount);
        Assert.assertTrue(testCase.description, (testCase.expected.first).containsAll(actualVolume));
        Assert.assertTrue(testCase.description + " Mounts", (testCase.expected.second).containsAll(actualVolumeMount));
    }
}
Also used : VolumeConfigKeys(org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys) HashMap(java.util.HashMap) Matchers.anyString(org.mockito.Matchers.anyString) LinkedList(java.util.LinkedList) V1VolumeMount(io.kubernetes.client.openapi.models.V1VolumeMount) V1VolumeBuilder(io.kubernetes.client.openapi.models.V1VolumeBuilder) V1Volume(io.kubernetes.client.openapi.models.V1Volume) TestTuple(org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple) LinkedList(java.util.LinkedList) List(java.util.List) V1VolumeMountBuilder(io.kubernetes.client.openapi.models.V1VolumeMountBuilder) HashMap(java.util.HashMap) V1ConfigMap(io.kubernetes.client.openapi.models.V1ConfigMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) Pair(org.apache.heron.common.basics.Pair) Test(org.junit.Test)

Example 5 with TestTuple

use of org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple in project heron by twitter.

the class V1ControllerTest method testLoadPodFromTemplateInvalidConfigMap.

@Test
public void testLoadPodFromTemplateInvalidConfigMap() {
    // ConfigMap with an invalid Pod Template.
    final String invalidPodTemplate = "apiVersion: apps/v1\n" + "kind: InvalidTemplate\n" + "metadata:\n" + "  name: heron-tracker\n" + "  namespace: default\n" + "template:\n" + "  metadata:\n" + "    labels:\n" + "      app: heron-tracker\n" + "  spec:\n";
    final V1ConfigMap configMap = new V1ConfigMapBuilder().withNewMetadata().withName(CONFIGMAP_NAME).endMetadata().addToData(POD_TEMPLATE_NAME, invalidPodTemplate).build();
    // Test case container.
    // Input: ConfigMap to setup mock V1Controller, Boolean flag for executor/manager switch.
    // Output: The expected Pod template as a string.
    final List<TestTuple<Pair<V1ConfigMap, Boolean>, String>> testCases = new LinkedList<>();
    testCases.add(new TestTuple<>("Executor invalid Pod Template", new Pair<>(configMap, true), "Error parsing"));
    testCases.add(new TestTuple<>("Manager invalid Pod Template", new Pair<>(configMap, false), "Error parsing"));
    // Test loop.
    for (TestTuple<Pair<V1ConfigMap, Boolean>, String> testCase : testCases) {
        doReturn(testCase.input.first).when(v1ControllerWithPodTemplate).getConfigMap(anyString());
        String message = "";
        try {
            v1ControllerWithPodTemplate.loadPodFromTemplate(testCase.input.second);
        } catch (TopologySubmissionException e) {
            message = e.getMessage();
        }
        Assert.assertTrue(message.contains(testCase.expected));
    }
}
Also used : V1ConfigMapBuilder(io.kubernetes.client.openapi.models.V1ConfigMapBuilder) TopologySubmissionException(org.apache.heron.scheduler.TopologySubmissionException) TestTuple(org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple) Matchers.anyString(org.mockito.Matchers.anyString) V1ConfigMap(io.kubernetes.client.openapi.models.V1ConfigMap) LinkedList(java.util.LinkedList) Pair(org.apache.heron.common.basics.Pair) Test(org.junit.Test)

Aggregations

LinkedList (java.util.LinkedList)11 TestTuple (org.apache.heron.scheduler.kubernetes.KubernetesUtils.TestTuple)11 Test (org.junit.Test)11 Matchers.anyString (org.mockito.Matchers.anyString)10 V1ConfigMap (io.kubernetes.client.openapi.models.V1ConfigMap)8 Pair (org.apache.heron.common.basics.Pair)6 TopologySubmissionException (org.apache.heron.scheduler.TopologySubmissionException)6 V1ConfigMapBuilder (io.kubernetes.client.openapi.models.V1ConfigMapBuilder)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 V1VolumeMount (io.kubernetes.client.openapi.models.V1VolumeMount)3 V1VolumeMountBuilder (io.kubernetes.client.openapi.models.V1VolumeMountBuilder)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 V1Volume (io.kubernetes.client.openapi.models.V1Volume)2 V1VolumeBuilder (io.kubernetes.client.openapi.models.V1VolumeBuilder)2 VolumeConfigKeys (org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys)2 Quantity (io.kubernetes.client.custom.Quantity)1 V1Container (io.kubernetes.client.openapi.models.V1Container)1 V1ContainerBuilder (io.kubernetes.client.openapi.models.V1ContainerBuilder)1 V1PodSpec (io.kubernetes.client.openapi.models.V1PodSpec)1