You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/09/05 04:31:56 UTC

[13/45] ignite git commit: IGNITE-1348: Moved GridGain's .Net module to Ignite.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
new file mode 100644
index 0000000..beb2c0f
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAffinityTest.cs
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cluster;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Portable;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Affinity key tests.
+    /// </summary>
+    public class CacheAffinityTest
+    {
+        /// <summary>
+        ///
+        /// </summary>
+        [TestFixtureSetUp]
+        public virtual void StartGrids()
+        {
+            TestUtils.KillProcesses();
+
+            IgniteConfigurationEx cfg = new IgniteConfigurationEx();
+
+            cfg.JvmClasspath = TestUtils.CreateTestClasspath();
+            cfg.JvmOptions = TestUtils.TestJavaOptions();
+            cfg.SpringConfigUrl = "config\\native-client-test-cache-affinity.xml";
+
+            for (int i = 0; i < 3; i++)
+            {
+                cfg.GridName = "grid-" + i;
+
+                Ignition.Start(cfg);
+            }
+        }
+
+        /// <summary>
+        /// Tear-down routine.
+        /// </summary>
+        [TestFixtureTearDown]
+        public virtual void StopGrids()
+        {
+            for (int i = 0; i < 3; i++)
+                Ignition.Stop("grid-" + i, true);
+        }
+
+        /// <summary>
+        /// Test affinity key.
+        /// </summary>
+        [Test]
+        public void TestAffinity()
+        {
+            IIgnite g = Ignition.GetIgnite("grid-0");
+
+            ICacheAffinity aff = g.Affinity(null);
+
+            IClusterNode node = aff.MapKeyToNode(new AffinityTestKey(0, 1));
+
+            for (int i = 0; i < 10; i++)
+                Assert.AreEqual(node.Id, aff.MapKeyToNode(new AffinityTestKey(i, 1)).Id);
+        }
+
+        /// <summary>
+        /// Test affinity with portable flag.
+        /// </summary>
+        [Test]
+        public void TestAffinityPortable()
+        {
+            IIgnite g = Ignition.GetIgnite("grid-0");
+
+            ICacheAffinity aff = g.Affinity(null);  
+
+            IPortableObject affKey = g.Portables().ToPortable<IPortableObject>(new AffinityTestKey(0, 1));
+
+            IClusterNode node = aff.MapKeyToNode(affKey);
+
+            for (int i = 0; i < 10; i++)
+            {
+                IPortableObject otherAffKey =
+                    g.Portables().ToPortable<IPortableObject>(new AffinityTestKey(i, 1));
+
+                Assert.AreEqual(node.Id, aff.MapKeyToNode(otherAffKey).Id);
+            }
+        }
+
+        /// <summary>
+        /// Affinity key.
+        /// </summary>
+        public class AffinityTestKey
+        {
+            /** ID. */
+            private int _id;
+
+            /** Affinity key. */
+            private int _affKey;
+
+            /// <summary>
+            /// Constructor.
+            /// </summary>
+            /// <param name="id">ID.</param>
+            /// <param name="affKey">Affinity key.</param>
+            public AffinityTestKey(int id, int affKey)
+            {
+                _id = id;
+                _affKey = affKey;
+            }
+
+            /** <inheritdoc /> */
+            public override bool Equals(object obj)
+            {
+                AffinityTestKey other = obj as AffinityTestKey;
+
+                return other != null && _id == other._id;
+            }
+
+            /** <inheritdoc /> */
+            public override int GetHashCode()
+            {
+                return _id;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheDynamicStartTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheDynamicStartTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheDynamicStartTest.cs
new file mode 100644
index 0000000..210d80c
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheDynamicStartTest.cs
@@ -0,0 +1,281 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using System;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Portable;
+    using Apache.Ignite.Core.Tests.Query;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests for dynamic a cache start.
+    /// </summary>
+    public class CacheDynamicStartTest
+    {
+        /** Grid name: data. */
+        private const string GridData = "d";
+
+        /** Grid name: data, no configuration. */
+        private const string GridDataNoCfg = "dnc";
+
+        /** Grid name: client. */
+        private const string GridClient = "c";
+
+        /** Cache name: partitioned, transactional. */
+        private const string CacheTx = "p";
+
+        /** Cache name: atomic. */
+        private const string CacheAtomic = "pa";
+
+        /** Cache name: dummy. */
+        private const string CacheDummy = "dummy";
+        
+        /// <summary>
+        /// Set up routine.
+        /// </summary>
+        [SetUp]
+        public void SetUp()
+        {
+            TestUtils.KillProcesses();
+
+            Ignition.Start(CreateConfiguration(GridData, @"config/dynamic/dynamic-data.xml"));
+            Ignition.Start(CreateConfiguration(GridDataNoCfg, @"config/dynamic/dynamic-data-no-cfg.xml"));
+            Ignition.Start(CreateConfiguration(GridClient, @"config/dynamic/dynamic-client.xml"));
+        }
+
+        /// <summary>
+        /// Tear down routine.
+        /// </summary>
+        [TearDown]
+        public void StopGrids()
+        {
+            Ignition.Stop(GridData, true);
+            Ignition.Stop(GridDataNoCfg, true);
+            Ignition.Stop(GridClient, true);
+        }
+
+        /// <summary>
+        /// Create configuration.
+        /// </summary>
+        /// <param name="name">Grid name.</param>
+        /// <param name="springCfg">Spring configuration.</param>
+        /// <returns>Configuration.</returns>
+        private static IgniteConfigurationEx CreateConfiguration(string name, string springCfg)
+        {
+            IgniteConfigurationEx cfg = new IgniteConfigurationEx();
+
+            PortableConfiguration portCfg = new PortableConfiguration();
+
+            ICollection<PortableTypeConfiguration> portTypeCfgs = new List<PortableTypeConfiguration>();
+
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(DynamicTestKey)));
+            portTypeCfgs.Add(new PortableTypeConfiguration(typeof(DynamicTestValue)));
+
+            portCfg.TypeConfigurations = portTypeCfgs;
+
+            cfg.GridName = name;
+            cfg.PortableConfiguration = portCfg;
+            cfg.JvmClasspath = TestUtils.CreateTestClasspath();
+            cfg.JvmOptions = TestUtils.TestJavaOptions();
+            cfg.SpringConfigUrl = springCfg;
+
+            return cfg;
+        }
+
+        /// <summary>
+        /// Try getting not configured cache.
+        /// </summary>
+        [Test]
+        public void TestNoStarted()
+        {
+            Assert.Throws<ArgumentException>(() =>
+            {
+                Ignition.GetIgnite(GridData).Cache<CacheTestKey, PortablePerson>(CacheDummy);
+            });
+
+            Assert.Throws<ArgumentException>(() =>
+            {
+                Ignition.GetIgnite(GridDataNoCfg).Cache<CacheTestKey, PortablePerson>(CacheDummy);
+            });
+
+            Assert.Throws<ArgumentException>(() =>
+            {
+                Ignition.GetIgnite(GridClient).Cache<CacheTestKey, PortablePerson>(CacheDummy);
+            });
+        }
+
+        /// <summary>
+        /// Test TX cache.
+        /// </summary>
+        [Test]
+        public void TestTransactional()
+        {
+            Check(CacheTx);
+        }
+
+        /// <summary>
+        /// Test ATOMIC cache.
+        /// </summary>
+        [Test]
+        public void TestAtomic()
+        {
+            Check(CacheAtomic);
+        }
+
+        /// <summary>
+        /// Check routine.
+        /// </summary>
+        /// <param name="cacheName">Cache name.</param>
+        private void Check(string cacheName)
+        {
+            ICache<DynamicTestKey, DynamicTestValue> cacheData =
+                Ignition.GetIgnite(GridData).Cache<DynamicTestKey, DynamicTestValue>(cacheName);
+
+            ICache<DynamicTestKey, DynamicTestValue> cacheDataNoCfg =
+                Ignition.GetIgnite(GridDataNoCfg).Cache<DynamicTestKey, DynamicTestValue>(cacheName);
+
+            ICache<DynamicTestKey, DynamicTestValue> cacheClient =
+                Ignition.GetIgnite(GridClient).Cache<DynamicTestKey, DynamicTestValue>(cacheName);
+
+            DynamicTestKey key1 = new DynamicTestKey(1);
+            DynamicTestKey key2 = new DynamicTestKey(2);
+            DynamicTestKey key3 = new DynamicTestKey(3);
+
+            DynamicTestValue val1 = new DynamicTestValue(1);
+            DynamicTestValue val2 = new DynamicTestValue(2);
+            DynamicTestValue val3 = new DynamicTestValue(3);
+
+            cacheData.Put(key1, val1);
+            Assert.AreEqual(val1, cacheData.Get(key1));
+            Assert.AreEqual(val1, cacheDataNoCfg.Get(key1));
+            Assert.AreEqual(val1, cacheClient.Get(key1));
+
+            cacheDataNoCfg.Put(key2, val2);
+            Assert.AreEqual(val2, cacheData.Get(key2));
+            Assert.AreEqual(val2, cacheDataNoCfg.Get(key2));
+            Assert.AreEqual(val2, cacheClient.Get(key2));
+
+            cacheClient.Put(key3, val3);
+            Assert.AreEqual(val3, cacheData.Get(key3));
+            Assert.AreEqual(val3, cacheDataNoCfg.Get(key3));
+            Assert.AreEqual(val3, cacheClient.Get(key3));
+
+            for (int i = 0; i < 10000; i++)
+                cacheClient.Put(new DynamicTestKey(i), new DynamicTestValue(1));
+
+            int sizeClient = cacheClient.LocalSize();
+
+            Assert.AreEqual(0, sizeClient);
+        }
+    }
+
+    /// <summary>
+    /// Key for dynamic cache start tests.
+    /// </summary>
+    class DynamicTestKey
+    {
+        /// <summary>
+        /// Default constructor.
+        /// </summary>
+        public DynamicTestKey()
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="id">ID.</param>
+        public DynamicTestKey(int id)
+        {
+            Id = id;
+        }
+
+        /// <summary>
+        /// ID.
+        /// </summary>
+        public int Id
+        {
+            get;
+            set;
+        }
+
+        /** <inheritdoc /> */
+        public override bool Equals(object obj)
+        {
+            DynamicTestKey other = obj as DynamicTestKey;
+
+            return other != null && Id == other.Id;
+        }
+
+        /** <inheritdoc /> */
+        public override int GetHashCode()
+        {
+            return Id;
+        }
+    }
+
+    /// <summary>
+    /// Value for dynamic cache start tests.
+    /// </summary>
+    class DynamicTestValue
+    {
+        /// <summary>
+        /// Default constructor.
+        /// </summary>
+        public DynamicTestValue()
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="id">ID.</param>
+        public DynamicTestValue(int id)
+        {
+            Id = id;
+        }
+
+        /// <summary>
+        /// ID.
+        /// </summary>
+        public int Id
+        {
+            get;
+            set;
+        }
+
+        /** <inheritdoc /> */
+        public override bool Equals(object obj)
+        {
+            DynamicTestValue other = obj as DynamicTestValue;
+
+            return other != null && Id == other.Id;
+        }
+
+        /** <inheritdoc /> */
+        public override int GetHashCode()
+        {
+            return Id;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheEntryTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheEntryTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheEntryTest.cs
new file mode 100644
index 0000000..8464b8e
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheEntryTest.cs
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Impl.Cache;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// <see cref="CacheEntry{TK,TV}"/> tests.
+    /// </summary>
+    public class CacheEntryTest
+    {
+        /// <summary>
+        /// Tests equality members.
+        /// </summary>
+        [Test]
+        public void TestEquality()
+        {
+            var entry1 = new CacheEntry<int, int>(1, 2);
+            var entry2 = new CacheEntry<int, int>(1, 2);
+            var entry3 = new CacheEntry<int, int>(1, 3);
+
+            Assert.AreEqual(entry1, entry2);
+            Assert.AreNotEqual(entry1, entry3);
+
+            var boxedEntry1 = (object) entry1;
+            var boxedEntry2 = (object) entry2;
+            var boxedEntry3 = (object) entry3;
+
+            Assert.IsFalse(ReferenceEquals(boxedEntry1, boxedEntry2));
+
+            Assert.AreEqual(boxedEntry1, boxedEntry2);
+            Assert.AreNotEqual(boxedEntry1, boxedEntry3);
+        }
+
+        /// <summary>
+        /// Tests with hash data structures.
+        /// </summary>
+        [Test]
+        public void TestHashCode()
+        {
+            var entry1 = new CacheEntry<int, int>(1, 2);
+            var entry2 = new CacheEntry<int, int>(1, 2);
+            var entry3 = new CacheEntry<int, int>(1, 3);
+
+            var set = new HashSet<object> {entry1};
+
+            Assert.IsTrue(set.Contains(entry1));
+            Assert.IsTrue(set.Contains(entry2));
+            Assert.IsFalse(set.Contains(entry3));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheForkedTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheForkedTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheForkedTest.cs
new file mode 100644
index 0000000..04aff5f
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheForkedTest.cs
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using System.IO;
+    using Apache.Ignite.Core.Tests.Process;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Tests cache with a standalone process.
+    /// </summary>
+    [Ignore("IGNITE-1367")]
+    public class CacheForkedTest
+    {
+        /** */
+        private IIgnite _grid;
+
+        /// <summary>
+        /// Set up.
+        /// </summary>
+        [TestFixtureSetUp]
+        public void SetUp()
+        {
+            const string springConfigUrl = "config\\compute\\compute-grid1.xml";
+            
+            // ReSharper disable once UnusedVariable
+            var proc = new IgniteProcess(
+                "-jvmClasspath=" + TestUtils.CreateTestClasspath(),
+                "-springConfigUrl=" + Path.GetFullPath(springConfigUrl),
+                "-J-ea",
+                "-J-Xcheck:jni",
+                "-J-Xms512m",
+                "-J-Xmx512m",
+                "-J-DIGNITE_QUIET=false"
+                );
+
+            _grid = Ignition.Start(new IgniteConfiguration
+            {
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                JvmOptions = TestUtils.TestJavaOptions(),
+                SpringConfigUrl = springConfigUrl
+            });
+
+            Assert.IsTrue(_grid.WaitTopology(2, 30000));
+        }
+
+        /// <summary>
+        /// Tear down.
+        /// </summary>
+        [TestFixtureTearDown]
+        public void TearDown()
+        {
+            IgniteProcess.KillAll();
+
+            Ignition.StopAll(true);
+        }
+
+        /// <summary>
+        /// Tests cache clear.
+        /// </summary>
+        [Test]
+        public void TestClearCache()
+        {
+            _grid.Cache<object, object>(null).Clear();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
new file mode 100644
index 0000000..b60c254
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    public class CacheLocalAtomicTest : CacheAbstractTest
+    {
+        protected override int CachePartitions()
+        {
+            return 1;
+        }
+
+        protected override int GridCount()
+        {
+            return 1;
+        }
+
+        protected override string CacheName()
+        {
+            return "local_atomic";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return false;
+        }
+
+        protected override bool LocalCache()
+        {
+            return true;
+        }
+
+        protected override int Backups()
+        {
+            return 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
new file mode 100644
index 0000000..02cb987
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    public class CacheLocalTest : CacheAbstractTest
+    {
+        protected override int CachePartitions()
+        {
+            return 1;
+        }
+
+        protected override int GridCount()
+        {
+            return 1;
+        }
+
+        protected override string CacheName()
+        {
+            return "local";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return true;
+        }
+        protected override bool LocalCache()
+        {
+            return true;
+        }
+
+        protected override int Backups()
+        {
+            return 0;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
new file mode 100644
index 0000000..4f6e7a0
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CachePartitionedAtomicNearEnabledTest : CacheAbstractTest
+    {
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "partitioned_atomic_near";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return true;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return false;
+        }
+
+        protected override int Backups()
+        {
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
new file mode 100644
index 0000000..ab59c64
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CachePartitionedAtomicTest : CacheAbstractTest
+    {
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "partitioned_atomic";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return false;
+        }
+
+        protected override int Backups()
+        {
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
new file mode 100644
index 0000000..830698b
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CachePartitionedNearEnabledTest : CacheAbstractTest
+    {
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "partitioned_near";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return true;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return true;
+        }
+
+        protected override int Backups()
+        {
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
new file mode 100644
index 0000000..02d3208
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CachePartitionedTest : CacheAbstractTest
+    {
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "partitioned";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return true;
+        }
+
+        protected override int Backups()
+        {
+            return 1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
new file mode 100644
index 0000000..db6f5a5
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CacheReplicatedAtomicTest : CacheAbstractTest
+    {
+        protected override int CachePartitions()
+        {
+            return 512;
+        }
+
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "replicated_atomic";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return false;
+        }
+
+        protected override int Backups()
+        {
+            return GridCount() - 1;
+        }
+
+        protected override bool ReplicatedCache()
+        {
+            return true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
new file mode 100644
index 0000000..7c70222
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using NUnit.Framework;
+
+    [Category(TestUtils.CategoryIntensive)]
+    public class CacheReplicatedTest : CacheAbstractTest
+    {
+        protected override int CachePartitions()
+        {
+            return 512;
+        }
+
+        protected override int GridCount()
+        {
+            return 3;
+        }
+
+        protected override string CacheName()
+        {
+            return "replicated";
+        }
+
+        protected override bool NearEnabled()
+        {
+            return false;
+        }
+
+        protected override bool TxEnabled()
+        {
+            return true;
+        }
+
+        protected override int Backups()
+        {
+            return GridCount() - 1;
+        }
+
+        protected override bool ReplicatedCache()
+        {
+            return true;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
new file mode 100644
index 0000000..93f5973
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheTestAsyncWrapper.cs
@@ -0,0 +1,436 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache
+{
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Expiry;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Cache.Query.Continuous;
+    using Apache.Ignite.Core.Common;
+
+    /// <summary>
+    /// Wraps IGridCache implementation to simplify async mode testing.
+    /// </summary>
+    internal class CacheTestAsyncWrapper<TK, TV> : ICache<TK, TV>
+    {
+        private readonly ICache<TK, TV> _cache;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="CacheTestAsyncWrapper{K, V}"/> class.
+        /// </summary>
+        /// <param name="cache">The cache to be wrapped.</param>
+        public CacheTestAsyncWrapper(ICache<TK, TV> cache)
+        {
+            Debug.Assert(cache.IsAsync, "GridCacheTestAsyncWrapper only works with async caches.");
+
+            _cache = cache;
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithAsync()
+        {
+            return this;
+        }
+
+        /** <inheritDoc /> */
+        public bool IsAsync
+        {
+            get { return true; }
+        }
+
+        /** <inheritDoc /> */
+        public IFuture GetFuture()
+        {
+            Debug.Fail("GridCacheTestAsyncWrapper.Future() should not be called. It always returns null.");
+            return null;
+        }
+
+        /** <inheritDoc /> */
+        public IFuture<TResult> GetFuture<TResult>()
+        {
+            Debug.Fail("GridCacheTestAsyncWrapper.Future() should not be called. It always returns null.");
+            return null;
+        }
+
+        /** <inheritDoc /> */
+        public string Name
+        {
+            get { return _cache.Name; }
+        }
+
+        /** <inheritDoc /> */
+        public IIgnite Ignite
+        {
+            get { return _cache.Ignite; }
+        }
+
+        /** <inheritDoc /> */
+        public bool IsEmpty
+        {
+            get { return _cache.IsEmpty; }
+        }
+
+        /** <inheritDoc /> */
+        public bool KeepPortable
+        {
+            get { return _cache.KeepPortable; }
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithSkipStore()
+        {
+            return _cache.WithSkipStore().WrapAsync();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithExpiryPolicy(IExpiryPolicy plc)
+        {
+            return _cache.WithExpiryPolicy(plc).WrapAsync();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK1, TV1> WithKeepPortable<TK1, TV1>()
+        {
+            return _cache.WithKeepPortable<TK1, TV1>().WrapAsync();
+        }
+        
+        /** <inheritDoc /> */
+        public void LoadCache(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            _cache.LoadCache(p, args);
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalLoadCache(ICacheEntryFilter<TK, TV> p, params object[] args)
+        {
+            _cache.LocalLoadCache(p, args);
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public bool ContainsKey(TK key)
+        {
+            _cache.ContainsKey(key);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public bool ContainsKeys(IEnumerable<TK> keys)
+        {
+            _cache.ContainsKeys(keys);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public TV LocalPeek(TK key, params CachePeekMode[] modes)
+        {
+            _cache.LocalPeek(key, modes);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public TV Get(TK key)
+        {
+            _cache.Get(key);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public IDictionary<TK, TV> GetAll(IEnumerable<TK> keys)
+        {
+            _cache.GetAll(keys);
+            return GetResult<IDictionary<TK, TV>>();
+        }
+
+        /** <inheritDoc /> */
+        public void Put(TK key, TV val)
+        {
+            _cache.Put(key, val);
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public TV GetAndPut(TK key, TV val)
+        {
+            _cache.GetAndPut(key, val);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public TV GetAndReplace(TK key, TV val)
+        {
+            _cache.GetAndReplace(key, val);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public TV GetAndRemove(TK key)
+        {
+            _cache.GetAndRemove(key);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public bool PutIfAbsent(TK key, TV val)
+        {
+            _cache.PutIfAbsent(key, val);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public TV GetAndPutIfAbsent(TK key, TV val)
+        {
+            _cache.GetAndPutIfAbsent(key, val);
+            return GetResult<TV>();
+        }
+
+        /** <inheritDoc /> */
+        public bool Replace(TK key, TV val)
+        {
+            _cache.Replace(key, val);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public bool Replace(TK key, TV oldVal, TV newVal)
+        {
+            _cache.Replace(key, oldVal, newVal);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public void PutAll(IDictionary<TK, TV> vals)
+        {
+            _cache.PutAll(vals);
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalEvict(IEnumerable<TK> keys)
+        {
+            _cache.LocalEvict(keys);
+        }
+
+        /** <inheritDoc /> */
+        public void Clear()
+        {
+            _cache.Clear();
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public void Clear(TK key)
+        {
+            _cache.Clear(key);
+        }
+
+        /** <inheritDoc /> */
+        public void ClearAll(IEnumerable<TK> keys)
+        {
+            _cache.ClearAll(keys);
+        }
+
+        /** <inheritDoc /> */
+        public void LocalClear(TK key)
+        {
+            _cache.LocalClear(key);
+        }
+
+        /** <inheritDoc /> */
+        public void LocalClearAll(IEnumerable<TK> keys)
+        {
+            _cache.LocalClearAll(keys);
+        }
+
+        /** <inheritDoc /> */
+        public bool Remove(TK key)
+        {
+            _cache.Remove(key);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public bool Remove(TK key, TV val)
+        {
+            _cache.Remove(key, val);
+            return GetResult<bool>();
+        }
+
+        /** <inheritDoc /> */
+        public void RemoveAll(IEnumerable<TK> keys)
+        {
+            _cache.RemoveAll(keys);
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public void RemoveAll()
+        {
+            _cache.RemoveAll();
+            WaitResult();
+        }
+
+        /** <inheritDoc /> */
+        public int LocalSize(params CachePeekMode[] modes)
+        {
+            return _cache.LocalSize(modes);
+        }
+
+        /** <inheritDoc /> */
+        public int Size(params CachePeekMode[] modes)
+        {
+            _cache.Size(modes);
+            return GetResult<int>();
+        }
+
+        /** <inheritDoc /> */
+        public void LocalPromote(IEnumerable<TK> keys)
+        {
+            _cache.LocalPromote(keys);
+        }
+        
+        /** <inheritDoc /> */
+        public IQueryCursor<ICacheEntry<TK, TV>> Query(QueryBase qry)
+        {
+            return _cache.Query(qry);
+        }
+
+        /** <inheritDoc /> */
+        public IQueryCursor<IList> QueryFields(SqlFieldsQuery qry)
+        {
+            return _cache.QueryFields(qry);
+        }
+
+        /** <inheritDoc /> */
+        IContinuousQueryHandle ICache<TK, TV>.QueryContinuous(ContinuousQuery<TK, TV> qry)
+        {
+            return _cache.QueryContinuous(qry);
+        }
+
+        /** <inheritDoc /> */
+        public IContinuousQueryHandle<ICacheEntry<TK, TV>> QueryContinuous(ContinuousQuery<TK, TV> qry, QueryBase initialQry)
+        {
+            return _cache.QueryContinuous(qry, initialQry);
+        }
+
+        /** <inheritDoc /> */
+        public IEnumerable<ICacheEntry<TK, TV>> GetLocalEntries(params CachePeekMode[] peekModes)
+        {
+            return _cache.GetLocalEntries(peekModes);
+        }
+
+        /** <inheritDoc /> */
+        public TR Invoke<TR, TA>(TK key, ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg)
+        {
+            _cache.Invoke(key, processor, arg);
+            
+            return GetResult<TR>();
+        }
+
+        /** <inheritDoc /> */
+        public IDictionary<TK, ICacheEntryProcessorResult<TR>> InvokeAll<TR, TA>(IEnumerable<TK> keys, 
+            ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg)
+        {
+            _cache.InvokeAll(keys, processor, arg);
+
+            return GetResult<IDictionary<TK, ICacheEntryProcessorResult<TR>>>();
+        }
+
+        /** <inheritDoc /> */
+        public ICacheLock Lock(TK key)
+        {
+            return _cache.Lock(key);
+        }
+
+        /** <inheritDoc /> */
+        public ICacheLock LockAll(IEnumerable<TK> keys)
+        {
+            return _cache.LockAll(keys);
+        }
+
+        /** <inheritDoc /> */
+        public bool IsLocalLocked(TK key, bool byCurrentThread)
+        {
+            return _cache.IsLocalLocked(key, byCurrentThread);
+        }
+
+        /** <inheritDoc /> */
+        public ICacheMetrics GetMetrics()
+        {
+            return _cache.GetMetrics();
+        }
+
+        /** <inheritDoc /> */
+        public IFuture Rebalance()
+        {
+            return _cache.Rebalance();
+        }
+
+        /** <inheritDoc /> */
+        public ICache<TK, TV> WithNoRetries()
+        {
+            return _cache.WithNoRetries();
+        }
+
+        /** <inheritDoc /> */
+        public IEnumerator<ICacheEntry<TK, TV>> GetEnumerator()
+        {
+            return _cache.GetEnumerator();
+        }
+
+        /** <inheritDoc /> */
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return GetEnumerator();
+        }
+
+        /// <summary>
+        /// Waits for the async result.
+        /// </summary>
+        private void WaitResult()
+        {
+            GetResult<object>();
+        }
+
+        /// <summary>
+        /// Gets the async result.
+        /// </summary>
+        private T GetResult<T>()
+        {
+            return _cache.GetFuture<T>().Get();
+        }
+    }
+
+    /// <summary>
+    /// Extension methods for IGridCache.
+    /// </summary>
+    public static class CacheExtensions
+    {
+        /// <summary>
+        /// Wraps specified instance into GridCacheTestAsyncWrapper.
+        /// </summary>
+        public static ICache<TK, TV> WrapAsync<TK, TV>(this ICache<TK, TV> cache)
+        {
+            return new CacheTestAsyncWrapper<TK, TV>(cache);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/5cec202c/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
new file mode 100644
index 0000000..85227b6
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs
@@ -0,0 +1,928 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Tests.Cache.Query
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Text;
+    using Apache.Ignite.Core.Cache;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Impl;
+    using Apache.Ignite.Core.Impl.Portable;
+    using Apache.Ignite.Core.Portable;
+    using NUnit.Framework;
+
+    /// <summary>
+    /// Queries tests.
+    /// </summary>
+    public class CacheQueriesTest
+    {
+        /** Grid count. */
+        private const int GridCnt = 2;
+
+        /** Cache name. */
+        private const string CacheName = "cache";
+
+        /** Path to XML configuration. */
+        private const string CfgPath = "config\\cache-query.xml";
+
+        /** Maximum amount of items in cache. */
+        private const int MaxItemCnt = 100;
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [TestFixtureSetUp]
+        public virtual void StartGrids()
+        {
+            TestUtils.JvmDebug = true;
+            TestUtils.KillProcesses();
+
+            IgniteConfigurationEx cfg = new IgniteConfigurationEx
+            {
+                PortableConfiguration = new PortableConfiguration
+                {
+                    TypeConfigurations = new[]
+                    {
+                        new PortableTypeConfiguration(typeof (QueryPerson)),
+                        new PortableTypeConfiguration(typeof (PortableScanQueryFilter<QueryPerson>)),
+                        new PortableTypeConfiguration(typeof (PortableScanQueryFilter<PortableUserObject>))
+                    }
+                },
+                JvmClasspath = TestUtils.CreateTestClasspath(),
+                JvmOptions = TestUtils.TestJavaOptions(),
+                SpringConfigUrl = CfgPath
+            };
+
+            for (int i = 0; i < GridCnt; i++)
+            {
+                cfg.GridName = "grid-" + i;
+
+                Ignition.Start(cfg);
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [TestFixtureTearDown]
+        public virtual void StopGrids()
+        {
+            for (int i = 0; i < GridCnt; i++)
+                Ignition.Stop("grid-" + i, true);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [SetUp]
+        public virtual void BeforeTest()
+        {
+            Console.WriteLine("Test started: " + TestContext.CurrentContext.Test.Name);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        [TearDown]
+        public virtual void AfterTest()
+        {
+            var cache = Cache();
+
+            for (int i = 0; i < GridCnt; i++)
+            {
+                for (int j = 0; j < MaxItemCnt; j++)
+                    cache.Remove(j);
+
+                Assert.IsTrue(cache.IsEmpty);
+            }
+
+            Console.WriteLine("Test finished: " + TestContext.CurrentContext.Test.Name);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="idx"></param>
+        /// <returns></returns>
+        public IIgnite GetIgnite(int idx)
+        {
+            return Ignition.GetIgnite("grid-" + idx);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="idx"></param>
+        /// <returns></returns>
+        public ICache<int, QueryPerson> Cache(int idx)
+        {
+            return GetIgnite(idx).Cache<int, QueryPerson>(CacheName);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
+        public ICache<int, QueryPerson> Cache()
+        {
+            return Cache(0);
+        }
+
+        /// <summary>
+        /// Test arguments validation for SQL queries.
+        /// </summary>
+        [Test]
+        public void TestValidationSql()
+        {
+            // 1. No sql.
+            Assert.Throws<ArgumentException>(() =>
+                { Cache().Query(new SqlQuery(typeof(QueryPerson), null)); });
+
+            // 2. No type.
+            Assert.Throws<ArgumentException>(() =>
+                { Cache().Query(new SqlQuery((string)null, "age >= 50")); });
+        }
+
+        /// <summary>
+        /// Test arguments validation for SQL fields queries.
+        /// </summary>
+        [Test]
+        public void TestValidationSqlFields()
+        {
+            // 1. No sql.
+            Assert.Throws<ArgumentException>(() => { Cache().QueryFields(new SqlFieldsQuery(null)); });
+        }
+
+        /// <summary>
+        /// Test arguments validation for TEXT queries.
+        /// </summary>
+        [Test]
+        public void TestValidationText()
+        {
+            // 1. No text.
+            Assert.Throws<ArgumentException>(() =>
+                { Cache().Query(new TextQuery(typeof(QueryPerson), null)); });
+
+            // 2. No type.
+            Assert.Throws<ArgumentException>(() =>
+                { Cache().Query(new TextQuery((string)null, "Ivanov")); });
+        }
+
+        /// <summary>
+        /// Cursor tests.
+        /// </summary>
+        [Test]
+        [SuppressMessage("ReSharper", "ReturnValueOfPureMethodIsNotUsed")]
+        public void TestCursor()
+        {
+            var cache0 = Cache().WithAsync();
+
+            cache0.WithAsync().Put(1, new QueryPerson("Ivanov", 30));
+
+            IFuture<object> res = cache0.GetFuture<object>();
+
+            res.Get();
+
+            Cache().Put(1, new QueryPerson("Ivanov", 30));
+            Cache().Put(1, new QueryPerson("Petrov", 40));
+            Cache().Put(1, new QueryPerson("Sidorov", 50));
+
+            SqlQuery qry = new SqlQuery(typeof(QueryPerson), "age >= 20");
+
+            // 1. Test GetAll().
+            using (IQueryCursor<ICacheEntry<int, QueryPerson>> cursor = Cache().Query(qry))
+            {
+                cursor.GetAll();
+
+                Assert.Throws<InvalidOperationException>(() => { cursor.GetAll(); });
+                Assert.Throws<InvalidOperationException>(() => { cursor.GetEnumerator(); });
+            }
+
+            // 2. Test GetEnumerator.
+            using (IQueryCursor<ICacheEntry<int, QueryPerson>> cursor = Cache().Query(qry))
+            {
+                cursor.GetEnumerator();
+
+                Assert.Throws<InvalidOperationException>(() => { cursor.GetAll(); });
+                Assert.Throws<InvalidOperationException>(() => { cursor.GetEnumerator(); });
+            }
+        }
+
+        /// <summary>
+        /// Test enumerator.
+        /// </summary>
+        [Test]
+        [SuppressMessage("ReSharper", "UnusedVariable")]
+        public void TestEnumerator()
+        {
+            Cache().Put(1, new QueryPerson("Ivanov", 30));
+            Cache().Put(2, new QueryPerson("Petrov", 40));
+            Cache().Put(3, new QueryPerson("Sidorov", 50));
+            Cache().Put(4, new QueryPerson("Unknown", 60));
+
+            // 1. Empty result set.
+            using (
+                IQueryCursor<ICacheEntry<int, QueryPerson>> cursor =
+                    Cache().Query(new SqlQuery(typeof(QueryPerson), "age = 100")))
+            {
+                IEnumerator<ICacheEntry<int, QueryPerson>> e = cursor.GetEnumerator();
+
+                Assert.Throws<InvalidOperationException>(() =>
+                    { ICacheEntry<int, QueryPerson> entry = e.Current; });
+
+                Assert.IsFalse(e.MoveNext());
+
+                Assert.Throws<InvalidOperationException>(() =>
+                    { ICacheEntry<int, QueryPerson> entry = e.Current; });
+
+                Assert.Throws<NotSupportedException>(() => e.Reset());
+            }
+
+            SqlQuery qry = new SqlQuery(typeof (QueryPerson), "age < 60");
+
+            // 2. Page size is bigger than result set.
+            qry.PageSize = 4;
+            CheckEnumeratorQuery(qry);
+
+            // 3. Page size equal to result set.
+            qry.PageSize = 3;
+            CheckEnumeratorQuery(qry);
+
+            // 4. Page size if less than result set.
+            qry.PageSize = 2;
+            CheckEnumeratorQuery(qry);
+        }
+
+        /// <summary>
+        /// Test SQL query arguments passing.
+        /// </summary>
+        public void TestSqlQueryArguments()
+        {
+            Cache().Put(1, new QueryPerson("Ivanov", 30));
+            Cache().Put(2, new QueryPerson("Petrov", 40));
+            Cache().Put(3, new QueryPerson("Sidorov", 50));
+
+            // 1. Empty result set.
+            using (
+                IQueryCursor<ICacheEntry<int, QueryPerson>> cursor =
+                    Cache().Query(new SqlQuery(typeof(QueryPerson), "age < ?", 50)))
+            {
+                foreach (ICacheEntry<int, QueryPerson> entry in cursor.GetAll())
+                    Assert.IsTrue(entry.Key == 1 || entry.Key == 2);
+            }
+        }
+
+        /// <summary>
+        /// Test SQL fields query arguments passing.
+        /// </summary>
+        public void TestSqlFieldsQueryArguments()
+        {
+            Cache().Put(1, new QueryPerson("Ivanov", 30));
+            Cache().Put(2, new QueryPerson("Petrov", 40));
+            Cache().Put(3, new QueryPerson("Sidorov", 50));
+
+            // 1. Empty result set.
+            using (
+                IQueryCursor<IList> cursor = Cache().QueryFields(
+                    new SqlFieldsQuery("SELECT age FROM QueryPerson WHERE age < ?", 50)))
+            {
+                foreach (IList entry in cursor.GetAll())
+                    Assert.IsTrue((int) entry[0] < 50);
+            }
+        }
+
+        /// <summary>
+        /// Check query result for enumerator test.
+        /// </summary>
+        /// <param name="qry">QUery.</param>
+        private void CheckEnumeratorQuery(SqlQuery qry)
+        {
+            using (IQueryCursor<ICacheEntry<int, QueryPerson>> cursor = Cache().Query(qry))
+            {
+                bool first = false;
+                bool second = false;
+                bool third = false;
+
+                foreach (var entry in cursor)
+                {
+                    if (entry.Key == 1)
+                    {
+                        first = true;
+
+                        Assert.AreEqual("Ivanov", entry.Value.Name);
+                        Assert.AreEqual(30, entry.Value.Age);
+                    }
+                    else if (entry.Key == 2)
+                    {
+                        second = true;
+
+                        Assert.AreEqual("Petrov", entry.Value.Name);
+                        Assert.AreEqual(40, entry.Value.Age);
+                    }
+                    else if (entry.Key == 3)
+                    {
+                        third = true;
+
+                        Assert.AreEqual("Sidorov", entry.Value.Name);
+                        Assert.AreEqual(50, entry.Value.Age);
+                    }
+                    else
+                        Assert.Fail("Unexpected value: " + entry);
+                }
+
+                Assert.IsTrue(first && second && third);
+            }
+        }
+
+        /// <summary>
+        /// Check SQL query.
+        /// </summary>
+        [Test]
+        public void TestSqlQuery()
+        {
+            CheckSqlQuery(MaxItemCnt, false, false);
+        }
+
+        /// <summary>
+        /// Check SQL query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestSqlQueryPortable()
+        {
+            CheckSqlQuery(MaxItemCnt, false, true);
+        }
+
+        /// <summary>
+        /// Check local SQL query.
+        /// </summary>
+        [Test]
+        public void TestSqlQueryLocal()
+        {
+            CheckSqlQuery(MaxItemCnt, true, false);
+        }
+
+        /// <summary>
+        /// Check local SQL query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestSqlQueryLocalPortable()
+        {
+            CheckSqlQuery(MaxItemCnt, true, true);
+        }
+
+        /// <summary>
+        /// Check SQL query.
+        /// </summary>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        /// <param name="keepPortable">Keep portable flag.</param>
+        private void CheckSqlQuery(int cnt, bool loc, bool keepPortable)
+        {
+            var cache = Cache();
+
+            // 1. Populate cache with data, calculating expected count in parallel.
+            var exp = PopulateCache(cache, loc, cnt, x => x < 50);
+
+            // 2. Validate results.
+            SqlQuery qry = loc ?  new SqlQuery(typeof(QueryPerson), "age < 50", true) :
+                new SqlQuery(typeof(QueryPerson), "age < 50");
+
+            ValidateQueryResults(cache, qry, exp, keepPortable);
+        }
+
+        /// <summary>
+        /// Check SQL fields query.
+        /// </summary>
+        [Test]
+        public void TestSqlFieldsQuery()
+        {
+            CheckSqlFieldsQuery(MaxItemCnt, false);
+        }
+
+        /// <summary>
+        /// Check local SQL fields query.
+        /// </summary>
+        [Test]
+        public void TestSqlFieldsQueryLocal()
+        {
+            CheckSqlFieldsQuery(MaxItemCnt, true);
+        }
+
+        /// <summary>
+        /// Check SQL fields query.
+        /// </summary>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        private void CheckSqlFieldsQuery(int cnt, bool loc)
+        {
+            var cache = Cache();
+
+            // 1. Populate cache with data, calculating expected count in parallel.
+            var exp = PopulateCache(cache, loc, cnt, x => x < 50);
+
+            // 2. Vlaidate results.
+            SqlFieldsQuery qry = loc ? new SqlFieldsQuery("SELECT name, age FROM QueryPerson WHERE age < 50", true) :
+                new SqlFieldsQuery("SELECT name, age FROM QueryPerson WHERE age < 50");
+
+            using (IQueryCursor<IList> cursor = cache.QueryFields(qry))
+            {
+                HashSet<int> exp0 = new HashSet<int>(exp);
+
+                foreach (var entry in cursor.GetAll())
+                {
+                    Assert.AreEqual(2, entry.Count);
+                    Assert.AreEqual(entry[0].ToString(), entry[1].ToString());
+
+                    exp0.Remove((int)entry[1]);
+                }
+
+                Assert.AreEqual(0, exp0.Count);
+            }
+
+            using (IQueryCursor<IList> cursor = cache.QueryFields(qry))
+            {
+                HashSet<int> exp0 = new HashSet<int>(exp);
+
+                foreach (var entry in cursor)
+                {
+                    Assert.AreEqual(entry[0].ToString(), entry[1].ToString());
+
+                    exp0.Remove((int)entry[1]);
+                }
+
+                Assert.AreEqual(0, exp0.Count);
+            }
+        }
+
+        /// <summary>
+        /// Check text query.
+        /// </summary>
+        [Test]
+        public void TestTextQuery()
+        {
+            CheckTextQuery(MaxItemCnt, false, false);
+        }
+
+        /// <summary>
+        /// Check SQL query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestTextQueryPortable()
+        {
+            CheckTextQuery(MaxItemCnt, false, true);
+        }
+
+        /// <summary>
+        /// Check local SQL query.
+        /// </summary>
+        [Test]
+        public void TestTextQueryLocal()
+        {
+            CheckTextQuery(MaxItemCnt, true, false);
+        }
+
+        /// <summary>
+        /// Check local SQL query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestTextQueryLocalPortable()
+        {
+            CheckTextQuery(MaxItemCnt, true, true);
+        }
+
+        /// <summary>
+        /// Check text query.
+        /// </summary>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        /// <param name="keepPortable">Keep portable flag.</param>
+        private void CheckTextQuery(int cnt, bool loc, bool keepPortable)
+        {
+            var cache = Cache();
+
+            // 1. Populate cache with data, calculating expected count in parallel.
+            var exp = PopulateCache(cache, loc, cnt, x => x.ToString().StartsWith("1"));
+
+            // 2. Validate results.
+            TextQuery qry = loc ? new TextQuery(typeof(QueryPerson), "1*", true) :
+                new TextQuery(typeof(QueryPerson), "1*");
+
+            ValidateQueryResults(cache, qry, exp, keepPortable);
+        }
+
+        /// <summary>
+        /// Check scan query.
+        /// </summary>
+        [Test]
+        public void TestScanQuery()
+        {
+            CheckScanQuery<QueryPerson>(MaxItemCnt, false, false);
+        }
+
+        /// <summary>
+        /// Check scan query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestScanQueryPortable()
+        {
+            CheckScanQuery<PortableUserObject>(MaxItemCnt, false, true);
+        }
+
+        /// <summary>
+        /// Check local scan query.
+        /// </summary>
+        [Test]
+        public void TestScanQueryLocal()
+        {
+            CheckScanQuery<QueryPerson>(MaxItemCnt, true, false);
+        }
+
+        /// <summary>
+        /// Check local scan query in portable mode.
+        /// </summary>
+        [Test]
+        public void TestScanQueryLocalPortable()
+        {
+            CheckScanQuery<PortableUserObject>(MaxItemCnt, true, true);
+        }
+
+        /// <summary>
+        /// Check scan query with partitions.
+        /// </summary>
+        [Test]
+        [Ignore("IGNITE-1012")]
+        public void TestScanQueryPartitions([Values(true, false)]  bool loc)
+        {
+            CheckScanQueryPartitions<QueryPerson>(MaxItemCnt, loc, false);
+        }
+
+        /// <summary>
+        /// Check scan query with partitions in portable mode.
+        /// </summary>
+        [Test]
+        [Ignore("IGNITE-1012")]
+        public void TestScanQueryPartitionsPortable([Values(true, false)]  bool loc)
+        {
+            CheckScanQueryPartitions<PortableUserObject>(MaxItemCnt, loc, true);
+        }
+
+        /// <summary>
+        /// Tests that query attempt on non-indexed cache causes an exception.
+        /// </summary>
+        [Test]
+        public void TestIndexingDisabledError()
+        {
+            var cache = GetIgnite(0).GetOrCreateCache<int, QueryPerson>("nonindexed_cache");
+
+            var queries = new QueryBase[]
+            {
+                new TextQuery(typeof (QueryPerson), "1*"),
+                new SqlQuery(typeof (QueryPerson), "age < 50")
+            };
+
+            foreach (var qry in queries)
+            {
+                var err = Assert.Throws<IgniteException>(() => cache.Query(qry));
+
+                Assert.AreEqual("Indexing is disabled for cache: nonindexed_cache. " +
+                    "Use setIndexedTypes or setTypeMetadata methods on CacheConfiguration to enable.", err.Message);
+            }
+        }
+
+        /// <summary>
+        /// Check scan query.
+        /// </summary>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        /// <param name="keepPortable">Keep portable flag.</param>
+        private void CheckScanQuery<TV>(int cnt, bool loc, bool keepPortable)
+        {
+            var cache = Cache();
+
+            // No predicate
+            var exp = PopulateCache(cache, loc, cnt, x => true);
+            var qry = new ScanQuery<int, TV>();
+            ValidateQueryResults(cache, qry, exp, keepPortable);
+
+            // Serializable
+            exp = PopulateCache(cache, loc, cnt, x => x < 50);
+            qry = new ScanQuery<int, TV>(new ScanQueryFilter<TV>());
+            ValidateQueryResults(cache, qry, exp, keepPortable);
+
+            // Portable
+            exp = PopulateCache(cache, loc, cnt, x => x < 50);
+            qry = new ScanQuery<int, TV>(new PortableScanQueryFilter<TV>());
+            ValidateQueryResults(cache, qry, exp, keepPortable);
+
+            // Exception
+            exp = PopulateCache(cache, loc, cnt, x => x < 50);
+            qry = new ScanQuery<int, TV>(new ScanQueryFilter<TV> {ThrowErr = true});
+            
+            var ex = Assert.Throws<IgniteException>(() => ValidateQueryResults(cache, qry, exp, keepPortable));
+            Assert.AreEqual(ScanQueryFilter<TV>.ErrMessage, ex.Message);
+        }
+
+        /// <summary>
+        /// Checks scan query with partitions.
+        /// </summary>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        /// <param name="keepPortable">Keep portable flag.</param>
+        private void CheckScanQueryPartitions<TV>(int cnt, bool loc, bool keepPortable)
+        {
+            StopGrids();
+            StartGrids();
+
+            var cache = Cache();
+
+            var aff = cache.Ignite.Affinity(CacheName);
+            var exp = PopulateCache(cache, loc, cnt, x => true);  // populate outside the loop (slow)
+
+            for (var part = 0; part < aff.Partitions; part++)
+            {
+                //var exp0 = new HashSet<int>(exp.Where(x => aff.Partition(x) == part)); // filter expected keys
+                var exp0 = new HashSet<int>();
+                foreach (var x in exp)
+                    if (aff.Partition(x) == part)
+                        exp0.Add(x);
+
+                var qry = new ScanQuery<int, TV> { Partition = part };
+
+                Console.WriteLine("Checking query on partition " + part);
+                ValidateQueryResults(cache, qry, exp0, keepPortable);
+            }
+
+            // Partitions with predicate
+            exp = PopulateCache(cache, loc, cnt, x => x < 50);  // populate outside the loop (slow)
+
+            for (var part = 0; part < aff.Partitions; part++)
+            {
+                //var exp0 = new HashSet<int>(exp.Where(x => aff.Partition(x) == part)); // filter expected keys
+                var exp0 = new HashSet<int>();
+                foreach (var x in exp)
+                    if (aff.Partition(x) == part)
+                        exp0.Add(x);
+
+                var qry = new ScanQuery<int, TV>(new ScanQueryFilter<TV>()) { Partition = part };
+
+                Console.WriteLine("Checking predicate query on partition " + part);
+                ValidateQueryResults(cache, qry, exp0, keepPortable);
+            }
+            
+        }
+
+        /// <summary>
+        /// Validates the query results.
+        /// </summary>
+        /// <param name="cache">Cache.</param>
+        /// <param name="qry">Query.</param>
+        /// <param name="exp">Expected keys.</param>
+        /// <param name="keepPortable">Keep portable flag.</param>
+        private static void ValidateQueryResults(ICache<int, QueryPerson> cache, QueryBase qry, HashSet<int> exp,
+            bool keepPortable)
+        {
+            if (keepPortable)
+            {
+                var cache0 = cache.WithKeepPortable<int, IPortableObject>();
+
+                using (var cursor = cache0.Query(qry))
+                {
+                    HashSet<int> exp0 = new HashSet<int>(exp);
+                    var all = new List<ICacheEntry<int, object>>();
+
+                    foreach (var entry in cursor.GetAll())
+                    {
+                        all.Add(entry);
+
+                        Assert.AreEqual(entry.Key.ToString(), entry.Value.Field<string>("name"));
+                        Assert.AreEqual(entry.Key, entry.Value.Field<int>("age"));
+
+                        exp0.Remove(entry.Key);
+                    }
+
+                    AssertMissingExpectedKeys(exp0, cache, all);
+                }
+
+                using (var cursor = cache0.Query(qry))
+                {
+                    HashSet<int> exp0 = new HashSet<int>(exp);
+                    var all = new List<ICacheEntry<int, object>>();
+
+                    foreach (var entry in cursor)
+                    {
+                        all.Add(entry);
+
+                        Assert.AreEqual(entry.Key.ToString(), entry.Value.Field<string>("name"));
+                        Assert.AreEqual(entry.Key, entry.Value.Field<int>("age"));
+
+                        exp0.Remove(entry.Key);
+                    }
+
+                    AssertMissingExpectedKeys(exp0, cache, all);
+                }
+            }
+            else
+            {
+                using (var cursor = cache.Query(qry))
+                {
+                    HashSet<int> exp0 = new HashSet<int>(exp);
+                    var all = new List<ICacheEntry<int, object>>();
+
+                    foreach (var entry in cursor.GetAll())
+                    {
+                        all.Add(entry);
+
+                        Assert.AreEqual(entry.Key.ToString(), entry.Value.Name);
+                        Assert.AreEqual(entry.Key, entry.Value.Age);
+
+                        exp0.Remove(entry.Key);
+                    }
+
+                    AssertMissingExpectedKeys(exp0, cache, all);
+                }
+
+                using (var cursor = cache.Query(qry))
+                {
+                    HashSet<int> exp0 = new HashSet<int>(exp);
+                    var all = new List<ICacheEntry<int, object>>();
+
+                    foreach (var entry in cursor)
+                    {
+                        all.Add(entry);
+
+                        Assert.AreEqual(entry.Key.ToString(), entry.Value.Name);
+                        Assert.AreEqual(entry.Key, entry.Value.Age);
+
+                        exp0.Remove(entry.Key);
+                    }
+
+                    AssertMissingExpectedKeys(exp0, cache, all);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Asserts that all expected entries have been received.
+        /// </summary>
+        private static void AssertMissingExpectedKeys(ICollection<int> exp, ICache<int, QueryPerson> cache, 
+            IList<ICacheEntry<int, object>> all)
+        {
+            if (exp.Count == 0)
+                return;
+
+            var sb = new StringBuilder();
+            var aff = cache.Ignite.Affinity(cache.Name);
+
+            foreach (var key in exp)
+            {
+                var part = aff.Partition(key);
+                sb.AppendFormat(
+                    "Query did not return expected key '{0}' (exists: {1}), partition '{2}', partition nodes: ", 
+                    key, cache.Get(key) != null, part);
+
+                var partNodes = aff.MapPartitionToPrimaryAndBackups(part);
+
+                foreach (var node in partNodes)
+                    sb.Append(node).Append("  ");
+
+                sb.AppendLine(";");
+            }
+
+            sb.Append("Returned keys: ");
+
+            foreach (var e in all)
+                sb.Append(e.Key).Append(" ");
+
+            sb.AppendLine(";");
+
+            Assert.Fail(sb.ToString());
+        }
+
+        /// <summary>
+        /// Populates the cache with random entries and returns expected results set according to filter.
+        /// </summary>
+        /// <param name="cache">The cache.</param>
+        /// <param name="cnt">Amount of cache entries to create.</param>
+        /// <param name="loc">Local query flag.</param>
+        /// <param name="expectedEntryFilter">The expected entry filter.</param>
+        /// <returns>Expected results set.</returns>
+        private static HashSet<int> PopulateCache(ICache<int, QueryPerson> cache,  bool loc, int cnt,
+            Func<int, bool> expectedEntryFilter)
+        {
+            var rand = new Random();
+
+            var exp = new HashSet<int>();
+
+            for (var i = 0; i < cnt; i++)
+            {
+                var val = rand.Next(100);
+
+                cache.Put(val, new QueryPerson(val.ToString(), val));
+
+                if (expectedEntryFilter(val) && (!loc || cache.Ignite.Affinity(cache.Name)
+                    .IsPrimary(cache.Ignite.Cluster.LocalNode, val)))
+                    exp.Add(val);
+            }
+
+            return exp;
+        }
+    }
+
+    /// <summary>
+    /// Person.
+    /// </summary>
+    public class QueryPerson
+    {
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        public QueryPerson()
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="name">Name.</param>
+        /// <param name="age">Age.</param>
+        public QueryPerson(string name, int age)
+        {
+            Name = name;
+            Age = age;
+        }
+
+        /// <summary>
+        /// Name.
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// Age.
+        /// </summary>
+        public int Age { get; set; }
+    }
+
+    /// <summary>
+    /// Query filter.
+    /// </summary>
+    [Serializable]
+    public class ScanQueryFilter<TV> : ICacheEntryFilter<int, TV>
+    {
+        // Error message
+        public const string ErrMessage = "Error in ScanQueryFilter.Invoke";
+
+        // Error flag
+        public bool ThrowErr { get; set; }
+
+        /** <inheritdoc /> */
+        public bool Invoke(ICacheEntry<int, TV> entry)
+        {
+            if (ThrowErr)
+                throw new Exception(ErrMessage);
+
+            return entry.Key < 50;
+        }
+    }
+
+    /// <summary>
+    /// Portable query filter.
+    /// </summary>
+    public class PortableScanQueryFilter<TV> : ScanQueryFilter<TV>, IPortableMarshalAware
+    {
+        /** <inheritdoc /> */
+        public void WritePortable(IPortableWriter writer)
+        {
+            var w = writer.RawWriter();
+
+            w.WriteBoolean(ThrowErr);
+        }
+
+        /** <inheritdoc /> */
+        public void ReadPortable(IPortableReader reader)
+        {
+            var r = reader.RawReader();
+
+            ThrowErr = r.ReadBoolean();
+        }
+    }
+}