ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [12/52] [abbrv] incubator-ignite git commit: # IGNITE-226: WIP.
Date Fri, 13 Feb 2015 13:14:15 GMT
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsFileMapSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsFileMapSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsFileMapSelfTest.java
new file mode 100644
index 0000000..7328e12
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsFileMapSelfTest.java
@@ -0,0 +1,337 @@
+/*
+ * 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.internal.util.typedef.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.testframework.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import static org.apache.ignite.internal.processors.igfs.IgfsFileAffinityRange.*;
+
+/**
+ * File map self test.
+ */
+public class IgfsFileMapSelfTest extends IgfsCommonAbstractTest {
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRanges() throws Exception {
+        IgfsFileMap map = new IgfsFileMap();
+
+        IgniteUuid[] affKeys = new IgniteUuid[20];
+
+        for (int i = 0; i < affKeys.length; i++)
+            affKeys[i] = IgniteUuid.randomUuid();
+
+        int numOfRanges = 0;
+
+        do {
+            for (int i = 0; i < 2 * numOfRanges + 1; i++) {
+                long off1 = i * 10;
+                long off2 = i * 10 + 5;
+                long off3 = i * 10 + 8;
+
+                IgniteUuid affKey = i % 2 == 0 ? null : affKeys[i / 2];
+
+                assertEquals("For i: " + i, affKey, map.affinityKey(off1, false));
+                assertEquals("For i: " + i, affKey, map.affinityKey(off2, false));
+                assertEquals("For i: " + i, affKey, map.affinityKey(off3, false));
+            }
+
+            map.addRange(new IgfsFileAffinityRange(10 + 20 * numOfRanges, 19 + 20 * numOfRanges,
+                affKeys[numOfRanges]));
+
+            numOfRanges++;
+        } while (numOfRanges < 20);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testAddUpdateAdd() throws Exception {
+        IgfsFileMap map = new IgfsFileMap();
+
+        IgniteUuid affKey = IgniteUuid.randomUuid();
+
+        map.addRange(new IgfsFileAffinityRange(0, 9, affKey));
+
+        map.updateRangeStatus(new IgfsFileAffinityRange(0, 9, affKey), RANGE_STATUS_MOVING);
+
+        map.addRange(new IgfsFileAffinityRange(10, 19, affKey));
+
+        List<IgfsFileAffinityRange> ranges = map.ranges();
+
+        assertEquals(2, ranges.size());
+
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(0).status());
+        assertTrue(ranges.get(0).regionEqual(new IgfsFileAffinityRange(0, 9, affKey)));
+
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(1).status());
+        assertTrue(ranges.get(1).regionEqual(new IgfsFileAffinityRange(10, 19, affKey)));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRangeUpdate1() throws Exception {
+        IgfsFileMap map = new IgfsFileMap();
+
+        IgniteUuid affKey = IgniteUuid.randomUuid();
+
+        for (int i = 0; i < 4; i++)
+            map.addRange(new IgfsFileAffinityRange(i * 20 + 10, i * 20 + 19, affKey));
+
+        // Middle, first, last.
+        map.updateRangeStatus(new IgfsFileAffinityRange(30, 39, affKey), RANGE_STATUS_MOVING);
+        map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey), RANGE_STATUS_MOVING);
+        map.updateRangeStatus(new IgfsFileAffinityRange(70, 79, affKey), RANGE_STATUS_MOVING);
+
+        List<IgfsFileAffinityRange> ranges = map.ranges();
+
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(0).status());
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(1).status());
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(2).status());
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(3).status());
+
+        // Middle, first, last.
+        map.updateRangeStatus(new IgfsFileAffinityRange(30, 39, affKey), RANGE_STATUS_MOVED);
+        map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey), RANGE_STATUS_MOVED);
+        map.updateRangeStatus(new IgfsFileAffinityRange(70, 79, affKey), RANGE_STATUS_MOVED);
+
+        ranges = map.ranges();
+
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(0).status());
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(1).status());
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(2).status());
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(3).status());
+
+        // Middle, first, last.
+        map.deleteRange(new IgfsFileAffinityRange(30, 39, affKey));
+        map.deleteRange(new IgfsFileAffinityRange(10, 19, affKey));
+        map.deleteRange(new IgfsFileAffinityRange(70, 79, affKey));
+
+        ranges = map.ranges();
+
+        assertEquals(1, ranges.size());
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(0).status());
+        assertTrue(ranges.get(0).regionEqual(new IgfsFileAffinityRange(50, 59, affKey)));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRangeUpdate2() throws Exception {
+        IgfsFileMap map = new IgfsFileMap();
+
+        IgniteUuid affKey = IgniteUuid.randomUuid();
+
+        for (int i = 0; i < 4; i++)
+            map.addRange(new IgfsFileAffinityRange(i * 20 + 10, i * 20 + 19, affKey));
+
+        // Middle, first, last.
+        map.updateRangeStatus(new IgfsFileAffinityRange(30, 35, affKey), RANGE_STATUS_MOVING);
+        map.updateRangeStatus(new IgfsFileAffinityRange(10, 15, affKey), RANGE_STATUS_MOVING);
+        map.updateRangeStatus(new IgfsFileAffinityRange(70, 75, affKey), RANGE_STATUS_MOVING);
+
+        List<IgfsFileAffinityRange> ranges = map.ranges();
+
+        assertEquals(7, ranges.size());
+
+        int idx = 0;
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(10, 15, affKey)));
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(16, 19, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(30, 35, affKey)));
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(36, 39, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(50, 59, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(70, 75, affKey)));
+        assertEquals(RANGE_STATUS_MOVING, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(76, 79, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+
+        // Middle, first, last.
+        map.updateRangeStatus(new IgfsFileAffinityRange(30, 35, affKey), RANGE_STATUS_MOVED);
+        map.updateRangeStatus(new IgfsFileAffinityRange(10, 15, affKey), RANGE_STATUS_MOVED);
+        map.updateRangeStatus(new IgfsFileAffinityRange(70, 75, affKey), RANGE_STATUS_MOVED);
+
+        idx = 0;
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(10, 15, affKey)));
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(16, 19, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(30, 35, affKey)));
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(36, 39, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(50, 59, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(70, 75, affKey)));
+        assertEquals(RANGE_STATUS_MOVED, ranges.get(idx).status());
+        idx++;
+
+        assertTrue(ranges.get(idx).regionEqual(new IgfsFileAffinityRange(76, 79, affKey)));
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(idx).status());
+
+        // Middle, first, last.
+        map.deleteRange(new IgfsFileAffinityRange(30, 35, affKey));
+        map.deleteRange(new IgfsFileAffinityRange(10, 15, affKey));
+        map.deleteRange(new IgfsFileAffinityRange(70, 75, affKey));
+
+        ranges = map.ranges();
+
+        assertEquals(4, ranges.size());
+
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(0).status());
+        assertTrue(ranges.get(0).regionEqual(new IgfsFileAffinityRange(16, 19, affKey)));
+
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(1).status());
+        assertTrue(ranges.get(1).regionEqual(new IgfsFileAffinityRange(36, 39, affKey)));
+
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(2).status());
+        assertTrue(ranges.get(2).regionEqual(new IgfsFileAffinityRange(50, 59, affKey)));
+
+        assertEquals(RANGE_STATUS_INITIAL, ranges.get(3).status());
+        assertTrue(ranges.get(3).regionEqual(new IgfsFileAffinityRange(76, 79, affKey)));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testInvalidRangeUpdates() throws Exception {
+        final IgfsFileMap map = new IgfsFileMap();
+
+        final IgniteUuid affKey1 = IgniteUuid.randomUuid();
+        final IgniteUuid affKey2 = IgniteUuid.randomUuid();
+
+        map.addRange(new IgfsFileAffinityRange(10, 19, affKey1));
+        map.addRange(new IgfsFileAffinityRange(30, 39, affKey1));
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                map.updateRangeStatus(new IgfsFileAffinityRange(0, 5, affKey1), RANGE_STATUS_MOVING);
+
+                return null;
+            }
+        }, IgfsInvalidRangeException.class, null);
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                map.updateRangeStatus(new IgfsFileAffinityRange(15, 19, affKey1), RANGE_STATUS_MOVING);
+
+                return null;
+            }
+        }, IgfsInvalidRangeException.class, null);
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                map.updateRangeStatus(new IgfsFileAffinityRange(10, 19, affKey2), RANGE_STATUS_MOVING);
+
+                return null;
+            }
+        }, AssertionError.class, null);
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                map.updateRangeStatus(new IgfsFileAffinityRange(10, 22, affKey1), RANGE_STATUS_MOVING);
+
+                return null;
+            }
+        }, AssertionError.class, null);
+
+        assertEquals(2, map.ranges().size());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testRangeSplit() throws Exception {
+        IgniteUuid affKey = IgniteUuid.randomUuid();
+
+        IgfsFileAffinityRange range = new IgfsFileAffinityRange(0, 9999, affKey);
+
+        Collection<IgfsFileAffinityRange> split = range.split(10000);
+
+        assertEquals(1, split.size());
+        assertTrue(range.regionEqual(F.first(split)));
+
+        split = range.split(5000);
+
+        assertEquals(2, split.size());
+
+        Iterator<IgfsFileAffinityRange> it = split.iterator();
+
+        IgfsFileAffinityRange part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(0, 4999, affKey)));
+
+        part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(5000, 9999, affKey)));
+
+        split = range.split(3000);
+
+        assertEquals(4, split.size());
+
+        it = split.iterator();
+
+        part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(0, 2999, affKey)));
+
+        part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(3000, 5999, affKey)));
+
+        part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(6000, 8999, affKey)));
+
+        part = it.next();
+
+        assertTrue(part.regionEqual(new IgfsFileAffinityRange(9000, 9999, affKey)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsGroupDataBlockKeyMapperHashSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsGroupDataBlockKeyMapperHashSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsGroupDataBlockKeyMapperHashSelfTest.java
new file mode 100644
index 0000000..35e99b2
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsGroupDataBlockKeyMapperHashSelfTest.java
@@ -0,0 +1,136 @@
+/*
+ * 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.igfs.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+
+import java.util.concurrent.*;
+
+/**
+ * Tests for {@link org.apache.ignite.igfs.IgfsGroupDataBlocksKeyMapper} hash.
+ */
+public class IgfsGroupDataBlockKeyMapperHashSelfTest extends IgfsCommonAbstractTest {
+    /**
+     * @throws Exception If failed.
+     */
+    public void testDistribution() throws Exception {
+        for (int i = 0; i < 100; i++) {
+            int grpSize = ThreadLocalRandom.current().nextInt(2, 100000);
+            int partCnt = ThreadLocalRandom.current().nextInt(1, grpSize);
+
+            checkDistribution(grpSize, partCnt);
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testIntOverflowDistribution() throws Exception {
+        for (int i = 0; i < 100; i++)
+            checkIntOverflowDistribution(ThreadLocalRandom.current().nextInt(1, Integer.MAX_VALUE));
+    }
+
+    /**
+     * @param mapper GGFS blocks mapper.
+     * @param fileId GGFS file ID.
+     * @param blockId File block ID.
+     * @param partCnt Total partitions count.
+     * @return Partition index.
+     */
+    private int partition(IgfsGroupDataBlocksKeyMapper mapper, IgniteUuid fileId, long blockId, int partCnt) {
+        return U.safeAbs((Integer) mapper.affinityKey(new IgfsBlockKey(fileId, null, false, blockId)) % partCnt);
+    }
+
+    /**
+     * Check hash code generation for the given group size and partitions count.
+     *
+     * @throws Exception If failed.
+     */
+    public void checkDistribution(int grpSize, int partCnt) throws Exception {
+        IgniteUuid fileId = IgniteUuid.randomUuid();
+
+        IgfsGroupDataBlocksKeyMapper mapper = new IgfsGroupDataBlocksKeyMapper(grpSize);
+
+        int lastPart = 0;
+
+        boolean first = true;
+
+        for (int i = 0; i < 10; i++) {
+            // Ensure that all blocks within the group has the same hash codes.
+            boolean firstInGroup = true;
+
+            for (int j = 0; j < grpSize; j++) {
+                int part = partition(mapper, fileId, i * grpSize + j, partCnt);
+
+                if (firstInGroup) {
+                    if (first)
+                        first = false;
+                    else
+                        assert checkPartition(lastPart, part, partCnt) :
+                            "[fileId = " + fileId + ", i=" + i + ", j=" + j + ", grpSize= " + grpSize +
+                                ", partCnt=" + partCnt + ", lastPart=" + lastPart + ", part=" + part + ']';
+
+                    firstInGroup = false;
+                }
+                else
+                    assert part == lastPart;
+
+                lastPart = part;
+            }
+        }
+    }
+
+    /**
+     * Check distribution for integer overflow.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("NumericOverflow")
+    public void checkIntOverflowDistribution(int partCnt) throws Exception {
+        IgniteUuid fileId = IgniteUuid.randomUuid();
+
+        IgfsGroupDataBlocksKeyMapper mapper = new IgfsGroupDataBlocksKeyMapper(1);
+
+        int part1 = partition(mapper, fileId, Integer.MAX_VALUE - 1, partCnt);
+        int part2 = partition(mapper, fileId, Integer.MAX_VALUE, partCnt);
+        int part3 = partition(mapper, fileId, (long)Integer.MAX_VALUE + 1, partCnt);
+
+        assert checkPartition(part1, part2, partCnt) :
+            "[fileId = " + fileId + "part1=" + part1 + ", part2=" + part2 + ", partCnt=" + partCnt + ']';
+
+        assert checkPartition(part2, part3, partCnt) :
+            "[fileId = " + fileId + "part1=" + part2 + ", part3=" + part3 + ", partCnt=" + partCnt + ']';
+    }
+
+    /**
+     * Check correct partition shift.
+     *
+     * @param prevPart Previous partition.
+     * @param part Current partition.
+     * @param totalParts Total partitions.
+     * @return {@code true} if previous and current partitions have correct values.
+     */
+    private boolean checkPartition(int prevPart, int part, int totalParts) {
+        return U.safeAbs(prevPart - part) == 1 ||
+            (part == 0 && prevPart == totalParts - 1) ||
+            (prevPart == 0 && part == totalParts - 1);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
new file mode 100644
index 0000000..84fdafe
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetaManagerSelfTest.java
@@ -0,0 +1,475 @@
+/*
+ * 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.configuration.*;
+import org.apache.ignite.igfs.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+import org.jetbrains.annotations.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheDistributionMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+import static org.apache.ignite.internal.processors.igfs.IgfsFileInfo.*;
+import static org.apache.ignite.testframework.GridTestUtils.*;
+
+/**
+ * {@link IgfsMetaManager} test case.
+ */
+public class IgfsMetaManagerSelfTest extends IgfsCommonAbstractTest {
+    /** Test IP finder. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Meta-information cache name. */
+    private static final String META_CACHE_NAME = "replicated";
+
+    /** Data cache name. */
+    public static final String DATA_CACHE_NAME = "data";
+
+    /** Test nodes count. */
+    private static final int NODES_CNT = 4;
+
+    /** Meta manager to test. */
+    private IgfsMetaManager mgr;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        IgfsEx ggfs = (IgfsEx)grid(0).fileSystem("ggfs");
+
+        mgr = ggfs.context().meta();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setCacheConfiguration(cacheConfiguration(META_CACHE_NAME), cacheConfiguration(DATA_CACHE_NAME));
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        IgfsConfiguration ggfsCfg = new IgfsConfiguration();
+
+        ggfsCfg.setMetaCacheName(META_CACHE_NAME);
+        ggfsCfg.setDataCacheName(DATA_CACHE_NAME);
+        ggfsCfg.setName("ggfs");
+
+        cfg.setGgfsConfiguration(ggfsCfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    protected CacheConfiguration cacheConfiguration(String cacheName) {
+        CacheConfiguration cacheCfg = defaultCacheConfiguration();
+
+        cacheCfg.setName(cacheName);
+
+        if (META_CACHE_NAME.equals(cacheName))
+            cacheCfg.setCacheMode(REPLICATED);
+        else {
+            cacheCfg.setCacheMode(PARTITIONED);
+            cacheCfg.setDistributionMode(PARTITIONED_ONLY);
+
+            cacheCfg.setBackups(0);
+            cacheCfg.setAffinityMapper(new IgfsGroupDataBlocksKeyMapper(128));
+        }
+
+        cacheCfg.setQueryIndexEnabled(false);
+        cacheCfg.setWriteSynchronizationMode(FULL_SYNC);
+        cacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        return cacheCfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        mgr.igfsCtx.ggfs().format();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startGrids(NODES_CNT);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * Test properties management in meta-cache.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("NullableProblems")
+    public void testUpdateProperties() throws Exception {
+        assertEmpty(mgr.directoryListing(ROOT_ID));
+
+        IgfsFileInfo dir = new IgfsFileInfo(true, null);
+        IgfsFileInfo file = new IgfsFileInfo(new IgfsFileInfo(400, null, false, null), 1);
+
+        assertNull(mgr.putIfAbsent(ROOT_ID, "dir", dir));
+        assertNull(mgr.putIfAbsent(ROOT_ID, "file", file));
+
+        assertEquals(F.asMap("dir", new IgfsListingEntry(dir), "file", new IgfsListingEntry(file)),
+            mgr.directoryListing(ROOT_ID));
+
+        //GridGgfsFileInfo tmp = mgr.info(dir.id());
+
+        assertEquals(dir, mgr.info(dir.id()));
+        assertEquals(file, mgr.info(file.id()));
+
+        for (IgniteBiTuple<IgniteUuid, String> tup: Arrays.asList(F.t(dir.id(), "dir"), F.t(file.id(), "file"))) {
+            IgniteUuid fileId = tup.get1();
+            String fileName = tup.get2();
+
+            for (Map<String, String> props : Arrays.asList(null, Collections.<String, String>emptyMap()))
+                expectsUpdatePropertiesFail(fileId, props, AssertionError.class, "Expects not-empty file's properties");
+
+            String key1 = UUID.randomUUID().toString();
+            String key2 = UUID.randomUUID().toString();
+
+            IgfsFileInfo info = mgr.info(fileId);
+
+            assertNull("Expects empty properties are not stored: " + info, getFieldValue(info, "props"));
+            assertEquals("Expects empty properties are not stored: " + info, Collections.<String, String>emptyMap(),
+                info.properties());
+
+            info = mgr.updateProperties(ROOT_ID, fileId, fileName, F.asMap(key1, "1"));
+
+            assertEquals("Unexpected stored properties: " + info, F.asMap(key1, "1"), info.properties());
+
+            info = mgr.updateProperties(ROOT_ID, fileId, fileName, F.asMap(key2, "2"));
+
+            assertEquals("Unexpected stored properties: " + info, F.asMap(key1, "1", key2, "2"), info.properties());
+
+            info = mgr.updateProperties(ROOT_ID, fileId, fileName, F.<String, String>asMap(key1, null));
+
+            assertEquals("Unexpected stored properties: " + info, F.asMap(key2, "2"), info.properties());
+
+            info = mgr.updateProperties(ROOT_ID, fileId, fileName, F.<String, String>asMap(key2, null));
+
+            assertNull("Expects empty properties are not stored: " + info, getFieldValue(info, "props"));
+            assertEquals("Expects empty properties are not stored: " + info, Collections.<String, String>emptyMap(),
+                info.properties());
+
+            assertNull(mgr.updateProperties(ROOT_ID, fileId, "not_exists", F.<String, String>asMap(key2, null)));
+        }
+
+        mgr.removeIfEmpty(ROOT_ID, "dir", dir.id(), new IgfsPath("/dir"), true);
+        mgr.removeIfEmpty(ROOT_ID, "file", file.id(), new IgfsPath("/file"), true);
+
+        assertNull(mgr.updateProperties(ROOT_ID, dir.id(), "dir", F.asMap("p", "7")));
+        assertNull(mgr.updateProperties(ROOT_ID, file.id(), "file", F.asMap("q", "8")));
+    }
+
+    /**
+     * Test file system structure in meta-cache.
+     *
+     * @throws Exception If failed.
+     */
+    public void testStructure() throws Exception {
+        IgfsFileInfo rootInfo = new IgfsFileInfo();
+        // Test empty structure.
+        assertEmpty(mgr.directoryListing(ROOT_ID));
+        assertEquals(rootInfo, mgr.info(ROOT_ID));
+        assertEquals(F.asMap(ROOT_ID, rootInfo), mgr.infos(Arrays.asList(ROOT_ID)));
+
+        IgfsFileInfo a = new IgfsFileInfo(true, null);
+        IgfsFileInfo b = new IgfsFileInfo(true, null);
+        IgfsFileInfo f1 = new IgfsFileInfo(400, null, false, null);
+        IgfsFileInfo f2 = new IgfsFileInfo(new IgfsFileInfo(400, null, false, null), 0);
+        IgfsFileInfo f3 = new IgfsFileInfo(new IgfsFileInfo(400, null, false, null), 200000L);
+
+        // Validate 'add file' operation.
+        assertNull(mgr.putIfAbsent(ROOT_ID, "a", a));
+        assertNull(mgr.putIfAbsent(ROOT_ID, "f1", f1));
+        assertNull(mgr.putIfAbsent(a.id(), "b", b));
+        assertNull(mgr.putIfAbsent(a.id(), "f2", f2));
+        assertNull(mgr.putIfAbsent(b.id(), "f3", f3));
+
+        assertEquals(b.id(), mgr.putIfAbsent(a.id(), "b", f3));
+        expectsPutIfAbsentFail(a.id(), "c", f3, "Failed to add file details into cache");
+
+        assertEquals(F.asMap("a", new IgfsListingEntry(a), "f1", new IgfsListingEntry(f1)),
+            mgr.directoryListing(ROOT_ID));
+
+        assertEquals(F.asMap("b", new IgfsListingEntry(b), "f2", new IgfsListingEntry(f2)),
+            mgr.directoryListing(a.id()));
+
+        assertEquals(F.asMap("f3", new IgfsListingEntry(f3)), mgr.directoryListing(b.id()));
+
+        // Validate empty files listings.
+        for (IgfsFileInfo info : Arrays.asList(f1, f2, f3)) {
+            assertEmpty(mgr.directoryListing(info.id()));
+        }
+
+        // Validate 'file info' operations.
+        for (IgfsFileInfo info : Arrays.asList(rootInfo, a, b, f1, f2, f3)) {
+            assertEquals(info, mgr.info(info.id()));
+            assertEquals(F.asMap(info.id(), info), mgr.infos(Arrays.asList(info.id())));
+        }
+
+        // Validate 'file ID' operations.
+        assertEquals(ROOT_ID, mgr.fileId(new IgfsPath("/")));
+        assertEquals(a.id(), mgr.fileId(new IgfsPath("/a")));
+        assertEquals(b.id(), mgr.fileId(new IgfsPath("/a/b")));
+        assertEquals(f1.id(), mgr.fileId(new IgfsPath("/f1")));
+        assertEquals(f2.id(), mgr.fileId(new IgfsPath("/a/f2")));
+        assertEquals(f3.id(), mgr.fileId(new IgfsPath("/a/b/f3")));
+        assertNull(mgr.fileId(new IgfsPath("/f4")));
+        assertNull(mgr.fileId(new IgfsPath("/a/f5")));
+        assertNull(mgr.fileId(new IgfsPath("/a/b/f6")));
+
+        assertEquals(a.id(), mgr.fileId(ROOT_ID, "a"));
+        assertEquals(b.id(), mgr.fileId(a.id(), "b"));
+        assertEquals(f1.id(), mgr.fileId(ROOT_ID, "f1"));
+        assertEquals(f2.id(), mgr.fileId(a.id(), "f2"));
+        assertEquals(f3.id(), mgr.fileId(b.id(), "f3"));
+        assertNull(mgr.fileId(ROOT_ID, "f4"));
+        assertNull(mgr.fileId(a.id(), "f5"));
+        assertNull(mgr.fileId(b.id(), "f6"));
+
+        assertEquals(Arrays.asList(ROOT_ID), mgr.fileIds(new IgfsPath("/")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id()), mgr.fileIds(new IgfsPath("/a")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id(), b.id()), mgr.fileIds(new IgfsPath("/a/b")));
+        assertEquals(Arrays.asList(ROOT_ID, f1.id()), mgr.fileIds(new IgfsPath("/f1")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id(), f2.id()), mgr.fileIds(new IgfsPath("/a/f2")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id(), b.id(), f3.id()), mgr.fileIds(new IgfsPath("/a/b/f3")));
+        assertEquals(Arrays.asList(ROOT_ID, null), mgr.fileIds(new IgfsPath("/f4")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id(), null), mgr.fileIds(new IgfsPath("/a/f5")));
+        assertEquals(Arrays.asList(ROOT_ID, a.id(), b.id(), null), mgr.fileIds(new IgfsPath("/a/b/f6")));
+        assertEquals(Arrays.asList(ROOT_ID, null, null, null, null), mgr.fileIds(new IgfsPath("/f7/a/b/f6")));
+
+        // Validate 'rename' operation.
+        final IgniteUuid rndId = IgniteUuid.randomUuid();
+
+        // One of participated files does not exist in cache.
+        expectsRenameFail(ROOT_ID, "b", rndId, "b2", rndId, "Failed to lock source directory (not found?)");
+        expectsRenameFail(b.id(), "b", rndId, "b2", rndId, "Failed to lock source directory (not found?)");
+        expectsRenameFail(ROOT_ID, "b", ROOT_ID, "b2", rndId, "Failed to lock destination directory (not found?)");
+        expectsRenameFail(b.id(), "b", ROOT_ID, "b2", rndId, "Failed to lock destination directory (not found?)");
+        expectsRenameFail(rndId, "b", ROOT_ID, "b2", ROOT_ID, "Failed to lock target file (not found?)");
+        expectsRenameFail(rndId, "b", b.id(), "b2", b.id(), "Failed to lock target file (not found?)");
+
+        // Target file ID differ from the file ID resolved from the source directory for source file name.
+        expectsRenameFail(b.id(), "a", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source directory");
+        expectsRenameFail(f1.id(), "a", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source directory");
+        expectsRenameFail(f2.id(), "a", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source directory");
+        expectsRenameFail(f3.id(), "a", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source directory");
+
+        // Invalid source file name (not found).
+        expectsRenameFail(a.id(), "u1", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source");
+        expectsRenameFail(a.id(), "u2", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source");
+        expectsRenameFail(a.id(), "u3", ROOT_ID, "q", ROOT_ID, "Failed to remove file name from the source");
+
+        // Invalid destination file - already exists.
+        expectsRenameFail(a.id(), "a", ROOT_ID, "f1", ROOT_ID, "Failed to add file name into the destination");
+        expectsRenameFail(f2.id(), "f2", a.id(), "f1", ROOT_ID, "Failed to add file name into the destination");
+        expectsRenameFail(f3.id(), "f3", b.id(), "f1", ROOT_ID, "Failed to add file name into the destination");
+        expectsRenameFail(b.id(), "b", a.id(), "f2", a.id(), "Failed to add file name into the destination");
+
+        System.out.println("/: " + mgr.directoryListing(ROOT_ID));
+        System.out.println("a: " + mgr.directoryListing(a.id()));
+        System.out.println("b: " + mgr.directoryListing(b.id()));
+        System.out.println("f3: " + mgr.directoryListing(f3.id()));
+
+        mgr.move(a.id(), "a", ROOT_ID, "a2", ROOT_ID);
+        mgr.move(b.id(), "b", a.id(), "b2", a.id());
+
+        assertNotNull(mgr.info(b.id()));
+
+        mgr.move(f3.id(), "f3", b.id(), "f3-2", a.id());
+
+        assertNotNull(mgr.info(b.id()));
+
+        mgr.move(f3.id(), "f3-2", a.id(), "f3", b.id());
+        mgr.move(b.id(), "b2", a.id(), "b", a.id());
+        mgr.move(a.id(), "a2", ROOT_ID, "a", ROOT_ID);
+
+        // Validate 'remove' operation.
+        for (int i = 0; i < 100; i++) {
+            // One of participants doesn't exist.
+            assertNull(mgr.removeIfEmpty(ROOT_ID, "a", IgniteUuid.randomUuid(), new IgfsPath("/a"), true));
+            assertNull(mgr.removeIfEmpty(IgniteUuid.randomUuid(), "a", IgniteUuid.randomUuid(),
+                new IgfsPath("/" + IgniteUuid.randomUuid() + "/a"), true));
+        }
+
+        expectsRemoveFail(ROOT_ID, "a", a.id(), new IgfsPath("/a"),
+            "Failed to remove file (directory is not empty)");
+        expectsRemoveFail(a.id(), "b", b.id(), new IgfsPath("/a/b"),
+            "Failed to remove file (directory is not empty)");
+        assertNull(mgr.removeIfEmpty(ROOT_ID, "a", f1.id(), new IgfsPath("/a"), true));
+        assertNull(mgr.removeIfEmpty(a.id(), "b", f1.id(), new IgfsPath("/a/b"), true));
+
+        assertEquals(f3, mgr.removeIfEmpty(b.id(), "f3", f3.id(), new IgfsPath("/a/b/f3"), true));
+
+        assertEquals(F.asMap("a", new IgfsListingEntry(a), "f1", new IgfsListingEntry(f1)),
+            mgr.directoryListing(ROOT_ID));
+
+        assertEquals(F.asMap("b", new IgfsListingEntry(b), "f2", new IgfsListingEntry(f2)),
+            mgr.directoryListing(a.id()));
+
+        assertEmpty(mgr.directoryListing(b.id()));
+
+        assertEquals(b, mgr.removeIfEmpty(a.id(), "b", b.id(), new IgfsPath("/a/b"), true));
+
+        assertEquals(F.asMap("a", new IgfsListingEntry(a), "f1", new IgfsListingEntry(f1)),
+            mgr.directoryListing(ROOT_ID));
+
+        assertEquals(F.asMap("f2", new IgfsListingEntry(f2)), mgr.directoryListing(a.id()));
+
+        assertEmpty(mgr.directoryListing(b.id()));
+
+        // Validate last actual data received from 'remove' operation.
+        IgfsFileInfo newF2 = mgr.updateInfo(f2.id(), new C1<IgfsFileInfo, IgfsFileInfo>() {
+            @Override public IgfsFileInfo apply(IgfsFileInfo e) {
+                return new IgfsFileInfo(e, e.length() + 20);
+            }
+        });
+
+        assertNotNull(newF2);
+        assertEquals(f2.id(), newF2.id());
+        assertNotSame(f2, newF2);
+
+        assertEquals(newF2, mgr.removeIfEmpty(a.id(), "f2", f2.id(), new IgfsPath("/a/f2"), true));
+
+        assertEquals(F.asMap("a", new IgfsListingEntry(a), "f1", new IgfsListingEntry(f1)),
+            mgr.directoryListing(ROOT_ID));
+
+        assertEmpty(mgr.directoryListing(a.id()));
+        assertEmpty(mgr.directoryListing(b.id()));
+
+        assertEquals(f1, mgr.removeIfEmpty(ROOT_ID, "f1", f1.id(), new IgfsPath("/f1"), true));
+
+        assertEquals(F.asMap("a", new IgfsListingEntry(a)), mgr.directoryListing(ROOT_ID));
+
+        assertEmpty(mgr.directoryListing(a.id()));
+        assertEmpty(mgr.directoryListing(b.id()));
+
+        assertEquals(a, mgr.removeIfEmpty(ROOT_ID, "a", a.id(), new IgfsPath("/a"), true));
+
+        assertEmpty(mgr.directoryListing(ROOT_ID));
+        assertEmpty(mgr.directoryListing(a.id()));
+        assertEmpty(mgr.directoryListing(b.id()));
+    }
+
+    /**
+     * Validate passed map is empty.
+     *
+     * @param map Map to validate it is empty.
+     */
+    private void assertEmpty(Map map) {
+        assertEquals(Collections.emptyMap(), map);
+    }
+
+    /**
+     * Test expected failures for 'update properties' operation.
+     *
+     * @param fileId File ID.
+     * @param props File properties to set.
+     * @param msg Failure message if expected exception was not thrown.
+     */
+    private void expectsUpdatePropertiesFail(@Nullable final IgniteUuid fileId, @Nullable final Map<String, String> props,
+        Class<? extends Throwable> cls, @Nullable String msg) {
+        assertThrows(log, new Callable() {
+            @Override
+            public Object call() throws Exception {
+                return mgr.updateProperties(null, fileId, "file", props);
+            }
+        }, cls, msg);
+    }
+
+    /**
+     * Test expected failures for 'add file' operation.
+     *
+     * @param parentId Parent file ID.
+     * @param fileName New file name in the parent's listing.
+     * @param fileInfo New file initial details.
+     * @param msg Failure message if expected exception was not thrown.
+     */
+    private void expectsPutIfAbsentFail(final IgniteUuid parentId, final String fileName, final IgfsFileInfo fileInfo,
+        @Nullable String msg) {
+        Throwable err = assertThrows(log, new Callable() {
+            @Override public Object call() throws Exception {
+                return mgr.putIfAbsent(parentId, fileName, fileInfo);
+            }
+        }, IgniteCheckedException.class, msg);
+
+        assertTrue("Unexpected cause: " + err.getCause(), err.getCause() instanceof IgfsException);
+    }
+
+    /**
+     * Test expected failures for 'move file' operation.
+     *
+     * @param fileId File ID to rename.
+     * @param srcFileName Original file name in the parent's listing.
+     * @param srcParentId Source parent directory ID.
+     * @param destFileName New file name in the parent's listing after renaming.
+     * @param destParentId Destination parent directory ID.
+     * @param msg Failure message if expected exception was not thrown.
+     */
+    private void expectsRenameFail(final IgniteUuid fileId, final String srcFileName, final IgniteUuid srcParentId,
+        final String destFileName, final IgniteUuid destParentId, @Nullable String msg) {
+        Throwable err = assertThrowsInherited(log, new Callable() {
+            @Override
+            public Object call() throws Exception {
+                mgr.move(fileId, srcFileName, srcParentId, destFileName, destParentId);
+
+                return null;
+            }
+        }, IgniteCheckedException.class, msg);
+
+        assertTrue("Unexpected cause: " + err.getCause(), err.getCause() instanceof IgfsException);
+    }
+
+    /**
+     * Test expected failures for 'remove file' operation.
+     *
+     * @param parentId Parent file ID to remove file from.
+     * @param fileName File name in the parent's listing.
+     * @param fileId File ID to remove.
+     * @param path Removed file path.
+     * @param msg Failure message if expected exception was not thrown.
+     */
+    private void expectsRemoveFail(final IgniteUuid parentId, final String fileName, final IgniteUuid fileId,
+        final IgfsPath path, @Nullable String msg) {
+        Throwable err = assertThrows(log, new Callable() {
+            @Nullable @Override public Object call() throws Exception {
+                mgr.removeIfEmpty(parentId, fileName, fileId, path, true);
+
+                return null;
+            }
+        }, IgniteCheckedException.class, msg);
+
+        assertTrue("Unexpected cause: " + err.getCause(), err.getCause() instanceof IgfsDirectoryNotEmptyException);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetricsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetricsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetricsSelfTest.java
new file mode 100644
index 0000000..c383138
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsMetricsSelfTest.java
@@ -0,0 +1,536 @@
+/*
+ * 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.configuration.*;
+import org.apache.ignite.igfs.*;
+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.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+
+import java.util.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+import static org.apache.ignite.igfs.IgfsMode.*;
+
+/**
+ * Test for GGFS metrics.
+ */
+public class IgfsMetricsSelfTest 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");
+    }};
+
+    /** Test nodes count. */
+    private static final int NODES_CNT = 3;
+
+    /** IP finder for the grid with the primary file system. */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** Primary GGFS instances. */
+    private static IgniteFs[] ggfsPrimary;
+
+    /** Secondary GGFS instance. */
+    private static IgniteFs ggfsSecondary;
+
+    /** Primary file system block size. */
+    public static final int PRIMARY_BLOCK_SIZE = 512;
+
+    /** Secondary file system block size. */
+    public static final int SECONDARY_BLOCK_SIZE = 512;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTestsStarted() throws Exception {
+        startSecondary();
+        startPrimary();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTestsStopped() throws Exception {
+        stopAllGrids(false);
+    }
+
+    /**
+     * Start a grid with the primary file system.
+     *
+     * @throws Exception If failed.
+     */
+    private void startPrimary() throws Exception {
+        ggfsPrimary = new IgniteFs[NODES_CNT];
+
+        for (int i = 0; i < NODES_CNT; i++) {
+            Ignite g = G.start(primaryConfiguration(i));
+
+            ggfsPrimary[i] = g.fileSystem(GGFS_PRIMARY);
+        }
+    }
+
+    /**
+     * Get configuration for a grid with the primary file system.
+     *
+     * @param idx Node index.
+     * @return Configuration.
+     * @throws Exception If failed.
+     */
+    private IgniteConfiguration primaryConfiguration(int idx) throws Exception {
+        IgfsConfiguration ggfsCfg = new IgfsConfiguration();
+
+        ggfsCfg.setDataCacheName("dataCache");
+        ggfsCfg.setMetaCacheName("metaCache");
+        ggfsCfg.setName(GGFS_PRIMARY);
+        ggfsCfg.setBlockSize(PRIMARY_BLOCK_SIZE);
+        ggfsCfg.setDefaultMode(PRIMARY);
+        ggfsCfg.setSecondaryFileSystem(ggfsSecondary);
+
+        Map<String, IgfsMode> pathModes = new HashMap<>();
+
+        pathModes.put("/fileRemote", 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.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-" + idx);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+        cfg.setCacheConfiguration(dataCacheCfg, metaCacheCfg);
+        cfg.setGgfsConfiguration(ggfsCfg);
+
+        cfg.setLocalHost("127.0.0.1");
+
+        return cfg;
+    }
+
+    /**
+     * 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(SECONDARY_BLOCK_SIZE);
+        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");
+
+        Ignite g = G.start(cfg);
+
+        ggfsSecondary = g.fileSystem(GGFS_SECONDARY);
+    }
+
+    /** @throws Exception If failed. */
+    public void testMetrics() throws Exception {
+        IgniteFs fs = ggfsPrimary[0];
+
+        assertNotNull(fs);
+
+        IgfsMetrics m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(0, m.directoriesCount());
+        assertEquals(0, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        fs.mkdirs(new IgfsPath("/dir1"));
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(1, m.directoriesCount());
+        assertEquals(0, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        fs.mkdirs(new IgfsPath("/dir1/dir2/dir3"));
+        fs.mkdirs(new IgfsPath("/dir4"));
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(0, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        IgfsOutputStream out1 = fs.create(new IgfsPath("/dir1/file1"), false);
+        IgfsOutputStream out2 = fs.create(new IgfsPath("/dir1/file2"), false);
+        IgfsOutputStream out3 = fs.create(new IgfsPath("/dir1/dir2/file"), false);
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(3, m.filesOpenedForWrite());
+
+        out1.write(new byte[10]);
+        out2.write(new byte[20]);
+        out3.write(new byte[30]);
+
+        out1.close();
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(2, m.filesOpenedForWrite());
+
+        out2.close();
+        out3.close();
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        IgfsOutputStream out = fs.append(new IgfsPath("/dir1/file1"), false);
+
+        out.write(new byte[20]);
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(1, m.filesOpenedForWrite());
+
+        out.write(new byte[20]);
+
+        out.close();
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        IgfsInputStream in1 = fs.open(new IgfsPath("/dir1/file1"));
+        IgfsInputStream in2 = fs.open(new IgfsPath("/dir1/file2"));
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(2, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        in1.close();
+        in2.close();
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(4, m.directoriesCount());
+        assertEquals(3, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        fs.delete(new IgfsPath("/dir1/file1"), false);
+        fs.delete(new IgfsPath("/dir1/dir2"), true);
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(2, m.directoriesCount());
+        assertEquals(1, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+
+        fs.delete(new IgfsPath("/"), true);
+
+        m = fs.metrics();
+
+        assertNotNull(m);
+        assertEquals(0, m.directoriesCount());
+        assertEquals(0, m.filesCount());
+        assertEquals(0, m.filesOpenedForRead());
+        assertEquals(0, m.filesOpenedForWrite());
+    }
+
+    /** @throws Exception If failed. */
+    public void testMultipleClose() throws Exception {
+        IgniteFs fs = ggfsPrimary[0];
+
+        IgfsOutputStream out = fs.create(new IgfsPath("/file"), false);
+
+        out.close();
+        out.close();
+
+        IgfsInputStream in = fs.open(new IgfsPath("/file"));
+
+        in.close();
+        in.close();
+
+        IgfsMetrics m = fs.metrics();
+
+        assertEquals(0, m.filesOpenedForWrite());
+        assertEquals(0, m.filesOpenedForRead());
+    }
+
+    /**
+     * Test block metrics.
+     *
+     * @throws Exception If failed.
+     */
+    public void testBlockMetrics() throws Exception {
+        IgfsEx ggfs = (IgfsEx)ggfsPrimary[0];
+
+        IgfsPath fileRemote = new IgfsPath("/fileRemote");
+        IgfsPath file1 = new IgfsPath("/file1");
+        IgfsPath file2 = new IgfsPath("/file2");
+
+        // Create remote file and write some data to it.
+        IgfsOutputStream out = ggfsSecondary.create(fileRemote, 256, true, null, 1, 256, null);
+
+        int rmtBlockSize = ggfsSecondary.info(fileRemote).blockSize();
+
+        out.write(new byte[rmtBlockSize]);
+        out.close();
+
+        // Start metrics measuring.
+        IgfsMetrics initMetrics = ggfs.metrics();
+
+        // Create empty file.
+        ggfs.create(file1, 256, true, null, 1, 256, null).close();
+
+        int blockSize = ggfs.info(file1).blockSize();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 0, 0, 0, 0, 0, 0);
+
+        // Write two blocks to the file.
+        IgfsOutputStream os = ggfs.append(file1, false);
+        os.write(new byte[blockSize * 2]);
+        os.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 0, 0, 0, 2, 0, blockSize * 2);
+
+        // Write one more file (one block).
+        os = ggfs.create(file2, 256, true, null, 1, 256, null);
+        os.write(new byte[blockSize]);
+        os.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 0, 0, 0, 3, 0, blockSize * 3);
+
+        // Read data from the first file.
+        IgfsInputStreamAdapter is = ggfs.open(file1);
+        is.readFully(0, new byte[blockSize * 2]);
+        is.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 2, 0, blockSize * 2, 3, 0, blockSize * 3);
+
+        // Read data from the second file with hits.
+        is = ggfs.open(file2);
+        is.readChunks(0, blockSize);
+        is.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 3, 0, blockSize * 3, 3, 0, blockSize * 3);
+
+        // Clear the first file.
+        ggfs.create(file1, true).close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 3, 0, blockSize * 3, 3, 0, blockSize * 3);
+
+        // Delete the second file.
+        ggfs.delete(file2, false);
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 3, 0, blockSize * 3, 3, 0, blockSize * 3);
+
+        // Read remote file.
+        is = ggfs.open(fileRemote);
+        is.readChunks(0, rmtBlockSize);
+        is.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 4, 1, blockSize * 3 + rmtBlockSize, 3, 0, blockSize * 3);
+
+        // Lets wait for blocks will be placed to cache
+        U.sleep(300);
+
+        // Read remote file again.
+        is = ggfs.open(fileRemote);
+        is.readChunks(0, rmtBlockSize);
+        is.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 5, 1, blockSize * 3 + rmtBlockSize * 2, 3, 0, blockSize * 3);
+
+        IgfsMetrics metrics = ggfs.metrics();
+
+        assert metrics.secondarySpaceSize() == rmtBlockSize;
+
+        // Write some data to the file working in DUAL mode.
+        os = ggfs.append(fileRemote, false);
+        os.write(new byte[rmtBlockSize]);
+        os.close();
+
+        // Additional block read here due to file ending synchronization.
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 5, 1, blockSize * 3 + rmtBlockSize * 2, 4, 1,
+            blockSize * 3 + rmtBlockSize);
+
+        metrics = ggfs.metrics();
+
+        assert metrics.secondarySpaceSize() == rmtBlockSize * 2;
+
+        ggfs.delete(fileRemote, false);
+
+        U.sleep(300);
+
+        assert ggfs.metrics().secondarySpaceSize() == 0;
+
+        // Write partial block to the first file.
+        os = ggfs.append(file1, false);
+        os.write(new byte[blockSize / 2]);
+        os.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 5, 1, blockSize * 3 + rmtBlockSize * 2, 5, 1,
+            blockSize * 7 / 2 + rmtBlockSize);
+
+        // Now read partial block.
+        // Read remote file again.
+        is = ggfs.open(file1);
+        is.seek(blockSize * 2);
+        is.readChunks(0, blockSize / 2);
+        is.close();
+
+        checkBlockMetrics(initMetrics, ggfs.metrics(), 6, 1, blockSize * 7 / 2 + rmtBlockSize * 2, 5, 1,
+            blockSize * 7 / 2 + rmtBlockSize);
+
+        ggfs.resetMetrics();
+
+        metrics = ggfs.metrics();
+
+        assert metrics.blocksReadTotal() == 0;
+        assert metrics.blocksReadRemote() == 0;
+        assert metrics.blocksWrittenTotal() == 0;
+        assert metrics.blocksWrittenRemote() == 0;
+        assert metrics.bytesRead() == 0;
+        assert metrics.bytesReadTime() == 0;
+        assert metrics.bytesWritten() == 0;
+        assert metrics.bytesWriteTime() == 0;
+    }
+
+    /**
+     * Ensure overall block-related metrics correctness.
+     *
+     * @param initMetrics Initial metrics.
+     * @param metrics Metrics to check.
+     * @param blocksRead Blocks read remote.
+     * @param blocksReadRemote Blocks read remote.
+     * @param bytesRead Bytes read.
+     * @param blocksWrite Blocks write.
+     * @param blocksWriteRemote Blocks write remote.
+     * @param bytesWrite Bytes write.
+     * @throws Exception If failed.
+     */
+    private void checkBlockMetrics(IgfsMetrics initMetrics, IgfsMetrics metrics, long blocksRead,
+        long blocksReadRemote, long bytesRead, long blocksWrite, long blocksWriteRemote, long bytesWrite)
+        throws Exception {
+        assert metrics != null;
+
+        assertEquals(blocksRead, metrics.blocksReadTotal() - initMetrics.blocksReadTotal());
+        assertEquals(blocksReadRemote, metrics.blocksReadRemote() - initMetrics.blocksReadRemote());
+        assertEquals(bytesRead, metrics.bytesRead() - initMetrics.bytesRead());
+
+        assertEquals(blocksWrite, metrics.blocksWrittenTotal() - initMetrics.blocksWrittenTotal());
+        assertEquals(blocksWriteRemote, metrics.blocksWrittenRemote() - initMetrics.blocksWrittenRemote());
+        assertEquals(bytesWrite, metrics.bytesWritten() - initMetrics.bytesWritten());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModeResolverSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModeResolverSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModeResolverSelfTest.java
new file mode 100644
index 0000000..254f2ad
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModeResolverSelfTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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 junit.framework.*;
+import org.apache.ignite.igfs.*;
+import org.apache.ignite.internal.util.typedef.*;
+
+import java.util.*;
+
+import static org.apache.ignite.igfs.IgfsMode.*;
+
+/**
+ *
+ */
+public class IgfsModeResolverSelfTest extends TestCase {
+    /** */
+    private IgfsModeResolver resolver;
+
+    /** {@inheritDoc} */
+    @Override protected void setUp() throws Exception {
+        resolver = new IgfsModeResolver(DUAL_SYNC, Arrays.asList(
+            new T2<>(new IgfsPath("/a/b/"), PRIMARY),
+            new T2<>(new IgfsPath("/a/b/c/d"), PROXY)));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testResolve() throws Exception {
+        assertEquals(DUAL_SYNC, resolver.resolveMode(new IgfsPath("/")));
+        assertEquals(DUAL_SYNC, resolver.resolveMode(new IgfsPath("/a")));
+        assertEquals(DUAL_SYNC, resolver.resolveMode(new IgfsPath("/a/1")));
+        assertEquals(PRIMARY, resolver.resolveMode(new IgfsPath("/a/b")));
+        assertEquals(PRIMARY, resolver.resolveMode(new IgfsPath("/a/b/c")));
+        assertEquals(PRIMARY, resolver.resolveMode(new IgfsPath("/a/b/c/2")));
+        assertEquals(PROXY, resolver.resolveMode(new IgfsPath("/a/b/c/d")));
+        assertEquals(PROXY, resolver.resolveMode(new IgfsPath("/a/b/c/d/e")));
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testResolveChildren() throws Exception {
+        assertEquals(new HashSet<IgfsMode>(){{add(DUAL_SYNC); add(PRIMARY); add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/")));
+        assertEquals(new HashSet<IgfsMode>(){{add(DUAL_SYNC); add(PRIMARY); add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a")));
+        assertEquals(new HashSet<IgfsMode>(){{add(DUAL_SYNC);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/1")));
+        assertEquals(new HashSet<IgfsMode>(){{add(PRIMARY); add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/b")));
+        assertEquals(new HashSet<IgfsMode>(){{add(PRIMARY); add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/b/c")));
+        assertEquals(new HashSet<IgfsMode>(){{add(PRIMARY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/b/c/2")));
+        assertEquals(new HashSet<IgfsMode>(){{add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/b/c/d")));
+        assertEquals(new HashSet<IgfsMode>(){{add(PROXY);}},
+            resolver.resolveChildrenModes(new IgfsPath("/a/b/c/d/e")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java
new file mode 100644
index 0000000..3904766
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsModesSelfTest.java
@@ -0,0 +1,604 @@
+/*
+ * 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.configuration.*;
+import org.apache.ignite.igfs.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.util.typedef.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.lang.*;
+import org.apache.ignite.spi.discovery.tcp.*;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*;
+
+import java.util.*;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheMode.*;
+import static org.apache.ignite.igfs.IgfsMode.*;
+
+/**
+ * GGFS modes self test.
+ */
+public class IgfsModesSelfTest extends IgfsCommonAbstractTest {
+    /** Grid instance hosting primary GGFS. */
+    private IgniteEx grid;
+
+    /** Primary GGFS. */
+    private IgfsImpl ggfs;
+
+    /** Secondary GGFS. */
+    private IgfsImpl ggfsSecondary;
+
+    /** Default GGFS mode. */
+    private IgfsMode mode;
+
+    /** Modes map. */
+    private Map<String, IgfsMode> pathModes;
+
+    /** Whether to set "null" mode. */
+    private boolean setNullMode;
+
+    /** Whether to set secondary file system URI. */
+    private boolean setSecondaryFs;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        mode = null;
+        pathModes = null;
+
+        setNullMode = false;
+        setSecondaryFs = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        G.stopAll(true);
+    }
+
+    /**
+     * Perform initial startup.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("NullableProblems")
+    private void startUp() throws Exception {
+        startUpSecondary();
+
+        IgfsConfiguration ggfsCfg = new IgfsConfiguration();
+
+        ggfsCfg.setDataCacheName("partitioned");
+        ggfsCfg.setMetaCacheName("replicated");
+        ggfsCfg.setName("ggfs");
+        ggfsCfg.setBlockSize(512 * 1024);
+
+        if (setNullMode)
+            ggfsCfg.setDefaultMode(null);
+        else if (mode != null)
+            ggfsCfg.setDefaultMode(mode);
+
+        ggfsCfg.setPathModes(pathModes);
+
+        if (setSecondaryFs)
+            ggfsCfg.setSecondaryFileSystem(ggfsSecondary);
+
+        CacheConfiguration cacheCfg = defaultCacheConfiguration();
+
+        cacheCfg.setName("partitioned");
+        cacheCfg.setCacheMode(PARTITIONED);
+        cacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY);
+        cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        cacheCfg.setAffinityMapper(new IgfsGroupDataBlocksKeyMapper(128));
+        cacheCfg.setBackups(0);
+        cacheCfg.setQueryIndexEnabled(false);
+        cacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        CacheConfiguration metaCacheCfg = defaultCacheConfiguration();
+
+        metaCacheCfg.setName("replicated");
+        metaCacheCfg.setCacheMode(REPLICATED);
+        metaCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        metaCacheCfg.setQueryIndexEnabled(false);
+        metaCacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setGridName("ggfs-grid");
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+        cfg.setDiscoverySpi(discoSpi);
+        cfg.setCacheConfiguration(metaCacheCfg, cacheCfg);
+        cfg.setGgfsConfiguration(ggfsCfg);
+
+        cfg.setLocalHost("127.0.0.1");
+        cfg.setConnectorConfiguration(null);
+
+        grid = (IgniteEx)G.start(cfg);
+
+        ggfs = (IgfsImpl)grid.fileSystem("ggfs");
+    }
+
+    /**
+     * Startup secondary file system.
+     *
+     * @throws Exception If failed.
+     */
+    private void startUpSecondary() throws Exception {
+        IgfsConfiguration ggfsCfg = new IgfsConfiguration();
+
+        ggfsCfg.setDataCacheName("partitioned");
+        ggfsCfg.setMetaCacheName("replicated");
+        ggfsCfg.setName("ggfs-secondary");
+        ggfsCfg.setBlockSize(512 * 1024);
+        ggfsCfg.setDefaultMode(PRIMARY);
+        ggfsCfg.setIpcEndpointConfiguration(new HashMap<String, String>() {{
+            put("type", "tcp");
+            put("port", "11500");
+        }});
+
+        CacheConfiguration cacheCfg = defaultCacheConfiguration();
+
+        cacheCfg.setName("partitioned");
+        cacheCfg.setCacheMode(PARTITIONED);
+        cacheCfg.setDistributionMode(CacheDistributionMode.PARTITIONED_ONLY);
+        cacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        cacheCfg.setAffinityMapper(new IgfsGroupDataBlocksKeyMapper(128));
+        cacheCfg.setBackups(0);
+        cacheCfg.setQueryIndexEnabled(false);
+        cacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        CacheConfiguration metaCacheCfg = defaultCacheConfiguration();
+
+        metaCacheCfg.setName("replicated");
+        metaCacheCfg.setCacheMode(REPLICATED);
+        metaCacheCfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        metaCacheCfg.setQueryIndexEnabled(false);
+        metaCacheCfg.setAtomicityMode(TRANSACTIONAL);
+
+        IgniteConfiguration cfg = new IgniteConfiguration();
+
+        cfg.setGridName("ggfs-grid-secondary");
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(new TcpDiscoveryVmIpFinder(true));
+
+        cfg.setDiscoverySpi(discoSpi);
+        cfg.setCacheConfiguration(metaCacheCfg, cacheCfg);
+        cfg.setGgfsConfiguration(ggfsCfg);
+
+        cfg.setLocalHost("127.0.0.1");
+        cfg.setConnectorConfiguration(null);
+
+        ggfsSecondary = (IgfsImpl)G.start(cfg).fileSystem("ggfs-secondary");
+    }
+
+    /**
+     * Set GGFS modes for particular paths.
+     *
+     * @param modes Modes.
+     */
+    @SafeVarargs
+    final void pathModes(IgniteBiTuple<String, IgfsMode>... modes) {
+        assert modes != null;
+
+        pathModes = new LinkedHashMap<>(modes.length, 1.0f);
+
+        for (IgniteBiTuple<String, IgfsMode> mode : modes)
+            pathModes.put(mode.getKey(), mode.getValue());
+    }
+
+    /**
+     * Test predefined path modes for PRIMARY mode.
+     *
+     * @throws Exception If failed.
+     */
+    public void testDefaultFoldersPrimary() throws Exception {
+        setSecondaryFs = true;
+
+        mode = DUAL_ASYNC;
+
+        startUp();
+
+        checkMode("/ignite/primary", PRIMARY);
+        checkMode("/ignite/primary/", PRIMARY);
+        checkMode("/ignite/primary/subfolder", PRIMARY);
+        checkMode("/ignite/primary/folder/file.txt", PRIMARY);
+        checkMode("/ignite/primaryx", DUAL_ASYNC);
+        checkMode("/ignite/primaryx/", DUAL_ASYNC);
+        checkMode("/ignite/primaryx/subfolder", DUAL_ASYNC);
+        checkMode("/ignite/primaryx/folder/file.txt", DUAL_ASYNC);
+    }
+
+    /**
+     * Test predefined path modes for all modes except of PRIMARY mode.
+     *
+     * @throws Exception If failed.
+     */
+    public void testDefaultFoldersNonPrimary() throws Exception {
+        setSecondaryFs = true;
+
+        mode = PRIMARY;
+
+        startUp();
+
+        checkMode("/ignite/proxy", PROXY);
+        checkMode("/ignite/proxy/", PROXY);
+        checkMode("/ignite/proxy/subfolder", PROXY);
+        checkMode("/ignite/proxy/folder/file.txt", PROXY);
+        checkMode("/ignite/proxyx", PRIMARY);
+        checkMode("/ignite/proxyx/", PRIMARY);
+        checkMode("/ignite/proxyx/subfolder", PRIMARY);
+        checkMode("/ignite/proxyx/folder/file.txt", PRIMARY);
+
+        checkMode("/userdir/ignite/proxy", PRIMARY);
+        checkMode("/userdir/ignite/proxy/", PRIMARY);
+        checkMode("/userdir/ignite/proxy/subfolder", PRIMARY);
+        checkMode("/userdir/ignite/proxy/folder/file.txt", PRIMARY);
+
+        checkMode("/ignite/sync", DUAL_SYNC);
+        checkMode("/ignite/sync/", DUAL_SYNC);
+        checkMode("/ignite/sync/subfolder", DUAL_SYNC);
+        checkMode("/ignite/sync/folder/file.txt", DUAL_SYNC);
+        checkMode("/ignite/syncx", PRIMARY);
+        checkMode("/ignite/syncx/", PRIMARY);
+        checkMode("/ignite/syncx/subfolder", PRIMARY);
+        checkMode("/ignite/syncx/folder/file.txt", PRIMARY);
+
+        checkMode("/userdir/ignite/sync", PRIMARY);
+        checkMode("/userdir/ignite/sync/", PRIMARY);
+        checkMode("/userdir/ignite/sync/subfolder", PRIMARY);
+        checkMode("/userdir/ignite/sync/folder/file.txt", PRIMARY);
+
+        checkMode("/ignite/async", DUAL_ASYNC);
+        checkMode("/ignite/async/", DUAL_ASYNC);
+        checkMode("/ignite/async/subfolder", DUAL_ASYNC);
+        checkMode("/ignite/async/folder/file.txt", DUAL_ASYNC);
+        checkMode("/ignite/asyncx", PRIMARY);
+        checkMode("/ignite/asyncx/", PRIMARY);
+        checkMode("/ignite/asyncx/subfolder", PRIMARY);
+        checkMode("/ignite/asyncx/folder/file.txt", PRIMARY);
+
+        checkMode("/userdir/ignite/async", PRIMARY);
+        checkMode("/userdir/ignite/async/", PRIMARY);
+        checkMode("/userdir/ignite/async/subfolder", PRIMARY);
+        checkMode("/userdir/ignite/async/folder/file.txt", PRIMARY);
+    }
+
+    /**
+     * Ensure that in case secondary file system URI is not provided, all predefined have no special mappings. This test
+     * doesn't make sense for PRIMARY mode since in case URI is not provided DUAL_* modes automatically transforms to
+     * PRIMARY and for PROXY mode we will have an exception during startup.
+     *
+     * @throws Exception If failed.
+     */
+    public void testDefaultsNoSecondaryUriNonPrimary() throws Exception {
+        startUp();
+
+        checkMode("/ignite/proxy", PRIMARY);
+        checkMode("/ignite/proxy/", PRIMARY);
+        checkMode("/ignite/proxy/subfolder", PRIMARY);
+        checkMode("/ignite/proxy/folder/file.txt", PRIMARY);
+
+        checkMode("/ignite/sync", PRIMARY);
+        checkMode("/ignite/sync/", PRIMARY);
+        checkMode("/ignite/sync/subfolder", PRIMARY);
+        checkMode("/ignite/sync/folder/file.txt", PRIMARY);
+
+        checkMode("/ignite/async", PRIMARY);
+        checkMode("/ignite/async/", PRIMARY);
+        checkMode("/ignite/async/subfolder", PRIMARY);
+        checkMode("/ignite/async/folder/file.txt", PRIMARY);
+    }
+
+    /**
+     * Ensure that it is impossible to override mappings for /ignite/* folders.
+     *
+     * @throws Exception If failed.
+     */
+    public void testDefaultFoldersOverride() throws Exception {
+        setSecondaryFs = true;
+
+        mode = DUAL_ASYNC;
+
+        pathModes(F.t("/ignite/primary", PROXY), F.t("/ignite/proxy", DUAL_SYNC),
+            F.t("/ignite/sync", DUAL_ASYNC), F.t("/ignite/async", PRIMARY));
+
+        startUp();
+
+        checkMode("/ignite/primary", PRIMARY);
+        checkMode("/ignite/proxy", PROXY);
+        checkMode("/ignite/sync", DUAL_SYNC);
+        checkMode("/ignite/async", DUAL_ASYNC);
+    }
+
+    /**
+     * Ensure that DUAL_ASYNC mode is set by default.
+     *
+     * @throws Exception If failed.
+     */
+    public void testModeDefaultIsNotSet() throws Exception {
+        setSecondaryFs = true;
+
+        startUp();
+
+        checkMode("/dir", DUAL_ASYNC);
+    }
+
+    /**
+     * Ensure that when mode is set, it is correctly resolved.
+     *
+     * @throws Exception If failed.
+     */
+    public void testModeDefaultIsSet() throws Exception {
+        mode = DUAL_SYNC;
+
+        setSecondaryFs = true;
+
+        startUp();
+
+        checkMode("/dir", DUAL_SYNC);
+    }
+
+    /**
+     * Ensure that Grid doesn't start in case default mode is SECONDARY and secondary FS URI is not provided.
+     *
+     * @throws Exception If failed.
+     */
+    public void testModeSecondaryNoUri() throws Exception {
+        mode = PROXY;
+
+        String errMsg = null;
+
+        try {
+            startUp();
+        }
+        catch (IgniteException e) {
+            errMsg = e.getCause().getCause().getMessage();
+        }
+
+        assertTrue(errMsg.startsWith(
+            "Grid configuration parameter invalid: secondaryFileSystem cannot be null when mode is SECONDARY"));
+    }
+
+    /**
+     * Ensure that modes are resolved correctly when path modes are set.
+     *
+     * @throws Exception If failed.
+     */
+    public void testPathMode() throws Exception {
+        pathModes(F.t("/dir1", PROXY), F.t("/dir2", DUAL_SYNC),
+            F.t("/dir3", PRIMARY), F.t("/dir4", PRIMARY));
+
+        mode = DUAL_ASYNC;
+
+        setSecondaryFs = true;
+
+        startUp();
+
+        checkMode("/dir", DUAL_ASYNC);
+        checkMode("/dir1", PROXY);
+        checkMode("/dir2", DUAL_SYNC);
+
+        checkMode("/dir3", PRIMARY);
+        checkMode("/somedir/dir3", DUAL_ASYNC);
+
+        checkMode("/dir4", PRIMARY);
+        checkMode("/dir4/subdir", PRIMARY);
+        checkMode("/somedir/dir4", DUAL_ASYNC);
+        checkMode("/somedir/dir4/subdir", DUAL_ASYNC);
+    }
+
+    /**
+     * Ensure that path modes switch to PRIMARY in case secondary FS config is not provided.
+     *
+     * @throws Exception If failed.
+     */
+    public void testPathModeSwitchToPrimary() throws Exception {
+        mode = DUAL_SYNC;
+
+        pathModes(F.t("/dir1", PRIMARY), F.t("/dir2", DUAL_SYNC));
+
+        startUp();
+
+        checkMode("/dir", PRIMARY);
+        checkMode("/dir1", PRIMARY);
+        checkMode("/dir2", PRIMARY);
+    }
+
+    /**
+     * Ensure that Grid doesn't start in case path mode is SECONDARY and secondary FS config path is not provided.
+     *
+     * @throws Exception If failed.
+     */
+    public void testPathModeSecondaryNoCfg() throws Exception {
+        pathModes(F.t("dir", PROXY));
+
+        String errMsg = null;
+
+        try {
+            startUp();
+        }
+        catch (IgniteException e) {
+            errMsg = e.getCause().getCause().getMessage();
+        }
+
+        assertTrue(errMsg.startsWith(
+            "Grid configuration parameter invalid: secondaryFileSystem cannot be null when mode is SECONDARY"));
+    }
+
+    /**
+     * Ensure that data is not propagated to the secondary GGFS in PRIMARY mode.
+     *
+     * @throws Exception If failed.
+     */
+    public void testPropagationPrimary() throws Exception {
+        mode = PRIMARY;
+
+        checkPropagation();
+    }
+
+    /**
+     * Ensure that data is propagated to the secondary GGFS in DUAL_SYNC mode.
+     *
+     * @throws Exception If failed.
+     */
+    public void testPropagationDualSync() throws Exception {
+        mode = DUAL_SYNC;
+
+        checkPropagation();
+    }
+
+    /**
+     * Ensure that data is propagated to the secondary GGFS in DUAL_SYNC mode.
+     *
+     * @throws Exception If failed.
+     */
+    public void _testPropagationDualAsync() throws Exception {
+        mode = DUAL_ASYNC;
+
+        checkPropagation();
+    }
+
+    /**
+     * Resolve GGFS mode for the given path and compare it with expected one.
+     *
+     * @param pathStr Path ot resolve.
+     * @param expMode Expected mode.
+     * @throws Exception If failed.
+     */
+    private void checkMode(String pathStr, IgfsMode expMode) throws Exception {
+        assert ggfs != null;
+
+        IgfsPath path = new IgfsPath(pathStr);
+
+        IgfsModeResolver rslvr = ggfs.modeResolver();
+
+        IgfsMode mode = rslvr.resolveMode(path);
+
+        assertEquals(expMode, mode);
+    }
+
+    /**
+     * Check propagation of various operations to secondary file system.
+     *
+     * @throws Exception If failed.
+     */
+    private void checkPropagation() throws Exception {
+        byte[] testData1 = new byte[] {0, 1, 2, 3, 4, 5, 6, 7};
+        byte[] testData2 = new byte[] {8, 9, 10, 11};
+        byte[] testData = Arrays.copyOf(testData1, testData1.length + testData2.length);
+
+        U.arrayCopy(testData2, 0, testData, testData1.length, testData2.length);
+
+        setSecondaryFs = true;
+
+        startUp();
+
+        boolean primaryNotUsed = mode == PROXY;
+        boolean secondaryUsed = mode != PRIMARY;
+
+        IgfsPath dir = new IgfsPath("/dir");
+        IgfsPath file = new IgfsPath("/dir/file");
+
+        // Create new directory.
+        ggfs.mkdirs(dir);
+
+        // Create new file.
+        IgfsOutputStream os = ggfs.create(file, 1024, true, null, 0, 2048, null);
+
+        os.write(testData1);
+
+        os.close();
+
+        // Re-open it and append.
+        os = ggfs.append(file, 1024, false, null);
+
+        os.write(testData2);
+
+        os.close();
+
+        // Check file content.
+        IgfsInputStream is = ggfs.open(file);
+
+        assertEquals(testData.length, is.length());
+
+        byte[] data = new byte[testData.length];
+
+        is.read(data, 0, testData.length);
+
+        is.close();
+
+        assert Arrays.equals(testData, data);
+
+        if (secondaryUsed) {
+            assert ggfsSecondary.exists(dir);
+            assert ggfsSecondary.exists(file);
+
+            // In ASYNC mode we wait at most 2 seconds for background writer to finish.
+            for (int i = 0; i < 20; i++) {
+                IgfsInputStream isSecondary = null;
+
+                try {
+                    isSecondary = ggfsSecondary.open(file);
+
+                    if (isSecondary.length() == testData.length)
+                        break;
+                    else
+                        U.sleep(100);
+                }
+                finally {
+                    U.closeQuiet(isSecondary);
+                }
+            }
+
+            IgfsInputStream isSecondary = ggfsSecondary.open(file);
+
+            assertEquals(testData.length, isSecondary.length());
+
+            isSecondary.read(data, 0, testData.length);
+
+            assert Arrays.equals(testData, data);
+        }
+        else {
+            assert !ggfsSecondary.exists(dir);
+            assert !ggfsSecondary.exists(file);
+        }
+
+        int cacheSize = grid.cachex("partitioned").size();
+
+        if (primaryNotUsed)
+            assert cacheSize == 0;
+        else
+            assert cacheSize != 0;
+
+        // Now delete all.
+        ggfs.delete(dir, true);
+
+        assert !ggfs.exists(dir);
+        assert !ggfs.exists(file);
+
+        assert !ggfsSecondary.exists(dir);
+        assert !ggfsSecondary.exists(file);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapTieredSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapTieredSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapTieredSelfTest.java
new file mode 100644
index 0000000..b1a6f8f
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapTieredSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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 static org.apache.ignite.cache.CacheMemoryMode.*;
+import static org.apache.ignite.igfs.IgfsMode.*;
+
+/**
+ * Tests for PRIMARY mode and OFFHEAP_TIERED memory.
+ */
+public class IgfsPrimaryOffheapTieredSelfTest extends IgfsAbstractSelfTest {
+    /**
+     * Constructor.
+     */
+    public IgfsPrimaryOffheapTieredSelfTest() {
+        super(PRIMARY, OFFHEAP_TIERED);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/141f8282/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapValuesSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapValuesSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapValuesSelfTest.java
new file mode 100644
index 0000000..172ade1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/igfs/IgfsPrimaryOffheapValuesSelfTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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 static org.apache.ignite.cache.CacheMemoryMode.*;
+import static org.apache.ignite.igfs.IgfsMode.*;
+
+/**
+ * Tests for PRIMARY mode and OFFHEAP_VALUES memory.
+ */
+public class IgfsPrimaryOffheapValuesSelfTest extends IgfsAbstractSelfTest {
+    /**
+     * Constructor.
+     */
+    public IgfsPrimaryOffheapValuesSelfTest() {
+        super(PRIMARY, OFFHEAP_VALUES);
+    }
+}


Mime
View raw message