Repository: incubator-ratis Updated Branches: refs/heads/master 9b84d79cf -> 737db6543
RATIS-306. Support multiple storage directories. Contributed by Nanda kumar Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/737db654 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/737db654 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/737db654 Branch: refs/heads/master Commit: 737db65432f41de9f0931781f462ac3e2ee5a763 Parents: 9b84d79 Author: Tsz Wo Nicholas Sze <[email protected]> Authored: Mon Oct 8 21:35:02 2018 +0800 Committer: Tsz Wo Nicholas Sze <[email protected]> Committed: Mon Oct 8 21:35:02 2018 +0800 ---------------------------------------------------------------------- .../java/org/apache/ratis/conf/ConfUtils.java | 15 +++ .../org/apache/ratis/conf/RaftProperties.java | 27 ++++ .../ratis/examples/arithmetic/cli/Server.java | 3 +- .../ratis/server/RaftServerConfigKeys.java | 12 +- .../ratis/server/impl/RaftServerProxy.java | 43 ++++--- .../apache/ratis/server/impl/ServerState.java | 38 +++++- .../java/org/apache/ratis/MiniRaftCluster.java | 2 +- .../ratis/server/TestRaftServerConfigKeys.java | 98 ++++++++++++++ .../ratis/server/impl/TestServerState.java | 127 +++++++++++++++++++ .../ratis/server/storage/TestCacheEviction.java | 3 +- .../server/storage/TestRaftLogReadWrite.java | 4 +- .../server/storage/TestRaftLogSegment.java | 3 +- .../server/storage/TestSegmentedRaftLog.java | 2 +- 13 files changed, 343 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java ---------------------------------------------------------------------- diff --git a/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java b/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java index 430dbf0..453ea0e 100644 --- a/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java +++ b/ratis-common/src/main/java/org/apache/ratis/conf/ConfUtils.java @@ -30,6 +30,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.net.InetSocketAddress; import java.util.Arrays; +import java.util.List; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -132,6 +133,13 @@ public interface ConfUtils { return get(fileGetter, key, defaultValue, logger, assertions); } + @SafeVarargs + static List<File> getFiles( + BiFunction<String, List<File>, List<File>> fileGetter, + String key, List<File> defaultValue, Consumer<String> logger, BiConsumer<String, List<File>>... assertions) { + return get(fileGetter, key, defaultValue, logger, assertions); + } + @SafeVarargs static SizeInBytes getSizeInBytes( @@ -195,6 +203,13 @@ public interface ConfUtils { } @SafeVarargs + static void setFiles( + BiConsumer<String, List<File>> fileSetter, String key, List<File> value, + BiConsumer<String, List<File>>... assertions) { + set(fileSetter, key, value, assertions); + } + + @SafeVarargs static void setSizeInBytes( BiConsumer<String, String> stringSetter, String key, SizeInBytes value, BiConsumer<String, Long>... assertions) { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-common/src/main/java/org/apache/ratis/conf/RaftProperties.java ---------------------------------------------------------------------- diff --git a/ratis-common/src/main/java/org/apache/ratis/conf/RaftProperties.java b/ratis-common/src/main/java/org/apache/ratis/conf/RaftProperties.java index 03582b9..9b853d6 100644 --- a/ratis-common/src/main/java/org/apache/ratis/conf/RaftProperties.java +++ b/ratis-common/src/main/java/org/apache/ratis/conf/RaftProperties.java @@ -48,6 +48,7 @@ import java.util.function.BiFunction; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; /** * Provides access to configuration parameters. The current implementation is a @@ -637,6 +638,26 @@ public class RaftProperties { return valueString == null? defaultValue: new File(valueString); } + /** + * Get the value of the <code>name</code> property as a list + * of <code>File</code>. + * The value of the property specifies a list of comma separated path names. + * If no such property is specified, then <code>defaultValue</code> is + * returned. + * + * @param name the property name. + * @param defaultValue default value. + * @return property value as a List of File, or <code>defaultValue</code>. + */ + public List<File> getFiles(String name, List<File> defaultValue) { + String valueString = getRaw(name); + if (null == valueString) { + return defaultValue; + } + String[] paths = getTrimmedStrings(name); + return Arrays.stream(paths).map(File::new).collect(Collectors.toList()); + } + public void setFile(String name, File value) { try { set(name, value.getCanonicalPath()); @@ -646,6 +667,12 @@ public class RaftProperties { } } + public void setFiles(String name, List<File> value) { + String paths = value.stream().map(File::getAbsolutePath) + .collect(Collectors.joining(",")); + set(name, paths); + } + /** @return property value; if it is not set, return the default value. */ public SizeInBytes getSizeInBytes(String name, SizeInBytes defaultValue) { final String valueString = getTrimmed(name); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java ---------------------------------------------------------------------- diff --git a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java index 564dfcf..f5be3e1 100644 --- a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java +++ b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java @@ -33,6 +33,7 @@ import org.apache.ratis.statemachine.StateMachine; import org.apache.ratis.util.NetUtils; import java.io.File; +import java.util.Collections; import java.util.Objects; /** @@ -59,7 +60,7 @@ public class Server extends SubCommandBase { final int port = NetUtils.createSocketAddr(getPeer(peerId).getAddress()).getPort(); GrpcConfigKeys.Server.setPort(properties, port); properties.setInt(GrpcConfigKeys.OutputStream.RETRY_TIMES_KEY, Integer.MAX_VALUE); - RaftServerConfigKeys.setStorageDir(properties, storageDir); + RaftServerConfigKeys.setStorageDirs(properties, Collections.singletonList(storageDir)); StateMachine stateMachine = new ArithmeticStateMachine(); final RaftGroup raftGroup = RaftGroup.valueOf(RaftGroupId.valueOf(ByteString.copyFromUtf8(raftGroupId)), peers); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java index c878c8f..33662c9 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java @@ -25,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -39,12 +41,12 @@ public interface RaftServerConfigKeys { String PREFIX = "raft.server"; String STORAGE_DIR_KEY = PREFIX + ".storage.dir"; - File STORAGE_DIR_DEFAULT = new File("/tmp/raft-server/"); - static File storageDir(RaftProperties properties) { - return getFile(properties::getFile, STORAGE_DIR_KEY, STORAGE_DIR_DEFAULT, getDefaultLog()); + List<File> STORAGE_DIR_DEFAULT = Collections.singletonList(new File("/tmp/raft-server/")); + static List<File> storageDirs(RaftProperties properties) { + return getFiles(properties::getFiles, STORAGE_DIR_KEY, STORAGE_DIR_DEFAULT, getDefaultLog()); } - static void setStorageDir(RaftProperties properties, File storageDir) { - setFile(properties::setFile, STORAGE_DIR_KEY, storageDir); + static void setStorageDirs(RaftProperties properties, List<File> storageDir) { + setFiles(properties::setFiles, STORAGE_DIR_KEY, storageDir); } /** http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java index f12905c..4622002 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerProxy.java @@ -41,16 +41,19 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; +import java.util.stream.Stream; public class RaftServerProxy implements RaftServer { public static final Logger LOG = LoggerFactory.getLogger(RaftServerProxy.class); @@ -163,25 +166,27 @@ public class RaftServerProxy implements RaftServer { /** Check the storage dir and add groups*/ void initGroups(RaftGroup group) { - final File dir = RaftServerConfigKeys.storageDir(properties); - if (dir.isDirectory()) { - for(File sub : dir.listFiles()) { - if (sub.isDirectory()) { - LOG.info("{}: found a subdirectory {}", getId(), sub); - try { - final RaftGroupId groupId = RaftGroupId.valueOf(UUID.fromString(sub.getName())); - if (group == null || !groupId.equals(group.getGroupId())) { - addGroup(RaftGroup.valueOf(groupId)); - } - } catch(Throwable t) { - LOG.warn(getId() + ": Failed to initialize the group directory " + sub.getAbsolutePath() + ". Ignoring it", t); - } - } - } - } - if (group != null) { - addGroup(group); - } + + final Optional<RaftGroup> raftGroup = Optional.ofNullable(group); + final Optional<RaftGroupId> raftGroupId = raftGroup.map(RaftGroup::getGroupId); + + RaftServerConfigKeys.storageDirs(properties).parallelStream() + .forEach((dir) -> Optional.ofNullable(dir.listFiles()) + .map(Arrays::stream).orElse(Stream.empty()) + .filter(File::isDirectory) + .forEach(sub -> { + try { + LOG.info("{}: found a subdirectory {}", getId(), sub); + final RaftGroupId groupId = RaftGroupId.valueOf(UUID.fromString(sub.getName())); + if (!raftGroupId.filter(groupId::equals).isPresent()) { + addGroup(RaftGroup.valueOf(groupId)); + } + } catch (Throwable t) { + LOG.warn(getId() + ": Failed to initialize the group directory " + + sub.getAbsolutePath() + ". Ignoring it", t); + } + })); + raftGroup.ifPresent(this::addGroup); } private CompletableFuture<RaftServerImpl> newRaftServerImpl(RaftGroup group) { http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java index 10afbfd..8fcc6b7 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java @@ -33,7 +33,14 @@ import org.apache.ratis.util.Timestamp; import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -90,10 +97,10 @@ public class ServerState implements Closeable { configurationManager = new ConfigurationManager(initialConf); LOG.info("{}: {}", id, configurationManager); - final File dir = RaftServerConfigKeys.storageDir(prop); // use full uuid string to create a subdirectory - storage = new RaftStorage(new File(dir, group.getGroupId().getUuid().toString()), - RaftServerConstants.StartupOption.REGULAR); + final File dir = chooseStorageDir(RaftServerConfigKeys.storageDirs(prop), + group.getGroupId().getUuid().toString()); + storage = new RaftStorage(dir, RaftServerConstants.StartupOption.REGULAR); snapshotManager = new SnapshotManager(storage, id); long lastApplied = initStatemachine(stateMachine, group.getGroupId()); @@ -120,6 +127,31 @@ public class ServerState implements Closeable { lastApplied, prop); } + + static File chooseStorageDir(List<File> volumes, String targetSubDir) throws IOException { + final Map<File, Integer> numberOfStorageDirPerVolume = new HashMap<>(); + final File[] empty = {}; + final List<File> resultList = new ArrayList<>(); + volumes.stream().flatMap(volume -> { + final File[] dirs = Optional.ofNullable(volume.listFiles()).orElse(empty); + numberOfStorageDirPerVolume.put(volume, dirs.length); + return Arrays.stream(dirs); + }).filter(dir -> targetSubDir.equals(dir.getName())) + .forEach(resultList::add); + + if (resultList.size() > 1) { + throw new IOException("More than one directories found for " + targetSubDir + ": " + resultList); + } + if (resultList.size() == 1) { + return resultList.get(0); + } + return numberOfStorageDirPerVolume.entrySet().stream() + .min(Comparator.comparing(Map.Entry::getValue)) + .map(Map.Entry::getKey) + .map(v -> new File(v, targetSubDir)) + .orElseThrow(() -> new IOException("No storage directory found.")); + } + private long initStatemachine(StateMachine sm, RaftGroupId groupId) throws IOException { sm.initialize(server.getProxy(), groupId, storage); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java b/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java index 7db7685..da81fc3 100644 --- a/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java +++ b/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java @@ -237,7 +237,7 @@ public abstract class MiniRaftCluster implements Closeable { LOG.info("Formatted directory {}", dir); } final RaftProperties prop = new RaftProperties(properties); - RaftServerConfigKeys.setStorageDir(prop, dir); + RaftServerConfigKeys.setStorageDirs(prop, Collections.singletonList(dir)); return newRaftServer(id, getStateMachineRegistry(properties), group, prop); } catch (IOException e) { throw new RuntimeException(e); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/TestRaftServerConfigKeys.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/TestRaftServerConfigKeys.java b/ratis-server/src/test/java/org/apache/ratis/server/TestRaftServerConfigKeys.java new file mode 100644 index 0000000..53c8871 --- /dev/null +++ b/ratis-server/src/test/java/org/apache/ratis/server/TestRaftServerConfigKeys.java @@ -0,0 +1,98 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 org.apache.ratis.server; + +import org.apache.ratis.BaseTest; +import org.apache.ratis.conf.RaftProperties; +import org.apache.ratis.util.FileUtils; +import org.apache.ratis.util.JavaUtils; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * Test cases to verify RaftServerConfigKeys. + */ +public class TestRaftServerConfigKeys { + + private static final Supplier<File> rootTestDir = JavaUtils.memoize( + () -> new File(BaseTest.getRootTestDir(), + TestRaftServerConfigKeys.class.getSimpleName() + + Integer.toHexString(ThreadLocalRandom.current().nextInt()))); + + @AfterClass + public static void tearDown() throws IOException { + FileUtils.deleteFully(rootTestDir.get()); + } + + /** + * Sets the value to <code>raft.server.storage.dir</code> via + * RaftServerConfigKeys and verifies it by reading directly from property. + */ + @Test + public void testStorageDirsProperty() { + final File testDir = new File( + rootTestDir.get(), UUID.randomUUID().toString()); + final List<File> directories = new ArrayList<>(); + final RaftProperties properties = new RaftProperties(); + + IntStream.range(0, 10).mapToObj((i) -> new File(testDir, + Integer.toString(i))).forEach(directories::add); + RaftServerConfigKeys.setStorageDirs(properties, directories); + + final String expected = directories.stream().map(File::getAbsolutePath) + .collect(Collectors.joining(",")); + final String actual = properties.get(RaftServerConfigKeys.STORAGE_DIR_KEY); + Assert.assertEquals(expected, actual); + } + + /** + * Sets the value to <code>raft.server.storage.dir</code> via + * RaftServerConfigKeys and also verifies the same via RaftServerConfigKeys. + */ + @Test + public void testStorageDirs() { + final File testDir = new File( + rootTestDir.get(), UUID.randomUUID().toString()); + final List<File> directories = new ArrayList<>(); + IntStream.range(0, 10).mapToObj((i) -> new File(testDir, + Integer.toString(i))).forEach(directories::add); + RaftProperties properties = new RaftProperties(); + RaftServerConfigKeys.setStorageDirs(properties, directories); + + final List<File> storageDirs = RaftServerConfigKeys.storageDirs(properties); + final List<String> expectedDirs = directories.stream() + .map(File::getAbsolutePath).collect(Collectors.toList()); + final List<String> actualDirs = storageDirs.stream() + .map(File::getAbsolutePath).collect(Collectors.toList()); + actualDirs.removeAll(expectedDirs); + Assert.assertEquals(directories.size(), storageDirs.size()); + Assert.assertEquals(0, actualDirs.size()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/impl/TestServerState.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/impl/TestServerState.java b/ratis-server/src/test/java/org/apache/ratis/server/impl/TestServerState.java new file mode 100644 index 0000000..5801d2b --- /dev/null +++ b/ratis-server/src/test/java/org/apache/ratis/server/impl/TestServerState.java @@ -0,0 +1,127 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 org.apache.ratis.server.impl; + +import org.apache.ratis.BaseTest; +import org.apache.ratis.util.FileUtils; +import org.apache.ratis.util.JavaUtils; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +/** + * Test cases to verify ServerState. + */ +public class TestServerState { + + private static final Supplier<File> rootTestDir = JavaUtils.memoize( + () -> new File(BaseTest.getRootTestDir(), + TestServerState.class.getSimpleName() + + Integer.toHexString(ThreadLocalRandom.current().nextInt()))); + + @AfterClass + public static void tearDown() throws IOException { + FileUtils.deleteFully(rootTestDir.get()); + } + + /** + * Tests choosing of storage directory when only one volume is configured. + * + * @throws IOException in case of exception. + */ + @Test + public void testChooseStorageDirWithOneVolume() throws IOException { + File testDir = new File(rootTestDir.get(), UUID.randomUUID().toString()); + List<File> directories = Collections.singletonList(testDir); + String subDirOne = UUID.randomUUID().toString(); + String subDirTwo = UUID.randomUUID().toString(); + File storageDirOne = ServerState.chooseStorageDir(directories, subDirOne); + File storageDirTwo = ServerState.chooseStorageDir(directories, subDirTwo); + File expectedOne = new File(testDir, subDirOne); + File expectedTwo = new File(testDir, subDirTwo); + Assert.assertEquals(expectedOne.getCanonicalPath(), + storageDirOne.getCanonicalPath()); + Assert.assertEquals(expectedTwo.getCanonicalPath(), + storageDirTwo.getCanonicalPath()); + } + + /** + * Tests choosing of storage directory when multiple volumes are configured. + * + * @throws IOException in case of exception. + */ + @Test + public void testChooseStorageDirWithMultipleVolumes() throws IOException { + File testDir = new File(rootTestDir.get(), UUID.randomUUID().toString()); + List<File> directories = new ArrayList<>(); + IntStream.range(0, 10).mapToObj((i) -> new File(testDir, + Integer.toString(i))).forEach((dir) -> { + try { + FileUtils.createDirectories(dir); + directories.add(dir); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + + directories.stream().filter((dir) -> Integer.parseInt(dir.getName()) != 6) + .forEach( + (dir) -> { + try { + FileUtils.createDirectories( + new File(dir, UUID.randomUUID().toString())); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + String subDir = UUID.randomUUID().toString(); + File storageDirectory = ServerState.chooseStorageDir(directories, subDir); + File expected = new File(directories.get(6), subDir); + Assert.assertEquals(expected.getCanonicalPath(), + storageDirectory.getCanonicalPath()); + } + + /** + * Tests choosing of storage directory when only no volume is configured. + * + * @throws IOException in case of exception. + */ + @Test + public void testChooseStorageDirWithNoVolume() { + try { + ServerState.chooseStorageDir( + Collections.emptyList(), UUID.randomUUID().toString()); + Assert.fail(); + } catch (IOException ex) { + String expectedErrMsg = "No storage directory found."; + Assert.assertEquals(expectedErrMsg, ex.getMessage()); + } + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/storage/TestCacheEviction.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestCacheEviction.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestCacheEviction.java index a8f5fab..a883727 100644 --- a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestCacheEviction.java +++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestCacheEviction.java @@ -40,6 +40,7 @@ import org.mockito.Mockito; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -156,7 +157,7 @@ public class TestCacheEviction extends BaseTest { final int maxCachedNum = RaftServerConfigKeys.Log.maxCachedSegmentNum(prop); File storageDir = getTestDir(); - RaftServerConfigKeys.setStorageDir(prop, storageDir); + RaftServerConfigKeys.setStorageDirs(prop, Collections.singletonList(storageDir)); RaftStorage storage = new RaftStorage(storageDir, RaftServerConstants.StartupOption.REGULAR); RaftServerImpl server = Mockito.mock(RaftServerImpl.class); http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogReadWrite.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogReadWrite.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogReadWrite.java index c218179..6ffb1bf 100644 --- a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogReadWrite.java +++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogReadWrite.java @@ -29,7 +29,6 @@ import org.apache.ratis.thirdparty.com.google.protobuf.CodedOutputStream; import org.apache.ratis.proto.RaftProtos.LogEntryProto; import org.apache.ratis.util.FileUtils; import org.apache.ratis.util.ProtoUtils; -import org.apache.ratis.util.SizeInBytes; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -41,6 +40,7 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -59,7 +59,7 @@ public class TestRaftLogReadWrite extends BaseTest { public void setup() throws Exception { storageDir = getTestDir(); RaftProperties properties = new RaftProperties(); - RaftServerConfigKeys.setStorageDir(properties, storageDir); + RaftServerConfigKeys.setStorageDirs(properties, Collections.singletonList(storageDir)); this.segmentMaxSize = RaftServerConfigKeys.Log.segmentSizeMax(properties).getSize(); this.preallocatedSize = http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogSegment.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogSegment.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogSegment.java index ce5a92d..8d696b1 100644 --- a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogSegment.java +++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestRaftLogSegment.java @@ -41,6 +41,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.apache.ratis.server.impl.RaftServerConstants.INVALID_LOG_INDEX; @@ -62,7 +63,7 @@ public class TestRaftLogSegment extends BaseTest { public void setup() throws Exception { RaftProperties properties = new RaftProperties(); storageDir = getTestDir(); - RaftServerConfigKeys.setStorageDir(properties, storageDir); + RaftServerConfigKeys.setStorageDirs(properties, Collections.singletonList(storageDir)); this.segmentMaxSize = RaftServerConfigKeys.Log.segmentSizeMax(properties).getSize(); this.preallocatedSize = http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/737db654/ratis-server/src/test/java/org/apache/ratis/server/storage/TestSegmentedRaftLog.java ---------------------------------------------------------------------- diff --git a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestSegmentedRaftLog.java b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestSegmentedRaftLog.java index 890f31b..0de9e8a 100644 --- a/ratis-server/src/test/java/org/apache/ratis/server/storage/TestSegmentedRaftLog.java +++ b/ratis-server/src/test/java/org/apache/ratis/server/storage/TestSegmentedRaftLog.java @@ -87,7 +87,7 @@ public class TestSegmentedRaftLog extends BaseTest { public void setup() throws Exception { storageDir = getTestDir(); properties = new RaftProperties(); - RaftServerConfigKeys.setStorageDir(properties, storageDir); + RaftServerConfigKeys.setStorageDirs(properties, Collections.singletonList(storageDir)); storage = new RaftStorage(storageDir, RaftServerConstants.StartupOption.REGULAR); this.segmentMaxSize = RaftServerConfigKeys.Log.segmentSizeMax(properties).getSize();
