From 11f09f0a68a62a447132ea212b3d4509ee82fa12 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Thu, 27 Aug 2015 12:33:04 -0400 Subject: [PATCH] add basic unit test --- .../elasticsearch/index/shard/ShardPath.java | 4 +-- .../index/shard/NewPathForShardTest.java | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/index/shard/ShardPath.java b/core/src/main/java/org/elasticsearch/index/shard/ShardPath.java index c9ebb17fab0..b2b26c12d19 100644 --- a/core/src/main/java/org/elasticsearch/index/shard/ShardPath.java +++ b/core/src/main/java/org/elasticsearch/index/shard/ShardPath.java @@ -204,8 +204,6 @@ public final class ShardPath { final Path dataPath; final Path statePath; - final String indexUUID = indexSettings.get(IndexMetaData.SETTING_INDEX_UUID, IndexMetaData.INDEX_UUID_NA_VALUE); - if (NodeEnvironment.hasCustomDataPath(indexSettings)) { dataPath = env.resolveCustomLocation(indexSettings, shardId); statePath = env.nodePaths()[0].resolve(shardId); @@ -246,6 +244,8 @@ public final class ShardPath { dataPath = statePath; } + final String indexUUID = indexSettings.get(IndexMetaData.SETTING_INDEX_UUID, IndexMetaData.INDEX_UUID_NA_VALUE); + return new ShardPath(NodeEnvironment.hasCustomDataPath(indexSettings), dataPath, statePath, indexUUID, shardId); } diff --git a/core/src/test/java/org/elasticsearch/index/shard/NewPathForShardTest.java b/core/src/test/java/org/elasticsearch/index/shard/NewPathForShardTest.java index 4d8023b2062..b151bf88851 100644 --- a/core/src/test/java/org/elasticsearch/index/shard/NewPathForShardTest.java +++ b/core/src/test/java/org/elasticsearch/index/shard/NewPathForShardTest.java @@ -29,7 +29,10 @@ import java.nio.file.attribute.FileAttributeView; import java.nio.file.attribute.FileStoreAttributeView; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.lucene.mockfile.FilterFileSystem; @@ -178,6 +181,7 @@ public class NewPathForShardTest extends ESTestCase { public void testSelectNewPathForShard() throws Exception { Path path = PathUtils.get(createTempDir().toString()); + // Use 2 data paths: String[] paths = new String[] {path.resolve("a").toString(), path.resolve("b").toString()}; @@ -192,5 +196,35 @@ public class NewPathForShardTest extends ESTestCase { assertEquals("mocka", nodePaths[0].fileStore.name()); assertEquals("mockb", nodePaths[1].fileStore.name()); + + // a has lots of free space, but b has little, so new shard should go to a: + aFileStore.usableSpace = 100000; + bFileStore.usableSpace = 1000; + + ShardId shardId = new ShardId("index", 0); + ShardPath result = ShardPath.selectNewPathForShard(nodeEnv, shardId, Settings.EMPTY, 100, Collections.emptyMap()); + assertTrue(result.getDataPath().toString().contains("/a/")); + + // test the reverse: b has lots of free space, but a has little, so new shard should go to b: + aFileStore.usableSpace = 1000; + bFileStore.usableSpace = 100000; + + shardId = new ShardId("index", 0); + result = ShardPath.selectNewPathForShard(nodeEnv, shardId, Settings.EMPTY, 100, Collections.emptyMap()); + assertTrue(result.getDataPath().toString().contains("/b/")); + + // now a and be have equal usable space; we allocate two shards to the node, and each should go to different paths: + aFileStore.usableSpace = 100000; + bFileStore.usableSpace = 100000; + + Map dataPathToShardCount = new HashMap<>(); + ShardPath result1 = ShardPath.selectNewPathForShard(nodeEnv, shardId, Settings.EMPTY, 100, dataPathToShardCount); + dataPathToShardCount.put(NodeEnvironment.shardStatePathToDataPath(result1.getDataPath()), 1); + ShardPath result2 = ShardPath.selectNewPathForShard(nodeEnv, shardId, Settings.EMPTY, 100, dataPathToShardCount); + + // This was the original failure: on a node with 2 disks that have nearly equal + // free space, we would always allocate all incoming shards to the one path that + // had the most free space: + assertNotEquals(result1.getDataPath(), result2.getDataPath()); } }