|
@@ -18,90 +18,67 @@
|
|
|
|
|
|
package org.apache.zookeeper.server;
|
|
|
|
|
|
+import static org.junit.Assert.assertTrue;
|
|
|
+
|
|
|
import java.io.File;
|
|
|
import java.io.RandomAccessFile;
|
|
|
|
|
|
import org.apache.zookeeper.CreateMode;
|
|
|
-import org.apache.zookeeper.PortAssignment;
|
|
|
-import org.apache.zookeeper.WatchedEvent;
|
|
|
-import org.apache.zookeeper.Watcher;
|
|
|
-import org.apache.zookeeper.ZKTestCase;
|
|
|
-import org.apache.zookeeper.ZooKeeper;
|
|
|
import org.apache.zookeeper.ZooDefs.Ids;
|
|
|
+import org.apache.zookeeper.ZooKeeper;
|
|
|
import org.apache.zookeeper.test.ClientBase;
|
|
|
-import org.junit.Assert;
|
|
|
import org.junit.Test;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
|
|
/**
|
|
|
- * this test checks that the server works
|
|
|
- * even if the last snapshot is invalidated
|
|
|
- * by corruption or if the server crashes
|
|
|
- * while generating the snapshot.
|
|
|
+ * This test checks that the server works even if the last snapshot is
|
|
|
+ * invalidated by corruption or if the server crashes while generating the
|
|
|
+ * snapshot.
|
|
|
*/
|
|
|
-public class InvalidSnapshotTest extends ZKTestCase implements Watcher {
|
|
|
- private static final String HOSTPORT =
|
|
|
- "127.0.0.1:" + PortAssignment.unique();
|
|
|
- private static final int CONNECTION_TIMEOUT = 3000;
|
|
|
+public class InvalidSnapshotTest extends ClientBase {
|
|
|
+ private static final Logger LOG =
|
|
|
+ LoggerFactory.getLogger(InvalidSnapshotTest.class);
|
|
|
+
|
|
|
+ public InvalidSnapshotTest() {
|
|
|
+ SyncRequestProcessor.setSnapCount(100);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * this test does the main work of testing
|
|
|
- * an invalid snapshot
|
|
|
- * @throws Exception
|
|
|
+ * Validate that the server can come up on an invalid snapshot - by
|
|
|
+ * reverting to a prior snapshot + associated logs.
|
|
|
*/
|
|
|
@Test
|
|
|
public void testInvalidSnapshot() throws Exception {
|
|
|
- File tmpDir = ClientBase.createTmpDir();
|
|
|
- ClientBase.setupTestEnv();
|
|
|
- ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
|
|
|
- SyncRequestProcessor.setSnapCount(100);
|
|
|
- final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
|
|
|
- ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
|
|
|
- f.startup(zks);
|
|
|
- Assert.assertTrue("waiting for server being up ",
|
|
|
- ClientBase.waitForServerUp(HOSTPORT,CONNECTION_TIMEOUT));
|
|
|
- ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
|
|
|
- try {
|
|
|
- for (int i=0; i< 2000; i++) {
|
|
|
- zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE,
|
|
|
- CreateMode.PERSISTENT);
|
|
|
- }
|
|
|
- } finally {
|
|
|
- zk.close();
|
|
|
- }
|
|
|
- f.shutdown();
|
|
|
- Assert.assertTrue("waiting for server to shutdown",
|
|
|
- ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
|
|
|
- // now corrupt the snapshot
|
|
|
- File snapFile = zks.getTxnLogFactory().findMostRecentSnapshot();
|
|
|
- RandomAccessFile raf = new RandomAccessFile(snapFile, "rws");
|
|
|
- raf.setLength(3);
|
|
|
- raf.close();
|
|
|
- // now restart the server and see if it starts
|
|
|
- zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
|
|
|
- SyncRequestProcessor.setSnapCount(100);
|
|
|
- f = ServerCnxnFactory.createFactory(PORT, -1);
|
|
|
- f.startup(zks);
|
|
|
- Assert.assertTrue("waiting for server being up ",
|
|
|
- ClientBase.waitForServerUp(HOSTPORT,CONNECTION_TIMEOUT));
|
|
|
- // the server should come up
|
|
|
- zk = new ZooKeeper(HOSTPORT, 20000, this);
|
|
|
- try {
|
|
|
- Assert.assertTrue("the node should exist",
|
|
|
- (zk.exists("/invalidsnap-1999", false) != null));
|
|
|
- f.shutdown();
|
|
|
- Assert.assertTrue("waiting for server to shutdown",
|
|
|
- ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
|
|
|
- } finally {
|
|
|
- zk.close();
|
|
|
- }
|
|
|
+ ZooKeeper zk = createClient();
|
|
|
+ try {
|
|
|
+ for (int i = 0; i < 2000; i++) {
|
|
|
+ zk.create("/invalidsnap-" + i, new byte[0],
|
|
|
+ Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ zk.close();
|
|
|
+ }
|
|
|
+ NIOServerCnxnFactory factory = (NIOServerCnxnFactory)serverFactory;
|
|
|
+ stopServer();
|
|
|
|
|
|
- f.shutdown();
|
|
|
- Assert.assertTrue("waiting for server to shutdown",
|
|
|
- ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
|
|
|
- }
|
|
|
+ // now corrupt the snapshot
|
|
|
+ File snapFile = factory.zkServer.getTxnLogFactory().findMostRecentSnapshot();
|
|
|
+ LOG.info("Corrupting " + snapFile);
|
|
|
+ RandomAccessFile raf = new RandomAccessFile(snapFile, "rws");
|
|
|
+ raf.setLength(3);
|
|
|
+ raf.close();
|
|
|
|
|
|
- public void process(WatchedEvent event) {
|
|
|
- // do nothing for now
|
|
|
- }
|
|
|
+ // now restart the server
|
|
|
+ startServer();
|
|
|
|
|
|
+ // verify that the expected data exists and wasn't lost
|
|
|
+ zk = createClient();
|
|
|
+ try {
|
|
|
+ assertTrue("the node should exist",
|
|
|
+ (zk.exists("/invalidsnap-1999", false) != null));
|
|
|
+ } finally {
|
|
|
+ zk.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|