use of org.apache.heron.common.basics.Pair in project heron by twitter.
the class FirstFitDecreasingPackingTest method testScaleDownTwoComponentsRemoveContainer.
@Test
public void testScaleDownTwoComponentsRemoveContainer() throws Exception {
@SuppressWarnings({ "unchecked", "rawtypes" }) Pair<Integer, InstanceId>[] initialComponentInstances = new Pair[] { new Pair<>(1, new InstanceId(SPOUT_NAME, 1, 0)), new Pair<>(1, new InstanceId(SPOUT_NAME, 2, 1)), new Pair<>(1, new InstanceId(BOLT_NAME, 3, 0)), new Pair<>(1, new InstanceId(BOLT_NAME, 4, 1)), new Pair<>(3, new InstanceId(SPOUT_NAME, 5, 2)), new Pair<>(3, new InstanceId(SPOUT_NAME, 6, 3)), new Pair<>(3, new InstanceId(BOLT_NAME, 7, 2)), new Pair<>(3, new InstanceId(BOLT_NAME, 8, 3)) };
Map<String, Integer> componentChanges = new HashMap<>();
componentChanges.put(SPOUT_NAME, -2);
componentChanges.put(BOLT_NAME, -2);
@SuppressWarnings({ "unchecked", "rawtypes" }) Pair<Integer, InstanceId>[] expectedComponentInstances = new Pair[] { new Pair<>(1, new InstanceId(SPOUT_NAME, 1, 0)), new Pair<>(1, new InstanceId(SPOUT_NAME, 2, 1)), new Pair<>(1, new InstanceId(BOLT_NAME, 3, 0)), new Pair<>(1, new InstanceId(BOLT_NAME, 4, 1)) };
doScaleDownTest(initialComponentInstances, componentChanges, expectedComponentInstances);
}
use of org.apache.heron.common.basics.Pair in project heron by twitter.
the class V1Controller method getPodTemplateLocation.
/**
* Extracts the <code>ConfigMap</code> and <code>Pod Template</code> names from the CLI parameter.
* @param isExecutor Flag to indicate loading of <code>Pod Template</code> for <code>Executor</code>
* or <code>Manager</code>.
* @return A pair of the form <code>(ConfigMap, Pod Template)</code>.
*/
@VisibleForTesting
protected Pair<String, String> getPodTemplateLocation(boolean isExecutor) {
final String podTemplateConfigMapName = KubernetesContext.getPodTemplateConfigMapName(getConfiguration(), isExecutor);
if (podTemplateConfigMapName == null) {
return null;
}
try {
final int splitPoint = podTemplateConfigMapName.indexOf(".");
final String configMapName = podTemplateConfigMapName.substring(0, splitPoint);
final String podTemplateName = podTemplateConfigMapName.substring(splitPoint + 1);
if (configMapName.isEmpty() || podTemplateName.isEmpty()) {
throw new IllegalArgumentException("Empty ConfigMap or Pod Template name");
}
return new Pair<>(configMapName, podTemplateName);
} catch (IndexOutOfBoundsException | IllegalArgumentException e) {
final String message = "Invalid ConfigMap and/or Pod Template name";
KubernetesUtils.logExceptionWithDetails(LOG, message, e);
throw new TopologySubmissionException(message);
}
}
use of org.apache.heron.common.basics.Pair in project heron by twitter.
the class KubernetesContextTest method createVolumeClaimTemplates.
/**
* Create test cases for <code>Volume Claim Templates</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 createVolumeClaimTemplates(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_CLAIM_PREFIX + "%%s.%%s", processName);
// With Storage Class Name.
final Map<String, Map<VolumeConfigKeys, String>> expectedWithStorageClassName = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.claimName, passingValue);
put(VolumeConfigKeys.storageClassName, passingValue);
put(VolumeConfigKeys.sizeLimit, passingValue);
put(VolumeConfigKeys.accessModes, passingValue);
put(VolumeConfigKeys.volumeMode, passingValue);
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configWithStorageClass = 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, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": PVC with Storage Class name", new Pair<>(configWithStorageClass, isExecutor), expectedWithStorageClassName));
// Without Storage Class Name.
final Map<String, Map<VolumeConfigKeys, String>> expectedWithoutStorageClassName = ImmutableMap.of(volumeNameValid, new HashMap<VolumeConfigKeys, String>() {
{
put(VolumeConfigKeys.claimName, passingValue);
put(VolumeConfigKeys.sizeLimit, passingValue);
put(VolumeConfigKeys.accessModes, passingValue);
put(VolumeConfigKeys.volumeMode, passingValue);
put(VolumeConfigKeys.path, passingValue);
put(VolumeConfigKeys.subPath, passingValue);
put(VolumeConfigKeys.readOnly, passingValue);
}
});
final Config configWithoutStorageClass = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "claimName"), 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, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": PVC with Storage Class name", new Pair<>(configWithoutStorageClass, isExecutor), expectedWithoutStorageClassName));
// Ignored.
final Config configIgnored = 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, "readOnly"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": PVC with ignored keys", new Pair<>(configIgnored, !isExecutor), new HashMap<>()));
}
use of org.apache.heron.common.basics.Pair in project heron by twitter.
the class KubernetesContextTest method createVolumeClaimTemplatesErrors.
/**
* Create test cases for <code>Volume Claim Templates</code> errors.
* @param testCases Test case container.
* Input: [0] Config, [1] Boolean to indicate Manager/Executor.
* Output: Error message
* @param isExecutor Boolean to indicate Manager/Executor test case generation.
*/
private void createVolumeClaimTemplatesErrors(List<TestTuple<Pair<Config, Boolean>, String>> testCases, boolean isExecutor) {
final String volumeNameValid = "volume-name-valid";
final String passingValue = "should-pass";
final String failureValue = "Should-Fail";
final String processName = isExecutor ? KubernetesConstants.EXECUTOR_NAME : KubernetesConstants.MANAGER_NAME;
final String keyPattern = String.format(KubernetesContext.KUBERNETES_VOLUME_CLAIM_PREFIX + "%%s.%%s", processName);
// Required Claim Name.
final Config configRequiredClaimName = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "path"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": Missing Claim Name should trigger exception", new Pair<>(configRequiredClaimName, isExecutor), "require a `claimName`"));
// Invalid Claim Name.
final Config configInvalidClaimName = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "claimName"), failureValue).build();
testCases.add(new TestTuple<>(processName + ": Invalid Claim Name should trigger exception", new Pair<>(configInvalidClaimName, isExecutor), String.format("Volume `%s`: `claimName`", volumeNameValid)));
// Invalid Storage Class Name.
final Config configInvalidStorageClassName = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "claimName"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "storageClassName"), failureValue).build();
testCases.add(new TestTuple<>(processName + ": Invalid Storage Class Name should trigger exception", new Pair<>(configInvalidStorageClassName, isExecutor), String.format("Volume `%s`: `storageClassName`", volumeNameValid)));
// Invalid Storage Class Name.
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).build();
testCases.add(new TestTuple<>(processName + ": Invalid option should trigger exception", new Pair<>(configInvalidOption, isExecutor), String.format("Volume `%s`: Invalid Persistent", volumeNameValid)));
}
use of org.apache.heron.common.basics.Pair in project heron by twitter.
the class KubernetesContextTest method createVolumeNFSError.
/**
* Create test cases for <code>NFS</code> errors.
* @param testCases Test case container.
* Input: [0] Config, [1] Boolean to indicate Manager/Executor.
* Output: Error message
* @param isExecutor Boolean to indicate Manager/Executor test case generation.
*/
private void createVolumeNFSError(List<TestTuple<Pair<Config, Boolean>, String>> testCases, boolean isExecutor) {
final String volumeNameValid = "volume-name-valid";
final String passingValue = "should-pass";
final String failureValue = "Should-Fail";
final String processName = isExecutor ? KubernetesConstants.EXECUTOR_NAME : KubernetesConstants.MANAGER_NAME;
final String keyPattern = String.format(KubernetesContext.KUBERNETES_VOLUME_NFS_PREFIX + "%%s.%%s", processName);
// Server is missing.
final Config configNoServer = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "readOnly"), "false").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": No `server` should trigger exception", new Pair<>(configNoServer, isExecutor), "`NFS` volumes require a"));
// Server is invalid.
final Config configInvalidServer = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "").put(String.format(keyPattern, volumeNameValid, "readOnly"), "false").put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), passingValue).put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": Invalid `server` should trigger exception", new Pair<>(configInvalidServer, isExecutor), "`NFS` volumes require a"));
// Path on NFS missing.
final Config configNoNFSPath = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "readOnly"), "false").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": No path on NFS should trigger exception", new Pair<>(configNoNFSPath, isExecutor), "NFS requires a path on"));
// Path on NFS is empty.
final Config configEmptyNFSPath = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "readOnly"), "false").put(String.format(keyPattern, volumeNameValid, "pathOnNFS"), "").put(String.format(keyPattern, volumeNameValid, "path"), passingValue).put(String.format(keyPattern, volumeNameValid, "subPath"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": No path on NFS should trigger exception", new Pair<>(configEmptyNFSPath, isExecutor), "NFS requires a path on"));
// Invalid option.
final Config configInvalidOption = Config.newBuilder().put(String.format(keyPattern, volumeNameValid, "server"), "nfs-server.default.local").put(String.format(keyPattern, volumeNameValid, "readOnly"), "false").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, "accessModes"), passingValue).build();
testCases.add(new TestTuple<>(processName + ": Invalid option should trigger exception", new Pair<>(configInvalidOption, isExecutor), "Invalid NFS option"));
}
Aggregations