http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsNewLineDelimiterRecordResolverSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsNewLineDelimiterRecordResolverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsNewLineDelimiterRecordResolverSelfTest.java deleted file mode 100644 index 5b635f6..0000000 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsNewLineDelimiterRecordResolverSelfTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.ignite.internal.processors.fs.split; - -import org.apache.ignite.igfs.*; -import org.apache.ignite.igfs.mapreduce.*; -import org.apache.ignite.igfs.mapreduce.records.*; -import org.apache.ignite.internal.util.typedef.*; - -import static org.apache.ignite.igfs.mapreduce.records.IgfsNewLineRecordResolver.*; - -/** - * New line split resolver self test. - */ -public class IgfsNewLineDelimiterRecordResolverSelfTest extends IgfsAbstractRecordResolverSelfTest { - /** - * Test new line delimtier record resovler. - * - * @throws Exception If failed. - */ - public void test() throws Exception{ - byte[] data = array(F.t(wrap(1), 8), F.t(wrap(SYM_LF), 1), F.t(wrap(1), 8), F.t(wrap(SYM_CR, SYM_LF), 1), - F.t(wrap(1), 8)); - - assertSplit(0, 4, 0, 9, data); - assertSplit(0, 9, 0, 9, data); - assertSplit(0, 13, 0, 19, data); - assertSplit(0, 19, 0, 19, data); - assertSplit(0, 23, 0, 27, data); - assertSplit(0, 27, 0, 27, data); - - assertSplitNull(2, 2, data); - assertSplitNull(2, 7, data); - assertSplit(2, 11, 9, 10, data); - assertSplit(2, 17, 9, 10, data); - assertSplit(2, 21, 9, 18, data); - assertSplit(2, 25, 9, 18, data); - - assertSplit(9, 4, 9, 10, data); - assertSplit(9, 10, 9, 10, data); - assertSplit(9, 14, 9, 18, data); - assertSplit(9, 18, 9, 18, data); - - assertSplitNull(11, 2, data); - assertSplitNull(11, 8, data); - assertSplit(11, 12, 19, 8, data); - assertSplit(11, 16, 19, 8, data); - - assertSplit(19, 4, 19, 8, data); - assertSplit(19, 8, 19, 8, data); - - assertSplitNull(21, 2, data); - assertSplitNull(21, 6, data); - } - - /** - * Check split resolution. - * - * @param suggestedStart Suggested start. - * @param suggestedLen Suggested length. - * @param expStart Expected start. - * @param expLen Expected length. - * @param data File data. - * @throws Exception If failed. - */ - public void assertSplit(long suggestedStart, long suggestedLen, long expStart, long expLen, byte[] data) - throws Exception { - write(data); - - IgfsNewLineRecordResolver rslvr = resolver(); - - IgfsFileRange split; - - try (IgfsInputStream is = read()) { - split = rslvr.resolveRecords(ggfs, is, split(suggestedStart, suggestedLen)); - } - - assert split != null : "Split is null."; - assert split.start() == expStart : "Incorrect start [expected=" + expStart + ", actual=" + split.start() + ']'; - assert split.length() == expLen : "Incorrect length [expected=" + expLen + ", actual=" + split.length() + ']'; - } - - /** - * Check the split resolution resulted in {@code null}. - * - * @param suggestedStart Suggested start. - * @param suggestedLen Suggested length. - * @param data File data. - * @throws Exception If failed. - */ - public void assertSplitNull(long suggestedStart, long suggestedLen, byte[] data) - throws Exception { - write(data); - - IgfsNewLineRecordResolver rslvr = resolver(); - - IgfsFileRange split; - - try (IgfsInputStream is = read()) { - split = rslvr.resolveRecords(ggfs, is, split(suggestedStart, suggestedLen)); - } - - assert split == null : "Split is not null."; - } - - /** - * Create resolver. - * - * @return Resolver. - */ - private IgfsNewLineRecordResolver resolver() { - return IgfsNewLineRecordResolver.NEW_LINE; - } -}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsStringDelimiterRecordResolverSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsStringDelimiterRecordResolverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsStringDelimiterRecordResolverSelfTest.java deleted file mode 100644 index 757229c..0000000 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/fs/split/IgfsStringDelimiterRecordResolverSelfTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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.ignite.internal.processors.fs.split; - -import org.apache.ignite.igfs.*; -import org.apache.ignite.igfs.mapreduce.*; -import org.apache.ignite.igfs.mapreduce.records.*; -import org.apache.ignite.internal.util.typedef.*; - -import java.nio.charset.*; - -/** - * String delimiter split resolver self-test. - */ -public class IgfsStringDelimiterRecordResolverSelfTest extends IgfsAbstractRecordResolverSelfTest { - /** Charset used in tests. */ - private static final Charset UTF8 = Charset.forName("UTF-8"); - - /** - * Test split resolver. - * - * @throws Exception If failed. - */ - public void testResolver() throws Exception { - String delim = "aaaaaaaa"; - - byte[] delimBytes = delim.getBytes(UTF8); - byte[] data = array(F.t(wrap(1), 8), F.t(delimBytes, 1), F.t(wrap(1), 8)); - - assertSplit(0, 4, 0, 16, data, delim); - assertSplit(0, 8, 0, 16, data, delim); - assertSplit(0, 12, 0, 16, data, delim); - assertSplit(0, 16, 0, 16, data, delim); - assertSplit(0, 20, 0, 24, data, delim); - assertSplit(0, 24, 0, 24, data, delim); - - assertSplitNull(2, 2, data, delim); - assertSplitNull(2, 6, data, delim); - assertSplitNull(2, 10, data, delim); - assertSplitNull(2, 14, data, delim); - assertSplit(2, 18, 16, 8, data, delim); - assertSplit(2, 22, 16, 8, data, delim); - - assertSplitNull(8, 4, data, delim); - assertSplitNull(8, 8, data, delim); - assertSplit(8, 12, 16, 8, data, delim); - assertSplit(8, 16, 16, 8, data, delim); - - assertSplitNull(10, 2, data, delim); - assertSplitNull(10, 6, data, delim); - assertSplit(10, 10, 16, 8, data, delim); - assertSplit(10, 14, 16, 8, data, delim); - - assertSplit(16, 4, 16, 8, data, delim); - assertSplit(16, 8, 16, 8, data, delim); - - assertSplitNull(18, 2, data, delim); - assertSplitNull(18, 6, data, delim); - } - - /** - * Check split resolution. - * - * @param suggestedStart Suggested start. - * @param suggestedLen Suggested length. - * @param expStart Expected start. - * @param expLen Expected length. - * @param data File data. - * @param delims Delimiters. - * @throws Exception If failed. - */ - public void assertSplit(long suggestedStart, long suggestedLen, long expStart, long expLen, byte[] data, - String... delims) throws Exception { - write(data); - - IgfsByteDelimiterRecordResolver rslvr = resolver(delims); - - IgfsFileRange split; - - try (IgfsInputStream is = read()) { - split = rslvr.resolveRecords(ggfs, is, split(suggestedStart, suggestedLen)); - } - - assert split != null : "Split is null."; - assert split.start() == expStart : "Incorrect start [expected=" + expStart + ", actual=" + split.start() + ']'; - assert split.length() == expLen : "Incorrect length [expected=" + expLen + ", actual=" + split.length() + ']'; - } - - /** - * Check the split resolution resulted in {@code null}. - * - * @param suggestedStart Suggested start. - * @param suggestedLen Suggested length. - * @param data File data. - * @param delims Delimiters. - * @throws Exception If failed. - */ - public void assertSplitNull(long suggestedStart, long suggestedLen, byte[] data, String... delims) - throws Exception { - write(data); - - IgfsStringDelimiterRecordResolver rslvr = resolver(delims); - - IgfsFileRange split; - - try (IgfsInputStream is = read()) { - split = rslvr.resolveRecords(ggfs, is, split(suggestedStart, suggestedLen)); - } - - assert split == null : "Split is not null."; - } - - /** - * Create resolver. - * - * @param delims Delimiters. - * @return Resolver. - */ - private IgfsStringDelimiterRecordResolver resolver(String... delims) { - return new IgfsStringDelimiterRecordResolver(UTF8, delims); - } -} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/GridCacheIgfsPerBlockLruEvictionPolicySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/GridCacheIgfsPerBlockLruEvictionPolicySelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/GridCacheIgfsPerBlockLruEvictionPolicySelfTest.java new file mode 100644 index 0000000..9e31ba8 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/GridCacheIgfsPerBlockLruEvictionPolicySelfTest.java @@ -0,0 +1,485 @@ +/* + * 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.ignite.internal.processors.igfs; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.ignitefs.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.igfs.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.processors.cache.*; +import org.apache.ignite.internal.util.lang.*; +import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.apache.ignite.testframework.*; + +import java.util.*; +import java.util.concurrent.*; + +import static org.apache.ignite.cache.CacheAtomicityMode.*; +import static org.apache.ignite.cache.CacheMode.*; +import static org.apache.ignite.igfs.IgfsMode.*; + +/** + * Tests for GGFS per-block LR eviction policy. + */ +@SuppressWarnings({"ConstantConditions", "ThrowableResultOfMethodCallIgnored"}) +public class GridCacheIgfsPerBlockLruEvictionPolicySelfTest extends IgfsCommonAbstractTest { + /** Primary GGFS name. */ + private static final String GGFS_PRIMARY = "ggfs-primary"; + + /** Primary GGFS name. */ + private static final String GGFS_SECONDARY = "ggfs-secondary"; + + /** Secondary file system REST endpoint configuration map. */ + private static final Map<String, String> SECONDARY_REST_CFG = new HashMap<String, String>() {{ + put("type", "tcp"); + put("port", "11500"); + }}; + + /** File working in PRIMARY mode. */ + public static final IgfsPath FILE = new IgfsPath("/file"); + + /** File working in DUAL mode. */ + public static final IgfsPath FILE_RMT = new IgfsPath("/fileRemote"); + + /** Primary GGFS instances. */ + private static IgfsImpl ggfsPrimary; + + /** Secondary GGFS instance. */ + private static IgniteFs secondaryFs; + + /** Primary file system data cache. */ + private static GridCacheAdapter<IgfsBlockKey, byte[]> dataCache; + + /** Eviction policy */ + private static CacheIgfsPerBlockLruEvictionPolicy evictPlc; + + /** + * Start a grid with the primary file system. + * + * @throws Exception If failed. + */ + private void startPrimary() throws Exception { + IgfsConfiguration ggfsCfg = new IgfsConfiguration(); + + ggfsCfg.setDataCacheName("dataCache"); + ggfsCfg.setMetaCacheName("metaCache"); + ggfsCfg.setName(GGFS_PRIMARY); + ggfsCfg.setBlockSize(512); + ggfsCfg.setDefaultMode(PRIMARY); + ggfsCfg.setPrefetchBlocks(1); + ggfsCfg.setSequentialReadsBeforePrefetch(Integer.MAX_VALUE); + ggfsCfg.setSecondaryFileSystem(secondaryFs); + + Map<String, IgfsMode> pathModes = new HashMap<>(); + + pathModes.put(FILE_RMT.toString(), DUAL_SYNC); + + ggfsCfg.setPathModes(pathModes); + + CacheConfiguration dataCacheCfg = defaultCacheConfiguration(); + + dataCacheCfg.setName("dataCache"); + dataCacheCfg.setCacheMode(PARTITIONED); + dataCacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY); + dataCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); + dataCacheCfg.setAtomicityMode(TRANSACTIONAL); + + evictPlc = new CacheIgfsPerBlockLruEvictionPolicy(); + + dataCacheCfg.setEvictionPolicy(evictPlc); + dataCacheCfg.setAffinityMapper(new IgfsGroupDataBlocksKeyMapper(128)); + dataCacheCfg.setBackups(0); + dataCacheCfg.setQueryIndexEnabled(false); + + CacheConfiguration metaCacheCfg = defaultCacheConfiguration(); + + metaCacheCfg.setName("metaCache"); + metaCacheCfg.setCacheMode(REPLICATED); + metaCacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY); + metaCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); + metaCacheCfg.setQueryIndexEnabled(false); + metaCacheCfg.setAtomicityMode(TRANSACTIONAL); + + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setGridName("grid-primary"); + + TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); + + discoSpi.setIpFinder(new TcpDiscoveryVmIpFinder(true)); + + cfg.setDiscoverySpi(discoSpi); + cfg.setCacheConfiguration(dataCacheCfg, metaCacheCfg); + cfg.setGgfsConfiguration(ggfsCfg); + + cfg.setLocalHost("127.0.0.1"); + cfg.setConnectorConfiguration(null); + + Ignite g = G.start(cfg); + + ggfsPrimary = (IgfsImpl)g.fileSystem(GGFS_PRIMARY); + + dataCache = ggfsPrimary.context().kernalContext().cache().internalCache( + ggfsPrimary.context().configuration().getDataCacheName()); + } + + /** + * Start a grid with the secondary file system. + * + * @throws Exception If failed. + */ + private void startSecondary() throws Exception { + IgfsConfiguration ggfsCfg = new IgfsConfiguration(); + + ggfsCfg.setDataCacheName("dataCache"); + ggfsCfg.setMetaCacheName("metaCache"); + ggfsCfg.setName(GGFS_SECONDARY); + ggfsCfg.setBlockSize(512); + ggfsCfg.setDefaultMode(PRIMARY); + ggfsCfg.setIpcEndpointConfiguration(SECONDARY_REST_CFG); + + CacheConfiguration dataCacheCfg = defaultCacheConfiguration(); + + dataCacheCfg.setName("dataCache"); + dataCacheCfg.setCacheMode(PARTITIONED); + dataCacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY); + dataCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); + dataCacheCfg.setAffinityMapper(new IgfsGroupDataBlocksKeyMapper(128)); + dataCacheCfg.setBackups(0); + dataCacheCfg.setQueryIndexEnabled(false); + dataCacheCfg.setAtomicityMode(TRANSACTIONAL); + + CacheConfiguration metaCacheCfg = defaultCacheConfiguration(); + + metaCacheCfg.setName("metaCache"); + metaCacheCfg.setCacheMode(REPLICATED); + metaCacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY); + metaCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); + metaCacheCfg.setQueryIndexEnabled(false); + metaCacheCfg.setAtomicityMode(TRANSACTIONAL); + + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setGridName("grid-secondary"); + + TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); + + discoSpi.setIpFinder(new TcpDiscoveryVmIpFinder(true)); + + cfg.setDiscoverySpi(discoSpi); + cfg.setCacheConfiguration(dataCacheCfg, metaCacheCfg); + cfg.setGgfsConfiguration(ggfsCfg); + + cfg.setLocalHost("127.0.0.1"); + cfg.setConnectorConfiguration(null); + + Ignite g = G.start(cfg); + + secondaryFs = g.fileSystem(GGFS_SECONDARY); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + try { + // Cleanup. + ggfsPrimary.format(); + + while (!dataCache.isEmpty()) + U.sleep(100); + + checkEvictionPolicy(0, 0); + } + finally { + stopAllGrids(false); + } + } + + /** + * Startup primary and secondary file systems. + * + * @throws Exception If failed. + */ + private void start() throws Exception { + startSecondary(); + startPrimary(); + + evictPlc.setMaxBlocks(0); + evictPlc.setMaxSize(0); + evictPlc.setExcludePaths(null); + } + + /** + * Test how evictions are handled for a file working in PRIMARY mode. + * + * @throws Exception If failed. + */ + public void testFilePrimary() throws Exception { + start(); + + // Create file in primary mode. It must not be propagated to eviction policy. + ggfsPrimary.create(FILE, true).close(); + + checkEvictionPolicy(0, 0); + + int blockSize = ggfsPrimary.info(FILE).blockSize(); + + append(FILE, blockSize); + + checkEvictionPolicy(0, 0); + + read(FILE, 0, blockSize); + + checkEvictionPolicy(0, 0); + } + + /** + * Test how evictions are handled for a file working in PRIMARY mode. + * + * @throws Exception If failed. + */ + public void testFileDual() throws Exception { + start(); + + ggfsPrimary.create(FILE_RMT, true).close(); + + checkEvictionPolicy(0, 0); + + int blockSize = ggfsPrimary.info(FILE_RMT).blockSize(); + + // File write. + append(FILE_RMT, blockSize); + + checkEvictionPolicy(1, blockSize); + + // One more write. + append(FILE_RMT, blockSize); + + checkEvictionPolicy(2, blockSize * 2); + + // Read. + read(FILE_RMT, 0, blockSize); + + checkEvictionPolicy(2, blockSize * 2); + } + + /** + * Ensure that a DUAL mode file is not propagated to eviction policy + * + * @throws Exception If failed. + */ + public void testFileDualExclusion() throws Exception { + start(); + + evictPlc.setExcludePaths(Collections.singleton(FILE_RMT.toString())); + + // Create file in primary mode. It must not be propagated to eviction policy. + ggfsPrimary.create(FILE_RMT, true).close(); + + checkEvictionPolicy(0, 0); + + int blockSize = ggfsPrimary.info(FILE_RMT).blockSize(); + + append(FILE_RMT, blockSize); + + checkEvictionPolicy(0, 0); + + read(FILE_RMT, 0, blockSize); + + checkEvictionPolicy(0, 0); + } + + /** + * Ensure that exception is thrown in case we are trying to rename file with one exclude setting to the file with + * another. + * + * @throws Exception If failed. + */ + public void testRenameDifferentExcludeSettings() throws Exception { + start(); + + GridTestUtils.assertThrows(log, new Callable<Object>() { + @Override public Object call() throws Exception { + ggfsPrimary.rename(FILE, FILE_RMT); + + return null; + } + }, IgfsInvalidPathException.class, "Cannot move file to a path with different eviction exclude setting " + + "(need to copy and remove)"); + + GridTestUtils.assertThrows(log, new Callable<Object>() { + @Override public Object call() throws Exception { + ggfsPrimary.rename(FILE_RMT, FILE); + + return null; + } + }, IgfsInvalidPathException.class, "Cannot move file to a path with different eviction exclude setting " + + "(need to copy and remove)"); + } + + /** + * Test eviction caused by too much blocks. + * + * @throws Exception If failed. + */ + public void testBlockCountEviction() throws Exception { + start(); + + int blockCnt = 3; + + evictPlc.setMaxBlocks(blockCnt); + + ggfsPrimary.create(FILE_RMT, true).close(); + + checkEvictionPolicy(0, 0); + + int blockSize = ggfsPrimary.info(FILE_RMT).blockSize(); + + // Write blocks up to the limit. + append(FILE_RMT, blockSize * blockCnt); + + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Write one more block what should cause eviction. + append(FILE_RMT, blockSize); + + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Read the first block. + read(FILE_RMT, 0, blockSize); + + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + checkMetrics(1, 1); + } + + /** + * Test eviction caused by too big data size. + * + * @throws Exception If failed. + */ + public void testDataSizeEviction() throws Exception { + start(); + + ggfsPrimary.create(FILE_RMT, true).close(); + + int blockCnt = 3; + int blockSize = ggfsPrimary.info(FILE_RMT).blockSize(); + + evictPlc.setMaxSize(blockSize * blockCnt); + + // Write blocks up to the limit. + append(FILE_RMT, blockSize * blockCnt); + + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Reset metrics. + ggfsPrimary.resetMetrics(); + + // Read the first block what should cause reordering. + read(FILE_RMT, 0, blockSize); + + checkMetrics(1, 0); + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Write one more block what should cause eviction of the block 2. + append(FILE_RMT, blockSize); + + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Read the first block. + read(FILE_RMT, 0, blockSize); + + checkMetrics(2, 0); + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + + // Read the second block (which was evicted). + read(FILE_RMT, blockSize, blockSize); + + checkMetrics(3, 1); + checkEvictionPolicy(blockCnt, blockCnt * blockSize); + } + + /** + * Read some data from the given file with the given offset. + * + * @param path File path. + * @param off Offset. + * @param len Length. + * @throws Exception If failed. + */ + private void read(IgfsPath path, int off, int len) throws Exception { + IgfsInputStream is = ggfsPrimary.open(path); + + is.readFully(off, new byte[len]); + + is.close(); + } + + /** + * Append some data to the given file. + * + * @param path File path. + * @param len Data length. + * @throws Exception If failed. + */ + private void append(IgfsPath path, int len) throws Exception { + IgfsOutputStream os = ggfsPrimary.append(path, false); + + os.write(new byte[len]); + + os.close(); + } + + /** + * Check metrics counters. + * + * @param blocksRead Expected blocks read. + * @param blocksReadRmt Expected blocks read remote. + * @throws Exception If failed. + */ + public void checkMetrics(final long blocksRead, final long blocksReadRmt) throws Exception { + assert GridTestUtils.waitForCondition(new GridAbsPredicate() { + @Override public boolean apply() { + IgfsMetrics metrics = ggfsPrimary.metrics(); + + return metrics.blocksReadTotal() == blocksRead && metrics.blocksReadRemote() == blocksReadRmt; + } + }, 5000) : "Unexpected metrics [expectedBlocksReadTotal=" + blocksRead + ", actualBlocksReadTotal=" + + ggfsPrimary.metrics().blocksReadTotal() + ", expectedBlocksReadRemote=" + blocksReadRmt + + ", actualBlocksReadRemote=" + ggfsPrimary.metrics().blocksReadRemote() + ']'; + } + + /** + * Check eviction policy state. + * + * @param curBlocks Current blocks. + * @param curBytes Current bytes. + */ + private void checkEvictionPolicy(final int curBlocks, final long curBytes) throws IgniteInterruptedCheckedException { + assert GridTestUtils.waitForCondition(new GridAbsPredicate() { + @Override public boolean apply() { + return evictPlc.getCurrentBlocks() == curBlocks && evictPlc.getCurrentSize() == curBytes; + } + }, 5000) : "Unexpected counts [expectedBlocks=" + curBlocks + ", actualBlocks=" + evictPlc.getCurrentBlocks() + + ", expectedBytes=" + curBytes + ", currentBytes=" + curBytes + ']'; + } +}
