From commits-return-6152-archive-asf-public=cust-asf.ponee.io@zookeeper.apache.org Tue Feb 20 20:27:41 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id C9D09180654 for ; Tue, 20 Feb 2018 20:27:39 +0100 (CET) Received: (qmail 26656 invoked by uid 500); 20 Feb 2018 19:27:38 -0000 Mailing-List: contact commits-help@zookeeper.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@zookeeper.apache.org Delivered-To: mailing list commits@zookeeper.apache.org Received: (qmail 26645 invoked by uid 99); 20 Feb 2018 19:27:38 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 20 Feb 2018 19:27:38 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id ADE77E0A10; Tue, 20 Feb 2018 19:27:38 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: afine@apache.org To: commits@zookeeper.apache.org Message-Id: <5bd49dcd22e54f35aa467aa9e46c717e@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: zookeeper git commit: ZOOKEEPER-2967: Add check to validate dataDir and dataLogDir parameters at startup Date: Tue, 20 Feb 2018 19:27:38 +0000 (UTC) Repository: zookeeper Updated Branches: refs/heads/branch-3.5 bcd6cae87 -> b3be8a75c ZOOKEEPER-2967: Add check to validate dataDir and dataLogDir parameters at startup ZOOKEEPER-2967: Add check to validate dataDir and dataLogDir parameters at startup This PR adds a check to protect ZK against configuring dataDir and dataLogDir opposingly. When FileTxnSnapLog is created, it checks if transaction log directory contains snapshot files or vice versa, snapshot directory contains transaction log files. If so, the check throws LogdirContentCheckException or SnapdirContentCheckException, respectively, which translates to DatadirException at ZK startup in QuorumPeerMain and ZooKeeperServerMain. If the two directories are the same, then no check is done. For testing, I've added 4 new unit tests which cover the following cases: transaction log and snapshot directories are different and they are used correctly (no Exception) transaction log and snapshot directories are the same (in this case no check is done) transaction log and snapshot directories are different and transaction log directory contains snapshot files (LogdirContentCheckException -> ZK quits) transaction log and snapshot directories are different and snapshot directory contains transaction log files (SnapdirContentCheckException -> ZK quits) Author: Mark Fenes Reviewers: Andor Molnár , Abraham Fine Closes #458 from mfenes/ZOOKEEPER-2967_3.5 Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/b3be8a75 Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/b3be8a75 Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/b3be8a75 Branch: refs/heads/branch-3.5 Commit: b3be8a75ca6ecfb61692d80a678af86a027b07fe Parents: bcd6cae Author: Mark Fenes Authored: Tue Feb 20 11:27:27 2018 -0800 Committer: Abraham Fine Committed: Tue Feb 20 11:27:27 2018 -0800 ---------------------------------------------------------------------- .../zookeeper/server/persistence/FileSnap.java | 10 +- .../server/persistence/FileTxnLog.java | 22 +-- .../server/persistence/FileTxnSnapLog.java | 46 +++++ .../zookeeper/server/persistence/Util.java | 26 ++- .../server/persistence/FileTxnSnapLogTest.java | 174 ++++++++++++++++++- .../test/AtomicFileOutputStreamTest.java | 2 +- .../org/apache/zookeeper/test/ClientBase.java | 21 ++- 7 files changed, 276 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/main/org/apache/zookeeper/server/persistence/FileSnap.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/persistence/FileSnap.java b/src/java/main/org/apache/zookeeper/server/persistence/FileSnap.java index 30ce7c7..f6f2ac5 100644 --- a/src/java/main/org/apache/zookeeper/server/persistence/FileSnap.java +++ b/src/java/main/org/apache/zookeeper/server/persistence/FileSnap.java @@ -57,6 +57,8 @@ public class FileSnap implements SnapShot { public final static int SNAP_MAGIC = ByteBuffer.wrap("ZKSN".getBytes()).getInt(); + public static final String SNAPSHOT_FILE_PREFIX = "snapshot"; + public FileSnap(File snapDir) { this.snapDir = snapDir; } @@ -97,7 +99,7 @@ public class FileSnap implements SnapShot { if (!foundValid) { throw new IOException("Not able to find valid snapshots in " + snapDir); } - dt.lastProcessedZxid = Util.getZxidFromName(snap.getName(), "snapshot"); + dt.lastProcessedZxid = Util.getZxidFromName(snap.getName(), SNAPSHOT_FILE_PREFIX); return dt.lastProcessedZxid; } @@ -145,7 +147,7 @@ public class FileSnap implements SnapShot { * @throws IOException */ private List findNValidSnapshots(int n) throws IOException { - List files = Util.sortDataDir(snapDir.listFiles(),"snapshot", false); + List files = Util.sortDataDir(snapDir.listFiles(), SNAPSHOT_FILE_PREFIX, false); int count = 0; List list = new ArrayList(); for (File f : files) { @@ -175,13 +177,13 @@ public class FileSnap implements SnapShot { * @throws IOException */ public List findNRecentSnapshots(int n) throws IOException { - List files = Util.sortDataDir(snapDir.listFiles(), "snapshot", false); + List files = Util.sortDataDir(snapDir.listFiles(), SNAPSHOT_FILE_PREFIX, false); int count = 0; List list = new ArrayList(); for (File f: files) { if (count == n) break; - if (Util.getZxidFromName(f.getName(), "snapshot") != -1) { + if (Util.getZxidFromName(f.getName(), SNAPSHOT_FILE_PREFIX) != -1) { count++; list.add(f); } http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java index 9edc38e..72ec606 100644 --- a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java +++ b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnLog.java @@ -99,6 +99,8 @@ public class FileTxnLog implements TxnLog { public final static int VERSION = 2; + public static final String LOG_FILE_PREFIX = "log"; + /** Maximum time we allow for elapsed fsync before WARNing */ private final static long fsyncWarningThresholdMS; @@ -208,12 +210,10 @@ public class FileTxnLog implements TxnLog { } if (logStream==null) { if(LOG.isInfoEnabled()){ - LOG.info("Creating new log file: log." + - Long.toHexString(hdr.getZxid())); + LOG.info("Creating new log file: " + Util.makeLogName(hdr.getZxid())); } - logFileWrite = new File(logDir, ("log." + - Long.toHexString(hdr.getZxid()))); + logFileWrite = new File(logDir, Util.makeLogName(hdr.getZxid())); fos = new FileOutputStream(logFileWrite); logStream=new BufferedOutputStream(fos); oa = BinaryOutputArchive.getArchive(logStream); @@ -290,12 +290,12 @@ public class FileTxnLog implements TxnLog { * @return */ public static File[] getLogFiles(File[] logDirList,long snapshotZxid) { - List files = Util.sortDataDir(logDirList, "log", true); + List files = Util.sortDataDir(logDirList, LOG_FILE_PREFIX, true); long logZxid = 0; // Find the log file that starts before or at the same time as the // zxid of the snapshot for (File f : files) { - long fzxid = Util.getZxidFromName(f.getName(), "log"); + long fzxid = Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX); if (fzxid > snapshotZxid) { continue; } @@ -307,7 +307,7 @@ public class FileTxnLog implements TxnLog { } List v=new ArrayList(5); for (File f : files) { - long fzxid = Util.getZxidFromName(f.getName(), "log"); + long fzxid = Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX); if (fzxid < logZxid) { continue; } @@ -324,7 +324,7 @@ public class FileTxnLog implements TxnLog { public long getLastLoggedZxid() { File[] files = getLogFiles(logDir.listFiles(), 0); long maxLog=files.length>0? - Util.getZxidFromName(files[files.length-1].getName(),"log"):-1; + Util.getZxidFromName(files[files.length-1].getName(),LOG_FILE_PREFIX):-1; // if a log file is more recent we must scan it to find // the highest zxid @@ -622,13 +622,13 @@ public class FileTxnLog implements TxnLog { */ void init() throws IOException { storedFiles = new ArrayList(); - List files = Util.sortDataDir(FileTxnLog.getLogFiles(logDir.listFiles(), 0), "log", false); + List files = Util.sortDataDir(FileTxnLog.getLogFiles(logDir.listFiles(), 0), LOG_FILE_PREFIX, false); for (File f: files) { - if (Util.getZxidFromName(f.getName(), "log") >= zxid) { + if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) >= zxid) { storedFiles.add(f); } // add the last logfile that is less than the zxid - else if (Util.getZxidFromName(f.getName(), "log") < zxid) { + else if (Util.getZxidFromName(f.getName(), LOG_FILE_PREFIX) < zxid) { storedFiles.add(f); break; } http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java index 852452e..eef87a6 100644 --- a/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java +++ b/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java @@ -19,6 +19,7 @@ package org.apache.zookeeper.server.persistence; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.util.List; import java.util.Map; @@ -130,10 +131,41 @@ public class FileTxnSnapLog { throw new DatadirException("Cannot write to snap directory " + this.snapDir); } + // check content of transaction log and snapshot dirs if they are two different directories + // See ZOOKEEPER-2967 for more details + if(!this.dataDir.getPath().equals(this.snapDir.getPath())){ + checkLogDir(); + checkSnapDir(); + } + txnLog = new FileTxnLog(this.dataDir); snapLog = new FileSnap(this.snapDir); } + private void checkLogDir() throws LogDirContentCheckException { + File[] files = this.dataDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return Util.isSnapshotFileName(name); + } + }); + if (files != null && files.length > 0) { + throw new LogDirContentCheckException("Log directory has snapshot files. Check if dataLogDir and dataDir configuration is correct."); + } + } + + private void checkSnapDir() throws SnapDirContentCheckException { + File[] files = this.snapDir.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return Util.isLogFileName(name); + } + }); + if (files != null && files.length > 0) { + throw new SnapDirContentCheckException("Snapshot directory has log files. Check if dataLogDir and dataDir configuration is correct."); + } + } + /** * get the datadir used by this filetxn * snap log @@ -437,4 +469,18 @@ public class FileTxnSnapLog { super(msg, e); } } + + @SuppressWarnings("serial") + public static class LogDirContentCheckException extends DatadirException { + public LogDirContentCheckException(String msg) { + super(msg); + } + } + + @SuppressWarnings("serial") + public static class SnapDirContentCheckException extends DatadirException { + public SnapDirContentCheckException(String msg) { + super(msg); + } + } } http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/main/org/apache/zookeeper/server/persistence/Util.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/persistence/Util.java b/src/java/main/org/apache/zookeeper/server/persistence/Util.java index bf1abaa..8efc772 100644 --- a/src/java/main/org/apache/zookeeper/server/persistence/Util.java +++ b/src/java/main/org/apache/zookeeper/server/persistence/Util.java @@ -83,7 +83,7 @@ public class Util { * @return file name */ public static String makeLogName(long zxid) { - return "log." + Long.toHexString(zxid); + return FileTxnLog.LOG_FILE_PREFIX + "." + Long.toHexString(zxid); } /** @@ -93,7 +93,7 @@ public class Util { * @return file name */ public static String makeSnapshotName(long zxid) { - return "snapshot." + Long.toHexString(zxid); + return FileSnap.SNAPSHOT_FILE_PREFIX + "." + Long.toHexString(zxid); } /** @@ -157,7 +157,7 @@ public class Util { * @throws IOException */ public static boolean isValidSnapshot(File f) throws IOException { - if (f==null || Util.getZxidFromName(f.getName(), "snapshot") == -1) + if (f==null || Util.getZxidFromName(f.getName(), FileSnap.SNAPSHOT_FILE_PREFIX) == -1) return false; // Check for a valid snapshot @@ -294,5 +294,25 @@ public class Util { Collections.sort(filelist, new DataDirFileComparator(prefix, ascending)); return filelist; } + + /** + * Returns true if fileName is a log file name. + * + * @param fileName + * @return + */ + public static boolean isLogFileName(String fileName) { + return fileName.startsWith(FileTxnLog.LOG_FILE_PREFIX + "."); + } + + /** + * Returns true if fileName is a snapshot file name. + * + * @param fileName + * @return + */ + public static boolean isSnapshotFileName(String fileName) { + return fileName.startsWith(FileSnap.SNAPSHOT_FILE_PREFIX + "."); + } } http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/test/org/apache/zookeeper/server/persistence/FileTxnSnapLogTest.java ---------------------------------------------------------------------- diff --git a/src/java/test/org/apache/zookeeper/server/persistence/FileTxnSnapLogTest.java b/src/java/test/org/apache/zookeeper/server/persistence/FileTxnSnapLogTest.java index 71e9c8d..9334d93 100644 --- a/src/java/test/org/apache/zookeeper/server/persistence/FileTxnSnapLogTest.java +++ b/src/java/test/org/apache/zookeeper/server/persistence/FileTxnSnapLogTest.java @@ -22,8 +22,11 @@ import org.apache.jute.Record; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.server.Request; import org.apache.zookeeper.test.ClientBase; +import org.apache.zookeeper.test.TestUtils; import org.apache.zookeeper.txn.SetDataTxn; import org.apache.zookeeper.txn.TxnHeader; +import org.junit.After; +import org.junit.Before; import org.junit.Assert; import org.junit.Test; @@ -32,12 +35,134 @@ import java.io.IOException; public class FileTxnSnapLogTest { + private File tmpDir; + + private File logDir; + + private File snapDir; + + private File logVersionDir; + + private File snapVersionDir; + + @Before + public void setUp() throws Exception { + tmpDir = ClientBase.createEmptyTestDir(); + logDir = new File(tmpDir, "logdir"); + snapDir = new File(tmpDir, "snapdir"); + } + + @After + public void tearDown() throws Exception { + if(tmpDir != null){ + TestUtils.deleteFileRecursively(tmpDir); + } + this.tmpDir = null; + this.logDir = null; + this.snapDir = null; + this.logVersionDir = null; + this.snapVersionDir = null; + } + + private File createVersionDir(File parentDir) { + File versionDir = new File(parentDir, FileTxnSnapLog.version + FileTxnSnapLog.VERSION); + versionDir.mkdirs(); + return versionDir; + } + + private void createLogFile(File dir, long zxid) throws IOException { + File file = new File(dir.getPath() + File.separator + Util.makeLogName(zxid)); + file.createNewFile(); + } + + private void createSnapshotFile(File dir, long zxid) throws IOException { + File file = new File(dir.getPath() + File.separator + Util.makeSnapshotName(zxid)); + file.createNewFile(); + } + + private void twoDirSetupWithCorrectFiles() throws IOException { + logVersionDir = createVersionDir(logDir); + snapVersionDir = createVersionDir(snapDir); + + // transaction log files in log dir + createLogFile(logVersionDir,1); + createLogFile(logVersionDir,2); + + // snapshot files in snap dir + createSnapshotFile(snapVersionDir,1); + createSnapshotFile(snapVersionDir,2); + } + + private void singleDirSetupWithCorrectFiles() throws IOException { + logVersionDir = createVersionDir(logDir); + + // transaction log and snapshot files in the same dir + createLogFile(logVersionDir,1); + createLogFile(logVersionDir,2); + createSnapshotFile(logVersionDir,1); + createSnapshotFile(logVersionDir,2); + } + + private FileTxnSnapLog createFileTxnSnapLogWithNoAutoCreateDataDir(File logDir, File snapDir) throws IOException { + return createFileTxnSnapLogWithAutoCreateDataDir(logDir, snapDir, "false"); + } + + private FileTxnSnapLog createFileTxnSnapLogWithAutoCreateDataDir(File logDir, File snapDir, String autoCreateValue) throws IOException { + String priorAutocreateDirValue = System.getProperty(FileTxnSnapLog.ZOOKEEPER_DATADIR_AUTOCREATE); + System.setProperty(FileTxnSnapLog.ZOOKEEPER_DATADIR_AUTOCREATE, autoCreateValue); + FileTxnSnapLog fileTxnSnapLog; + try { + fileTxnSnapLog = new FileTxnSnapLog(logDir, snapDir); + } finally { + if (priorAutocreateDirValue == null) { + System.clearProperty(FileTxnSnapLog.ZOOKEEPER_DATADIR_AUTOCREATE); + } else { + System.setProperty(FileTxnSnapLog.ZOOKEEPER_DATADIR_AUTOCREATE, priorAutocreateDirValue); + } + } + return fileTxnSnapLog; + } + + /** + * Test verifies the auto creation of log dir and snap dir. + * Sets "zookeeper.datadir.autocreate" to true. + */ + @Test + public void testWithAutoCreateDataDir() throws IOException { + Assert.assertFalse("log directory already exists", logDir.exists()); + Assert.assertFalse("snapshot directory already exists", snapDir.exists()); + + FileTxnSnapLog fileTxnSnapLog = createFileTxnSnapLogWithAutoCreateDataDir(logDir, snapDir, "true"); + + Assert.assertTrue(logDir.exists()); + Assert.assertTrue(snapDir.exists()); + Assert.assertTrue(fileTxnSnapLog.getDataDir().exists()); + Assert.assertTrue(fileTxnSnapLog.getSnapDir().exists()); + } + + /** + * Test verifies server should fail when log dir or snap dir doesn't exist. + * Sets "zookeeper.datadir.autocreate" to false. + */ + @Test(expected = FileTxnSnapLog.DatadirException.class) + public void testWithoutAutoCreateDataDir() throws Exception { + Assert.assertFalse("log directory already exists", logDir.exists()); + Assert.assertFalse("snapshot directory already exists", snapDir.exists()); + + try { + createFileTxnSnapLogWithAutoCreateDataDir(logDir, snapDir, "false"); + } catch (FileTxnSnapLog.DatadirException e) { + Assert.assertFalse(logDir.exists()); + Assert.assertFalse(snapDir.exists()); + // rethrow exception + throw e; + } + Assert.fail("Expected exception from FileTxnSnapLog"); + } @Test public void testGetTxnLogSyncElapsedTime() throws IOException { - File tmpDir = ClientBase.createTmpDir(); - FileTxnSnapLog fileTxnSnapLog = new FileTxnSnapLog(new File(tmpDir, "data"), - new File(tmpDir, "data_txnlog")); + FileTxnSnapLog fileTxnSnapLog = createFileTxnSnapLogWithAutoCreateDataDir(logDir, snapDir, "true"); TxnHeader hdr = new TxnHeader(1, 1, 1, 1, ZooDefs.OpCode.setData); Record txn = new SetDataTxn("/foo", new byte[0], 1); @@ -53,4 +178,47 @@ public class FileTxnSnapLogTest { } } + @Test + public void testDirCheckWithCorrectFiles() throws IOException { + twoDirSetupWithCorrectFiles(); + + try { + createFileTxnSnapLogWithNoAutoCreateDataDir(logDir, snapDir); + } catch (FileTxnSnapLog.LogDirContentCheckException | FileTxnSnapLog.SnapDirContentCheckException e) { + Assert.fail("Should not throw ContentCheckException."); + } + } + + @Test + public void testDirCheckWithSingleDirSetup() throws IOException { + singleDirSetupWithCorrectFiles(); + + try { + createFileTxnSnapLogWithNoAutoCreateDataDir(logDir, logDir); + } catch (FileTxnSnapLog.LogDirContentCheckException | FileTxnSnapLog.SnapDirContentCheckException e) { + Assert.fail("Should not throw ContentCheckException."); + } + } + + @Test(expected = FileTxnSnapLog.LogDirContentCheckException.class) + public void testDirCheckWithSnapFilesInLogDir() throws IOException { + twoDirSetupWithCorrectFiles(); + + // add snapshot files to the log version dir + createSnapshotFile(logVersionDir,3); + createSnapshotFile(logVersionDir,4); + + createFileTxnSnapLogWithNoAutoCreateDataDir(logDir, snapDir); + } + + @Test(expected = FileTxnSnapLog.SnapDirContentCheckException.class) + public void testDirCheckWithLogFilesInSnapDir() throws IOException { + twoDirSetupWithCorrectFiles(); + + // add transaction log files to the snap version dir + createLogFile(snapVersionDir,3); + createLogFile(snapVersionDir,4); + + createFileTxnSnapLogWithNoAutoCreateDataDir(logDir, snapDir); + } } http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/test/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java ---------------------------------------------------------------------- diff --git a/src/java/test/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java b/src/java/test/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java index fe86f54..cbd2b77 100644 --- a/src/java/test/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java +++ b/src/java/test/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java @@ -43,7 +43,7 @@ public class AtomicFileOutputStreamTest extends ZKTestCase { @Before public void setupTestDir() throws IOException { - testDir = ClientBase.createTmpDir(); + testDir = ClientBase.createEmptyTestDir(); dstFile = new File(testDir, "test.txt"); } @After http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b3be8a75/src/java/test/org/apache/zookeeper/test/ClientBase.java ---------------------------------------------------------------------- diff --git a/src/java/test/org/apache/zookeeper/test/ClientBase.java b/src/java/test/org/apache/zookeeper/test/ClientBase.java index 7f381d2..129d815 100644 --- a/src/java/test/org/apache/zookeeper/test/ClientBase.java +++ b/src/java/test/org/apache/zookeeper/test/ClientBase.java @@ -368,12 +368,15 @@ public abstract class ClientBase extends ZKTestCase { } } + public static File createEmptyTestDir() throws IOException { + return createTmpDir(BASETEST, false); + } public static File createTmpDir() throws IOException { - return createTmpDir(BASETEST); + return createTmpDir(BASETEST, true); } - static File createTmpDir(File parentDir) throws IOException { + static File createTmpDir(File parentDir, boolean createInitFile) throws IOException { File tmpFile = File.createTempFile("test", ".junit", parentDir); // don't delete tmpFile - this ensures we don't attempt to create // a tmpDir with a duplicate name @@ -381,9 +384,21 @@ public abstract class ClientBase extends ZKTestCase { Assert.assertFalse(tmpDir.exists()); // never true if tmpfile does it's job Assert.assertTrue(tmpDir.mkdirs()); + // todo not every tmp directory needs this file + if (createInitFile) { + createInitializeFile(tmpDir); + } + return tmpDir; } + public static void createInitializeFile(File dir) throws IOException { + File initFile = new File(dir, "initialize"); + if (!initFile.exists()) { + Assert.assertTrue(initFile.createNewFile()); + } + } + private static int getPort(String hostPort) { String[] split = hostPort.split(":"); String portstr = split[split.length-1]; @@ -498,7 +513,7 @@ public abstract class ClientBase extends ZKTestCase { setUpAll(); - tmpDir = createTmpDir(BASETEST); + tmpDir = createTmpDir(BASETEST, true); startServer();