/** * Licensed to Cloudera, Inc. under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. Cloudera, Inc. licenses this file * to you 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 com.cloudera.flume.master; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Properties; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A variety of tests both for ZKClient and the ZKServer * * These tests spew exceptions ALL OVER THE PLACE. These are part of normal * zookeeper operation - the key is whether the tests pass or fail. */ public class TestZKClient { static final Logger LOG = LoggerFactory.getLogger(TestZKClient.class); /** * Tests bringing up and shutting down a standalone ZooKeeper instance */ @Test public void testStandaloneUpAndDown() throws Exception { ZKInProcessServer zk = new ZKInProcessServer(2181, "/tmp/flume-test-zk/"); zk.start(); ZooKeeper client = new ZooKeeper("localhost:2181", 5000, new Watcher() { public void process(WatchedEvent event) { } }); Thread.sleep(1000); List<String> children = client.getChildren("/", false); LOG.warn("Got " + children.size() + " children"); assertTrue(children.size() > 0); zk.stop(); } /** * Test bringing up several in-process servers to form an ensemble. */ @Test public void testMultipleDistributedUpAndDown() throws Exception { Properties properties = new Properties(); properties.setProperty("tickTime", "2000"); properties.setProperty("initLimit", "10"); properties.setProperty("syncLimit", "5"); properties.setProperty("maxClientCnxns", "0"); ZKInProcessServer[] zks = new ZKInProcessServer[3]; properties.setProperty("server.0", "localhost:3181:4181"); properties.setProperty("server.1", "localhost:3182:4182"); properties.setProperty("server.2", "localhost:3183:4183"); properties.setProperty("electionAlg", Integer.toString(3)); for (int i = 0; i < 3; ++i) { LOG.info("Starting server " + i); properties.setProperty("dataDir", "/tmp/flume-test-zk/datadir" + i); properties.setProperty("dataLogDir", "/tmp/flume-test-zk/datadir" + i + "/logs"); properties.setProperty("clientPort", Integer.toString(2181 + i)); properties.setProperty("serverID", "" + i); zks[i] = new ZKInProcessServer(properties); if (i < 2) { zks[i].startWithoutWaiting(); } else { zks[i].start(); } } ZKClient client = new ZKClient("localhost:2181"); client.init(); assertTrue(client.getChildren("/", false).size() > 0); for (ZKInProcessServer z : zks) { z.stop(); } } /** * Test a number of ZKClient operations */ @Test public void testZKClient() throws Exception { File temp = File.createTempFile("flume-zk-test", ""); temp.delete(); temp.mkdir(); temp.deleteOnExit(); ZKInProcessServer zk = new ZKInProcessServer(3181, temp.getAbsolutePath()); zk.start(); ZKClient client = new ZKClient("localhost:3181"); client.init(); client.ensureDeleted("/test-flume", -1); assertTrue("Delete not successful!", client.exists("/test-flume", false) == null); client.ensureExists("/test-flume", "hello world".getBytes()); Stat stat = new Stat(); byte[] data = client.getData("/test-flume", false, stat); String dataString = new String(data); assertEquals("Didn't get expected 'hello world' from getData - " + dataString, dataString, "hello world"); client.delete("/test-flume", stat.getVersion()); assertTrue("Final delete not successful!", client.exists("/test-flume", false) == null); zk.stop(); } /** * Test failure modes - should throw KeeperException when can't get to ZK. */ @Test(expected = KeeperException.class) public void testZKClientFailures() throws IOException, KeeperException, InterruptedException { ZKClient client = null; try { File temp = File.createTempFile("flume-zk-test", ""); temp.delete(); temp.mkdir(); temp.deleteOnExit(); ZKInProcessServer zk = new ZKInProcessServer(3181, temp.getAbsolutePath()); zk.start(); client = new ZKClient("localhost:3181"); client.init(); client.ensureDeleted("/dummy", -1); zk.stop(); } catch (IOException e) { assertTrue("IOException caught! " + e, false); } client.create("/dummy", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); } /** * Test sequential child commands */ @Test public void testZKSequentialChildren() throws InterruptedException, IOException, KeeperException { File temp = File.createTempFile("flume-zk-test", ""); temp.delete(); temp.mkdir(); temp.deleteOnExit(); ZKInProcessServer zk = new ZKInProcessServer(3181, temp.getAbsolutePath()); zk.start(); ZKClient client = new ZKClient("localhost:3181"); client.init(); client.ensureExists("/seqtests", new byte[0]); for (int i = 0; i < 10; ++i) { client.create("/seqtests/seqnode", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); } String child = client.getLastSequentialChild("/seqtests", "seqnode", false); assertEquals("Expected to get seqnode0000000009, got " + child, "seqnode0000000009", child); } }