You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by ki...@apache.org on 2012/10/25 01:14:59 UTC
[40/42] Refactoring the package names and removing jsql parser
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java b/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
new file mode 100644
index 0000000..99bf8ae
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
@@ -0,0 +1,266 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.model;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.helix.TestHelper;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.PropertyKey.Builder;
+import org.apache.helix.manager.zk.ZKHelixDataAccessor;
+import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.model.ClusterConstraints;
+import org.apache.helix.model.Message;
+import org.apache.helix.model.ClusterConstraints.ConstraintAttribute;
+import org.apache.helix.model.ClusterConstraints.ConstraintItem;
+import org.apache.helix.model.ClusterConstraints.ConstraintType;
+import org.apache.helix.model.Message.MessageType;
+import org.apache.log4j.Logger;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class TestConstraint extends ZkUnitTestBase
+{
+ private static Logger LOG = Logger.getLogger(TestConstraint.class);
+
+ @Test
+ public void testMsgConstraint()
+ {
+ String className = getShortClassName();
+ System.out.println("START testMsgConstraint() at "
+ + new Date(System.currentTimeMillis()));
+
+ String clusterName = "CLUSTER_" + className + "_msg";
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ ZNRecord record = new ZNRecord("testMsgConstraint");
+
+ // constraint0:
+ // "MESSAGE_TYPE=STATE_TRANSITION,CONSTRAINT_VALUE=ANY"
+ record.setMapField("constraint0", new TreeMap<String, String>());
+ record.getMapField("constraint0").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint0").put("CONSTRAINT_VALUE", "ANY");
+ ConstraintItem constraint0 = new ConstraintItem(record.getMapField("constraint0"));
+
+ // constraint1:
+ // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,CONSTRAINT_VALUE=ANY"
+ record.setMapField("constraint1", new TreeMap<String, String>());
+ record.getMapField("constraint1").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint1").put("TRANSITION", "OFFLINE-SLAVE");
+ record.getMapField("constraint1").put("CONSTRAINT_VALUE", "50");
+ ConstraintItem constraint1 = new ConstraintItem(record.getMapField("constraint1"));
+
+ // constraint2:
+ // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=.*,RESOURCE=TestDB,CONSTRAINT_VALUE=2";
+ record.setMapField("constraint2", new TreeMap<String, String>());
+ record.getMapField("constraint2").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint2").put("TRANSITION", "OFFLINE-SLAVE");
+ record.getMapField("constraint2").put("INSTANCE", ".*");
+ record.getMapField("constraint2").put("RESOURCE", "TestDB");
+ record.getMapField("constraint2").put("CONSTRAINT_VALUE", "2");
+ ConstraintItem constraint2 = new ConstraintItem(record.getMapField("constraint2"));
+
+ // constraint3:
+ // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=localhost_12918,RESOURCE=.*,CONSTRAINT_VALUE=1";
+ record.setMapField("constraint3", new TreeMap<String, String>());
+ record.getMapField("constraint3").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint3").put("TRANSITION", "OFFLINE-SLAVE");
+ record.getMapField("constraint3").put("INSTANCE", "localhost_12919");
+ record.getMapField("constraint3").put("RESOURCE", ".*");
+ record.getMapField("constraint3").put("CONSTRAINT_VALUE", "1");
+ ConstraintItem constraint3 = new ConstraintItem(record.getMapField("constraint3"));
+
+ // constraint4:
+ // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=.*,RESOURCE=.*,CONSTRAINT_VALUE=10"
+ record.setMapField("constraint4", new TreeMap<String, String>());
+ record.getMapField("constraint4").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint4").put("TRANSITION", "OFFLINE-SLAVE");
+ record.getMapField("constraint4").put("INSTANCE", ".*");
+ record.getMapField("constraint4").put("RESOURCE", ".*");
+ record.getMapField("constraint4").put("CONSTRAINT_VALUE", "10");
+ ConstraintItem constraint4 = new ConstraintItem(record.getMapField("constraint4"));
+
+ // constraint5:
+ // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=localhost_12918,RESOURCE=TestDB,CONSTRAINT_VALUE=5"
+ record.setMapField("constraint5", new TreeMap<String, String>());
+ record.getMapField("constraint5").put("MESSAGE_TYPE", "STATE_TRANSITION");
+ record.getMapField("constraint5").put("TRANSITION", "OFFLINE-SLAVE");
+ record.getMapField("constraint5").put("INSTANCE", "localhost_12918");
+ record.getMapField("constraint5").put("RESOURCE", "TestDB");
+ record.getMapField("constraint5").put("CONSTRAINT_VALUE", "5");
+ ConstraintItem constraint5 = new ConstraintItem(record.getMapField("constraint5"));
+
+ ZKHelixDataAccessor accessor =
+ new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+
+ accessor.setProperty(keyBuilder.constraint(ConstraintType.MESSAGE_CONSTRAINT.toString()),
+ new ClusterConstraints(record));
+
+ record =
+ accessor.getProperty(keyBuilder.constraint(ConstraintType.MESSAGE_CONSTRAINT.toString()))
+ .getRecord();
+ ClusterConstraints constraint = new ClusterConstraints(record);
+ // System.out.println("constraint: " + constraint);
+
+ // message1
+ Message msg1 =
+ createMessage(MessageType.STATE_TRANSITION,
+ "msgId-001",
+ "OFFLINE",
+ "SLAVE",
+ "TestDB",
+ "localhost_12918");
+
+ Map<ConstraintAttribute, String> msgAttr =
+ ClusterConstraints.toConstraintAttributes(msg1);
+ Set<ConstraintItem> matches = constraint.match(msgAttr);
+ System.out.println(msg1 + " matches(" + matches.size() + "): " + matches);
+ Assert.assertEquals(matches.size(), 5);
+ Assert.assertTrue(contains(matches, constraint0));
+ Assert.assertTrue(contains(matches, constraint1));
+ Assert.assertTrue(contains(matches, constraint2));
+ Assert.assertTrue(contains(matches, constraint4));
+ Assert.assertTrue(contains(matches, constraint5));
+
+ // message2
+ Message msg2 =
+ createMessage(MessageType.STATE_TRANSITION,
+ "msgId-002",
+ "OFFLINE",
+ "SLAVE",
+ "TestDB",
+ "localhost_12919");
+
+ msgAttr = ClusterConstraints.toConstraintAttributes(msg2);
+ matches = constraint.match(msgAttr);
+ System.out.println(msg2 + " matches(" + matches.size() + "): " + matches);
+ Assert.assertEquals(matches.size(), 5);
+ Assert.assertTrue(contains(matches, constraint0));
+ Assert.assertTrue(contains(matches, constraint1));
+ Assert.assertTrue(contains(matches, constraint2));
+ Assert.assertTrue(contains(matches, constraint3));
+ Assert.assertTrue(contains(matches, constraint4));
+
+ System.out.println("END testMsgConstraint() at "
+ + new Date(System.currentTimeMillis()));
+ }
+
+ @Test
+ public void testStateConstraint()
+ {
+ String className = getShortClassName();
+ System.out.println("START testStateConstraint() at "
+ + new Date(System.currentTimeMillis()));
+
+ String clusterName = "CLUSTER_" + className + "_state";
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ ZNRecord record = new ZNRecord("testStateConstraint");
+
+ // constraint0:
+ // "STATE=MASTER,CONSTRAINT_VALUE=1"
+ record.setMapField("constraint0", new TreeMap<String, String>());
+ record.getMapField("constraint0").put("STATE", "MASTER");
+ record.getMapField("constraint0").put("CONSTRAINT_VALUE", "1");
+ ConstraintItem constraint0 = new ConstraintItem(record.getMapField("constraint0"));
+
+ // constraint1:
+ // "STATE=MASTER,RESOURCE=TestDB,CONSTRAINT_VALUE=5"
+ record.setMapField("constraint1", new TreeMap<String, String>());
+ record.getMapField("constraint1").put("STATE", "MASTER");
+ record.getMapField("constraint1").put("RESOURCE", "TestDB");
+ record.getMapField("constraint1").put("CONSTRAINT_VALUE", "1");
+ ConstraintItem constraint1 = new ConstraintItem(record.getMapField("constraint1"));
+
+ // constraint2:
+ // "STATE=MASTER,RESOURCE=.*,CONSTRAINT_VALUE=2"
+ record.setMapField("constraint2", new TreeMap<String, String>());
+ record.getMapField("constraint2").put("STATE", "MASTER");
+ record.getMapField("constraint2").put("RESOURCE", ".*");
+ record.getMapField("constraint2").put("CONSTRAINT_VALUE", "2");
+ ConstraintItem constraint2 = new ConstraintItem(record.getMapField("constraint2"));
+
+ ZKHelixDataAccessor accessor =
+ new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+
+ accessor.setProperty(keyBuilder.constraint(ConstraintType.STATE_CONSTRAINT.toString()),
+ new ClusterConstraints(record));
+
+ record =
+ accessor.getProperty(keyBuilder.constraint(ConstraintType.STATE_CONSTRAINT.toString()))
+ .getRecord();
+ ClusterConstraints constraint = new ClusterConstraints(record);
+ // System.out.println("constraint: " + constraint);
+
+ // state1: hit rule2
+ Map<ConstraintAttribute, String> stateAttr1 =
+ new HashMap<ConstraintAttribute, String>();
+ stateAttr1.put(ConstraintAttribute.STATE, "MASTER");
+ stateAttr1.put(ConstraintAttribute.RESOURCE, "TestDB");
+
+ Set<ConstraintItem> matches = constraint.match(stateAttr1);
+ System.out.println(stateAttr1 + " matches(" + matches.size() + "): " + matches);
+ Assert.assertEquals(matches.size(), 3);
+ Assert.assertTrue(contains(matches, constraint0));
+ Assert.assertTrue(contains(matches, constraint1));
+ Assert.assertTrue(contains(matches, constraint2));
+
+ // matches = selectConstraints(matches, stateAttr1);
+ // System.out.println(stateAttr1 + " matches(" + matches.size() + "): " + matches);
+ // Assert.assertEquals(matches.size(), 2);
+ // Assert.assertTrue(contains(matches, constraint0));
+ // Assert.assertTrue(contains(matches, constraint1));
+
+ // state2: not hit any rules
+ Map<ConstraintAttribute, String> stateAttr2 =
+ new HashMap<ConstraintAttribute, String>();
+ stateAttr2.put(ConstraintAttribute.STATE, "MASTER");
+ stateAttr2.put(ConstraintAttribute.RESOURCE, "MyDB");
+
+ matches = constraint.match(stateAttr2);
+ System.out.println(stateAttr2 + " matches(" + matches.size() + "): " + matches);
+ Assert.assertEquals(matches.size(), 2);
+ Assert.assertTrue(contains(matches, constraint0));
+ Assert.assertTrue(contains(matches, constraint2));
+
+ // matches = selectConstraints(matches, stateAttr2);
+ // System.out.println(stateAttr2 + " matches(" + matches.size() + "): " + matches);
+ // Assert.assertEquals(matches.size(), 2);
+ // Assert.assertTrue(contains(matches, constraint0));
+ // Assert.assertTrue(contains(matches, constraint2));
+
+ System.out.println("END testStateConstraint() at "
+ + new Date(System.currentTimeMillis()));
+ }
+
+ private boolean contains(Set<ConstraintItem> constraints, ConstraintItem constraint)
+ {
+ for (ConstraintItem item : constraints)
+ {
+ if (item.toString().equals(constraint.toString()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/model/TestIdealState.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestIdealState.java b/helix-core/src/test/java/org/apache/helix/model/TestIdealState.java
new file mode 100644
index 0000000..551c9df
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/model/TestIdealState.java
@@ -0,0 +1,61 @@
+package org.apache.helix.model;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.helix.TestHelper;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.IdealState.IdealStateModeProperty;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class TestIdealState
+{
+ @Test
+ public void testGetInstanceSet()
+ {
+ String className = TestHelper.getTestClassName();
+ String methodName = TestHelper.getTestMethodName();
+ String testName = className + "_" + methodName;
+ System.out.println("START " + testName + " at "
+ + new Date(System.currentTimeMillis()));
+
+
+ IdealState idealState = new IdealState("idealState");
+ idealState.getRecord().setListField("TestDB_0", Arrays.asList("node_1", "node_2"));
+ Map<String, String> instanceState = new HashMap<String, String>();
+ instanceState.put("node_3", "MASTER");
+ instanceState.put("node_4", "SLAVE");
+ idealState.getRecord().setMapField("TestDB_1", instanceState);
+
+ // test AUTO mode
+ idealState.setIdealStateMode(IdealStateModeProperty.AUTO.toString());
+ Set<String> instances = idealState.getInstanceSet("TestDB_0");
+// System.out.println("instances: " + instances);
+ Assert.assertEquals(instances.size(), 2, "Should contain node_1 and node_2");
+ Assert.assertTrue(instances.contains("node_1"), "Should contain node_1 and node_2");
+ Assert.assertTrue(instances.contains("node_2"), "Should contain node_1 and node_2");
+
+ instances = idealState.getInstanceSet("TestDB_nonExist_auto");
+ Assert.assertEquals(instances, Collections.emptySet(), "Should get empty set");
+
+ // test CUSTOMIZED mode
+ idealState.setIdealStateMode(IdealStateModeProperty.CUSTOMIZED.toString());
+ instances = idealState.getInstanceSet("TestDB_1");
+// System.out.println("instances: " + instances);
+ Assert.assertEquals(instances.size(), 2, "Should contain node_3 and node_4");
+ Assert.assertTrue(instances.contains("node_3"), "Should contain node_3 and node_4");
+ Assert.assertTrue(instances.contains("node_4"), "Should contain node_3 and node_4");
+
+ instances = idealState.getInstanceSet("TestDB_nonExist_custom");
+ Assert.assertEquals(instances, Collections.emptySet(), "Should get empty set");
+
+ System.out.println("END " + testName + " at "
+ + new Date(System.currentTimeMillis()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/monitoring/TestParticipantMonitor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/TestParticipantMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/TestParticipantMonitor.java
new file mode 100644
index 0000000..6512343
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/TestParticipantMonitor.java
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package org.apache.helix.monitoring;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerNotification;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+
+import org.apache.helix.monitoring.ParticipantMonitor;
+import org.apache.helix.monitoring.StateTransitionContext;
+import org.apache.helix.monitoring.StateTransitionDataPoint;
+import org.apache.helix.monitoring.mbeans.ClusterMBeanObserver;
+import org.apache.log4j.Logger;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestParticipantMonitor
+{
+ static Logger _logger = Logger.getLogger(TestParticipantMonitor.class);
+
+ class ParticipantMonitorListener extends ClusterMBeanObserver
+ {
+ Map<String, Map<String, Object>> _beanValueMap = new HashMap<String, Map<String, Object>>();
+
+ public ParticipantMonitorListener(String domain)
+ throws InstanceNotFoundException, IOException,
+ MalformedObjectNameException, NullPointerException
+ {
+ super(domain);
+ init();
+ }
+
+ void init()
+ {
+ try
+ {
+ Set<ObjectInstance> existingInstances = _server.queryMBeans(new ObjectName(_domain+":Cluster=cluster,*"), null);
+ for(ObjectInstance instance : existingInstances)
+ {
+ String mbeanName = instance.getObjectName().toString();
+ // System.out.println("mbeanName: " + mbeanName);
+ addMBean(instance.getObjectName());
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.warn("fail to get all existing mbeans in " + _domain, e);
+ }
+ }
+
+ @Override
+ public void onMBeanRegistered(MBeanServerConnection server,
+ MBeanServerNotification mbsNotification)
+ {
+ addMBean(mbsNotification.getMBeanName());
+ }
+
+ void addMBean(ObjectName beanName)
+ {
+ try
+ {
+ MBeanInfo info = _server.getMBeanInfo(beanName);
+ MBeanAttributeInfo[] infos = info.getAttributes();
+ _beanValueMap.put(beanName.toString(), new HashMap<String, Object>());
+ for(MBeanAttributeInfo infoItem : infos)
+ {
+ Object val = _server.getAttribute(beanName, infoItem.getName());
+ // System.out.println(" " + infoItem.getName() + " : " + _server.getAttribute(beanName, infoItem.getName()) + " type : " + infoItem.getType());
+ _beanValueMap.get(beanName.toString()).put(infoItem.getName(), val);
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.error("Error getting bean info, domain="+_domain, e);
+ }
+ }
+
+ @Override
+ public void onMBeanUnRegistered(MBeanServerConnection server,
+ MBeanServerNotification mbsNotification)
+ {
+
+ }
+ }
+ @Test(groups={ "unitTest" })
+ public void TestReportData() throws InstanceNotFoundException, MalformedObjectNameException, NullPointerException, IOException, InterruptedException
+ {
+ System.out.println("START TestParticipantMonitor");
+ ParticipantMonitor monitor = new ParticipantMonitor();
+
+ int monitorNum = 0;
+
+ StateTransitionContext cxt = new StateTransitionContext("cluster", "instance", "db_1","a-b");
+ StateTransitionDataPoint data = new StateTransitionDataPoint(1000,1000,true);
+ monitor.reportTransitionStat(cxt, data);
+
+ data = new StateTransitionDataPoint(1000,1200,true);
+ monitor.reportTransitionStat(cxt, data);
+
+ ParticipantMonitorListener monitorListener = new ParticipantMonitorListener("CLMParticipantReport");
+ Thread.sleep(1000);
+ AssertJUnit.assertTrue(monitorListener._beanValueMap.size() == monitorNum + 1);
+
+ data = new StateTransitionDataPoint(1000,500,true);
+ monitor.reportTransitionStat(cxt, data);
+ Thread.sleep(1000);
+ AssertJUnit.assertTrue(monitorListener._beanValueMap.size() == monitorNum + 1);
+
+ data = new StateTransitionDataPoint(1000,500,true);
+ StateTransitionContext cxt2 = new StateTransitionContext("cluster", "instance", "db_2","a-b");
+ monitor.reportTransitionStat(cxt2, data);
+ monitor.reportTransitionStat(cxt2, data);
+ Thread.sleep(1000);
+ AssertJUnit.assertTrue(monitorListener._beanValueMap.size() == monitorNum + 2);
+
+ AssertJUnit.assertFalse(cxt.equals(cxt2));
+ AssertJUnit.assertFalse(cxt.equals(new Object()));
+ AssertJUnit.assertTrue(cxt.equals(new StateTransitionContext("cluster", "instance", "db_1","a-b")));
+
+ cxt2.getInstanceName();
+
+ ParticipantMonitorListener monitorListener2 = new ParticipantMonitorListener("CLMParticipantReport");
+
+ Thread.sleep(1000);
+ AssertJUnit.assertEquals(monitorListener2._beanValueMap.size() , monitorNum + 2);
+
+ monitorListener2.disconnect();
+ monitorListener.disconnect();
+ System.out.println("END TestParticipantMonitor");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/monitoring/TestStatCollector.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/TestStatCollector.java b/helix-core/src/test/java/org/apache/helix/monitoring/TestStatCollector.java
new file mode 100644
index 0000000..470baee
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/TestStatCollector.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.monitoring;
+
+import org.apache.helix.monitoring.StatCollector;
+import org.testng.annotations.Test;
+import org.testng.AssertJUnit;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class TestStatCollector
+{
+ @Test(groups={ "unitTest" })
+ public void TestCollectData()
+ {
+ StatCollector collector = new StatCollector();
+
+ int nPoints = 100;
+ for (int i = 0; i< nPoints; i++)
+ {
+ collector.addData(i*1000);
+ }
+ AssertJUnit.assertEquals(collector.getNumDataPoints(), nPoints);
+ AssertJUnit.assertEquals((long)collector.getMax(), 99000);
+ AssertJUnit.assertEquals((long)collector.getTotalSum(), 4950000);
+ AssertJUnit.assertEquals((long)collector.getPercentile(40), 39400);
+ AssertJUnit.assertEquals((long)collector.getMean(), 49500);
+ AssertJUnit.assertEquals((long)collector.getMin(), 0);
+
+ collector.reset();
+
+ AssertJUnit.assertEquals(collector.getNumDataPoints(), 0);
+ AssertJUnit.assertEquals((long)collector.getMax(), 0);
+ AssertJUnit.assertEquals((long)collector.getTotalSum(), 0);
+ AssertJUnit.assertEquals((long)collector.getPercentile(40), 0);
+ AssertJUnit.assertEquals((long)collector.getMean(), 0);
+ AssertJUnit.assertEquals((long)collector.getMin(), 0);
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterAlertItemMBeanCollection.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterAlertItemMBeanCollection.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterAlertItemMBeanCollection.java
new file mode 100644
index 0000000..d9db707
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterAlertItemMBeanCollection.java
@@ -0,0 +1,255 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.monitoring.mbeans;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.MBeanException;
+import javax.management.MalformedObjectNameException;
+import javax.management.ReflectionException;
+
+import org.apache.helix.ZNRecord;
+import org.apache.helix.alerts.AlertValueAndStatus;
+import org.apache.helix.alerts.Tuple;
+import org.apache.helix.healthcheck.TestWildcardAlert.TestClusterMBeanObserver;
+import org.apache.helix.monitoring.mbeans.ClusterAlertMBeanCollection;
+import org.apache.log4j.Logger;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class TestClusterAlertItemMBeanCollection
+{
+ private static final Logger _logger = Logger.getLogger(TestClusterAlertItemMBeanCollection.class);
+
+ @Test
+ public void TestAlertReportingHistory() throws InstanceNotFoundException, MalformedObjectNameException, NullPointerException, IOException, IntrospectionException, AttributeNotFoundException, ReflectionException, MBeanException
+ {
+ ClusterAlertMBeanCollection beanCollection = new ClusterAlertMBeanCollection();
+
+ String clusterName = "TestCluster";
+ String originAlert1 = "EXP(decay(1.0)(esv4-app7*.RestQueryStats@DBName=BizProfile.MinServerLatency))CMP(GREATER)CON(10)";
+ Map<String, AlertValueAndStatus> alertResultMap1 = new HashMap<String, AlertValueAndStatus>();
+ int nAlerts1 = 5;
+
+ String originAlert2 = "EXP(decay(1.0)(esv4-app9*.RestQueryStats@DBName=BizProfile.MaxServerLatency))CMP(GREATER)CON(10)";
+ Map<String, AlertValueAndStatus> alertResultMap2 = new HashMap<String, AlertValueAndStatus>();
+ int nAlerts2 = 3;
+
+ TestClusterMBeanObserver jmxMBeanObserver = new TestClusterMBeanObserver(ClusterAlertMBeanCollection.DOMAIN_ALERT);
+
+ for(int i = 0; i < nAlerts1; i++)
+ {
+ String alertName = "esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MinServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 0; i < nAlerts2; i++)
+ {
+ String alertName = "esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MaxServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ beanCollection.setAlerts(originAlert1, alertResultMap1, clusterName);
+ beanCollection.setAlerts(originAlert2, alertResultMap2, clusterName);
+
+ beanCollection.refreshAlertDelta(clusterName);
+ String summaryKey = ClusterAlertMBeanCollection.ALERT_SUMMARY + "_" + clusterName;
+ jmxMBeanObserver.refresh();
+
+ // Get the history list
+ String beanName = "HelixAlerts:alert=" + summaryKey;
+ Map<String, Object> beanValueMap = jmxMBeanObserver._beanValueMap.get(beanName);
+ String history1 = (String) (beanValueMap.get("AlertFiredHistory"));
+
+ StringReader sr = new StringReader(history1);
+ ObjectMapper mapper = new ObjectMapper();
+
+ // check the history
+
+ Map<String, String> delta = beanCollection.getRecentAlertDelta();
+ Assert.assertEquals(delta.size(), nAlerts1 + nAlerts2);
+ for(int i = 0; i < nAlerts1; i++)
+ {
+ String alertBeanName = "(esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MinServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("ON"));
+ }
+
+ for(int i = 0; i < nAlerts2; i++)
+ {
+ String alertBeanName = "(esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MaxServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("ON"));
+ }
+
+ alertResultMap1 = new HashMap<String, AlertValueAndStatus>();
+ for(int i = 0; i < 3; i++)
+ {
+ String alertName = "esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MinServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 3; i < 5; i++)
+ {
+ String alertName = "esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MinServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , false);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 7; i < 9; i++)
+ {
+ String alertName = "esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MinServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 0; i < 2; i++)
+ {
+ String alertName = "esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MaxServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , false);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 2; i < 3; i++)
+ {
+ String alertName = "esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MaxServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+ for(int i = 7; i < 9; i++)
+ {
+ String alertName = "esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MaxServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ beanCollection.setAlerts(originAlert1, alertResultMap1, clusterName);
+ beanCollection.refreshAlertDelta(clusterName);
+ jmxMBeanObserver.refresh();
+
+ beanValueMap = jmxMBeanObserver._beanValueMap.get(beanName);
+ history1 = (String) (beanValueMap.get("AlertFiredHistory"));
+
+ sr = new StringReader(history1);
+ mapper = new ObjectMapper();
+
+ // check the history
+ delta = beanCollection.getRecentAlertDelta();
+ Assert.assertEquals(delta.size(), 8);
+ for(int i = 3; i < 5; i++)
+ {
+ String alertBeanName = "(esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MinServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("OFF"));
+ }
+ for(int i = 7; i < 9; i++)
+ {
+ String alertBeanName = "(esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MinServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("ON"));
+ }
+
+ for(int i = 0; i < 2; i++)
+ {
+ String alertBeanName = "(esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MaxServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("OFF"));
+ }
+ for(int i = 7; i < 9; i++)
+ {
+ String alertBeanName = "(esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName#BizProfile.MaxServerLatency)GREATER(10)";
+ Assert.assertTrue(delta.get(alertBeanName).equals("ON"));
+ }
+ }
+ @Test
+ public void TestAlertRefresh() throws InstanceNotFoundException, MalformedObjectNameException, NullPointerException, IOException, IntrospectionException, AttributeNotFoundException, ReflectionException, MBeanException, InterruptedException
+ {
+ ClusterAlertMBeanCollection beanCollection = new ClusterAlertMBeanCollection();
+
+ String clusterName = "TestCluster";
+ String originAlert1 = "EXP(decay(1.0)(esv4-app7*.RestQueryStats@DBName=BizProfile.MinServerLatency))CMP(GREATER)CON(10)";
+ Map<String, AlertValueAndStatus> alertResultMap1 = new HashMap<String, AlertValueAndStatus>();
+ int nAlerts1 = 5;
+
+ String originAlert2 = "EXP(decay(1.0)(esv4-app9*.RestQueryStats@DBName=BizProfile.MaxServerLatency))CMP(GREATER)CON(10)";
+ Map<String, AlertValueAndStatus> alertResultMap2 = new HashMap<String, AlertValueAndStatus>();
+ int nAlerts2 = 3;
+
+ TestClusterMBeanObserver jmxMBeanObserver = new TestClusterMBeanObserver(ClusterAlertMBeanCollection.DOMAIN_ALERT);
+
+ for(int i = 0; i < nAlerts1; i++)
+ {
+ String alertName = "esv4-app7" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MinServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap1.put(alertName, valueAndStatus);
+ }
+
+ for(int i = 0; i < nAlerts2; i++)
+ {
+ String alertName = "esv4-app9" + i + ".stg.linkedin.com_12918.RestQueryStats@DBName=BizProfile.MaxServerLatency";
+ Tuple<String> value = new Tuple<String>();
+ value.add("22" + i);
+ AlertValueAndStatus valueAndStatus = new AlertValueAndStatus(value , true);
+ alertResultMap2.put(alertName, valueAndStatus);
+ }
+
+ beanCollection.setAlerts(originAlert1, alertResultMap1, clusterName);
+ beanCollection.setAlerts(originAlert2, alertResultMap2, clusterName);
+
+ beanCollection.refreshAlertDelta(clusterName);
+ String summaryKey = ClusterAlertMBeanCollection.ALERT_SUMMARY + "_" + clusterName;
+ jmxMBeanObserver.refresh();
+
+ Assert.assertEquals(jmxMBeanObserver._beanValueMap.size(), nAlerts2 + nAlerts1 + 1);
+
+ Thread.sleep(300);
+
+ beanCollection.setAlerts(originAlert1, alertResultMap1, clusterName);
+ beanCollection.checkMBeanFreshness(200);
+
+ Thread.sleep(500);
+
+ jmxMBeanObserver.refresh();
+
+ Assert.assertEquals(jmxMBeanObserver._beanValueMap.size(), nAlerts1 + 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
new file mode 100644
index 0000000..80c51c6
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.monitoring.mbeans;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.helix.DataAccessor;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixProperty;
+import org.apache.helix.Mocks;
+import org.apache.helix.NotificationContext;
+import org.apache.helix.PropertyType;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.model.ExternalView;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
+import org.apache.helix.monitoring.mbeans.ClusterStatusMonitor;
+import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.testng.annotations.Test;
+
+
+
+public class TestClusterStatusMonitor
+{
+ List<String> _instances;
+ List<ZNRecord> _liveInstances;
+ String _db = "DB";
+ String _db2 = "TestDB";
+ int _replicas = 3;
+ int _partitions = 50;
+ ZNRecord _externalView, _externalView2;
+
+ class MockDataAccessor extends Mocks.MockAccessor
+ {
+ public MockDataAccessor()
+ {
+ _instances = new ArrayList<String>();
+ for(int i = 0;i < 5; i++)
+ {
+ String instance = "localhost_"+(12918+i);
+ _instances.add(instance);
+ }
+ ZNRecord externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+ _instances, _partitions, _replicas, _db, "MASTER", "SLAVE");
+
+ ZNRecord externalView2 = IdealStateCalculatorForStorageNode.calculateIdealState(
+ _instances, 80, 2, _db2, "MASTER", "SLAVE");
+
+ }
+ public ZNRecord getProperty(PropertyType type, String resource)
+ {
+ if(type == PropertyType.IDEALSTATES || type == PropertyType.EXTERNALVIEW)
+ {
+ if(resource.equals(_db))
+ {
+ return _externalView;
+ }
+ else if(resource.equals(_db2))
+ {
+ return _externalView2;
+ }
+ }
+ return null;
+ }
+ }
+ class MockHelixManager extends Mocks.MockManager
+ {
+ MockDataAccessor _accessor = new MockDataAccessor();
+
+ @Override
+ public HelixDataAccessor getHelixDataAccessor()
+ {
+ return _accessor;
+ }
+
+ }
+ @Test()
+ public void TestReportData()
+ {
+ System.out.println("START TestClusterStatusMonitor at" + new Date(System.currentTimeMillis()));
+ List<String> _instances;
+ List<ZNRecord> _liveInstances = new ArrayList<ZNRecord>();
+ String _db = "DB";
+ int _replicas = 3;
+ int _partitions = 50;
+
+ _instances = new ArrayList<String>();
+ for(int i = 0;i < 5; i++)
+ {
+ String instance = "localhost_"+(12918+i);
+ _instances.add(instance);
+ ZNRecord metaData = new ZNRecord(instance);
+ metaData.setSimpleField(LiveInstanceProperty.SESSION_ID.toString(),
+ UUID.randomUUID().toString());
+ _liveInstances.add(metaData);
+ }
+ ZNRecord externalView = IdealStateCalculatorForStorageNode.calculateIdealState(
+ _instances, _partitions, _replicas, _db, "MASTER", "SLAVE");
+
+ ZNRecord externalView2 = IdealStateCalculatorForStorageNode.calculateIdealState(
+ _instances, 80, 2, "TestDB", "MASTER", "SLAVE");
+
+ List<ZNRecord> externalViews = new ArrayList<ZNRecord>();
+ externalViews.add(externalView);
+ externalViews.add(externalView2);
+
+ ClusterStatusMonitor monitor = new ClusterStatusMonitor("cluster1");
+ MockHelixManager manager = new MockHelixManager();
+ NotificationContext context = new NotificationContext(manager);
+ System.out.println("END TestClusterStatusMonitor at" + new Date(System.currentTimeMillis()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
new file mode 100644
index 0000000..c044b12
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
@@ -0,0 +1,172 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.monitoring.mbeans;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.helix.DataAccessor;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixProperty;
+import org.apache.helix.Mocks;
+import org.apache.helix.PropertyKey;
+import org.apache.helix.PropertyType;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.PropertyKey.Builder;
+import org.apache.helix.model.ExternalView;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
+import org.apache.helix.monitoring.mbeans.ResourceMonitor;
+import org.apache.helix.tools.IdealStateCalculatorForStorageNode;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestResourceMonitor
+{
+ String _clusterName = "Test-cluster";
+ String _dbName = "TestDB";
+ int _replicas = 3;
+ int _partitions = 50;
+
+ class MockHelixManager extends Mocks.MockManager
+ {
+ class MockDataAccessor extends Mocks.MockAccessor
+ {
+ @Override
+ public <T extends HelixProperty> List<T> getChildValues(PropertyKey key)
+ {
+ List<T> result = new ArrayList<T>();
+ PropertyType type = key.getType();
+ Class<? extends HelixProperty> clazz = key.getTypeClass();
+ if (type == PropertyType.EXTERNALVIEW)
+ {
+ HelixProperty typedInstance = HelixProperty.convertToTypedInstance(clazz, _externalView);
+ result.add((T) typedInstance);
+ return result;
+ }
+ else if (type == PropertyType.LIVEINSTANCES)
+ {
+ return (List<T>) HelixProperty.convertToTypedList(clazz, _liveInstances);
+ }
+
+ return result;
+ }
+
+ @Override
+ public <T extends HelixProperty> T getProperty(PropertyKey key)
+ {
+ PropertyType type = key.getType();
+ if (type == PropertyType.EXTERNALVIEW)
+ {
+ return (T) new ExternalView(_externalView);
+ }
+ else if (type == PropertyType.IDEALSTATES)
+ {
+ return (T) new IdealState(_idealState);
+ }
+ return null;
+ }
+ }
+
+ HelixDataAccessor _accessor = new MockDataAccessor();
+ ZNRecord _idealState;
+ ZNRecord _externalView;
+ List<String> _instances;
+ List<ZNRecord> _liveInstances;
+ String _db = "DB";
+
+ public MockHelixManager()
+ {
+ _liveInstances = new ArrayList<ZNRecord>();
+ _instances = new ArrayList<String>();
+ for(int i = 0;i<5; i++)
+ {
+ String instance = "localhost_"+(12918+i);
+ _instances.add(instance);
+ ZNRecord metaData = new ZNRecord(instance);
+ metaData.setSimpleField(LiveInstanceProperty.SESSION_ID.toString(),
+ UUID.randomUUID().toString());
+
+ }
+ _idealState= IdealStateCalculatorForStorageNode.calculateIdealState(_instances,
+ _partitions,
+ _replicas,
+ _dbName,
+ "MASTER",
+ "SLAVE");
+ _externalView = new ZNRecord(_idealState);
+ }
+
+ @Override
+ public HelixDataAccessor getHelixDataAccessor()
+ {
+ return _accessor;
+ }
+
+ }
+
+ @Test()
+ public void TestReportData()
+ {
+ MockHelixManager manager = new MockHelixManager();
+ ResourceMonitor monitor = new ResourceMonitor(_clusterName, _dbName);
+
+ HelixDataAccessor helixDataAccessor = manager.getHelixDataAccessor();
+ Builder keyBuilder = helixDataAccessor.keyBuilder();
+ ExternalView externalView =
+ helixDataAccessor.getProperty(keyBuilder.externalView(_dbName));
+ IdealState idealState = helixDataAccessor.getProperty(keyBuilder.idealStates(_dbName));
+
+ monitor.updateExternalView(externalView, idealState);
+
+ AssertJUnit.assertEquals(monitor.getDifferenceWithIdealStateGauge(), 0);
+ AssertJUnit.assertEquals(monitor.getErrorPartitionGauge(), 0);
+ AssertJUnit.assertEquals(monitor.getExternalViewPartitionGauge(), _partitions);
+ AssertJUnit.assertEquals(monitor.getPartitionGauge(), _partitions);
+ monitor.getBeanName();
+
+ int n = 4;
+ for (int i = 0; i < n; i++)
+ {
+ Map<String, String> map = externalView.getStateMap(_dbName + "_" + 3 * i);
+ String key = map.keySet().toArray()[0].toString();
+ map.put(key, "ERROR");
+ externalView.setStateMap(_dbName + "_" + 3 * i, map);
+ }
+
+ monitor.updateExternalView(externalView, idealState);
+ AssertJUnit.assertEquals(monitor.getDifferenceWithIdealStateGauge(), 0);
+ AssertJUnit.assertEquals(monitor.getErrorPartitionGauge(), n);
+ AssertJUnit.assertEquals(monitor.getExternalViewPartitionGauge(), _partitions);
+ AssertJUnit.assertEquals(monitor.getPartitionGauge(), _partitions);
+
+ n = 5;
+ for (int i = 0; i < n; i++)
+ {
+ externalView.getRecord().getMapFields().remove(_dbName + "_" + 4 * i);
+ }
+
+ monitor.updateExternalView(externalView, idealState);
+ AssertJUnit.assertEquals(monitor.getDifferenceWithIdealStateGauge(), n
+ * (_replicas + 1));
+ AssertJUnit.assertEquals(monitor.getErrorPartitionGauge(), 3);
+ AssertJUnit.assertEquals(monitor.getExternalViewPartitionGauge(), _partitions - n);
+ AssertJUnit.assertEquals(monitor.getPartitionGauge(), _partitions);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java b/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
new file mode 100644
index 0000000..04c41d3
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
@@ -0,0 +1,280 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.participant;
+
+import java.util.UUID;
+
+import org.apache.helix.ClusterMessagingService;
+import org.apache.helix.ConfigAccessor;
+import org.apache.helix.ConfigChangeListener;
+import org.apache.helix.ControllerChangeListener;
+import org.apache.helix.CurrentStateChangeListener;
+import org.apache.helix.DataAccessor;
+import org.apache.helix.ExternalViewChangeListener;
+import org.apache.helix.HealthStateChangeListener;
+import org.apache.helix.HelixAdmin;
+import org.apache.helix.HelixDataAccessor;
+import org.apache.helix.HelixManager;
+import org.apache.helix.IdealStateChangeListener;
+import org.apache.helix.InstanceType;
+import org.apache.helix.LiveInstanceChangeListener;
+import org.apache.helix.MessageListener;
+import org.apache.helix.PreConnectCallback;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.healthcheck.ParticipantHealthReportCollector;
+import org.apache.helix.manager.zk.ZKHelixDataAccessor;
+import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.store.PropertyStore;
+import org.apache.helix.store.zk.ZkHelixPropertyStore;
+
+
+public class MockZKHelixManager implements HelixManager
+{
+ private final ZKHelixDataAccessor _accessor;
+ private final String _instanceName;
+ private final String _clusterName;
+ private final InstanceType _type;
+
+ public MockZKHelixManager(String clusterName,
+ String instanceName,
+ InstanceType type,
+ ZkClient zkClient)
+ {
+ _instanceName = instanceName;
+ _clusterName = clusterName;
+ _type = type;
+ _accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(zkClient));
+ }
+
+ @Override
+ public void connect() throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean isConnected()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void disconnect()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addIdealStateChangeListener(IdealStateChangeListener listener) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addLiveInstanceChangeListener(LiveInstanceChangeListener listener) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addConfigChangeListener(ConfigChangeListener listener) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addMessageListener(MessageListener listener, String instanceName) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addCurrentStateChangeListener(CurrentStateChangeListener listener,
+ String instanceName,
+ String sessionId) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void addExternalViewChangeListener(ExternalViewChangeListener listener) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean removeListener(Object listener)
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public HelixDataAccessor getHelixDataAccessor()
+ {
+ return _accessor;
+ }
+
+ @Override
+ public String getClusterName()
+ {
+ return _clusterName;
+ }
+
+ @Override
+ public String getInstanceName()
+ {
+ return _instanceName;
+ }
+
+ @Override
+ public String getSessionId()
+ {
+ // TODO Auto-generated method stub
+ return UUID.randomUUID().toString();
+ }
+
+ @Override
+ public long getLastNotificationTime()
+ {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void addControllerListener(ControllerChangeListener listener)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public HelixAdmin getClusterManagmentTool()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public PropertyStore<ZNRecord> getPropertyStore()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ClusterMessagingService getMessagingService()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ParticipantHealthReportCollector getHealthReportCollector()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public InstanceType getInstanceType()
+ {
+ return _type;
+ }
+
+ @Override
+ public void addHealthStateChangeListener(HealthStateChangeListener listener,
+ String instanceName) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String getVersion()
+ {
+ // TODO Auto-generated method stub
+ return UUID.randomUUID().toString();
+ }
+
+ @Override
+ public StateMachineEngine getStateMachineEngine()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean isLeader()
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public ConfigAccessor getConfigAccessor()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void startTimerTasks()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void stopTimerTasks()
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public DataAccessor getDataAccessor()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void addPreConnectCallback(PreConnectCallback callback)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public ZkHelixPropertyStore<ZNRecord> getHelixPropertyStore()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerElection.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerElection.java b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerElection.java
new file mode 100644
index 0000000..9b0f166
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerElection.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.participant;
+
+import java.util.Date;
+
+import org.apache.helix.HelixManager;
+import org.apache.helix.InstanceType;
+import org.apache.helix.NotificationContext;
+import org.apache.helix.PropertyPathConfig;
+import org.apache.helix.PropertyType;
+import org.apache.helix.TestHelper;
+import org.apache.helix.ZNRecord;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.PropertyKey.Builder;
+import org.apache.helix.manager.zk.ZKHelixDataAccessor;
+import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.participant.DistClusterControllerElection;
+import org.apache.log4j.Logger;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestDistControllerElection extends ZkUnitTestBase
+{
+ private static Logger LOG = Logger.getLogger(TestDistControllerElection.class);
+
+ @Test()
+ public void testController() throws Exception
+ {
+ System.out.println("START TestDistControllerElection at "
+ + new Date(System.currentTimeMillis()));
+ String className = getShortClassName();
+
+ final String clusterName = CLUSTER_PREFIX + "_" + className + "_" + "testController";
+ String path = "/" + clusterName;
+ if (_gZkClient.exists(path))
+ {
+ _gZkClient.deleteRecursive(path);
+ }
+
+ ZKHelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+
+ final String controllerName = "controller_0";
+ HelixManager manager = new MockZKHelixManager(clusterName, controllerName,
+ InstanceType.CONTROLLER,
+ _gZkClient);
+
+ DistClusterControllerElection election = new DistClusterControllerElection(ZK_ADDR);
+ NotificationContext context = new NotificationContext(manager);
+ context.setType(NotificationContext.Type.INIT);
+ election.onControllerChange(context);
+
+// path = PropertyPathConfig.getPath(PropertyType.LEADER, clusterName);
+// ZNRecord leaderRecord = _gZkClient.<ZNRecord> readData(path);
+ LiveInstance liveInstance = accessor.getProperty(keyBuilder.controllerLeader());
+ AssertJUnit.assertEquals(controllerName, liveInstance.getInstanceName());
+ // AssertJUnit.assertNotNull(election.getController());
+ // AssertJUnit.assertNull(election.getLeader());
+
+ manager = new MockZKHelixManager(clusterName, "controller_1", InstanceType.CONTROLLER,
+ _gZkClient);
+ election = new DistClusterControllerElection(ZK_ADDR);
+ context = new NotificationContext(manager);
+ context.setType(NotificationContext.Type.INIT);
+ election.onControllerChange(context);
+// leaderRecord = _gZkClient.<ZNRecord> readData(path);
+ liveInstance = accessor.getProperty(keyBuilder.controllerLeader());
+ AssertJUnit.assertEquals(controllerName, liveInstance.getInstanceName());
+ // AssertJUnit.assertNull(election.getController());
+ // AssertJUnit.assertNull(election.getLeader());
+
+ System.out.println("END TestDistControllerElection at " + new Date(System.currentTimeMillis()));
+ }
+
+ @Test()
+ public void testControllerParticipant() throws Exception
+ {
+ String className = getShortClassName();
+ LOG.info("RUN " + className + " at " + new Date(System.currentTimeMillis()));
+
+ final String clusterName = CONTROLLER_CLUSTER_PREFIX + "_" + className + "_"
+ + "testControllerParticipant";
+ String path = "/" + clusterName;
+ if (_gZkClient.exists(path))
+ {
+ _gZkClient.deleteRecursive(path);
+ }
+
+ ZKHelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
+ Builder keyBuilder = accessor.keyBuilder();
+
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+
+ final String controllerName = "controller_0";
+ HelixManager manager = new MockZKHelixManager(clusterName, controllerName,
+ InstanceType.CONTROLLER_PARTICIPANT,
+ _gZkClient);
+
+ DistClusterControllerElection election = new DistClusterControllerElection(ZK_ADDR);
+ NotificationContext context = new NotificationContext(manager);
+ context.setType(NotificationContext.Type.CALLBACK);
+ election.onControllerChange(context);
+
+ LiveInstance liveInstance = accessor.getProperty(keyBuilder.controllerLeader());
+ AssertJUnit.assertEquals(controllerName, liveInstance.getInstanceName());
+
+// path = PropertyPathConfig.getPath(PropertyType.LEADER, clusterName);
+// ZNRecord leaderRecord = _gZkClient.<ZNRecord> readData(path);
+// AssertJUnit.assertEquals(controllerName, leaderRecord.getSimpleField("LEADER"));
+ // AssertJUnit.assertNotNull(election.getController());
+ // AssertJUnit.assertNotNull(election.getLeader());
+
+ manager = new MockZKHelixManager(clusterName, "controller_1",
+ InstanceType.CONTROLLER_PARTICIPANT,
+ _gZkClient);
+ election = new DistClusterControllerElection(ZK_ADDR);
+ context = new NotificationContext(manager);
+ context.setType(NotificationContext.Type.CALLBACK);
+ election.onControllerChange(context);
+
+ liveInstance = accessor.getProperty(keyBuilder.controllerLeader());
+ AssertJUnit.assertEquals(controllerName, liveInstance.getInstanceName());
+
+// leaderRecord = _gZkClient.<ZNRecord> readData(path);
+// AssertJUnit.assertEquals(controllerName, leaderRecord.getSimpleField("LEADER"));
+ // AssertJUnit.assertNull(election.getController());
+ // AssertJUnit.assertNull(election.getLeader());
+
+ LOG.info("END " + getShortClassName() + " at " + new Date(System.currentTimeMillis()));
+ }
+
+ @Test()
+ public void testParticipant() throws Exception
+ {
+ String className = getShortClassName();
+ LOG.info("RUN " + className + " at " + new Date(System.currentTimeMillis()));
+
+ final String clusterName = CLUSTER_PREFIX + "_" + className + "_" + "testParticipant";
+ String path = "/" + clusterName;
+ if (_gZkClient.exists(path))
+ {
+ _gZkClient.deleteRecursive(path);
+ }
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+
+ final String controllerName = "participant_0";
+ HelixManager manager = new MockZKHelixManager(clusterName, controllerName,
+ InstanceType.PARTICIPANT,
+ _gZkClient);
+
+ DistClusterControllerElection election = new DistClusterControllerElection(ZK_ADDR);
+ NotificationContext context = new NotificationContext(manager);
+ context.setType(NotificationContext.Type.INIT);
+ election.onControllerChange(context);
+
+ path = PropertyPathConfig.getPath(PropertyType.LEADER, clusterName);
+ ZNRecord leaderRecord = _gZkClient.<ZNRecord> readData(path, true);
+ AssertJUnit.assertNull(leaderRecord);
+ // AssertJUnit.assertNull(election.getController());
+ // AssertJUnit.assertNull(election.getLeader());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
new file mode 100644
index 0000000..3f57bbf
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
@@ -0,0 +1,135 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.participant;
+
+import org.apache.helix.NotificationContext;
+import org.apache.helix.TestHelper;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.model.Message;
+import org.apache.helix.model.Message.MessageType;
+import org.apache.helix.participant.DistClusterControllerStateModel;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+
+public class TestDistControllerStateModel extends ZkUnitTestBase
+{
+ final String clusterName = CLUSTER_PREFIX + "_" + getShortClassName();
+ DistClusterControllerStateModel stateModel = null;
+
+ @BeforeMethod()
+ public void beforeMethod()
+ {
+ stateModel = new DistClusterControllerStateModel(ZK_ADDR);
+ if (_gZkClient.exists("/" + clusterName))
+ {
+ _gZkClient.deleteRecursive("/" + clusterName);
+ }
+ TestHelper.setupEmptyCluster(_gZkClient, clusterName);
+ }
+
+ @Test()
+ public void testOnBecomeStandbyFromOffline()
+ {
+ stateModel.onBecomeStandbyFromOffline(null, null);
+ }
+
+ @Test()
+ public void testOnBecomeLeaderFromStandby()
+ {
+ Message message = new Message(MessageType.STATE_TRANSITION, "0");
+ message.setPartitionName(clusterName);
+ message.setTgtName("controller_0");
+ try
+ {
+ stateModel.onBecomeLeaderFromStandby(message, new NotificationContext(null));
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ stateModel.onBecomeStandbyFromLeader(message, new NotificationContext(null));
+ }
+
+ @Test()
+ public void testOnBecomeStandbyFromLeader()
+ {
+ Message message = new Message(MessageType.STATE_TRANSITION, "0");
+ message.setPartitionName(clusterName);
+ message.setTgtName("controller_0");
+ stateModel.onBecomeStandbyFromLeader(message, new NotificationContext(null));
+ }
+
+ @Test()
+ public void testOnBecomeOfflineFromStandby()
+ {
+ Message message = new Message(MessageType.STATE_TRANSITION, "0");
+ message.setPartitionName(clusterName);
+ message.setTgtName("controller_0");
+
+ stateModel.onBecomeOfflineFromStandby(message, null);
+ }
+
+ @Test()
+ public void testOnBecomeDroppedFromOffline()
+ {
+ stateModel.onBecomeDroppedFromOffline(null, null);
+ }
+
+ @Test()
+ public void testOnBecomeOfflineFromDropped()
+ {
+ stateModel.onBecomeOfflineFromDropped(null, null);
+ }
+
+ @Test()
+ public void testRollbackOnError()
+ {
+ Message message = new Message(MessageType.STATE_TRANSITION, "0");
+ message.setPartitionName(clusterName);
+ message.setTgtName("controller_0");
+ try
+ {
+ stateModel.onBecomeLeaderFromStandby(message, new NotificationContext(null));
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ stateModel.rollbackOnError(message, new NotificationContext(null), null);
+ }
+
+ @Test()
+ public void testReset()
+ {
+ Message message = new Message(MessageType.STATE_TRANSITION, "0");
+ message.setPartitionName(clusterName);
+ message.setTgtName("controller_0");
+ try
+ {
+ stateModel.onBecomeLeaderFromStandby(message, new NotificationContext(null));
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ stateModel.reset();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
new file mode 100644
index 0000000..554dca4
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.participant;
+
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.participant.DistClusterControllerStateModel;
+import org.apache.helix.participant.DistClusterControllerStateModelFactory;
+import org.testng.annotations.Test;
+import org.testng.annotations.Test;
+
+
+public class TestDistControllerStateModelFactory
+{
+ final String zkAddr = ZkUnitTestBase.ZK_ADDR;
+
+ @Test(groups = { "unitTest" })
+ public void testDistControllerStateModelFactory()
+ {
+ DistClusterControllerStateModelFactory factory = new DistClusterControllerStateModelFactory(zkAddr);
+ DistClusterControllerStateModel stateModel = factory.createNewStateModel("key");
+ stateModel.onBecomeStandbyFromOffline(null, null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java b/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
new file mode 100644
index 0000000..bd7a66f
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store;
+
+import java.util.Date;
+
+import org.apache.helix.ZNRecord;
+import org.apache.helix.store.PropertyJsonComparator;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestJsonComparator
+{
+ @Test (groups = {"unitTest"})
+ public void testJsonComparator()
+ {
+ System.out.println("START TestJsonComparator at " + new Date(System.currentTimeMillis()));
+
+ ZNRecord record = new ZNRecord("id1");
+ PropertyJsonComparator<ZNRecord> comparator = new PropertyJsonComparator<ZNRecord>(ZNRecord.class);
+ AssertJUnit.assertTrue(comparator.compare(null, null) == 0);
+ AssertJUnit.assertTrue(comparator.compare(null, record) == -1);
+ AssertJUnit.assertTrue(comparator.compare(record, null) == 1);
+ System.out.println("END TestJsonComparator at " + new Date(System.currentTimeMillis()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/TestPropertyStat.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestPropertyStat.java b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStat.java
new file mode 100644
index 0000000..bfeb212
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStat.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store;
+
+import org.apache.helix.store.PropertyStat;
+import org.testng.annotations.Test;
+import org.testng.AssertJUnit;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestPropertyStat
+{
+ @Test (groups = {"unitTest"})
+ public void testPropertyStat()
+ {
+ PropertyStat stat = new PropertyStat(0, 0);
+ AssertJUnit.assertEquals(0, stat.getLastModifiedTime());
+ AssertJUnit.assertEquals(0, stat.getVersion());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreException.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreException.java b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreException.java
new file mode 100644
index 0000000..813c96d
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreException.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store;
+
+import org.apache.helix.store.PropertyStoreException;
+import org.testng.annotations.Test;
+import org.testng.AssertJUnit;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestPropertyStoreException
+{
+ @Test (groups = {"unitTest"})
+ public void testPropertyStoreException()
+ {
+ PropertyStoreException exception = new PropertyStoreException("msg");
+ AssertJUnit.assertEquals(exception.getMessage(), "msg");
+
+ exception = new PropertyStoreException();
+ AssertJUnit.assertNull(exception.getMessage());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreFactory.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreFactory.java b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreFactory.java
new file mode 100644
index 0000000..c2fd8c1
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/TestPropertyStoreFactory.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store;
+
+import org.apache.helix.ZNRecord;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.store.PropertyJsonComparator;
+import org.apache.helix.store.PropertyJsonSerializer;
+import org.apache.helix.store.PropertyStore;
+import org.apache.helix.store.PropertyStoreFactory;
+import org.testng.Assert;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestPropertyStoreFactory extends ZkUnitTestBase
+{
+ @Test()
+ public void testZkPropertyStoreFactory()
+ {
+
+ try
+ {
+ PropertyStoreFactory.<ZNRecord> getZKPropertyStore(null, null, null);
+ Assert.fail("Should fail since zkAddr|serializer|root can't be null");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // OK
+ }
+
+ final String rootNamespace = "TestPropertyStoreFactory";
+ PropertyJsonSerializer<ZNRecord> serializer =
+ new PropertyJsonSerializer<ZNRecord>(ZNRecord.class);
+ try
+ {
+ PropertyStoreFactory.<ZNRecord> getZKPropertyStore("localhost:1812", serializer, rootNamespace);
+ Assert.fail("Should fail since zkAddr is not connectable");
+ }
+ catch (Exception e)
+ {
+ // OK
+ }
+
+ PropertyStore<ZNRecord> store =
+ PropertyStoreFactory.<ZNRecord> getZKPropertyStore(ZK_ADDR,
+ serializer,
+ rootNamespace);
+ Assert.assertNotNull(store);
+ }
+
+ @Test()
+ public void testFilePropertyStoreFactory()
+ {
+ final String rootNamespace = "/tmp/TestPropertyStoreFactory";
+ PropertyJsonSerializer<ZNRecord> serializer =
+ new PropertyJsonSerializer<ZNRecord>(ZNRecord.class);
+ PropertyJsonComparator<ZNRecord> comparator =
+ new PropertyJsonComparator<ZNRecord>(ZNRecord.class);
+ PropertyStore<ZNRecord> store;
+
+ boolean exceptionCaught = false;
+ try
+ {
+ store = PropertyStoreFactory.<ZNRecord> getFilePropertyStore(null, null, null);
+ }
+ catch (IllegalArgumentException e)
+ {
+ exceptionCaught = true;
+ }
+ AssertJUnit.assertTrue(exceptionCaught);
+
+ store =
+ PropertyStoreFactory.<ZNRecord> getFilePropertyStore(serializer,
+ rootNamespace,
+ comparator);
+ Assert.assertNotNull(store);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/TestZNRecordJsonSerializer.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestZNRecordJsonSerializer.java b/helix-core/src/test/java/org/apache/helix/store/TestZNRecordJsonSerializer.java
new file mode 100644
index 0000000..56ffce3
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/TestZNRecordJsonSerializer.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.helix.ZNRecord;
+import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.store.ZNRecordJsonSerializer;
+import org.apache.helix.store.zk.ZKPropertyStore;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class TestZNRecordJsonSerializer extends ZkUnitTestBase
+{
+
+ @Test
+ public void testZNRecordJsonSerializer() throws Exception
+ {
+ final String testRoot = getShortClassName();
+
+ System.out.println("START " + testRoot + " at " + new Date(System.currentTimeMillis()));
+
+ ZNRecord record = new ZNRecord("node1");
+ record.setSimpleField(ZNRecord.LIST_FIELD_BOUND, "" + 3);
+ List<String> list1 = Arrays.asList("one", "two", "three", "four");
+ List<String> list2 = Arrays.asList("a", "b", "c", "d");
+ List<String> list3 = Arrays.asList("x", "y");
+ record.setListField("list1", list1);
+ record.setListField("list2", list2);
+ record.setListField("list3", list3);
+
+ ZKPropertyStore<ZNRecord> store = new ZKPropertyStore<ZNRecord>(new ZkClient(ZK_ADDR),
+ new ZNRecordJsonSerializer(), "/" + testRoot);
+
+ store.setProperty("node1", record);
+ ZNRecord newRecord = store.getProperty("node1");
+ list1 = newRecord.getListField("list1");
+ Assert.assertTrue(list1.size() == 3);
+ Assert.assertTrue(list1.contains("one"));
+ Assert.assertTrue(list1.contains("two"));
+ Assert.assertTrue(list1.contains("three"));
+
+ list2 = newRecord.getListField("list2");
+ Assert.assertTrue(list2.size() == 3);
+ Assert.assertTrue(list2.contains("a"));
+ Assert.assertTrue(list2.contains("b"));
+ Assert.assertTrue(list2.contains("c"));
+
+ list3 = newRecord.getListField("list3");
+ Assert.assertTrue(list3.size() == 2);
+ Assert.assertTrue(list3.contains("x"));
+ Assert.assertTrue(list3.contains("y"));
+
+ System.out.println("END " + testRoot + " at " + new Date(System.currentTimeMillis()));
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/test/java/org/apache/helix/store/file/TestFilePropertyStore.java
----------------------------------------------------------------------
diff --git a/helix-core/src/test/java/org/apache/helix/store/file/TestFilePropertyStore.java b/helix-core/src/test/java/org/apache/helix/store/file/TestFilePropertyStore.java
new file mode 100644
index 0000000..b665621
--- /dev/null
+++ b/helix-core/src/test/java/org/apache/helix/store/file/TestFilePropertyStore.java
@@ -0,0 +1,156 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.store.file;
+
+import java.util.Date;
+import java.util.List;
+
+import org.I0Itec.zkclient.DataUpdater;
+import org.apache.helix.store.PropertyChangeListener;
+import org.apache.helix.store.PropertyJsonComparator;
+import org.apache.helix.store.PropertyJsonSerializer;
+import org.apache.helix.store.file.FilePropertyStore;
+import org.apache.log4j.Logger;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+
+public class TestFilePropertyStore
+{
+ private static Logger logger = Logger.getLogger(TestFilePropertyStore.class);
+ private static final String rootNamespace = "/tmp/TestFilePropertyStore";
+
+ public class TestPropertyChangeListener implements PropertyChangeListener<String>
+ {
+ public boolean _propertyChangeReceived = false;
+
+ @Override
+ public void onPropertyChange(String key)
+ {
+ logger.info("property changed at " + key);
+ _propertyChangeReceived = true;
+ }
+
+ }
+
+ public class TestUpdater implements DataUpdater<String>
+ {
+
+ @Override
+ public String update(String currentData)
+ {
+ return "new " + currentData;
+ }
+
+ }
+
+ @Test (groups = {"unitTest"})
+ public void testFilePropertyStore() throws Exception
+ {
+ System.out.println("START TestFilePropertyStore at " + new Date(System.currentTimeMillis()));
+
+ final int SLEEP_TIME = 2000;
+ PropertyJsonSerializer<String> serializer = new PropertyJsonSerializer<String>(String.class);
+ PropertyJsonComparator<String> comparator = new PropertyJsonComparator<String>(String.class);
+
+ FilePropertyStore<String> store = new FilePropertyStore<String>(serializer, rootNamespace,
+ comparator);
+ // store.removeRootNamespace();
+ // store.createRootNamespace();
+ store.start();
+
+ // test set
+ store.createPropertyNamespace("/child1");
+ store.setProperty("/child1/grandchild1", "grandchild1\n");
+ store.setProperty("/child1/grandchild2", "grandchild2\n");
+ store.createPropertyNamespace("/child1/grandchild3");
+ store.setProperty("/child1/grandchild3/grandgrandchild1", "grandgrandchild1\n");
+
+ // test get-names
+ List<String> names = store.getPropertyNames("/child1");
+ AssertJUnit.assertEquals(names.size(), 3);
+ AssertJUnit.assertTrue(names.contains("/child1/grandchild1"));
+ AssertJUnit.assertTrue(names.contains("/child1/grandchild2"));
+ AssertJUnit.assertTrue(names.contains("/child1/grandchild3/grandgrandchild1"));
+
+ // test get
+ String value = store.getProperty("nonExist");
+ AssertJUnit.assertEquals(value, null);
+ value = store.getProperty("/child1/grandchild2");
+ AssertJUnit.assertEquals(value, "grandchild2\n");
+ Thread.sleep(SLEEP_TIME);
+
+ // test subscribe
+ TestPropertyChangeListener listener1 = new TestPropertyChangeListener();
+ TestPropertyChangeListener listener2 = new TestPropertyChangeListener();
+
+ store.subscribeForPropertyChange("/child1", listener1);
+ store.subscribeForPropertyChange("/child1", listener1);
+ store.subscribeForPropertyChange("/child1", listener2);
+
+ store.setProperty("/child1/grandchild2", "grandchild2-new\n");
+ Thread.sleep(SLEEP_TIME);
+ AssertJUnit.assertEquals(listener1._propertyChangeReceived, true);
+ AssertJUnit.assertEquals(listener2._propertyChangeReceived, true);
+
+ listener1._propertyChangeReceived = false;
+ listener2._propertyChangeReceived = false;
+
+ // test unsubscribe
+ store.unsubscribeForPropertyChange("/child1", listener1);
+ store.setProperty("/child1/grandchild3/grandgrandchild1", "grandgrandchild1-new\n");
+ Thread.sleep(SLEEP_TIME);
+
+ AssertJUnit.assertEquals(listener1._propertyChangeReceived, false);
+ AssertJUnit.assertEquals(listener2._propertyChangeReceived, true);
+
+ listener2._propertyChangeReceived = false;
+
+ // test update property
+ store.updatePropertyUntilSucceed("child1/grandchild2", new TestUpdater());
+ value = store.getProperty("child1/grandchild2");
+ AssertJUnit.assertEquals("new grandchild2-new\n", value);
+
+ // test remove
+ store.removeProperty("/child1/grandchild2");
+ value = store.getProperty("/child1/grandchild2");
+ AssertJUnit.assertEquals(value, null);
+ Thread.sleep(SLEEP_TIME);
+ AssertJUnit.assertEquals(listener2._propertyChangeReceived, true);
+ listener2._propertyChangeReceived = false;
+
+ // test compare and set
+ boolean success = store.compareAndSet("/child1/grandchild1", "grandchild1-old\n",
+ "grandchild1-new\n", comparator);
+ AssertJUnit.assertEquals(success, false);
+
+ success = store.compareAndSet("/child1/grandchild1", "grandchild1\n",
+ "grandchild1-new\n", comparator);
+ AssertJUnit.assertEquals(success, true);
+
+ store.stop();
+
+ // test stop
+ listener2._propertyChangeReceived = false;
+ store.setProperty("/child1/grandchild3/grandgrandchild1", "grandgrandchild1-new-new\n");
+ Thread.sleep(SLEEP_TIME);
+ AssertJUnit.assertEquals(listener2._propertyChangeReceived, false);
+
+ store.unsubscribeForPropertyChange("/child1", listener2);
+ // store.stop();
+ System.out.println("END TestFilePropertyStore at " + new Date(System.currentTimeMillis()));
+ }
+}