|
12 | 12 |
|
13 | 13 | import org.apache.lucene.store.Directory;
|
14 | 14 | import org.apache.lucene.store.FilterDirectory;
|
| 15 | +import org.opensearch.action.admin.cluster.node.stats.NodeStats; |
| 16 | +import org.opensearch.action.admin.cluster.node.stats.NodesStatsRequest; |
| 17 | +import org.opensearch.action.admin.cluster.node.stats.NodesStatsResponse; |
15 | 18 | import org.opensearch.action.admin.indices.delete.DeleteIndexRequest;
|
16 | 19 | import org.opensearch.action.admin.indices.get.GetIndexRequest;
|
17 | 20 | import org.opensearch.action.admin.indices.get.GetIndexResponse;
|
|
28 | 31 | import org.opensearch.index.store.CompositeDirectory;
|
29 | 32 | import org.opensearch.index.store.remote.file.CleanerDaemonThreadLeakFilter;
|
30 | 33 | import org.opensearch.index.store.remote.filecache.FileCache;
|
| 34 | +import org.opensearch.index.store.remote.filecache.FileCacheStats; |
| 35 | +import org.opensearch.index.store.remote.filecache.FullFileCacheStats; |
31 | 36 | import org.opensearch.index.store.remote.utils.FileTypeUtils;
|
32 | 37 | import org.opensearch.indices.IndicesService;
|
33 | 38 | import org.opensearch.node.Node;
|
|
36 | 41 |
|
37 | 42 | import java.util.Arrays;
|
38 | 43 | import java.util.HashSet;
|
| 44 | +import java.util.Objects; |
39 | 45 | import java.util.Set;
|
| 46 | +import java.util.concurrent.ExecutionException; |
40 | 47 | import java.util.stream.Collectors;
|
41 | 48 |
|
42 | 49 | import static org.opensearch.test.hamcrest.OpenSearchAssertions.assertAcked;
|
|
49 | 56 | public class WritableWarmIT extends RemoteStoreBaseIntegTestCase {
|
50 | 57 |
|
51 | 58 | protected static final String INDEX_NAME = "test-idx-1";
|
| 59 | + protected static final String INDEX_NAME_2 = "test-idx-2"; |
52 | 60 | protected static final int NUM_DOCS_IN_BULK = 1000;
|
53 | 61 |
|
54 | 62 | /*
|
@@ -103,6 +111,7 @@ public void testWritableWarmFeatureFlagDisabled() {
|
103 | 111 | }
|
104 | 112 |
|
105 | 113 | public void testWritableWarmBasic() throws Exception {
|
| 114 | + |
106 | 115 | InternalTestCluster internalTestCluster = internalCluster();
|
107 | 116 | internalTestCluster.startClusterManagerOnlyNode();
|
108 | 117 | internalTestCluster.startDataAndSearchNodes(1);
|
@@ -168,4 +177,82 @@ public void testWritableWarmBasic() throws Exception {
|
168 | 177 | assertAcked(client().admin().indices().delete(new DeleteIndexRequest(INDEX_NAME)).get());
|
169 | 178 | fileCache.prune();
|
170 | 179 | }
|
| 180 | + |
| 181 | + public void testFullFileAndFileCacheStats() throws ExecutionException, InterruptedException { |
| 182 | + |
| 183 | + InternalTestCluster internalTestCluster = internalCluster(); |
| 184 | + internalTestCluster.startClusterManagerOnlyNode(); |
| 185 | + internalTestCluster.startDataAndSearchNodes(1); |
| 186 | + |
| 187 | + Settings settings = Settings.builder() |
| 188 | + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) |
| 189 | + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) |
| 190 | + .put(IndexModule.INDEX_STORE_LOCALITY_SETTING.getKey(), IndexModule.DataLocalityType.PARTIAL.name()) |
| 191 | + .build(); |
| 192 | + |
| 193 | + assertAcked(client().admin().indices().prepareCreate(INDEX_NAME_2).setSettings(settings).get()); |
| 194 | + |
| 195 | + // Verify from the cluster settings if the data locality is partial |
| 196 | + GetIndexResponse getIndexResponse = client().admin() |
| 197 | + .indices() |
| 198 | + .getIndex(new GetIndexRequest().indices(INDEX_NAME_2).includeDefaults(true)) |
| 199 | + .get(); |
| 200 | + |
| 201 | + Settings indexSettings = getIndexResponse.settings().get(INDEX_NAME_2); |
| 202 | + assertEquals(IndexModule.DataLocalityType.PARTIAL.name(), indexSettings.get(IndexModule.INDEX_STORE_LOCALITY_SETTING.getKey())); |
| 203 | + |
| 204 | + // Ingesting docs again before force merge |
| 205 | + indexBulk(INDEX_NAME_2, NUM_DOCS_IN_BULK); |
| 206 | + flushAndRefresh(INDEX_NAME_2); |
| 207 | + |
| 208 | + // ensuring cluster is green |
| 209 | + ensureGreen(); |
| 210 | + |
| 211 | + SearchResponse searchResponse = client().prepareSearch(INDEX_NAME_2).setQuery(QueryBuilders.matchAllQuery()).get(); |
| 212 | + // Asserting that search returns same number of docs as ingested |
| 213 | + assertHitCount(searchResponse, NUM_DOCS_IN_BULK); |
| 214 | + |
| 215 | + // Ingesting docs again before force merge |
| 216 | + indexBulk(INDEX_NAME_2, NUM_DOCS_IN_BULK); |
| 217 | + flushAndRefresh(INDEX_NAME_2); |
| 218 | + |
| 219 | + FileCache fileCache = internalTestCluster.getDataNodeInstance(Node.class).fileCache(); |
| 220 | + |
| 221 | + // TODO: Make these validation more robust. |
| 222 | + |
| 223 | + NodesStatsResponse nodesStatsResponse = client().admin().cluster().nodesStats(new NodesStatsRequest().all()).actionGet(); |
| 224 | + |
| 225 | + FileCacheStats fileCacheStats = nodesStatsResponse.getNodes().getFirst().getFileCacheStats(); |
| 226 | + FullFileCacheStats fullFileCacheStats = fileCacheStats.fullFileCacheStats(); |
| 227 | + |
| 228 | + if (Objects.isNull(fileCacheStats)) { |
| 229 | + fail("File Cache Stats should not be null"); |
| 230 | + } |
| 231 | + |
| 232 | + if (Objects.isNull(fullFileCacheStats)) { |
| 233 | + fail("Full File Cache Stats should not be null"); |
| 234 | + } |
| 235 | + |
| 236 | + // Deleting the index (so that ref count drops to zero for all the files) and then pruning the cache to clear it to avoid any file |
| 237 | + // leaks |
| 238 | + assertAcked(client().admin().indices().delete(new DeleteIndexRequest(INDEX_NAME_2)).get()); |
| 239 | + fileCache.prune(); |
| 240 | + |
| 241 | + NodesStatsResponse response = client().admin().cluster().nodesStats(new NodesStatsRequest().all()).actionGet(); |
| 242 | + int nonEmptyFileCacheNodes = 0; |
| 243 | + for (NodeStats stats : response.getNodes()) { |
| 244 | + FileCacheStats fcStats = stats.getFileCacheStats(); |
| 245 | + if (!Objects.isNull(fcStats)) { |
| 246 | + if (!isFileCacheEmpty(fcStats)) { |
| 247 | + nonEmptyFileCacheNodes++; |
| 248 | + } |
| 249 | + } |
| 250 | + } |
| 251 | + assertEquals(0, nonEmptyFileCacheNodes); |
| 252 | + |
| 253 | + } |
| 254 | + |
| 255 | + private boolean isFileCacheEmpty(FileCacheStats stats) { |
| 256 | + return stats.getUsed().getBytes() == 0L && stats.getActive().getBytes() == 0L; |
| 257 | + } |
171 | 258 | }
|
0 commit comments