@Test public void simpleIntegrationTest() throws Exception { // Logger.getRootLogger().setLevel(Level.INFO); String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; int n = 1; System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis())); TestHelper.setupCluster( clusterName, _zkaddr, 12918, // participant port "localhost", // participant name prefix "TestDB", // resource name prefix 1, // resources 4, // partitions per resource n, // number of nodes 1, // replicas "MasterSlave", true); // do rebalance HelixManager participant = new ZKHelixManager(clusterName, "localhost_12918", InstanceType.PARTICIPANT, _zkaddr); participant .getStateMachineEngine() .registerStateModelFactory(StateModelDefId.MasterSlave, new MockMSModelFactory()); participant.connect(); HelixManager controller = new ZKHelixManager(clusterName, "controller_0", InstanceType.CONTROLLER, _zkaddr); controller.connect(); boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(_zkaddr, clusterName)); Assert.assertTrue(result); // cleanup controller.disconnect(); participant.disconnect(); // verify all live-instances and leader nodes are gone ZKHelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, _baseAccessor); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); Assert.assertNull(accessor.getProperty(keyBuilder.liveInstance("localhost_12918"))); Assert.assertNull(accessor.getProperty(keyBuilder.controllerLeader())); System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis())); }
@Test public void testBounceAll() throws Exception { // pick numbers that don't divide evenly final int NUM_PARTICIPANTS = 5; final int NUM_PARTITIONS = 123; final int NUM_REPLICAS = 1; final String RESOURCE_PREFIX = "TestDB"; final String RESOURCE_NAME = RESOURCE_PREFIX + "0"; // create a cluster name based on this test name String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; System.out.println("START " + clusterName + " at " + new Date(System.currentTimeMillis())); // Set up cluster TestHelper.setupCluster( clusterName, ZK_ADDR, 12918, // participant port "localhost", // participant name prefix "TestDB", // resource name prefix 1, // resources NUM_PARTITIONS, // partitions per resource NUM_PARTICIPANTS, // number of nodes NUM_REPLICAS, // replicas "OnlineOffline", RebalanceMode.FULL_AUTO, // use FULL_AUTO mode to test node tagging true); // do rebalance // Start the participants HelixManager[] participants = new HelixManager[NUM_PARTICIPANTS]; for (int i = 0; i < NUM_PARTICIPANTS; i++) { final String instanceName = "localhost_" + (12918 + i); participants[i] = createParticipant(clusterName, instanceName); participants[i].connect(); } // Start the controller ClusterControllerManager controller = new ClusterControllerManager(ZK_ADDR, clusterName, "controller"); controller.syncStart(); // get an admin and accessor HelixAdmin helixAdmin = new ZKHelixAdmin(_gZkClient); BaseDataAccessor<ZNRecord> baseAccessor = new ZkBaseDataAccessor<ZNRecord>(_gZkClient); HelixDataAccessor accessor = new ZKHelixDataAccessor(clusterName, baseAccessor); PropertyKey.Builder keyBuilder = accessor.keyBuilder(); // do the test try { Thread.sleep(1000); // ensure that the external view coalesces boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(ZK_ADDR, clusterName)); Assert.assertTrue(result); ExternalView stableExternalView = accessor.getProperty(keyBuilder.externalView(RESOURCE_NAME)); for (HelixManager participant : participants) { // disable the controller, bounce the node, re-enable the controller, verify assignments // remained the same helixAdmin.enableCluster(clusterName, false); participant.disconnect(); Thread.sleep(1000); participant = createParticipant(clusterName, participant.getInstanceName()); participant.connect(); Thread.sleep(1000); helixAdmin.enableCluster(clusterName, true); Thread.sleep(1000); result = ClusterStateVerifier.verifyByZkCallback( new MatchingExternalViewVerifier(stableExternalView, clusterName)); Assert.assertTrue(result); } } finally { // clean up controller.syncStop(); for (HelixManager participant : participants) { participant.disconnect(); } System.out.println("END " + clusterName + " at " + new Date(System.currentTimeMillis())); } }
@Test public void testZKReconnect() throws Exception { final AtomicReference<ZkServer> zkServerRef = new AtomicReference<ZkServer>(); final int zkPort = TestHelper.getRandomPort(); final String zkAddr = String.format("localhost:%d", zkPort); ZkServer zkServer = TestHelper.startZkServer(zkAddr); zkServerRef.set(zkServer); String className = TestHelper.getTestClassName(); String methodName = TestHelper.getTestMethodName(); String clusterName = className + "_" + methodName; // Setup cluster LOG.info("Setup clusters"); ClusterSetup clusterSetup = new ClusterSetup(zkAddr); clusterSetup.addCluster(clusterName, true); // Registers and starts controller LOG.info("Starts controller"); HelixManager controller = HelixManagerFactory.getZKHelixManager(clusterName, null, InstanceType.CONTROLLER, zkAddr); controller.connect(); // Registers and starts participant LOG.info("Starts participant"); String hostname = "localhost"; String instanceId = String.format("%s_%d", hostname, 1); clusterSetup.addInstanceToCluster(clusterName, instanceId); HelixManager participant = HelixManagerFactory.getZKHelixManager( clusterName, instanceId, InstanceType.PARTICIPANT, zkAddr); participant.connect(); LOG.info("Register state machine"); final CountDownLatch latch = new CountDownLatch(1); participant .getStateMachineEngine() .registerStateModelFactory( "OnlineOffline", new StateModelFactory<StateModel>() { @Override public StateModel createNewStateModel(String stateUnitKey) { return new SimpleStateModel(latch); } }, "test"); String resourceName = "test-resource"; LOG.info("Ideal state assignment"); HelixAdmin helixAdmin = participant.getClusterManagmentTool(); helixAdmin.addResource( clusterName, resourceName, 1, "OnlineOffline", IdealState.RebalanceMode.CUSTOMIZED.toString()); IdealState idealState = helixAdmin.getResourceIdealState(clusterName, resourceName); idealState.setReplicas("1"); idealState.setStateModelFactoryName("test"); idealState.setPartitionState(resourceName + "_0", instanceId, "ONLINE"); LOG.info("Shutdown ZK server"); TestHelper.stopZkServer(zkServerRef.get()); Executors.newSingleThreadScheduledExecutor() .schedule( new Runnable() { @Override public void run() { try { LOG.info("Restart ZK server"); // zkServer.set(TestUtils.startZookeeper(zkDir, zkPort)); zkServerRef.set(TestHelper.startZkServer(zkAddr, null, false)); } catch (Exception e) { LOG.error(e.getMessage(), e); } } }, 2L, TimeUnit.SECONDS); // future.get(); LOG.info("Before update ideal state"); helixAdmin.setResourceIdealState(clusterName, resourceName, idealState); LOG.info("After update ideal state"); LOG.info("Wait for OFFLINE->ONLINE state transition"); try { Assert.assertTrue(latch.await(10, TimeUnit.SECONDS)); // wait until stable state boolean result = ClusterStateVerifier.verifyByZkCallback( new BestPossAndExtViewZkVerifier(zkAddr, clusterName)); Assert.assertTrue(result); } finally { participant.disconnect(); zkServerRef.get().shutdown(); } }
@Override public void dispose() { if (participantManager != null && participantManager.isConnected()) { participantManager.disconnect(); } }