This is an automated email from the ASF dual-hosted git repository. hulee pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/helix.git
commit ddc7ef2825f7e4cea5bac4d97e1c0369768c408a Author: Yi Wang <[email protected]> AuthorDate: Wed Apr 3 14:36:24 2019 -0700 More unit tests for InstanceValidationUtil RB=1617333 G=helix-reviewers A=jxue Signed-off-by: Hunter Lee <[email protected]> --- .../apache/helix/util/InstanceValidationUtil.java | 50 ++- .../helix/util/TestInstanceValidationUtil.java | 370 +++++++++++++++++++-- .../rest/server/json/instance/StoppableCheck.java | 3 + .../server/resources/helix/InstancesAccessor.java | 8 +- .../rest/server/service/InstanceServiceImpl.java | 12 +- .../helix/rest/server/TestInstancesAccessor.java | 57 ++-- .../helix/rest/server/TestPerInstanceAccessor.java | 20 +- .../server/json/instance/TestStoppableCheck.java | 12 +- 8 files changed, 422 insertions(+), 110 deletions(-) diff --git a/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java b/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java index a9692d8..244ecad 100644 --- a/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java +++ b/helix-core/src/main/java/org/apache/helix/util/InstanceValidationUtil.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; -import org.apache.helix.AccessOption; import org.apache.helix.ConfigAccessor; import org.apache.helix.HelixDataAccessor; import org.apache.helix.HelixDefinedState; @@ -38,7 +36,6 @@ import org.apache.helix.model.ExternalView; import org.apache.helix.model.IdealState; import org.apache.helix.model.InstanceConfig; import org.apache.helix.model.LiveInstance; -import org.apache.helix.model.RESTConfig; import org.apache.helix.model.StateModelDefinition; import org.apache.helix.task.TaskConstants; import org.slf4j.Logger; @@ -51,7 +48,6 @@ import com.google.common.collect.Sets; * Utility class for validating Helix properties * Warning: each method validates one single property of instance individually and independently. * One validation wouldn't depend on the results of other validations - * TODO: add unit tests */ public class InstanceValidationUtil { private static final Logger _logger = LoggerFactory.getLogger(InstanceValidationUtil.class); @@ -77,22 +73,19 @@ public class InstanceValidationUtil { */ public static boolean isEnabled(HelixDataAccessor dataAccessor, ConfigAccessor configAccessor, String clusterId, String instanceName) { - // TODO use static builder instance to reduce GC - PropertyKey propertyKey = new PropertyKey.Builder(clusterId).instanceConfig(instanceName); - InstanceConfig instanceConfig = dataAccessor.getProperty(propertyKey); + PropertyKey.Builder propertyKeyBuilder = dataAccessor.keyBuilder(); + InstanceConfig instanceConfig = dataAccessor.getProperty(propertyKeyBuilder.instanceConfig(instanceName)); ClusterConfig clusterConfig = configAccessor.getClusterConfig(clusterId); - // TODO deprecate instance level config checks once migrated the enable status to cluster config - // only - boolean enabledInInstanceConfig = instanceConfig != null && instanceConfig.getInstanceEnabled(); - - if (clusterConfig != null) { - Map<String, String> disabledInstances = clusterConfig.getDisabledInstances(); - boolean enabledInClusterConfig = - disabledInstances == null || !disabledInstances.keySet().contains(instanceName); - return enabledInClusterConfig && enabledInInstanceConfig; + // TODO deprecate instance level config checks once migrated the enable status to cluster config only + if (instanceConfig == null || clusterConfig == null) { + throw new HelixException("InstanceConfig or ClusterConfig is NULL"); } - return false; + boolean enabledInInstanceConfig = instanceConfig.getInstanceEnabled(); + Map<String, String> disabledInstances = clusterConfig.getDisabledInstances(); + boolean enabledInClusterConfig = + disabledInstances == null || !disabledInstances.keySet().contains(instanceName); + return enabledInClusterConfig && enabledInInstanceConfig; } /** @@ -104,10 +97,8 @@ public class InstanceValidationUtil { */ public static boolean isAlive(HelixDataAccessor dataAccessor, String clusterId, String instanceName) { - PropertyKey propertyKey = new PropertyKey.Builder(clusterId).liveInstance(instanceName); - - return dataAccessor.getBaseDataAccessor().exists(propertyKey.getPath(), - AccessOption.PERSISTENT); + LiveInstance liveInstance = dataAccessor.getProperty(dataAccessor.keyBuilder().liveInstance(instanceName)); + return liveInstance != null; } /** @@ -120,17 +111,15 @@ public class InstanceValidationUtil { */ public static boolean hasResourceAssigned(HelixDataAccessor dataAccessor, String clusterId, String instanceName) { - PropertyKey.Builder propertyKeyBuilder = new PropertyKey.Builder(clusterId); - PropertyKey liveInstanceKey = propertyKeyBuilder.liveInstance(instanceName); - LiveInstance liveInstance = dataAccessor.getProperty(liveInstanceKey); + PropertyKey.Builder propertyKeyBuilder = dataAccessor.keyBuilder(); + LiveInstance liveInstance = dataAccessor.getProperty(propertyKeyBuilder.liveInstance(instanceName)); if (liveInstance != null) { String sessionId = liveInstance.getSessionId(); - PropertyKey currentStatesKey = propertyKeyBuilder.currentStates(instanceName, sessionId); - List<String> resourceNames = dataAccessor.getChildNames(currentStatesKey); + List<String> resourceNames = dataAccessor.getChildNames(propertyKeyBuilder.currentStates(instanceName, sessionId)); for (String resourceName : resourceNames) { - PropertyKey key = propertyKeyBuilder.currentState(instanceName, sessionId, resourceName); - CurrentState currentState = dataAccessor.getProperty(key); + PropertyKey currentStateKey = propertyKeyBuilder.currentState(instanceName, sessionId, resourceName); + CurrentState currentState = dataAccessor.getProperty(currentStateKey); if (currentState != null && currentState.getPartitionStateMap().size() > 0) { return true; } @@ -150,7 +139,7 @@ public class InstanceValidationUtil { */ public static boolean hasDisabledPartitions(HelixDataAccessor dataAccessor, String clusterId, String instanceName) { - PropertyKey propertyKey = new PropertyKey.Builder(clusterId).instanceConfig(instanceName); + PropertyKey propertyKey = dataAccessor.keyBuilder().instanceConfig(instanceName); InstanceConfig instanceConfig = dataAccessor.getProperty(propertyKey); if (instanceConfig != null) { return !instanceConfig.getDisabledPartitionsMap().isEmpty(); @@ -168,7 +157,7 @@ public class InstanceValidationUtil { */ public static boolean hasValidConfig(HelixDataAccessor dataAccessor, String clusterId, String instanceName) { - PropertyKey propertyKey = new PropertyKey.Builder(clusterId).instanceConfig(instanceName); + PropertyKey propertyKey = dataAccessor.keyBuilder().instanceConfig(instanceName); InstanceConfig instanceConfig = dataAccessor.getProperty(propertyKey); return instanceConfig != null && instanceConfig.isValid(); } @@ -291,7 +280,6 @@ public class InstanceValidationUtil { /** * Check if sibling nodes of the instance meet min active replicas constraint * Two instances are sibling of each other if they host the same partition - * * WARNING: The check uses ExternalView to reduce network traffic but suffer from accuracy * due to external view propagation latency * diff --git a/helix-core/src/test/java/org/apache/helix/util/TestInstanceValidationUtil.java b/helix-core/src/test/java/org/apache/helix/util/TestInstanceValidationUtil.java index f26d2bb..5f72ee8 100644 --- a/helix-core/src/test/java/org/apache/helix/util/TestInstanceValidationUtil.java +++ b/helix-core/src/test/java/org/apache/helix/util/TestInstanceValidationUtil.java @@ -3,47 +3,353 @@ package org.apache.helix.util; import static org.mockito.Mockito.*; import java.util.Collections; +import java.util.List; +import org.apache.helix.ConfigAccessor; import org.apache.helix.HelixDataAccessor; import org.apache.helix.HelixException; import org.apache.helix.PropertyKey; import org.apache.helix.PropertyType; +import org.apache.helix.model.ClusterConfig; +import org.apache.helix.model.CurrentState; import org.apache.helix.model.ExternalView; +import org.apache.helix.model.IdealState; +import org.apache.helix.model.InstanceConfig; +import org.apache.helix.model.LiveInstance; import org.apache.helix.model.StateModelDefinition; import org.mockito.ArgumentMatcher; import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; - public class TestInstanceValidationUtil { private static final String TEST_CLUSTER = "testCluster"; private static final String TEST_INSTANCE = "instance0"; + @DataProvider + Object[][] isEnabledTestSuite() { + return new Object[][] { + { + true, true, true + }, { + true, false, false + }, { + false, true, false + }, { + false, false, false + } + }; + } + + @Test(dataProvider = "isEnabledTestSuite") + public void TestIsInstanceEnabled(boolean instanceConfigEnabled, boolean clusterConfigEnabled, + boolean expected) { + Mock mock = new Mock(); + InstanceConfig instanceConfig = new InstanceConfig(TEST_INSTANCE); + instanceConfig.setInstanceEnabled(instanceConfigEnabled); + doReturn(instanceConfig).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + ClusterConfig clusterConfig = new ClusterConfig(TEST_CLUSTER); + if (!clusterConfigEnabled) { + clusterConfig.setDisabledInstances(ImmutableMap.of(TEST_INSTANCE, "12345")); + } + when(mock.configAccessor.getClusterConfig(TEST_CLUSTER)).thenReturn(clusterConfig); + + boolean isEnabled = InstanceValidationUtil.isEnabled(mock.dataAccessor, mock.configAccessor, + TEST_CLUSTER, TEST_INSTANCE); + + Assert.assertEquals(isEnabled, expected); + } + + @Test(expectedExceptions = HelixException.class) + public void TestIsInstanceEnabled_whenInstanceConfigNull() { + Mock mock = new Mock(); + doReturn(null).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + when(mock.configAccessor.getClusterConfig(TEST_CLUSTER)) + .thenReturn(new ClusterConfig(TEST_CLUSTER)); + + InstanceValidationUtil.isEnabled(mock.dataAccessor, mock.configAccessor, TEST_CLUSTER, + TEST_INSTANCE); + } + + @Test(expectedExceptions = HelixException.class) + public void TestIsInstanceEnabled_whenClusterConfigNull() { + Mock mock = new Mock(); + doReturn(new InstanceConfig(TEST_INSTANCE)).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + when(mock.configAccessor.getClusterConfig(TEST_CLUSTER)).thenReturn(null); + + InstanceValidationUtil.isEnabled(mock.dataAccessor, mock.configAccessor, TEST_CLUSTER, + TEST_INSTANCE); + } + + @Test + public void TestIsInstanceAlive() { + Mock mock = new Mock(); + doReturn(new LiveInstance(TEST_INSTANCE)).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + + Assert + .assertTrue(InstanceValidationUtil.isAlive(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasResourceAssigned_success() { + String sessionId = "sessionId"; + String resource = "db"; + Mock mock = new Mock(); + LiveInstance liveInstance = new LiveInstance(TEST_INSTANCE); + liveInstance.setSessionId(sessionId); + doReturn(liveInstance).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + CurrentState currentState = mock(CurrentState.class); + when(currentState.getPartitionStateMap()).thenReturn(ImmutableMap.of("db0", "master")); + doReturn(currentState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + + Assert.assertTrue( + InstanceValidationUtil.hasResourceAssigned(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasResourceAssigned_fail() { + String sessionId = "sessionId"; + String resource = "db"; + Mock mock = new Mock(); + LiveInstance liveInstance = new LiveInstance(TEST_INSTANCE); + liveInstance.setSessionId(sessionId); + doReturn(liveInstance).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + CurrentState currentState = mock(CurrentState.class); + when(currentState.getPartitionStateMap()).thenReturn(Collections.<String, String> emptyMap()); + doReturn(currentState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + + Assert.assertFalse( + InstanceValidationUtil.hasResourceAssigned(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasResourceAssigned_whenNotAlive() { + Mock mock = new Mock(); + doReturn(null).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + + Assert.assertFalse( + InstanceValidationUtil.hasResourceAssigned(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasDisabledPartitions_false() { + Mock mock = new Mock(); + InstanceConfig instanceConfig = mock(InstanceConfig.class); + when(instanceConfig.getDisabledPartitionsMap()) + .thenReturn(Collections.<String, List<String>> emptyMap()); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))).thenReturn(instanceConfig); + + Assert.assertFalse(InstanceValidationUtil.hasDisabledPartitions(mock.dataAccessor, TEST_CLUSTER, + TEST_INSTANCE)); + } + + @Test + public void TestHasDisabledPartitions_true() { + Mock mock = new Mock(); + InstanceConfig instanceConfig = mock(InstanceConfig.class); + when(instanceConfig.getDisabledPartitionsMap()) + .thenReturn(ImmutableMap.of("db0", Collections.<String> emptyList())); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))).thenReturn(instanceConfig); + + Assert.assertTrue(InstanceValidationUtil.hasDisabledPartitions(mock.dataAccessor, TEST_CLUSTER, + TEST_INSTANCE)); + } + + @Test(expectedExceptions = HelixException.class) + public void TestHasDisabledPartitions_exception() { + Mock mock = new Mock(); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))).thenReturn(null); + + Assert.assertTrue(InstanceValidationUtil.hasDisabledPartitions(mock.dataAccessor, TEST_CLUSTER, + TEST_INSTANCE)); + } + + @Test + public void TestHasValidConfig_true() { + Mock mock = new Mock(); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))) + .thenReturn(new InstanceConfig(TEST_INSTANCE)); + + Assert.assertTrue( + InstanceValidationUtil.hasValidConfig(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasValidConfig_false() { + Mock mock = new Mock(); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))).thenReturn(null); + + Assert.assertFalse( + InstanceValidationUtil.hasValidConfig(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasErrorPartitions_true() { + String sessionId = "sessionId"; + String resource = "db"; + Mock mock = new Mock(); + LiveInstance liveInstance = new LiveInstance(TEST_INSTANCE); + liveInstance.setSessionId(sessionId); + doReturn(liveInstance).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + CurrentState currentState = mock(CurrentState.class); + when(currentState.getPartitionStateMap()).thenReturn(ImmutableMap.of("db0", "ERROR")); + doReturn(currentState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + + Assert.assertTrue( + InstanceValidationUtil.hasErrorPartitions(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test + public void TestHasErrorPartitions_false() { + String sessionId = "sessionId"; + String resource = "db"; + Mock mock = new Mock(); + LiveInstance liveInstance = new LiveInstance(TEST_INSTANCE); + liveInstance.setSessionId(sessionId); + doReturn(liveInstance).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.LIVEINSTANCES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + CurrentState currentState = mock(CurrentState.class); + when(currentState.getPartitionStateMap()).thenReturn(ImmutableMap.of("db0", "Master")); + doReturn(currentState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CURRENTSTATES))); + + Assert.assertFalse( + InstanceValidationUtil.hasErrorPartitions(mock.dataAccessor, TEST_CLUSTER, TEST_INSTANCE)); + } + + @Test(expectedExceptions = HelixException.class) + public void TestIsInstanceStable_exception_whenPersistAssignmentOff() { + Mock mock = new Mock(); + ClusterConfig clusterConfig = new ClusterConfig(TEST_CLUSTER); + clusterConfig.setPersistIntermediateAssignment(false); + when(mock.dataAccessor.getProperty(any(PropertyKey.class))).thenReturn(clusterConfig); + + InstanceValidationUtil.isInstanceStable(mock.dataAccessor, TEST_INSTANCE); + } + + @Test(expectedExceptions = HelixException.class) + public void TestIsInstanceStable_exception_whenExternalViewNull() { + String resource = "db"; + Mock mock = new Mock(); + ClusterConfig clusterConfig = new ClusterConfig(TEST_CLUSTER); + clusterConfig.setPersistIntermediateAssignment(true); + doReturn(clusterConfig).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + IdealState idealState = mock(IdealState.class); + when(idealState.isEnabled()).thenReturn(true); + when(idealState.getPartitionSet()).thenReturn(ImmutableSet.of("db0")); + when(idealState.getInstanceStateMap("db0")).thenReturn(ImmutableMap.of(TEST_INSTANCE, "Master")); + when(idealState.isValid()).thenReturn(true); + when(idealState.getStateModelDefRef()).thenReturn("MasterSlave"); + doReturn(idealState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + doReturn(null).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + InstanceValidationUtil.isInstanceStable(mock.dataAccessor, TEST_INSTANCE); + } + + @Test + public void TestIsInstanceStable_true() { + String resource = "db"; + Mock mock = new Mock(); + ClusterConfig clusterConfig = new ClusterConfig(TEST_CLUSTER); + clusterConfig.setPersistIntermediateAssignment(true); + doReturn(clusterConfig).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + IdealState idealState = mock(IdealState.class); + when(idealState.isEnabled()).thenReturn(Boolean.TRUE); + when(idealState.getPartitionSet()).thenReturn(ImmutableSet.of("db0")); + when(idealState.getInstanceStateMap("db0")) + .thenReturn(ImmutableMap.of(TEST_INSTANCE, "Master")); + idealState.setInstanceStateMap("db0", ImmutableMap.of(TEST_INSTANCE, "Master")); + doReturn(idealState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + ExternalView externalView = new ExternalView(resource); + externalView.setStateMap("db0", ImmutableMap.of(TEST_INSTANCE, "Master")); + doReturn(externalView).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + + boolean result = InstanceValidationUtil.isInstanceStable(mock.dataAccessor, TEST_INSTANCE); + Assert.assertTrue(result); + } + + @Test(description = "IdealState: slave state, ExternalView:Master state") + public void TestIsInstanceStable_false() { + String resource = "db"; + Mock mock = new Mock(); + ClusterConfig clusterConfig = new ClusterConfig(TEST_CLUSTER); + clusterConfig.setPersistIntermediateAssignment(true); + doReturn(clusterConfig).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.CONFIGS))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + IdealState idealState = mock(IdealState.class); + when(idealState.isEnabled()).thenReturn(true); + when(idealState.getPartitionSet()).thenReturn(ImmutableSet.of("db0")); + when(idealState.getInstanceStateMap("db0")).thenReturn(ImmutableMap.of(TEST_INSTANCE, "slave")); + when(idealState.isValid()).thenReturn(true); + when(idealState.getStateModelDefRef()).thenReturn("MasterSlave"); + doReturn(idealState).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + ExternalView externalView = new ExternalView(resource); + externalView.setStateMap("db0", ImmutableMap.of(TEST_INSTANCE, "Master")); + doReturn(externalView).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + + boolean result = InstanceValidationUtil.isInstanceStable(mock.dataAccessor, TEST_INSTANCE); + Assert.assertFalse(result); + } + @Test public void TestSiblingNodesActiveReplicaCheck_success() { String resource = "resource"; Mock mock = new Mock(); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); ExternalView externalView = mock(ExternalView.class); when(externalView.getMinActiveReplicas()).thenReturn(2); when(externalView.getStateModelDefRef()).thenReturn("MasterSlave"); when(externalView.getPartitionSet()).thenReturn(ImmutableSet.of("db0")); - when(externalView.getStateMap("db0")).thenReturn(ImmutableMap.of( - TEST_INSTANCE, "Master", - "instance1", "Slave", - "instance2", "Slave", - "instance3", "Slave")); - doReturn(externalView).when(mock.dataAccessor).getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + when(externalView.getStateMap("db0")).thenReturn(ImmutableMap.of(TEST_INSTANCE, "Master", + "instance1", "Slave", "instance2", "Slave", "instance3", "Slave")); + doReturn(externalView).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); StateModelDefinition stateModelDefinition = mock(StateModelDefinition.class); when(stateModelDefinition.getInitialState()).thenReturn("OFFLINE"); - doReturn(stateModelDefinition).when(mock.dataAccessor).getProperty(argThat(new PropertyKeyArgument(PropertyType.STATEMODELDEFS))); + doReturn(stateModelDefinition).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.STATEMODELDEFS))); - boolean result = InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); + boolean result = + InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); Assert.assertTrue(result); } @@ -52,54 +358,64 @@ public class TestInstanceValidationUtil { public void TestSiblingNodesActiveReplicaCheck_fail() { String resource = "resource"; Mock mock = new Mock(); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); ExternalView externalView = mock(ExternalView.class); when(externalView.getMinActiveReplicas()).thenReturn(3); when(externalView.getStateModelDefRef()).thenReturn("MasterSlave"); when(externalView.getPartitionSet()).thenReturn(ImmutableSet.of("db0")); - when(externalView.getStateMap("db0")).thenReturn(ImmutableMap.of( - TEST_INSTANCE, "Master", - "instance1", "Slave", - "instance2", "Slave")); - doReturn(externalView).when(mock.dataAccessor).getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + when(externalView.getStateMap("db0")).thenReturn( + ImmutableMap.of(TEST_INSTANCE, "Master", "instance1", "Slave", "instance2", "Slave")); + doReturn(externalView).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); StateModelDefinition stateModelDefinition = mock(StateModelDefinition.class); when(stateModelDefinition.getInitialState()).thenReturn("OFFLINE"); - doReturn(stateModelDefinition).when(mock.dataAccessor).getProperty(argThat(new PropertyKeyArgument(PropertyType.STATEMODELDEFS))); + doReturn(stateModelDefinition).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.STATEMODELDEFS))); - boolean result = InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); + boolean result = + InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); Assert.assertFalse(result); } - @Test (expectedExceptions = HelixException.class) + @Test(expectedExceptions = HelixException.class) public void TestSiblingNodesActiveReplicaCheck_exception_whenIdealStatesMisMatch() { String resource = "resource"; Mock mock = new Mock(); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); - doReturn(Collections.emptyList()).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + doReturn(Collections.emptyList()).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); ExternalView externalView = mock(ExternalView.class); when(externalView.getMinActiveReplicas()).thenReturn(-1); - doReturn(externalView).when(mock.dataAccessor).getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + doReturn(externalView).when(mock.dataAccessor) + .getProperty(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); } - @Test (expectedExceptions = HelixException.class) + @Test(expectedExceptions = HelixException.class) public void TestSiblingNodesActiveReplicaCheck_exception_whenMissingMinActiveReplicas() { String resource = "resource"; Mock mock = new Mock(); - doReturn(ImmutableList.of(resource)).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); - doReturn(Collections.emptyList()).when(mock.dataAccessor).getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); + doReturn(ImmutableList.of(resource)).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.IDEALSTATES))); + doReturn(Collections.emptyList()).when(mock.dataAccessor) + .getChildNames(argThat(new PropertyKeyArgument(PropertyType.EXTERNALVIEW))); InstanceValidationUtil.siblingNodesActiveReplicaCheck(mock.dataAccessor, TEST_INSTANCE); } private class Mock { HelixDataAccessor dataAccessor; + ConfigAccessor configAccessor; Mock() { this.dataAccessor = mock(HelixDataAccessor.class); + this.configAccessor = mock(ConfigAccessor.class); when(dataAccessor.keyBuilder()).thenReturn(new PropertyKey.Builder(TEST_CLUSTER)); } } diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/StoppableCheck.java b/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/StoppableCheck.java index 8567cdc..b78a9c6 100644 --- a/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/StoppableCheck.java +++ b/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/StoppableCheck.java @@ -20,6 +20,7 @@ package org.apache.helix.rest.server.json.instance; */ import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +39,8 @@ public class StoppableCheck { public StoppableCheck(boolean isStoppable, List<String> failedChecks) { this.isStoppable = isStoppable; + // sort the failed checks in order so that tests can always pass + Collections.sort(failedChecks); this.failedChecks = failedChecks; } diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java index a697e9b..3ff4e13 100644 --- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java +++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/InstancesAccessor.java @@ -8,12 +8,14 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; + import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; + import org.apache.commons.lang3.NotImplementedException; import org.apache.helix.HelixAdmin; import org.apache.helix.HelixDataAccessor; @@ -174,11 +176,11 @@ public class InstancesAccessor extends AbstractHelixResource { case zone_based: List<String> zoneBasedInstance = getZoneBasedInstances(clusterId, instances, orderOfZone); for (String instance : zoneBasedInstance) { - StoppableCheck stoppableCheck = + StoppableCheck stoppableCheckResult = instanceService.checkSingleInstanceStoppable(clusterId, instance, customizedInput); - if (!stoppableCheck.isStoppable()) { + if (!stoppableCheckResult.isStoppable()) { ArrayNode failedReasonsNode = failedStoppableInstances.putArray(instance); - for (String failedReason : stoppableCheck.getFailedChecks()) { + for (String failedReason : stoppableCheckResult.getFailedChecks()) { failedReasonsNode.add(JsonNodeFactory.instance.textNode(failedReason)); } } else { diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/service/InstanceServiceImpl.java b/helix-rest/src/main/java/org/apache/helix/rest/server/service/InstanceServiceImpl.java index 1ad4069..0c1d9ba 100644 --- a/helix-rest/src/main/java/org/apache/helix/rest/server/service/InstanceServiceImpl.java +++ b/helix-rest/src/main/java/org/apache/helix/rest/server/service/InstanceServiceImpl.java @@ -21,11 +21,11 @@ package org.apache.helix.rest.server.service; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; - import java.util.stream.Collectors; + import org.apache.helix.ConfigAccessor; import org.apache.helix.HelixDataAccessor; import org.apache.helix.HelixException; @@ -54,7 +54,7 @@ public class InstanceServiceImpl implements InstanceService { @Override public Map<String, Boolean> getInstanceHealthStatus(String clusterId, String instanceName, List<HealthCheck> healthChecks) { - Map<String, Boolean> healthStatus = new TreeMap<>(); + Map<String, Boolean> healthStatus = new HashMap<>(); for (HealthCheck healthCheck : healthChecks) { switch (healthCheck) { case INVALID_CONFIG: @@ -151,10 +151,8 @@ public class InstanceServiceImpl implements InstanceService { CustomRestClient customClient = CustomRestClientFactory.get(jsonContent); // TODO add the json content parse logic Map<String, Boolean> customStoppableCheck = - customClient.getInstanceStoppableCheck(Collections.<String, String> emptyMap()); - StoppableCheck stoppableCheck = - StoppableCheck.mergeStoppableChecks(helixStoppableCheck, customStoppableCheck); - return stoppableCheck; + customClient.getInstanceStoppableCheck(Collections.emptyMap()); + return StoppableCheck.mergeStoppableChecks(helixStoppableCheck, customStoppableCheck); } /** diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java index 80b4292..c3c8691 100644 --- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java +++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestInstancesAccessor.java @@ -1,51 +1,56 @@ package org.apache.helix.rest.server; -import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; + import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; + import org.apache.helix.TestHelper; import org.apache.helix.model.ClusterConfig; import org.apache.helix.model.InstanceConfig; import org.apache.helix.rest.server.resources.helix.InstancesAccessor; import org.apache.helix.rest.server.util.JerseyUriRequestBuilder; import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier; -import org.apache.helix.tools.ClusterVerifiers.HelixClusterVerifier; import org.codehaus.jackson.JsonNode; import org.testng.Assert; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; + public class TestInstancesAccessor extends AbstractTestClass { private final static String CLUSTER_NAME = "TestCluster_0"; @Test - public void testEndToEndChecks() { + public void testInstancesStoppable_zoneBased() { System.out.println("Start test :" + TestHelper.getTestMethodName()); // Select instances with zone based - String content = String - .format("{\"%s\":\"%s\",\"%s\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]}", + String content = + String.format("{\"%s\":\"%s\",\"%s\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]}", InstancesAccessor.InstancesProperties.selection_base.name(), InstancesAccessor.InstanceHealthSelectionBase.zone_based.name(), InstancesAccessor.InstancesProperties.instances.name(), "instance0", "instance1", "instance2", "instance3", "instance4", "instance5"); - Response response = - new JerseyUriRequestBuilder("clusters/{}/instances?command=stoppable").format(STOPPABLE_CLUSTER) - .post(this, Entity.entity(content, MediaType.APPLICATION_JSON_TYPE)); + Response response = new JerseyUriRequestBuilder("clusters/{}/instances?command=stoppable") + .format(STOPPABLE_CLUSTER) + .post(this, Entity.entity(content, MediaType.APPLICATION_JSON_TYPE)); String checkResult = response.readEntity(String.class); - Assert.assertEquals(checkResult, - "{\n \"instance_stoppable_parallel\" : [ ],\n" - + " \"instance_not_stoppable_with_reasons\" : {\n" - + " \"instance0\" : [ \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" - + " \"instance1\" : [ \"Helix:INSTANCE_NOT_STABLE\", \"Helix:INSTANCE_NOT_ENABLED\", \"Helix:EMPTY_RESOURCE_ASSIGNMENT\" ],\n" - + " \"instance2\" : [ \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" - + " \"instance3\" : [ \"Helix:HAS_DISABLED_PARTITION\", \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" - + " \"instance4\" : [ \"Helix:INSTANCE_NOT_STABLE\", \"Helix:INSTANCE_NOT_ALIVE\", \"Helix:EMPTY_RESOURCE_ASSIGNMENT\" ]\n }\n}\n"); + Assert.assertEquals(checkResult, "{\n" + " \"instance_stoppable_parallel\" : [ ],\n" + + " \"instance_not_stoppable_with_reasons\" : {\n" + + " \"instance0\" : [ \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" + + " \"instance1\" : [ \"Helix:EMPTY_RESOURCE_ASSIGNMENT\", \"Helix:INSTANCE_NOT_ENABLED\", \"Helix:INSTANCE_NOT_STABLE\" ],\n" + + " \"instance2\" : [ \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" + + " \"instance3\" : [ \"Helix:HAS_DISABLED_PARTITION\", \"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\" ],\n" + + " \"instance4\" : [ \"Helix:EMPTY_RESOURCE_ASSIGNMENT\", \"Helix:INSTANCE_NOT_ALIVE\", \"Helix:INSTANCE_NOT_STABLE\" ]\n" + + " }\n" + "}\n"); + } + @Test(dependsOnMethods = "testInstancesStoppable_zoneBased") + public void testInstancesStoppable_disableOneInstance() { // Disable one selected instance0, it should failed to check String instance = "instance0"; InstanceConfig instanceConfig = _configAccessor.getInstanceConfig(STOPPABLE_CLUSTER, instance); @@ -53,24 +58,22 @@ public class TestInstancesAccessor extends AbstractTestClass { instanceConfig.setInstanceEnabledForPartition("FakeResource", "FakePartition", false); _configAccessor.setInstanceConfig(STOPPABLE_CLUSTER, instance, instanceConfig); - Entity entity = - Entity.entity("", MediaType.APPLICATION_JSON_TYPE); - response = new JerseyUriRequestBuilder("clusters/{}/instances/{}/stoppable") + Entity entity = Entity.entity("", MediaType.APPLICATION_JSON_TYPE); + Response response = new JerseyUriRequestBuilder("clusters/{}/instances/{}/stoppable") .format(STOPPABLE_CLUSTER, instance).post(this, entity); - checkResult = response.readEntity(String.class); + String checkResult = response.readEntity(String.class); Assert.assertEquals(checkResult, - "{\"stoppable\":false,\"failedChecks\":[\"Helix:INSTANCE_NOT_STABLE\",\"Helix:HAS_DISABLED_PARTITION\",\"Helix:INSTANCE_NOT_ENABLED\",\"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\"]}"); + "{\"stoppable\":false,\"failedChecks\":[\"Helix:HAS_DISABLED_PARTITION\",\"Helix:INSTANCE_NOT_ENABLED\",\"Helix:INSTANCE_NOT_STABLE\",\"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\"]}"); // Reenable instance0, it should passed the check instanceConfig.setInstanceEnabled(true); instanceConfig.setInstanceEnabledForPartition("FakeResource", "FakePartition", true); _configAccessor.setInstanceConfig(STOPPABLE_CLUSTER, instance, instanceConfig); - HelixClusterVerifier - verifier = new BestPossibleExternalViewVerifier.Builder(STOPPABLE_CLUSTER).setZkAddr(ZK_ADDR).build(); - Assert.assertTrue(((BestPossibleExternalViewVerifier) verifier).verifyByPolling()); + BestPossibleExternalViewVerifier verifier = + new BestPossibleExternalViewVerifier.Builder(STOPPABLE_CLUSTER).setZkAddr(ZK_ADDR).build(); + Assert.assertTrue(verifier.verifyByPolling()); - entity = - Entity.entity("", MediaType.APPLICATION_JSON_TYPE); + entity = Entity.entity("", MediaType.APPLICATION_JSON_TYPE); response = new JerseyUriRequestBuilder("clusters/{}/instances/{}/stoppable") .format(STOPPABLE_CLUSTER, instance).post(this, entity); checkResult = response.readEntity(String.class); @@ -78,7 +81,7 @@ public class TestInstancesAccessor extends AbstractTestClass { "{\"stoppable\":false,\"failedChecks\":[\"Helix:MIN_ACTIVE_REPLICA_CHECK_FAILED\"]}"); } - @Test(dependsOnMethods = "testEndToEndChecks") + @Test(dependsOnMethods = "testInstancesStoppable_disableOneInstance") public void testGetAllInstances() throws IOException { System.out.println("Start test :" + TestHelper.getTestMethodName()); String body = new JerseyUriRequestBuilder("clusters/{}/instances").isBodyReturnExpected(true) diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java index cbc80ee..b3acea8 100644 --- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java +++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java @@ -22,7 +22,6 @@ package org.apache.helix.rest.server; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -43,7 +42,6 @@ import org.apache.helix.rest.server.resources.AbstractResource; import org.apache.helix.rest.server.resources.helix.InstancesAccessor; import org.apache.helix.rest.server.resources.helix.PerInstanceAccessor; import org.apache.helix.rest.server.util.JerseyUriRequestBuilder; -import org.apache.helix.util.InstanceValidationUtil; import org.codehaus.jackson.JsonNode; import org.testng.Assert; import org.testng.annotations.Test; @@ -65,13 +63,13 @@ public class TestPerInstanceAccessor extends AbstractTestClass { .format(STOPPABLE_CLUSTER, "instance1").post(this, entity); String stoppableCheckResult = response.readEntity(String.class); Assert.assertEquals(stoppableCheckResult, - "{\"stoppable\":false,\"failedChecks\":[\"Helix:INSTANCE_NOT_STABLE\"," - + "\"Helix:INSTANCE_NOT_ENABLED\",\"Helix:EMPTY_RESOURCE_ASSIGNMENT\"]}"); + "{\"stoppable\":false,\"failedChecks\":[\"Helix:EMPTY_RESOURCE_ASSIGNMENT\",\"Helix:INSTANCE_NOT_ENABLED\",\"Helix:INSTANCE_NOT_STABLE\"]}"); } - @Test (dependsOnMethods = "testIsInstanceStoppable") + @Test(dependsOnMethods = "testIsInstanceStoppable") public void testGetAllMessages() throws IOException { System.out.println("Start test :" + TestHelper.getTestMethodName()); + String testInstance = CLUSTER_NAME + "localhost_12926"; //Non-live instance String messageId = "msg1"; Message message = new Message(Message.MessageType.STATE_TRANSITION, messageId); @@ -83,11 +81,10 @@ public class TestPerInstanceAccessor extends AbstractTestClass { message.setTgtName("localhost_3"); message.setTgtSessionId("session_3"); HelixDataAccessor helixDataAccessor = new ZKHelixDataAccessor(CLUSTER_NAME, _baseAccessor); - helixDataAccessor.setProperty(helixDataAccessor.keyBuilder().message(INSTANCE_NAME, messageId), - message); + helixDataAccessor.setProperty(helixDataAccessor.keyBuilder().message(testInstance, messageId), message); String body = new JerseyUriRequestBuilder("clusters/{}/instances/{}/messages") - .isBodyReturnExpected(true).format(CLUSTER_NAME, INSTANCE_NAME).get(this); + .isBodyReturnExpected(true).format(CLUSTER_NAME, testInstance).get(this); JsonNode node = OBJECT_MAPPER.readTree(body); int newMessageCount = node.get(PerInstanceAccessor.PerInstanceProperties.total_message_count.name()).getIntValue(); @@ -99,6 +96,7 @@ public class TestPerInstanceAccessor extends AbstractTestClass { public void testGetMessagesByStateModelDef() throws IOException { System.out.println("Start test :" + TestHelper.getTestMethodName()); + String testInstance = CLUSTER_NAME + "localhost_12926"; //Non-live instance String messageId = "msg1"; Message message = new Message(Message.MessageType.STATE_TRANSITION, messageId); message.setStateModelDef("MasterSlave"); @@ -109,12 +107,12 @@ public class TestPerInstanceAccessor extends AbstractTestClass { message.setTgtName("localhost_3"); message.setTgtSessionId("session_3"); HelixDataAccessor helixDataAccessor = new ZKHelixDataAccessor(CLUSTER_NAME, _baseAccessor); - helixDataAccessor.setProperty(helixDataAccessor.keyBuilder().message(INSTANCE_NAME, messageId), + helixDataAccessor.setProperty(helixDataAccessor.keyBuilder().message(testInstance, messageId), message); String body = new JerseyUriRequestBuilder("clusters/{}/instances/{}/messages?stateModelDef=MasterSlave") - .isBodyReturnExpected(true).format(CLUSTER_NAME, INSTANCE_NAME).get(this); + .isBodyReturnExpected(true).format(CLUSTER_NAME, testInstance).get(this); JsonNode node = OBJECT_MAPPER.readTree(body); int newMessageCount = node.get(PerInstanceAccessor.PerInstanceProperties.total_message_count.name()).getIntValue(); @@ -123,7 +121,7 @@ public class TestPerInstanceAccessor extends AbstractTestClass { body = new JerseyUriRequestBuilder("clusters/{}/instances/{}/messages?stateModelDef=LeaderStandBy") - .isBodyReturnExpected(true).format(CLUSTER_NAME, INSTANCE_NAME).get(this); + .isBodyReturnExpected(true).format(CLUSTER_NAME, testInstance).get(this); node = OBJECT_MAPPER.readTree(body); newMessageCount = node.get(PerInstanceAccessor.PerInstanceProperties.total_message_count.name()).getIntValue(); diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/json/instance/TestStoppableCheck.java b/helix-rest/src/test/java/org/apache/helix/rest/server/json/instance/TestStoppableCheck.java index 25702cf..bcfc0e3 100644 --- a/helix-rest/src/test/java/org/apache/helix/rest/server/json/instance/TestStoppableCheck.java +++ b/helix-rest/src/test/java/org/apache/helix/rest/server/json/instance/TestStoppableCheck.java @@ -19,6 +19,7 @@ package org.apache.helix.rest.server.json.instance; * under the License. */ +import java.util.ArrayList; import java.util.Map; import org.testng.Assert; @@ -26,15 +27,17 @@ import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; - public class TestStoppableCheck { @Test public void whenSerializingStoppableCheck() throws JsonProcessingException { - StoppableCheck stoppableCheck = new StoppableCheck(false, ImmutableList.of("failedCheck")); + StoppableCheck stoppableCheck = new StoppableCheck(false, new ArrayList<String>() { + { + add("failedCheck"); + } + }); ObjectMapper mapper = new ObjectMapper(); String result = mapper.writeValueAsString(stoppableCheck); @@ -51,6 +54,7 @@ public class TestStoppableCheck { ObjectMapper mapper = new ObjectMapper(); String result = mapper.writeValueAsString(stoppableCheck); - Assert.assertEquals(result, "{\"stoppable\":false,\"failedChecks\":[\"Helix:check1\",\"Helix:check0\"]}"); + Assert.assertEquals(result, + "{\"stoppable\":false,\"failedChecks\":[\"Helix:check0\",\"Helix:check1\"]}"); } }
