use of org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys in project heron by twitter.
the class V1ControllerTest method testCreateVolumeMountsCLI.
@Test
public void testCreateVolumeMountsCLI() {
final String volumeNamePVC = "volume-name-pvc";
final String volumeNameHostPath = "volume-name-host-path";
final String volumeNameEmptyDir = "volume-name-empty-dir";
final String volumeNameNFS = "volume-name-nfs";
final String value = "inserted-value";
// Test case container.
// Input: [0] volume name, [1] volume options
// Output: The expected <V1VolumeMount>.
final List<TestTuple<Pair<String, Map<VolumeConfigKeys, String>>, V1VolumeMount>> testCases = new LinkedList<>();
// PVC.
final Map<VolumeConfigKeys, String> configPVC = ImmutableMap.<VolumeConfigKeys, String>builder().put(VolumeConfigKeys.claimName, value).put(VolumeConfigKeys.storageClassName, value).put(VolumeConfigKeys.sizeLimit, value).put(VolumeConfigKeys.accessModes, value).put(VolumeConfigKeys.volumeMode, value).put(VolumeConfigKeys.path, value).put(VolumeConfigKeys.subPath, value).put(VolumeConfigKeys.readOnly, "true").build();
final V1VolumeMount volumeMountPVC = new V1VolumeMountBuilder().withName(volumeNamePVC).withMountPath(value).withSubPath(value).withReadOnly(true).build();
testCases.add(new TestTuple<>("PVC volume mount", new Pair<>(volumeNamePVC, configPVC), volumeMountPVC));
// Host Path.
final Map<VolumeConfigKeys, String> configHostPath = ImmutableMap.<VolumeConfigKeys, String>builder().put(VolumeConfigKeys.type, "DirectoryOrCreate").put(VolumeConfigKeys.pathOnHost, value).put(VolumeConfigKeys.path, value).put(VolumeConfigKeys.subPath, value).put(VolumeConfigKeys.readOnly, "true").build();
final V1VolumeMount volumeMountHostPath = new V1VolumeMountBuilder().withName(volumeNameHostPath).withMountPath(value).withSubPath(value).withReadOnly(true).build();
testCases.add(new TestTuple<>("Host Path volume mount", new Pair<>(volumeNameHostPath, configHostPath), volumeMountHostPath));
// Empty Dir.
final Map<VolumeConfigKeys, String> configEmptyDir = ImmutableMap.<VolumeConfigKeys, String>builder().put(VolumeConfigKeys.sizeLimit, value).put(VolumeConfigKeys.medium, "Memory").put(VolumeConfigKeys.path, value).put(VolumeConfigKeys.subPath, value).put(VolumeConfigKeys.readOnly, "true").build();
final V1VolumeMount volumeMountEmptyDir = new V1VolumeMountBuilder().withName(volumeNameEmptyDir).withMountPath(value).withSubPath(value).withReadOnly(true).build();
testCases.add(new TestTuple<>("Empty Dir volume mount", new Pair<>(volumeNameEmptyDir, configEmptyDir), volumeMountEmptyDir));
// NFS.
final Map<VolumeConfigKeys, String> configNFS = ImmutableMap.<VolumeConfigKeys, String>builder().put(VolumeConfigKeys.server, "nfs.server.address").put(VolumeConfigKeys.readOnly, "true").put(VolumeConfigKeys.pathOnNFS, value).put(VolumeConfigKeys.path, value).put(VolumeConfigKeys.subPath, value).build();
final V1VolumeMount volumeMountNFS = new V1VolumeMountBuilder().withName(volumeNameNFS).withMountPath(value).withSubPath(value).withReadOnly(true).build();
testCases.add(new TestTuple<>("NFS volume mount", new Pair<>(volumeNameNFS, configNFS), volumeMountNFS));
// Test loop.
for (TestTuple<Pair<String, Map<VolumeConfigKeys, String>>, V1VolumeMount> testCase : testCases) {
V1VolumeMount actual = v1ControllerPodTemplate.createVolumeMountsCLI(testCase.input.first, testCase.input.second);
Assert.assertEquals(testCase.description, testCase.expected, actual);
}
}
use of org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys in project heron by twitter.
the class KubernetesContextTest method createVolumeConfigs.
/**
* Generate <code>Volume</code> Configs for testing.
* @param testCases Test case container.
* Input: [0] Config, [1] Boolean to indicate Manager/Executor.
* Output: [0] expectedKeys, [1] expectedOptionsKeys, [2] expectedOptionsValues.
* @param prefix Configuration prefix key to use in lookup.
*/
private void createVolumeConfigs(List<TestTuple<Pair<Config, Boolean>, Object[]>> testCases, String prefix) {
final String keyPattern = prefix + "%%s.%%s";
final String keyExecutor = String.format(keyPattern, KubernetesConstants.EXECUTOR_NAME);
final String keyManager = String.format(keyPattern, KubernetesConstants.MANAGER_NAME);
final String volumeNameOne = "volume-name-one";
final String volumeNameTwo = "volume-name-two";
final String claimName = "OnDeMaNd";
final String storageClassField = VolumeConfigKeys.storageClassName.name();
final String pathField = VolumeConfigKeys.path.name();
final String claimNameField = VolumeConfigKeys.claimName.name();
final String expectedStorageClass = "expected-storage-class";
final String expectedPath = "/path/for/volume/expected";
// Create test cases for Executor/Manager on even/odd indices respectively.
for (int idx = 0; idx < 2; ++idx) {
// Manager case is default.
boolean isExecutor = false;
String key = keyManager;
String description = KubernetesConstants.MANAGER_NAME;
// Executor case.
if (idx % 2 == 0) {
isExecutor = true;
key = keyExecutor;
description = KubernetesConstants.EXECUTOR_NAME;
}
final String storageClassKeyOne = String.format(key, volumeNameOne, storageClassField);
final String storageClassKeyTwo = String.format(key, volumeNameTwo, storageClassField);
final String pathKeyOne = String.format(key, volumeNameOne, pathField);
final String pathKeyTwo = String.format(key, volumeNameTwo, pathField);
final String claimNameKeyOne = String.format(key, volumeNameOne, claimNameField);
final String claimNameKeyTwo = String.format(key, volumeNameTwo, claimNameField);
final Config configPVC = Config.newBuilder().put(pathKeyOne, expectedPath).put(pathKeyTwo, expectedPath).put(claimNameKeyOne, claimName).put(claimNameKeyTwo, claimName).put(storageClassKeyOne, expectedStorageClass).put(storageClassKeyTwo, expectedStorageClass).build();
final List<String> expectedKeys = Arrays.asList(volumeNameOne, volumeNameTwo);
final List<VolumeConfigKeys> expectedOptionsKeys = Arrays.asList(VolumeConfigKeys.path, VolumeConfigKeys.storageClassName, VolumeConfigKeys.claimName);
final List<String> expectedOptionsValues = Arrays.asList(expectedPath, expectedStorageClass, claimName);
testCases.add(new TestTuple<>(description, new Pair<>(configPVC, isExecutor), new Object[] { expectedKeys, expectedOptionsKeys, expectedOptionsValues }));
final Config configPVCDisabled = Config.newBuilder().put(KubernetesContext.KUBERNETES_VOLUME_FROM_CLI_DISABLED, "true").put(pathKeyOne, expectedPath).put(pathKeyTwo, expectedPath).put(claimNameKeyOne, claimName).put(claimNameKeyTwo, claimName).put(storageClassKeyOne, expectedStorageClass).put(storageClassKeyTwo, expectedStorageClass).build();
testCases.add(new TestTuple<>(description + " Disabled should not error", new Pair<>(configPVCDisabled, !isExecutor), new Object[] { new LinkedList<String>(), new LinkedList<VolumeConfigKeys>(), new LinkedList<String>() }));
}
}
use of org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys in project heron by twitter.
the class KubernetesContextTest method createVolumeNFS.
/**
* Create test cases for <code>NFS</code>.
* @param testCases Test case container.
* Input: [0] Config, [1] Boolean to indicate Manager/Executor.
* Output: <code>Map<String, Map<VolumeConfigKeys, String></code>
* @param isExecutor Boolean to indicate Manager/Executor test case generation.
*/
private void createVolumeNFS(List<TestTuple<Pair<Config, Boolean>, Map<String, Map<VolumeConfigKeys, String>>>> testCases, boolean isExecutor) {
final String volumeNameValid = "volume-name-valid";
final String passingValue = "should-pass";
final String processName = isExecutor ? KubernetesConstants.EXECUTOR_NAME : KubernetesConstants.MANAGER_NAME;
final String keyPattern = String.format(KubernetesContext.KUBERNETES_VOLUME_NFS_PREFIX + "%%s.%%s", processName);
// With readOnly.
final Map<String, Map<VolumeConfigKeys, String>> expectedWithReadOnly = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.server, "nfs-server.default.local");
put(VolumeConfigKeys.readOnly, "true");
put(VolumeConfigKeys.pathOnNFS, passingValue);
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configWithReadOnly = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "readOnly"), "true").put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `NFS` with `readOnly`", new Pair<>(configWithReadOnly, isExecutor), expectedWithReadOnly));
// With readOnly.
final Map<String, Map<VolumeConfigKeys, String>> expectedWithoutReadOnly = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.server, "nfs-server.default.local");
put(VolumeConfigKeys.pathOnNFS, passingValue);
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configWithoutReadOnly = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `NFS` without `readOnly`", new Pair<>(configWithoutReadOnly, isExecutor), expectedWithoutReadOnly));
// Ignored.
final Config configIgnored = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "readOnly"), "true").put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `NFS` ignored", new Pair<>(configIgnored, !isExecutor), new HashMap<>()));
}
use of org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys in project heron by twitter.
the class KubernetesContextTest method createVolumeEmptyDir.
/**
* Create test cases for <code>Empty Directory</code>.
* @param testCases Test case container.
* Input: [0] Config, [1] Boolean to indicate Manager/Executor.
* Output: <code>Map<String, Map<VolumeConfigKeys, String></code>
* @param isExecutor Boolean to indicate Manager/Executor test case generation.
*/
private void createVolumeEmptyDir(List<TestTuple<Pair<Config, Boolean>, Map<String, Map<VolumeConfigKeys, String>>>> testCases, boolean isExecutor) {
final String volumeNameValid = "volume-name-valid";
final String passingValue = "should-pass";
final String processName = isExecutor ? KubernetesConstants.EXECUTOR_NAME : KubernetesConstants.MANAGER_NAME;
final String keyPattern = String.format(KubernetesContext.KUBERNETES_VOLUME_EMPTYDIR_PREFIX + "%%s.%%s", processName);
// With Medium.
final Map<String, Map<VolumeConfigKeys, String>> expectedWithMedium = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.sizeLimit, passingValue);
put(VolumeConfigKeys.medium, "Memory");
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configWithMedium = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), "Memory").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `emptyDir` with `medium`", new Pair<>(configWithMedium, isExecutor), expectedWithMedium));
// With empty Medium.
final Map<String, Map<VolumeConfigKeys, String>> expectedEmptyMedium = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.sizeLimit, passingValue);
put(VolumeConfigKeys.medium, "");
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configEmptyMedium = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), "").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `emptyDir` with empty `medium`", new Pair<>(configEmptyMedium, isExecutor), expectedEmptyMedium));
// Without Medium.
final Map<String, Map<VolumeConfigKeys, String>> expectedNoMedium = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.sizeLimit, passingValue);
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configNoMedium = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `emptyDir` without `medium`", new Pair<>(configNoMedium, isExecutor), expectedNoMedium));
// Ignored.
final Config configIgnored = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "sizeLimit"), passingValue).put(String.format(keyPattern, volumeNameValid, "medium"), "").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).put(String.format(keyPattern, volumeNameValid, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": `emptyDir` ignored", new Pair<>(configIgnored, !isExecutor), new HashMap<>()));
}
use of org.apache.heron.scheduler.kubernetes.KubernetesConstants.VolumeConfigKeys in project heron by twitter.
the class V1ControllerTest method testCreatePersistentVolumeClaims.
@Test
public void testCreatePersistentVolumeClaims() {
final String topologyName = "topology-name";
final String volumeNameOne = "volume-name-one";
final String volumeNameTwo = "volume-name-two";
final String volumeNameStatic = "volume-name-static";
final String claimNameOne = "OnDemand";
final String claimNameTwo = "claim-name-two";
final String claimNameStatic = "OnDEmaND";
final String storageClassName = "storage-class-name";
final String sizeLimit = "555Gi";
final String accessModesList = "ReadWriteOnce,ReadOnlyMany,ReadWriteMany";
final String accessModes = "ReadOnlyMany";
final String volumeMode = "VolumeMode";
final String path = "/path/to/mount/";
final String subPath = "/sub/path/to/mount/";
final Map<String, Map<VolumeConfigKeys, String>> mapPVCOpts = ImmutableMap.of(volumeNameOne, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.claimName, claimNameOne);
put(VolumeConfigKeys.storageClassName, storageClassName);
put(VolumeConfigKeys.sizeLimit, sizeLimit);
put(VolumeConfigKeys.accessModes, accessModesList);
put(VolumeConfigKeys.volumeMode, volumeMode);
put(VolumeConfigKeys.path, path);
}
}, volumeNameTwo, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.claimName, claimNameTwo);
put(VolumeConfigKeys.storageClassName, storageClassName);
put(VolumeConfigKeys.sizeLimit, sizeLimit);
put(VolumeConfigKeys.accessModes, accessModes);
put(VolumeConfigKeys.volumeMode, volumeMode);
put(VolumeConfigKeys.path, path);
put(VolumeConfigKeys.subPath, subPath);
}
}, volumeNameStatic, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.claimName, claimNameStatic);
put(VolumeConfigKeys.sizeLimit, sizeLimit);
put(VolumeConfigKeys.accessModes, accessModes);
put(VolumeConfigKeys.volumeMode, volumeMode);
put(VolumeConfigKeys.path, path);
put(VolumeConfigKeys.subPath, subPath);
}
});
final V1PersistentVolumeClaim claimOne = new V1PersistentVolumeClaimBuilder().withNewMetadata().withName(volumeNameOne).withLabels(V1Controller.getPersistentVolumeClaimLabels(topologyName)).endMetadata().withNewSpec().withStorageClassName(storageClassName).withAccessModes(Arrays.asList(accessModesList.split(","))).withVolumeMode(volumeMode).withNewResources().addToRequests("storage", new Quantity(sizeLimit)).endResources().endSpec().build();
final V1PersistentVolumeClaim claimStatic = new V1PersistentVolumeClaimBuilder().withNewMetadata().withName(volumeNameStatic).withLabels(V1Controller.getPersistentVolumeClaimLabels(topologyName)).endMetadata().withNewSpec().withStorageClassName("").withAccessModes(Collections.singletonList(accessModes)).withVolumeMode(volumeMode).withNewResources().addToRequests("storage", new Quantity(sizeLimit)).endResources().endSpec().build();
final List<V1PersistentVolumeClaim> expectedClaims = new LinkedList<>(Arrays.asList(claimOne, claimStatic));
final List<V1PersistentVolumeClaim> actualClaims = v1ControllerWithPodTemplate.createPersistentVolumeClaims(mapPVCOpts);
Assert.assertTrue(expectedClaims.containsAll(actualClaims));
}
Aggregations