You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/09/04 18:27:40 UTC
[26/55] [abbrv] 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/CacheAbstractTest.cs
----------------------------------------------------------------------
diff --git a/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
new file mode 100644
index 0000000..24d2b73
--- /dev/null
+++ b/modules/platform/src/test/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
@@ -0,0 +1,3321 @@
+/*
+ * 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 System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Expiry;
+ using Apache.Ignite.Core.Cluster;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Impl;
+ using Apache.Ignite.Core.Impl.Cache;
+ using Apache.Ignite.Core.Portable;
+ using Apache.Ignite.Core.Tests.Query;
+ using Apache.Ignite.Core.Transactions;
+ using NUnit.Framework;
+
+ /// <summary>
+ ///
+ /// </summary>
+ class CacheTestKey
+ {
+ /// <summary>
+ /// Default constructor.
+ /// </summary>
+ public CacheTestKey()
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="id">ID.</param>
+ public CacheTestKey(int id)
+ {
+ Id = id;
+ }
+
+ /// <summary>
+ /// ID.
+ /// </summary>
+ public int Id
+ {
+ get;
+ set;
+ }
+
+ /** <inheritdoc /> */
+ public override bool Equals(object obj)
+ {
+ CacheTestKey other = obj as CacheTestKey;
+
+ return other != null && Id == other.Id;
+ }
+
+ /** <inheritdoc /> */
+ public override int GetHashCode()
+ {
+ return Id;
+ }
+
+ /** <inheritdoc /> */
+ public override string ToString()
+ {
+ return new StringBuilder()
+ .Append(typeof(CacheTestKey).Name)
+ .Append(" [id=").Append(Id)
+ .Append(']').ToString();
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ class TestReferenceObject
+ {
+ public TestReferenceObject Obj;
+
+ /// <summary>
+ /// Default constructor.
+ /// </summary>
+ public TestReferenceObject()
+ {
+ // No-op.
+ }
+
+ public TestReferenceObject(TestReferenceObject obj)
+ {
+ Obj = obj;
+ }
+ }
+
+ [Serializable]
+ public class TestSerializableObject
+ {
+ public string Name { get; set; }
+ public int Id { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ if (ReferenceEquals(this, obj)) return true;
+
+ var other = (TestSerializableObject) obj;
+ return obj.GetType() == GetType() && (string.Equals(Name, other.Name) && Id == other.Id);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ Id;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Cache entry processor that adds argument value to the entry value.
+ /// </summary>
+ [Serializable]
+ public class AddArgCacheEntryProcessor : ICacheEntryProcessor<int, int, int, int>
+ {
+ // Expected exception text
+ public const string ExceptionText = "Exception from AddArgCacheEntryProcessor.";
+
+ // Error flag
+ public bool ThrowErr { get; set; }
+
+ // Error flag
+ public bool ThrowErrPortable { get; set; }
+
+ // Error flag
+ public bool ThrowErrNonSerializable { get; set; }
+
+ // Key value to throw error on
+ public int ThrowOnKey { get; set; }
+
+ // Remove flag
+ public bool Remove { get; set; }
+
+ // Exists flag
+ public bool Exists { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AddArgCacheEntryProcessor"/> class.
+ /// </summary>
+ public AddArgCacheEntryProcessor()
+ {
+ Exists = true;
+ ThrowOnKey = -1;
+ }
+
+ /** <inheritdoc /> */
+ int ICacheEntryProcessor<int, int, int, int>.Process(IMutableCacheEntry<int, int> entry, int arg)
+ {
+ if (ThrowOnKey < 0 || ThrowOnKey == entry.Key)
+ {
+ if (ThrowErr)
+ throw new Exception(ExceptionText);
+
+ if (ThrowErrPortable)
+ throw new PortableTestException {Info = ExceptionText};
+
+ if (ThrowErrNonSerializable)
+ throw new NonSerializableException();
+ }
+
+ Assert.AreEqual(Exists, entry.Exists);
+
+ if (Remove)
+ entry.Remove();
+ else
+ entry.Value = entry.Value + arg;
+
+ return entry.Value;
+ }
+
+ /** <inheritdoc /> */
+ public int Process(IMutableCacheEntry<int, int> entry, int arg)
+ {
+ throw new Exception("Invalid method");
+ }
+ }
+
+ /// <summary>
+ /// Portable add processor.
+ /// </summary>
+ public class PortableAddArgCacheEntryProcessor : AddArgCacheEntryProcessor, IPortableMarshalAware
+ {
+ /** <inheritdoc /> */
+ public void WritePortable(IPortableWriter writer)
+ {
+ var w = writer.RawWriter();
+
+ w.WriteBoolean(ThrowErr);
+ w.WriteBoolean(ThrowErrPortable);
+ w.WriteBoolean(ThrowErrNonSerializable);
+ w.WriteInt(ThrowOnKey);
+ w.WriteBoolean(Remove);
+ w.WriteBoolean(Exists);
+ }
+
+ /** <inheritdoc /> */
+ public void ReadPortable(IPortableReader reader)
+ {
+ var r = reader.RawReader();
+
+ ThrowErr = r.ReadBoolean();
+ ThrowErrPortable = r.ReadBoolean();
+ ThrowErrNonSerializable = r.ReadBoolean();
+ ThrowOnKey = r.ReadInt();
+ Remove = r.ReadBoolean();
+ Exists = r.ReadBoolean();
+ }
+ }
+
+ /// <summary>
+ /// Non-serializable processor.
+ /// </summary>
+ public class NonSerializableCacheEntryProcessor : AddArgCacheEntryProcessor
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Portable exception.
+ /// </summary>
+ public class PortableTestException : Exception, IPortableMarshalAware
+ {
+ /// <summary>
+ /// Gets or sets exception info.
+ /// </summary>
+ public string Info { get; set; }
+
+ /** <inheritdoc /> */
+ public override string Message
+ {
+ get { return Info; }
+ }
+
+ /** <inheritdoc /> */
+ public void WritePortable(IPortableWriter writer)
+ {
+ writer.RawWriter().WriteString(Info);
+ }
+
+ /** <inheritdoc /> */
+ public void ReadPortable(IPortableReader reader)
+ {
+ Info = reader.RawReader().ReadString();
+ }
+ }
+
+ /// <summary>
+ /// Non-serializable exception.
+ /// </summary>
+ public class NonSerializableException : Exception
+ {
+ // No-op
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [SuppressMessage("ReSharper", "UnusedVariable")]
+ public abstract class CacheAbstractTest {
+ /// <summary>
+ ///
+ /// </summary>
+ [TestFixtureSetUp]
+ public virtual void StartGrids() {
+ TestUtils.KillProcesses();
+
+ IgniteConfigurationEx cfg = new IgniteConfigurationEx();
+
+ PortableConfiguration portCfg = new PortableConfiguration();
+
+ ICollection<PortableTypeConfiguration> portTypeCfgs = new List<PortableTypeConfiguration>();
+
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortablePerson)));
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof(CacheTestKey)));
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof(TestReferenceObject)));
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableAddArgCacheEntryProcessor)));
+ portTypeCfgs.Add(new PortableTypeConfiguration(typeof(PortableTestException)));
+
+ portCfg.TypeConfigurations = portTypeCfgs;
+
+ cfg.PortableConfiguration = portCfg;
+ cfg.JvmClasspath = TestUtils.CreateTestClasspath();
+ cfg.JvmOptions = TestUtils.TestJavaOptions();
+ cfg.SpringConfigUrl = "config\\native-client-test-cache.xml";
+
+ for (int i = 0; i < GridCount(); i++) {
+ cfg.GridName = "grid-" + i;
+
+ Ignition.Start(cfg);
+ }
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ [TestFixtureTearDown]
+ public virtual void StopGrids() {
+ for (int i = 0; i < GridCount(); 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() {
+ for (int i = 0; i < GridCount(); i++)
+ Cache(i).RemoveAll();
+
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ if (!cache.IsEmpty)
+ {
+ var entries = Enumerable.Range(0, 2000)
+ .Select(x => new KeyValuePair<int, int>(x, cache.LocalPeek(x)))
+ .Where(x => x.Value != 0)
+ .Select(pair => pair.ToString() + GetKeyAffinity(cache, pair.Key))
+ .Aggregate((acc, val) => string.Format("{0}, {1}", acc, val));
+
+ Assert.Fail("Cache '{0}' is not empty in grid [{1}]: ({2})", CacheName(), i, entries);
+ }
+ }
+
+ Console.WriteLine("Test finished: " + TestContext.CurrentContext.Test.Name);
+ }
+
+ public IIgnite GetIgnite(int idx)
+ {
+ return Ignition.GetIgnite("grid-" + idx);
+ }
+
+ public ICache<int, int> Cache(int idx) {
+ return Cache<int, int>(idx);
+ }
+
+ public ICache<TK, TV> Cache<TK, TV>(int idx) {
+ return GetIgnite(idx).Cache<TK, TV>(CacheName());
+ }
+
+ public ICache<int, int> Cache()
+ {
+ return Cache<int, int>(0);
+ }
+
+ public ICache<TK, TV> Cache<TK, TV>()
+ {
+ return Cache<TK, TV>(0);
+ }
+
+ public ICacheAffinity Affinity()
+ {
+ return GetIgnite(0).Affinity(CacheName());
+ }
+
+ public ITransactions Transactions
+ {
+ get { return GetIgnite(0).Transactions; }
+ }
+
+ [Test]
+ public void TestCircularReference()
+ {
+ var cache = Cache().WithKeepPortable<int, object>();
+
+ TestReferenceObject obj1 = new TestReferenceObject();
+
+ obj1.Obj = new TestReferenceObject(obj1);
+
+ cache.Put(1, obj1);
+
+ var po = (IPortableObject) cache.Get(1);
+
+ Assert.IsNotNull(po);
+
+ TestReferenceObject objRef = po.Deserialize<TestReferenceObject>();
+
+ Assert.IsNotNull(objRef);
+ }
+
+ [Test]
+ public void TestName()
+ {
+ for (int i = 0; i < GridCount(); i++ )
+ Assert.AreEqual(CacheName(), Cache(i).Name);
+ }
+
+ [Test]
+ public void TestIsEmpty()
+ {
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ Assert.IsTrue(cache.IsEmpty);
+ }
+
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ cache.Put(PrimaryKeyForCache(cache), 1);
+ }
+
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ Assert.IsFalse(cache.IsEmpty);
+ }
+ }
+
+ [Test]
+ public void TestContainsKey()
+ {
+ var cache = Cache();
+
+ int key = PrimaryKeyForCache(cache);
+
+ cache.Put(key, 1);
+
+ Assert.IsTrue(cache.ContainsKey(key));
+ Assert.IsFalse(cache.ContainsKey(-1));
+ }
+
+ [Test]
+ public void TestContainsKeys()
+ {
+ var cache = Cache();
+
+ var keys = PrimaryKeysForCache(cache, 5);
+
+ Assert.IsFalse(cache.ContainsKeys(keys));
+
+ cache.PutAll(keys.ToDictionary(k => k, k => k));
+
+ Assert.IsTrue(cache.ContainsKeys(keys));
+
+ Assert.IsFalse(cache.ContainsKeys(keys.Concat(new[] {int.MaxValue})));
+ }
+
+ [Test]
+ public void TestPeek()
+ {
+ var cache = Cache();
+
+ int key1 = PrimaryKeyForCache(cache);
+
+ cache.Put(key1, 1);
+
+ Assert.AreEqual(1, cache.LocalPeek(key1));
+ Assert.AreEqual(0, cache.LocalPeek(-1));
+
+ Assert.AreEqual(1, cache.LocalPeek(key1, CachePeekMode.All));
+ Assert.AreEqual(0, cache.LocalPeek(-1, CachePeekMode.All));
+ }
+
+ [Test]
+ public void TestGet()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(0, cache.Get(3));
+ }
+
+ [Test]
+ public void TestGetAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(0, cache.Get(3));
+ }
+
+ [Test]
+ public void TestGetAll()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+ cache.Put(3, 3);
+ cache.Put(4, 4);
+ cache.Put(5, 5);
+
+ IDictionary<int, int> map = cache.GetAll(new List<int> { 0, 1, 2, 5 });
+
+ Assert.AreEqual(3, map.Count);
+
+ Assert.AreEqual(1, map[1]);
+ Assert.AreEqual(2, map[2]);
+ }
+
+ [Test]
+ public void TestGetAllAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+ cache.Put(3, 3);
+
+ var map = cache.GetAll(new List<int> { 0, 1, 2 });
+
+ Assert.AreEqual(2, map.Count);
+
+ Assert.AreEqual(1, map[1]);
+ Assert.AreEqual(2, map[2]);
+ }
+
+ [Test]
+ public void TestGetAndPut()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ int old = cache.GetAndPut(1, 1);
+
+ Assert.AreEqual(0, old);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ old = cache.GetAndPut(1, 2);
+
+ Assert.AreEqual(1, old);
+
+ Assert.AreEqual(2, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndReplace()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 10);
+
+ Assert.AreEqual(10, cache.GetAndReplace(1, 100));
+
+ Assert.AreEqual(0, cache.GetAndReplace(2, 2));
+
+ Assert.AreEqual(0, cache.Get(2));
+
+ Assert.AreEqual(100, cache.Get(1));
+
+ Assert.IsTrue(cache.Remove(1));
+ }
+
+ [Test]
+ public void TestGetAndRemove()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(0, cache.GetAndRemove(0));
+
+ Assert.AreEqual(1, cache.GetAndRemove(1));
+
+ Assert.AreEqual(0, cache.GetAndRemove(1));
+
+ Assert.AreEqual(0, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndPutAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ int old = cache.GetAndPut(1, 1);
+
+ Assert.AreEqual(0, old);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ old = cache.GetAndPut(1, 2);
+
+ Assert.AreEqual(1, old);
+
+ Assert.AreEqual(2, cache.Get(1));
+ }
+
+ [Test]
+ public void TestPut()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestPutxAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestPutIfAbsent()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ Assert.AreEqual(true, cache.PutIfAbsent(1, 1));
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(false, cache.PutIfAbsent(1, 2));
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndPutIfAbsent()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ Assert.AreEqual(0, cache.GetAndPutIfAbsent(1, 1));
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(1, cache.GetAndPutIfAbsent(1, 2));
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndPutIfAbsentAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ int old = cache.GetAndPutIfAbsent(1, 1);
+
+ Assert.AreEqual(0, old);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ old = cache.GetAndPutIfAbsent(1, 2);
+
+ Assert.AreEqual(1, old);
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestPutIfAbsentAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ Assert.IsTrue(cache.PutIfAbsent(1, 1));
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsFalse(cache.PutIfAbsent(1, 2));
+
+ Assert.AreEqual(1, cache.Get(1));
+ }
+
+ [Test]
+ public void TestReplace()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ bool success = cache.Replace(1, 1);
+
+ Assert.AreEqual(false, success);
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ success = cache.Replace(1, 2);
+
+ Assert.AreEqual(true, success);
+
+ Assert.AreEqual(2, cache.Get(1));
+
+ Assert.IsFalse(cache.Replace(1, -1, 3));
+
+ Assert.AreEqual(2, cache.Get(1));
+
+ Assert.IsTrue(cache.Replace(1, 2, 3));
+
+ Assert.AreEqual(3, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndReplaceAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ int old = cache.GetAndReplace(1, 1);
+
+ Assert.AreEqual(0, old);
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ old = cache.GetAndReplace(1, 2);
+
+ Assert.AreEqual(1, old);
+
+ Assert.AreEqual(2, cache.Get(1));
+
+ Assert.IsFalse(cache.Replace(1, -1, 3));
+
+ Assert.AreEqual(2, cache.Get(1));
+
+ Assert.IsTrue(cache.Replace(1, 2, 3));
+
+ Assert.AreEqual(3, cache.Get(1));
+ }
+
+ [Test]
+ public void TestReplacex()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ Assert.IsFalse(cache.Replace(1, 1));
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsTrue(cache.Replace(1, 2));
+
+ Assert.AreEqual(2, cache.Get(1));
+ }
+
+ [Test]
+ public void TestReplaceAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ Assert.IsFalse(cache.Replace(1, 1));
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsTrue(cache.Replace(1, 2));
+
+ Assert.AreEqual(2, cache.Get(1));
+ }
+
+ [Test]
+ public void TestPutAll()
+ {
+ var cache = Cache();
+
+ cache.PutAll(new Dictionary<int, int> { { 1, 1 }, { 2, 2 }, { 3, 3 } });
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+ }
+
+ [Test]
+ public void TestPutAllAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.PutAll(new Dictionary<int, int> { { 1, 1 }, { 2, 2 }, { 3, 3 } });
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+ }
+
+ /// <summary>
+ /// Expiry policy tests.
+ /// </summary>
+ [Test]
+ public void TestWithExpiryPolicy()
+ {
+ ICache<int, int> cache0 = Cache(0);
+
+ int key0;
+ int key1;
+
+ if (LocalCache())
+ {
+ key0 = 0;
+ key1 = 1;
+ }
+ else
+ {
+ key0 = PrimaryKeyForCache(cache0);
+ key1 = PrimaryKeyForCache(Cache(1));
+ }
+
+ // Test unchanged expiration.
+ ICache<int, int> cache = cache0.WithExpiryPolicy(new ExpiryPolicy(null, null, null));
+
+ cache.Put(key0, key0);
+ cache.Put(key1, key1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache.Put(key0, key0 + 1);
+ cache.Put(key1, key1 + 1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache.Get(key0);
+ cache.Get(key1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache0.RemoveAll(new List<int> { key0, key1 });
+
+ // Test eternal expiration.
+ cache = cache0.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.MaxValue, TimeSpan.MaxValue, TimeSpan.MaxValue));
+
+ cache.Put(key0, key0);
+ cache.Put(key1, key1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache.Put(key0, key0 + 1);
+ cache.Put(key1, key1 + 1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache.Get(key0);
+ cache.Get(key1);
+ Thread.Sleep(200);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+
+ cache0.RemoveAll(new List<int> { key0, key1 });
+
+ // Test zero expiration.
+ cache = cache0.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero));
+
+ cache.Put(key0, key0);
+ cache.Put(key1, key1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+ cache.Put(key0, key0 + 1);
+ cache.Put(key1, key1 + 1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ cache.Get(key0);
+ cache.Get(key1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.RemoveAll(new List<int> { key0, key1 });
+
+ // Test negative expiration.
+ cache = cache0.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.FromMilliseconds(-100),
+ TimeSpan.FromMilliseconds(-100), TimeSpan.FromMilliseconds(-100)));
+
+ cache.Put(key0, key0);
+ cache.Put(key1, key1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+ cache.Put(key0, key0 + 1);
+ cache.Put(key1, key1 + 1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ cache.Get(key0);
+ cache.Get(key1);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.RemoveAll(new List<int> { key0, key1 });
+
+ // Test regular expiration.
+ cache = cache0.WithExpiryPolicy(new ExpiryPolicy(TimeSpan.FromMilliseconds(100),
+ TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)));
+
+ cache.Put(key0, key0);
+ cache.Put(key1, key1);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+ Thread.Sleep(200);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ cache.Put(key0, key0 + 1);
+ cache.Put(key1, key1 + 1);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+ Thread.Sleep(200);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+
+ cache0.Put(key0, key0);
+ cache0.Put(key1, key1);
+ cache.Get(key0);
+ cache.Get(key1);
+ Assert.IsTrue(cache0.ContainsKey(key0));
+ Assert.IsTrue(cache0.ContainsKey(key1));
+ Thread.Sleep(200);
+ Assert.IsFalse(cache0.ContainsKey(key0));
+ Assert.IsFalse(cache0.ContainsKey(key1));
+ }
+
+ [Test]
+ public void TestEvict()
+ {
+ var cache = Cache();
+
+ int key = PrimaryKeyForCache(cache);
+
+ cache.Put(key, 1);
+
+ Assert.AreEqual(1, PeekInt(cache, key));
+
+ cache.LocalEvict(new[] {key});
+
+ Assert.AreEqual(0, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(0, PeekInt(cache, key));
+
+ Assert.AreEqual(1, cache.Get(key));
+
+ Assert.AreEqual(1, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(1, PeekInt(cache, key));
+ }
+
+ [Test]
+ public void TestEvictAllKeys()
+ {
+ var cache = Cache();
+
+ List<int> keys = PrimaryKeysForCache(cache, 3);
+
+ cache.Put(keys[0], 1);
+ cache.Put(keys[1], 2);
+ cache.Put(keys[2], 3);
+
+ Assert.AreEqual(1, PeekInt(cache, keys[0]));
+ Assert.AreEqual(2, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+
+ cache.LocalEvict(new List<int> { -1, keys[0], keys[1] });
+
+ Assert.AreEqual(1, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(0, PeekInt(cache, keys[0]));
+ Assert.AreEqual(0, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+
+ Assert.AreEqual(1, cache.Get(keys[0]));
+ Assert.AreEqual(2, cache.Get(keys[1]));
+
+ Assert.AreEqual(3, cache.LocalSize());
+
+ Assert.AreEqual(1, PeekInt(cache, keys[0]));
+ Assert.AreEqual(2, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+ }
+
+ [Test]
+ public void TestClear()
+ {
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ cache.Put(PrimaryKeyForCache(cache, 500), 1);
+
+ Assert.IsFalse(cache.IsEmpty);
+ }
+
+ Cache().Clear();
+
+ for (int i = 0; i < GridCount(); i++)
+ Assert.IsTrue(Cache(i).IsEmpty);
+ }
+
+ [Test]
+ public void TestClearKey()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 10);
+
+ foreach (var key in keys)
+ cache.Put(key, 3);
+
+ var i = cache.Size();
+
+ foreach (var key in keys)
+ {
+ cache.Clear(key);
+
+ Assert.AreEqual(0, cache.Get(key));
+
+ Assert.Less(cache.Size(), i);
+
+ i = cache.Size();
+ }
+ }
+
+ [Test]
+ public void TestClearKeys()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 10);
+
+ foreach (var key in keys)
+ cache.Put(key, 3);
+
+ cache.ClearAll(keys);
+
+ foreach (var key in keys)
+ Assert.AreEqual(0, cache.Get(key));
+ }
+
+ [Test]
+ public void TestLocalClearKey()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 10);
+
+ foreach (var key in keys)
+ cache.Put(key, 3);
+
+ var i = cache.Size();
+
+ foreach (var key in keys)
+ {
+ cache.LocalClear(key);
+
+ Assert.AreEqual(0, cache.LocalPeek(key));
+
+ Assert.Less(cache.Size(), i);
+
+ i = cache.Size();
+ }
+
+ cache.Clear();
+ }
+
+ [Test]
+ public void TestLocalClearKeys()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 10);
+
+ foreach (var key in keys)
+ cache.Put(key, 3);
+
+ cache.LocalClearAll(keys);
+
+ foreach (var key in keys)
+ Assert.AreEqual(0, cache.LocalPeek(key));
+
+ cache.Clear();
+ }
+
+ [Test]
+ public void TestRemove()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(true, cache.Remove(1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsFalse(cache.Remove(1, -1));
+ Assert.IsTrue(cache.Remove(1, 1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+ }
+
+ [Test]
+ public void TestGetAndRemoveAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(1, cache.GetAndRemove(1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsFalse(cache.Remove(1, -1));
+ Assert.IsTrue(cache.Remove(1, 1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+ }
+
+ [Test]
+ public void TestRemovex()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsFalse(cache.Remove(-1));
+ Assert.IsTrue(cache.Remove(1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+ }
+
+ [Test]
+ public void TestRemoveAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ cache.Put(1, 1);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.IsFalse(cache.Remove(-1));
+ Assert.IsTrue(cache.Remove(1));
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(1));
+ }
+
+ [Test]
+ public void TestRemoveAll()
+ {
+ var cache = Cache();
+
+ List<int> keys = PrimaryKeysForCache(cache, 2);
+
+ cache.Put(keys[0], 1);
+ cache.Put(keys[1], 2);
+
+ Assert.AreEqual(1, cache.Get(keys[0]));
+ Assert.AreEqual(2, cache.Get(keys[1]));
+
+ cache.RemoveAll();
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(keys[0]));
+ Assert.AreEqual(0, cache.Get(keys[1]));
+ }
+
+ [Test]
+ public void TestRemoveAllAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ List<int> keys = PrimaryKeysForCache(cache, 2);
+
+ cache.Put(keys[0], 1);
+ cache.Put(keys[1], 2);
+
+ Assert.AreEqual(1, cache.Get(keys[0]));
+ Assert.AreEqual(2, cache.Get(keys[1]));
+
+ cache.RemoveAll();
+
+ Assert.AreEqual(0, cache.Size());
+
+ Assert.AreEqual(0, cache.Get(keys[0]));
+ Assert.AreEqual(0, cache.Get(keys[1]));
+ }
+
+ [Test]
+ public void TestRemoveAllKeys()
+ {
+ var cache = Cache();
+
+ Assert.AreEqual(0, cache.Size());
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+ cache.Put(3, 3);
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+
+ cache.RemoveAll(new List<int> { 0, 1, 2 });
+
+ Assert.AreEqual(1, cache.Size(CachePeekMode.Primary));
+
+ Assert.AreEqual(0, cache.Get(1));
+ Assert.AreEqual(0, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+ }
+
+ [Test]
+ public void TestRemoveAllKeysAsync()
+ {
+ var cache = Cache().WithAsync().WrapAsync();
+
+ Assert.AreEqual(0, cache.Size());
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+ cache.Put(3, 3);
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+
+ cache.RemoveAll(new List<int> { 0, 1, 2 });
+
+ Assert.AreEqual(1, cache.Size(CachePeekMode.Primary));
+
+ Assert.AreEqual(0, cache.Get(1));
+ Assert.AreEqual(0, cache.Get(2));
+ Assert.AreEqual(3, cache.Get(3));
+ }
+
+ [Test]
+ public void TestSizes()
+ {
+ for (int i = 0; i < GridCount(); i++)
+ {
+ var cache = Cache(i);
+
+ List<int> keys = PrimaryKeysForCache(cache, 2);
+
+ foreach (int key in keys)
+ cache.Put(key, 1);
+
+ Assert.IsTrue(cache.Size() >= 2);
+ Assert.AreEqual(2, cache.LocalSize(CachePeekMode.Primary));
+ }
+
+ ICache<int, int> cache0 = Cache();
+
+ Assert.AreEqual(GridCount() * 2, cache0.Size(CachePeekMode.Primary));
+
+ if (!LocalCache() && !ReplicatedCache())
+ {
+ int nearKey = NearKeyForCache(cache0);
+
+ cache0.Put(nearKey, 1);
+
+ Assert.AreEqual(NearEnabled() ? 1 : 0, cache0.Size(CachePeekMode.Near));
+ }
+ }
+
+ [Test]
+ public void TestLocalSize()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 3);
+
+ cache.Put(keys[0], 1);
+ cache.Put(keys[1], 2);
+
+ var localSize = cache.LocalSize();
+
+ cache.LocalEvict(keys.Take(2).ToArray());
+
+ Assert.AreEqual(0, cache.LocalSize(CachePeekMode.Onheap));
+ Assert.AreEqual(localSize, cache.LocalSize(CachePeekMode.All));
+
+ cache.Put(keys[2], 3);
+
+ Assert.AreEqual(localSize + 1, cache.LocalSize(CachePeekMode.All));
+
+ cache.RemoveAll(keys.Take(2).ToArray());
+ }
+
+ /// <summary>
+ /// Test enumerators.
+ /// </summary>
+ [Test]
+ [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
+ public void TestEnumerators()
+ {
+ var cache = Cache();
+ var keys = PrimaryKeysForCache(cache, 2);
+
+ cache.Put(keys[0], keys[0] + 1);
+ cache.Put(keys[1], keys[1] + 1);
+
+ // Check distributed enumerator.
+ IEnumerable<ICacheEntry<int, int>> e = cache;
+
+ CheckEnumerator(e.GetEnumerator(), keys);
+ CheckEnumerator(e.GetEnumerator(), keys);
+
+ // Check local enumerator.
+ e = cache.GetLocalEntries();
+
+ CheckEnumerator(e.GetEnumerator(), keys);
+ CheckEnumerator(e.GetEnumerator(), keys);
+
+ // Evict and check peek modes.
+ cache.LocalEvict(new List<int> { keys[0] } );
+
+ e = cache.GetLocalEntries(CachePeekMode.Onheap);
+ CheckEnumerator(e.GetEnumerator(), new List<int> { keys[1] });
+ CheckEnumerator(e.GetEnumerator(), new List<int> { keys[1] });
+
+ e = cache.GetLocalEntries(CachePeekMode.All);
+ CheckEnumerator(e.GetEnumerator(), keys);
+ CheckEnumerator(e.GetEnumerator(), keys);
+
+ e = cache.GetLocalEntries(CachePeekMode.Onheap, CachePeekMode.Swap);
+ CheckEnumerator(e.GetEnumerator(), keys);
+ CheckEnumerator(e.GetEnumerator(), keys);
+
+ cache.Remove(keys[0]);
+ }
+
+ /// <summary>
+ /// Check enumerator content.
+ /// </summary>
+ /// <param name="e">Enumerator.</param>
+ /// <param name="keys">Keys.</param>
+ private static void CheckEnumerator(IEnumerator<ICacheEntry<int, int>> e, IList<int> keys)
+ {
+ CheckEnumerator0(e, keys);
+
+ e.Reset();
+
+ CheckEnumerator0(e, keys);
+
+ e.Dispose();
+
+ Assert.Throws<ObjectDisposedException>(() => { e.MoveNext(); });
+ Assert.Throws<ObjectDisposedException>(() => { var entry = e.Current; });
+ Assert.Throws<ObjectDisposedException>(e.Reset);
+
+ e.Dispose();
+ }
+
+ /// <summary>
+ /// Check enumerator content.
+ /// </summary>
+ /// <param name="e">Enumerator.</param>
+ /// <param name="keys">Keys.</param>
+ private static void CheckEnumerator0(IEnumerator<ICacheEntry<int, int>> e, IList<int> keys)
+ {
+ Assert.Throws<InvalidOperationException>(() => { var entry = e.Current; });
+
+ int cnt = 0;
+
+ while (e.MoveNext())
+ {
+ ICacheEntry<int, int> entry = e.Current;
+
+ Assert.IsTrue(keys.Contains(entry.Key), "Unexpected entry: " + entry);
+
+ Assert.AreEqual(entry.Key + 1, entry.Value);
+
+ cnt++;
+ }
+
+ Assert.AreEqual(keys.Count, cnt);
+
+ Assert.IsFalse(e.MoveNext());
+
+ Assert.Throws<InvalidOperationException>(() => { var entry = e.Current; });
+ }
+
+ [Test]
+ public void TestPromote()
+ {
+ var cache = Cache();
+
+ int key = PrimaryKeyForCache(cache);
+
+ cache.Put(key, 1);
+
+ Assert.AreEqual(1, PeekInt(cache, key));
+
+ cache.LocalEvict(new[] {key});
+
+ Assert.AreEqual(0, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(0, PeekInt(cache, key));
+
+ cache.LocalPromote(new[] { key });
+
+ Assert.AreEqual(1, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(1, PeekInt(cache, key));
+ }
+
+ [Test]
+ public void TestPromoteAll()
+ {
+ var cache = Cache();
+
+ List<int> keys = PrimaryKeysForCache(cache, 3);
+
+ cache.Put(keys[0], 1);
+ cache.Put(keys[1], 2);
+ cache.Put(keys[2], 3);
+
+ Assert.AreEqual(1, PeekInt(cache, keys[0]));
+ Assert.AreEqual(2, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+
+ cache.LocalEvict(new List<int> { -1, keys[0], keys[1] });
+
+ Assert.AreEqual(1, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(0, PeekInt(cache, keys[0]));
+ Assert.AreEqual(0, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+
+ cache.LocalPromote(new[] {keys[0], keys[1]});
+
+ Assert.AreEqual(3, cache.LocalSize(CachePeekMode.Onheap));
+
+ Assert.AreEqual(1, PeekInt(cache, keys[0]));
+ Assert.AreEqual(2, PeekInt(cache, keys[1]));
+ Assert.AreEqual(3, PeekInt(cache, keys[2]));
+ }
+
+ [Test]
+ public void TestPutGetPortable()
+ {
+ var cache = Cache<int, PortablePerson>();
+
+ PortablePerson obj1 = new PortablePerson("obj1", 1);
+
+ cache.Put(1, obj1);
+
+ obj1 = cache.Get(1);
+
+ Assert.AreEqual("obj1", obj1.Name);
+ Assert.AreEqual(1, obj1.Age);
+ }
+
+ [Test]
+ public void TestPutGetPortableAsync()
+ {
+ var cache = Cache<int, PortablePerson>().WithAsync().WrapAsync();
+
+ PortablePerson obj1 = new PortablePerson("obj1", 1);
+
+ cache.Put(1, obj1);
+
+ obj1 = cache.Get(1);
+
+ Assert.AreEqual("obj1", obj1.Name);
+ Assert.AreEqual(1, obj1.Age);
+ }
+
+ [Test]
+ public void TestPutGetPortableKey()
+ {
+ var cache = Cache<CacheTestKey, string>();
+
+ int cnt = 100;
+
+ for (int i = 0; i < cnt; i++)
+ cache.Put(new CacheTestKey(i), "val-" + i);
+
+ for (int i = 0; i < cnt; i++)
+ Assert.AreEqual("val-" + i, cache.Get(new CacheTestKey(i)));
+ }
+
+ [Test]
+ public void TestGetAsync2()
+ {
+ var cache = Cache().WithAsync();
+
+ for (int i = 0; i < 100; i++)
+ {
+ cache.Put(i, i);
+
+ cache.GetFuture<object>().Get();
+ }
+
+ var futs = new List<IFuture<int>>();
+
+ for (int i = 0; i < 1000; i++)
+ {
+ cache.Get(i % 100);
+
+ futs.Add(cache.GetFuture<int>());
+ }
+
+ for (int i = 0; i < 1000; i++) {
+ Assert.AreEqual(i % 100, futs[i].Get(), "Unexpected result: " + i);
+
+ Assert.IsTrue(futs[i].IsDone);
+ }
+ }
+
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestGetAsyncMultithreaded()
+ {
+ var cache = Cache().WithAsync();
+
+ for (int i = 0; i < 100; i++)
+ {
+ cache.Put(i, i);
+
+ cache.GetFuture<object>().Get();
+ }
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ for (int i = 0; i < 100; i++)
+ {
+ var futs = new List<IFuture<int>>();
+
+ for (int j = 0; j < 100; j++)
+ {
+ cache.Get(j);
+
+ futs.Add(cache.GetFuture<int>());
+ }
+
+ for (int j = 0; j < 100; j++)
+ Assert.AreEqual(j, futs[j].Get());
+ }
+ }, 10);
+ }
+
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPutxAsyncMultithreaded()
+ {
+ var cache = Cache().WithAsync();
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ Random rnd = new Random();
+
+ for (int i = 0; i < 50; i++)
+ {
+ var futs = new List<IFuture<object>>();
+
+ for (int j = 0; j < 10; j++)
+ {
+ cache.Put(rnd.Next(1000), i);
+
+ futs.Add(cache.GetFuture<object>());
+ }
+
+ foreach (var fut in futs)
+ fut.Get();
+ }
+ }, 5);
+ }
+
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestPutGetAsyncMultithreaded()
+ {
+ var cache = Cache<CacheTestKey, PortablePerson>().WithAsync();
+
+ const int threads = 10;
+ const int objPerThread = 1000;
+
+ int cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ // ReSharper disable once AccessToModifiedClosure
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ var futs = new List<IFuture<object>>();
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Put(new CacheTestKey(key), new PortablePerson("Person-" + key, key));
+
+ futs.Add(cache.GetFuture<object>());
+ }
+
+ foreach (var fut in futs)
+ {
+ fut.Get();
+
+ Assert.IsTrue(fut.IsDone);
+ }
+ }, threads);
+
+ for (int i = 0; i < threads; i++)
+ {
+ int threadIdx = i + 1;
+
+ for (int j = 0; j < objPerThread; j++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Get(new CacheTestKey(key));
+ var p = cache.GetFuture<PortablePerson>().Get();
+
+ Assert.IsNotNull(p);
+ Assert.AreEqual(key, p.Age);
+ Assert.AreEqual("Person-" + key, p.Name);
+ }
+ }
+
+ cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Put(new CacheTestKey(key), new PortablePerson("Person-" + key, key));
+
+ cache.GetFuture<object>().Get();
+ }
+ }, threads);
+
+ cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ var futs = new List<IFuture<PortablePerson>>();
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Get(new CacheTestKey(key));
+
+ futs.Add(cache.GetFuture<PortablePerson>());
+ }
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ var fut = futs[i];
+
+ int key = threadIdx * objPerThread + i;
+
+ var p = fut.Get();
+
+ Assert.IsNotNull(p);
+ Assert.AreEqual(key, p.Age);
+ Assert.AreEqual("Person-" + key, p.Name);
+ }
+ }, threads);
+ }
+
+ //[Test]
+ //[Category(TestUtils.CATEGORY_INTENSIVE)]
+ public void TestAsyncMultithreadedKeepPortable()
+ {
+ var cache = Cache().WithAsync().WithKeepPortable<CacheTestKey, PortablePerson>();
+ var portCache = Cache().WithAsync().WithKeepPortable<CacheTestKey, IPortableObject>();
+
+ const int threads = 10;
+ const int objPerThread = 1000;
+
+ int cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ // ReSharper disable once AccessToModifiedClosure
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ var futs = new List<IFuture<object>>();
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Put(new CacheTestKey(key), new PortablePerson("Person-" + key, key));
+
+ futs.Add(cache.GetFuture<object>());
+ }
+
+ foreach (var fut in futs)
+ Assert.IsNull(fut.Get());
+ }, threads);
+
+ for (int i = 0; i < threads; i++)
+ {
+ int threadIdx = i + 1;
+
+ for (int j = 0; j < objPerThread; j++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ IPortableObject p = portCache.Get(new CacheTestKey(key));
+
+ Assert.IsNotNull(p);
+ Assert.AreEqual(key, p.Field<int>("age"));
+ Assert.AreEqual("Person-" + key, p.Field<string>("name"));
+ }
+ }
+
+ cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ var futs = new List<IFuture<IPortableObject>>();
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ portCache.Get(new CacheTestKey(key));
+
+ futs.Add(cache.GetFuture<IPortableObject>());
+ }
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ var fut = futs[i];
+
+ int key = threadIdx * objPerThread + i;
+
+ var p = fut.Get();
+
+ Assert.IsNotNull(p);
+ Assert.AreEqual(key, p.Field<int>("age"));
+ Assert.AreEqual("Person-" + key, p.Field<string>("name"));
+ }
+ }, threads);
+
+ cntr = 0;
+
+ TestUtils.RunMultiThreaded(() =>
+ {
+ int threadIdx = Interlocked.Increment(ref cntr);
+
+ var futs = new List<IFuture<bool>>();
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ int key = threadIdx * objPerThread + i;
+
+ cache.Remove(new CacheTestKey(key));
+
+ futs.Add(cache.GetFuture<bool>());
+ }
+
+ for (int i = 0; i < objPerThread; i++)
+ {
+ var fut = futs[i];
+
+ Assert.AreEqual(true, fut.Get());
+ }
+ }, threads);
+ }
+
+ [Test]
+ [Ignore("IGNITE-835")]
+ public void TestLock()
+ {
+ if (!LockingEnabled())
+ return;
+
+ var cache = Cache();
+
+ const int key = 7;
+
+ // Lock
+ CheckLock(cache, key, () => cache.Lock(key));
+
+ // LockAll
+ CheckLock(cache, key, () => cache.LockAll(new[] { key, 2, 3, 4, 5 }));
+ }
+
+ /// <summary>
+ /// Internal lock test routine.
+ /// </summary>
+ /// <param name="cache">Cache.</param>
+ /// <param name="key">Key.</param>
+ /// <param name="getLock">Function to get the lock.</param>
+ private static void CheckLock(ICache<int, int> cache, int key, Func<ICacheLock> getLock)
+ {
+ var sharedLock = getLock();
+
+ using (sharedLock)
+ {
+ Assert.Throws<InvalidOperationException>(() => sharedLock.Exit()); // can't exit if not entered
+
+ sharedLock.Enter();
+
+ try
+ {
+ Assert.IsTrue(cache.IsLocalLocked(key, true));
+ Assert.IsTrue(cache.IsLocalLocked(key, false));
+
+ EnsureCannotLock(getLock, sharedLock);
+
+ sharedLock.Enter();
+
+ try
+ {
+ Assert.IsTrue(cache.IsLocalLocked(key, true));
+ Assert.IsTrue(cache.IsLocalLocked(key, false));
+
+ EnsureCannotLock(getLock, sharedLock);
+ }
+ finally
+ {
+ sharedLock.Exit();
+ }
+
+ Assert.IsTrue(cache.IsLocalLocked(key, true));
+ Assert.IsTrue(cache.IsLocalLocked(key, false));
+
+ EnsureCannotLock(getLock, sharedLock);
+
+ Assert.Throws<SynchronizationLockException>(() => sharedLock.Dispose()); // can't dispose while locked
+ }
+ finally
+ {
+ sharedLock.Exit();
+ }
+
+ Assert.IsFalse(cache.IsLocalLocked(key, true));
+ Assert.IsFalse(cache.IsLocalLocked(key, false));
+
+ var innerTask = new Task(() =>
+ {
+ Assert.IsTrue(sharedLock.TryEnter());
+ sharedLock.Exit();
+
+ using (var otherLock = getLock())
+ {
+ Assert.IsTrue(otherLock.TryEnter());
+ otherLock.Exit();
+ }
+ });
+
+ innerTask.Start();
+ innerTask.Wait();
+ }
+
+ Assert.IsFalse(cache.IsLocalLocked(key, true));
+ Assert.IsFalse(cache.IsLocalLocked(key, false));
+
+ var outerTask = new Task(() =>
+ {
+ using (var otherLock = getLock())
+ {
+ Assert.IsTrue(otherLock.TryEnter());
+ otherLock.Exit();
+ }
+ });
+
+ outerTask.Start();
+ outerTask.Wait();
+
+ Assert.Throws<ObjectDisposedException>(() => sharedLock.Enter()); // Can't enter disposed lock
+ }
+
+ /// <summary>
+ /// ENsure taht lock cannot be obtained by other threads.
+ /// </summary>
+ /// <param name="getLock">Get lock function.</param>
+ /// <param name="sharedLock">Shared lock.</param>
+ private static void EnsureCannotLock(Func<ICacheLock> getLock, ICacheLock sharedLock)
+ {
+ var task = new Task(() =>
+ {
+ Assert.IsFalse(sharedLock.TryEnter());
+ Assert.IsFalse(sharedLock.TryEnter(TimeSpan.FromMilliseconds(100)));
+
+ using (var otherLock = getLock())
+ {
+ Assert.IsFalse(otherLock.TryEnter());
+ Assert.IsFalse(otherLock.TryEnter(TimeSpan.FromMilliseconds(100)));
+ }
+ });
+
+ task.Start();
+ task.Wait();
+ }
+
+ [Test]
+ public void TestTxCommit()
+ {
+ TestTxCommit(false);
+ }
+
+ [Test]
+ public void TestTxCommitAsync()
+ {
+ TestTxCommit(true);
+ }
+
+ private void TestTxCommit(bool async)
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ ITransaction tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+
+ tx = Transactions.TxStart();
+
+ try
+ {
+ cache.Put(1, 1);
+
+ cache.Put(2, 2);
+
+ if (async)
+ {
+ var asyncTx = tx.WithAsync();
+
+ asyncTx.Commit();
+
+ var fut = asyncTx.GetFuture();
+
+ fut.Get();
+
+ Assert.IsTrue(fut.IsDone);
+ Assert.AreEqual(fut.Get(), null);
+ }
+ else
+ tx.Commit();
+ }
+ finally
+ {
+ tx.Dispose();
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(2, cache.Get(2));
+
+ tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+ }
+
+ [Test]
+ public void TestTxRollback()
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ cache.Put(2, 2);
+
+ ITransaction tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+
+ tx = Transactions.TxStart();
+
+ try {
+ cache.Put(1, 10);
+
+ cache.Put(2, 20);
+ }
+ finally {
+ tx.Rollback();
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(2, cache.Get(2));
+
+ Assert.IsNull(Transactions.Tx);
+ }
+
+ [Test]
+ public void TestTxClose()
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ cache.Put(2, 2);
+
+ ITransaction tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+
+ tx = Transactions.TxStart();
+
+ try
+ {
+ cache.Put(1, 10);
+
+ cache.Put(2, 20);
+ }
+ finally
+ {
+ tx.Dispose();
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(2, cache.Get(2));
+
+ tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+ }
+
+ [Test]
+ public void TestTxAllModes()
+ {
+ TestTxAllModes(false);
+
+ TestTxAllModes(true);
+
+ Console.WriteLine("Done");
+ }
+
+ protected void TestTxAllModes(bool withTimeout)
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ int cntr = 0;
+
+ foreach (TransactionConcurrency concurrency in Enum.GetValues(typeof(TransactionConcurrency))) {
+ foreach (TransactionIsolation isolation in Enum.GetValues(typeof(TransactionIsolation))) {
+ Console.WriteLine("Test tx [concurrency=" + concurrency + ", isolation=" + isolation + "]");
+
+ ITransaction tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+
+ tx = withTimeout
+ ? Transactions.TxStart(concurrency, isolation, TimeSpan.FromMilliseconds(1100), 10)
+ : Transactions.TxStart(concurrency, isolation);
+
+ Assert.AreEqual(concurrency, tx.Concurrency);
+ Assert.AreEqual(isolation, tx.Isolation);
+
+ if (withTimeout)
+ Assert.AreEqual(1100, tx.Timeout.TotalMilliseconds);
+
+ try {
+ cache.Put(1, cntr);
+
+ tx.Commit();
+ }
+ finally {
+ tx.Dispose();
+ }
+
+ tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+
+ Assert.AreEqual(cntr, cache.Get(1));
+
+ cntr++;
+ }
+ }
+ }
+
+ [Test]
+ public void TestTxAttributes()
+ {
+ if (!TxEnabled())
+ return;
+
+ ITransaction tx = Transactions.TxStart(TransactionConcurrency.Optimistic,
+ TransactionIsolation.RepeatableRead, TimeSpan.FromMilliseconds(2500), 100);
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+ Assert.AreEqual(TransactionConcurrency.Optimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.RepeatableRead, tx.Isolation);
+ Assert.AreEqual(2500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(TransactionState.Active, tx.State);
+ Assert.IsTrue(tx.StartTime.Ticks > 0);
+ Assert.AreEqual(tx.NodeId, GetIgnite(0).Cluster.LocalNode.Id);
+
+ DateTime startTime1 = tx.StartTime;
+
+ tx.Commit();
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+ Assert.AreEqual(TransactionState.Committed, tx.State);
+ Assert.AreEqual(TransactionConcurrency.Optimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.RepeatableRead, tx.Isolation);
+ Assert.AreEqual(2500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(startTime1, tx.StartTime);
+
+ Thread.Sleep(100);
+
+ tx = Transactions.TxStart(TransactionConcurrency.Pessimistic, TransactionIsolation.ReadCommitted,
+ TimeSpan.FromMilliseconds(3500), 200);
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+ Assert.AreEqual(TransactionConcurrency.Pessimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.ReadCommitted, tx.Isolation);
+ Assert.AreEqual(3500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(TransactionState.Active, tx.State);
+ Assert.IsTrue(tx.StartTime.Ticks > 0);
+ Assert.IsTrue(tx.StartTime > startTime1);
+
+ DateTime startTime2 = tx.StartTime;
+
+ tx.Rollback();
+
+ Assert.AreEqual(TransactionState.RolledBack, tx.State);
+ Assert.AreEqual(TransactionConcurrency.Pessimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.ReadCommitted, tx.Isolation);
+ Assert.AreEqual(3500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(startTime2, tx.StartTime);
+
+ Thread.Sleep(100);
+
+ tx = Transactions.TxStart(TransactionConcurrency.Optimistic, TransactionIsolation.RepeatableRead,
+ TimeSpan.FromMilliseconds(2500), 100);
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+ Assert.AreEqual(TransactionConcurrency.Optimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.RepeatableRead, tx.Isolation);
+ Assert.AreEqual(2500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(TransactionState.Active, tx.State);
+ Assert.IsTrue(tx.StartTime > startTime2);
+
+ DateTime startTime3 = tx.StartTime;
+
+ tx.Commit();
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+ Assert.AreEqual(TransactionState.Committed, tx.State);
+ Assert.AreEqual(TransactionConcurrency.Optimistic, tx.Concurrency);
+ Assert.AreEqual(TransactionIsolation.RepeatableRead, tx.Isolation);
+ Assert.AreEqual(2500, tx.Timeout.TotalMilliseconds);
+ Assert.AreEqual(startTime3, tx.StartTime);
+ }
+
+ [Test]
+ public void TestTxRollbackOnly()
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ cache.Put(1, 1);
+
+ cache.Put(2, 2);
+
+ ITransaction tx = Transactions.TxStart();
+
+ cache.Put(1, 10);
+
+ cache.Put(2, 20);
+
+ Assert.IsFalse(tx.IsRollbackOnly);
+
+ tx.SetRollbackonly();
+
+ Assert.IsTrue(tx.IsRollbackOnly);
+
+ Assert.AreEqual(TransactionState.MarkedRollback, tx.State);
+
+ try
+ {
+ tx.Commit();
+
+ Assert.Fail("Commit must fail.");
+ }
+ catch (IgniteException e)
+ {
+ Console.WriteLine("Expected exception: " + e);
+ }
+
+ tx.Dispose();
+
+ Assert.AreEqual(TransactionState.RolledBack, tx.State);
+
+ Assert.IsTrue(tx.IsRollbackOnly);
+
+ Assert.AreEqual(1, cache.Get(1));
+
+ Assert.AreEqual(2, cache.Get(2));
+
+ tx = Transactions.Tx;
+
+ Assert.IsNull(tx);
+ }
+
+ [Test]
+ public void TestTxMetrics()
+ {
+ if (!TxEnabled())
+ return;
+
+ var cache = Cache();
+
+ var startTime = DateTime.UtcNow.AddSeconds(-1);
+
+ Transactions.ResetMetrics();
+
+ var metrics = Transactions.GetMetrics();
+
+ Assert.AreEqual(0, metrics.TxCommits);
+ Assert.AreEqual(0, metrics.TxRollbacks);
+
+ using (Transactions.TxStart())
+ {
+ cache.Put(1, 1);
+ }
+
+ using (var tx = Transactions.TxStart())
+ {
+ cache.Put(1, 1);
+ tx.Commit();
+ }
+
+ metrics = Transactions.GetMetrics();
+
+ Assert.AreEqual(1, metrics.TxCommits);
+ Assert.AreEqual(1, metrics.TxRollbacks);
+
+ Assert.LessOrEqual(startTime, metrics.CommitTime);
+ Assert.LessOrEqual(startTime, metrics.RollbackTime);
+
+ Assert.GreaterOrEqual(DateTime.UtcNow, metrics.CommitTime);
+ Assert.GreaterOrEqual(DateTime.UtcNow, metrics.RollbackTime);
+ }
+
+ [Test]
+ public void TestTxStateAndExceptions()
+ {
+ if (!TxEnabled())
+ return;
+
+ var tx = Transactions.TxStart();
+
+ Assert.AreEqual(TransactionState.Active, tx.State);
+
+ tx.Rollback();
+
+ Assert.AreEqual(TransactionState.RolledBack, tx.State);
+
+ try
+ {
+ tx.Commit();
+ Assert.Fail();
+ }
+ catch (InvalidOperationException)
+ {
+ // Expected
+ }
+
+ tx = Transactions.TxStart().WithAsync();
+
+ Assert.AreEqual(TransactionState.Active, tx.State);
+
+ tx.Commit();
+
+ tx.GetFuture().Get();
+
+ Assert.AreEqual(TransactionState.Committed, tx.State);
+
+ tx.Rollback(); // Illegal, but should not fail here; will fail in future
+
+ try
+ {
+ tx.GetFuture<object>().Get();
+ Assert.Fail();
+ }
+ catch (InvalidOperationException)
+ {
+ // Expected
+ }
+ }
+
+ /// <summary>
+ /// Test thraed-locals leak.
+ /// </summary>
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestThreadLocalLeak()
+ {
+ var cache = Cache<string, string>();
+
+ Exception err = null;
+
+ const int threadCnt = 10;
+
+ Thread[] threads = new Thread[threadCnt];
+
+ ThreadStart[] threadStarts = new ThreadStart[threadCnt];
+
+ for (int j = 0; j < threadCnt; j++)
+ {
+ string key = "key" + j;
+
+ threadStarts[j] = () =>
+ {
+ try
+ {
+ cache.Put(key, key);
+
+ Assert.AreEqual(key, cache.Get(key));
+ }
+ catch (Exception e)
+ {
+ Interlocked.CompareExchange(ref err, e, null);
+
+ Assert.Fail("Unexpected error: " + e);
+ }
+ };
+ }
+
+ for (int i = 0; i < 100 && err == null; i++)
+ {
+ for (int j = 0 ; j < threadCnt; j++) {
+ Thread t = new Thread(threadStarts[j]);
+
+ threads[j] = t;
+ }
+
+ foreach (Thread t in threads)
+ t.Start();
+
+ foreach (Thread t in threads)
+ t.Join();
+
+ if (i % 500 == 0)
+ {
+ Console.WriteLine("Iteration: " + i);
+
+ GC.Collect();
+ }
+ }
+
+ Assert.IsNull(err);
+ }
+
+ //// TODO [Test]
+ //public void TestCacheEntryGetSetRemove()
+ //{
+ // TestCacheEntryGetSetRemove(false);
+ //}
+
+ //// TODO [Test]
+ //public void TestCacheEntryGetSetRemoveAsync()
+ //{
+ // TestCacheEntryGetSetRemove(true);
+ //}
+
+ //private void TestCacheEntryGetSetRemove(bool async)
+ //{
+ // IGridCache cache = Cache();
+
+ // int key = PrimaryKeyForCache(cache);
+
+ // IGridCacheEntry<int, int> e = cache.Entry(key);
+
+ // Assert.IsNotNull(e);
+
+ // if (async)
+ // {
+ // IGridFuture<int> fut = e.GetAsync();
+
+ // Assert.IsNull(fut.Result);
+
+ // Assert.IsTrue(fut.IsDone);
+
+ // fut = e.SetAsync(10);
+
+ // Assert.IsNull(fut.Result);
+
+ // Assert.IsTrue(fut.IsDone);
+
+ // fut = e.GetAsync();
+
+ // Assert.AreEqual(10, fut.Result);
+
+ // Assert.IsTrue(fut.IsDone);
+ // }
+ // else
+ // {
+ // Assert.IsNull(e.Get());
+
+ // Assert.IsNull(e.Set(10));
+
+ // Assert.AreEqual(10, e.Get());
+ // }
+
+ // Assert.AreEqual(10, cache.Get(key));
+
+ // if (async)
+ // {
+ // IGridFuture<int> fut = e.RemoveAsync();
+
+ // Assert.AreEqual(10, fut.Result);
+
+ // Assert.IsTrue(fut.IsDone);
+ // }
+ // else
+ // Assert.AreEqual(10, e.Remove());
+
+ // Assert.IsNull(e.Get());
+
+ // Assert.IsNull(cache.Get(key));
+ //}
+
+ /**
+ * Test tries to provoke garbage collection for .Net future before it was completed to verify
+ * futures pinning works.
+ */
+ [Test]
+ [Category(TestUtils.CategoryIntensive)]
+ public void TestFuturesGc()
+ {
+ var cache = Cache().WithAsync();
+
+ cache.Put(1, 1);
+
+ for (int i = 0; i < 10; i++)
+ {
+ TestUtils.RunMultiThreaded(() =>
+ {
+ for (int j = 0; j < 1000; j++)
+ cache.Get(1);
+ }, 5);
+
+ GC.Collect();
+
+ cache.Get(1);
+ Assert.AreEqual(1, cache.GetFuture<int>().Get());
+ }
+
+ Thread.Sleep(2000);
+ }
+
+ [Test]
+ public void TestPartitions()
+ {
+ ICacheAffinity aff = Affinity();
+
+ for (int i = 0; i < 5; i++ )
+ Assert.AreEqual(CachePartitions(), aff.Partitions);
+ }
+
+ [Test]
+ public void TestKeyPartition()
+ {
+ ICacheAffinity aff = Affinity();
+
+ {
+ ISet<int> parts = new HashSet<int>();
+
+ for (int i = 0; i < 1000; i++)
+ parts.Add(aff.Partition(i));
+
+ if (LocalCache())
+ Assert.AreEqual(1, parts.Count);
+ else
+ Assert.IsTrue(parts.Count > 10);
+ }
+
+ {
+ ISet<int> parts = new HashSet<int>();
+
+ for (int i = 0; i < 1000; i++)
+ parts.Add(aff.Partition("key" + i));
+
+ if (LocalCache())
+ Assert.AreEqual(1, parts.Count);
+ else
+ Assert.IsTrue(parts.Count > 10);
+ }
+ }
+
+ [Test]
+ public void TestIsPrimaryOrBackup()
+ {
+ ICacheAffinity aff = Affinity();
+
+ ICollection<IClusterNode> nodes = GetIgnite(0).Cluster.Nodes();
+
+ Assert.IsTrue(nodes.Count > 0);
+
+ IClusterNode node = nodes.First();
+
+ {
+ bool found = false;
+
+ for (int i = 0; i < 1000; i++)
+ {
+ if (aff.IsPrimary(node, i))
+ {
+ Assert.IsTrue(aff.IsPrimaryOrBackup(node, i));
+
+ found = true;
+
+ if (nodes.Count > 1)
+ Assert.IsFalse(aff.IsPrimary(nodes.Last(), i));
+
+ break;
+ }
+ }
+
+ Assert.IsTrue(found, "Failed to find primary key for node " + node);
+ }
+
+ if (nodes.Count > 1)
+ {
+ bool found = false;
+
+ for (int i = 0; i < 1000; i++)
+ {
+ if (aff.IsBackup(node, i))
+ {
+ Assert.IsTrue(aff.IsPrimaryOrBackup(node, i));
+
+ found = true;
+
+ break;
+ }
+ }
+
+ Assert.IsTrue(found, "Failed to find backup key for node " + node);
+ }
+ }
+
+ [Test]
+ public void TestNodePartitions()
+ {
+ ICacheAffinity aff = Affinity();
+
+ ICollection<IClusterNode> nodes = GetIgnite(0).Cluster.Nodes();
+
+ Assert.IsTrue(nodes.Count > 0);
+
+ if (nodes.Count == 1)
+ {
+ IClusterNode node = nodes.First();
+
+ int[] parts = aff.BackupPartitions(node);
+
+ Assert.AreEqual(0, parts.Length);
+
+ parts = aff.AllPartitions(node);
+
+ Assert.AreEqual(CachePartitions(), parts.Length);
+ }
+ else
+ {
+ IList<int> allPrimaryParts = new List<int>();
+ IList<int> allBackupParts = new List<int>();
+ IList<int> allParts = new List<int>();
+
+ foreach(IClusterNode node in nodes) {
+ int[] parts = aff.PrimaryPartitions(node);
+
+ foreach (int part in parts)
+ allPrimaryParts.Add(part);
+
+ parts = aff.BackupPartitions(node);
+
+ foreach (int part in parts)
+ allBackupParts.Add(part);
+
+ parts = aff.AllPartitions(node);
+
+ foreach (int part in parts)
+ allParts.Add(part);
+ }
+
+ Assert.AreEqual(CachePartitions(), allPrimaryParts.Count);
+ Assert.AreEqual(CachePartitions() * Backups(), allBackupParts.Count);
+ Assert.AreEqual(CachePartitions() * (Backups() + 1), allParts.Count);
+ }
+ }
+
+ [Test]
+ public void TestAffinityKey()
+ {
+ ICacheAffinity aff = Affinity();
+
+ Assert.AreEqual(10, aff.AffinityKey<int, int>(10));
+
+ Assert.AreEqual("string", aff.AffinityKey<string, string>("string"));
+ }
+
+ [Test]
+ public void TestMapToNode()
+ {
+ ICacheAffinity aff = Affinity();
+
+ const int key = 1;
+
+ IClusterNode node = aff.MapKeyToNode(key);
+
+ Assert.IsNotNull(node);
+
+ Assert.IsTrue(GetIgnite(0).Cluster.Nodes().Contains(node));
+
+ Assert.IsTrue(aff.IsPrimary(node, key));
+
+ Assert.IsTrue(aff.IsPrimaryOrBackup(node, key));
+
+ Assert.IsFalse(aff.IsBackup(node, key));
+
+ int part = aff.Partition(key);
+
+ IClusterNode partNode = aff.MapPartitionToNode(part);
+
+ Assert.AreEqual(node, partNode);
+ }
+
+ [Test]
+ public void TestMapToPrimaryAndBackups()
+ {
+ ICacheAffinity aff = Affinity();
+
+ const int key = 1;
+
+ IList<IClusterNode> nodes = aff.MapKeyToPrimaryAndBackups(key);
+
+ Assert.IsTrue(nodes.Count > 0);
+
+ for (int i = 0; i < nodes.Count; i++)
+ {
+ if (i == 0)
+ Assert.IsTrue(aff.IsPrimary(nodes[i], key));
+ else
+ Assert.IsTrue(aff.IsBackup(nodes[i], key));
+ }
+
+ int part = aff.Partition(key);
+
+ IList<IClusterNode> partNodes = aff.MapPartitionToPrimaryAndBackups(part);
+
+ Assert.AreEqual(nodes, partNodes);
+ }
+
+ [Test]
+ public void TestMapKeysToNodes()
+ {
+ ICacheAffinity aff = Affinity();
+
+ IList<int> keys = new List<int> {1, 2, 3};
+
+ IDictionary<IClusterNode, IList<int>> map = aff.MapKeysToNodes(keys);
+
+ Assert.IsTrue(map.Count > 0);
+
+ foreach (int key in keys)
+ {
+ IClusterNode primary = aff.MapKeyToNode(key);
+
+ Assert.IsTrue(map.ContainsKey(primary));
+
+ IList<int> nodeKeys = map[primary];
+
+ Assert.IsNotNull(nodeKeys);
+
+ Assert.IsTrue(nodeKeys.Contains(key));
+ }
+ }
+
+ [Test]
+ public void TestMapPartitionsToNodes()
+ {
+ ICacheAffinity aff = Affinity();
+
+ if (LocalCache())
+ {
+ IList<int> parts = new List<int> { 0 };
+
+ IDictionary<int, IClusterNode> map = aff.MapPartitionsToNodes(parts);
+
+ Assert.AreEqual(parts.Count, map.Count);
+
+ Assert.AreEqual(GetIgnite(0).Cluster.LocalNode, map[0]);
+ }
+ else
+ {
+ IList<int> parts = new List<int> { 1, 2, 3 };
+
+ IDictionary<int, IClusterNode> map = aff.MapPartitionsToNodes(parts);
+
+ Assert.AreEqual(parts.Count, map.Count);
+
+ foreach (int part in parts)
+ {
+ Assert.IsTrue(map.ContainsKey(part));
+
+ IClusterNode primary = aff.MapPartitionToNode(part);
+
+ Assert.AreEqual(primary, map[part], "Wrong node for partition: " + part);
+ }
+ }
+ }
+
+ [Test]
+ public void TestKeepPortableFlag()
+ {
+ TestKeepPortableFlag(false);
+ }
+
+ [Test]
+ public void TestKeepPortableFlagAsync()
+ {
+ TestKeepPortableFlag(true);
+ }
+
+ [Test]
+ public void TestNearKeys()
+ {
+ if (!NearEnabled())
+ return;
+
+ const int count = 20;
+
+ var cache = Cache();
+ var aff = cache.Ignite.Affinity(cache.Name);
+ var node = cache.Ignite.Cluster.LocalNode;
+
+ for (int i = 0; i < count; i++)
+ cache.Put(i, -i - 1);
+
+ var nearKeys = Enumerable.Range(0, count).Where(x => !aff.IsPrimaryOrBackup(node, x)).ToArray();
+
+ var nearKeysString = nearKeys.Select(x => x.ToString()).Aggregate((x, y) => x + ", " + y);
+
+ Console.WriteLine("Near keys: " + nearKeysString);
+
+ foreach (var nearKey in nearKeys.Take(3))
+ Assert.AreNotEqual(0, cache.Get(nearKey));
+ }
+
+ [Test]
+ public void TestSerializable()
+ {
+ var cache = Cache<int, TestSerializableObject>();
+
+ var obj = new TestSerializableObject {Name = "Vasya", Id = 128};
+
+ cache.Put(1, obj);
+
+ var resultObj = cache.Get(1);
+
+ Assert.AreEqual(obj, resultObj);
+ }
+
+ [Test]
+ public void TestInvoke()
+ {
+ TestInvoke(false);
+ }
+
+ [Test]
+ public void TestInvokeAsync()
+ {
+ TestInvoke(true);
+ }
+
+ private void TestInvoke(bool async)
+ {
+ TestInvoke<AddArgCacheEntryProcessor>(async);
+ TestInvoke<PortableAddArgCacheEntryProcessor>(async);
+
+ try
+ {
+ TestInvoke<NonSerializableCacheEntryProcessor>(async);
+ Assert.Fail();
+ }
+ catch (SerializationException)
+ {
+ // Expected
+ }
+ }
+
+ private void TestInvoke<T>(bool async) where T: AddArgCacheEntryProcessor, new()
+ {
+ var cache = async ? Cache().WithAsync().WrapAsync() : Cache();
+
+ cache.Clear();
+
+ const int key = 1;
+ const int value = 3;
+ const int arg = 5;
+
+ cache.Put(key, value);
+
+ // Existing entry
+ Assert.AreEqual(value + arg, cache.Invoke(key, new T(), arg));
+ Assert.AreEqual(value + arg, cache.Get(key));
+
+ // Non-existing entry
+ Assert.AreEqual(arg, cache.Invoke(10, new T {Exists = false}, arg));
+ Assert.AreEqual(arg, cache.Get(10));
+
+ // Remove entry
+ Assert.AreEqual(0, cache.Invoke(key, new T {Remove = true}, arg));
+ Assert.AreEqual(0, cache.Get(key));
+
+ // Test exceptions
+ AssertThrowsCacheEntryProcessorException(() => cache.Invoke(key, new T {ThrowErr = true}, arg));
+ AssertThrowsCacheEntryProcessorException(
+ () => cache.Invoke(key, new T {ThrowErrPortable = true}, arg));
+ AssertThrowsCacheEntryProcessorException(
+ () => cache.Invoke(key, new T { ThrowErrNonSerializable = true }, arg), "SerializationException");
+ }
+
+ private static void AssertThrowsCacheEntryProcessorException(Action action, string containsText = null)
+ {
+ try
+ {
+ action();
+
+ Assert.Fail();
+ }
+ catch (Exception ex)
+ {
+ Assert.IsInstanceOf<CacheEntryProcessorException>(ex);
+
+ if (string.IsNullOrEmpty(containsText))
+ Assert.AreEqual(ex.InnerException.Message, AddArgCacheEntryProcessor.ExceptionText);
+ else
+ Assert.IsTrue(ex.ToString().Contains(containsText));
+ }
+ }
+
+ [Test]
+ public void TestInvokeAll()
+ {
+ TestInvokeAll(false);
+ }
+
+ [Test]
+ public void TestInvokeAllAsync()
+ {
+ TestInvokeAll(true);
+ }
+
+ private void TestInvokeAll(bool async)
+ {
+ for (var i = 1; i < 10; i++)
+ {
+ TestInvokeAll<AddArgCacheEntryProcessor>(async, i);
+ TestInvokeAll<PortableAddArgCacheEntryProcessor>(async, i);
+
+ try
+ {
+ TestInvokeAll<NonSerializableCacheEntryProcessor>(async, i);
+ Assert.Fail();
+ }
+ catch (SerializationException)
+ {
+ // Expected
+ }
+ }
+ }
+
+ public void TestInvokeAll<T>(bool async, int entryCount) where T : AddArgCacheEntryProcessor, new()
+ {
+ var cache = async ? Cache().WithAsync().WrapAsync() : Cache();
+
+ var entries = Enumerable.Range(1, entryCount).ToDictionary(x => x, x => x + 1);
+
+ cache.PutAll(entries);
+
+ const int arg = 5;
+
+ // Existing entries
+ var res = cache.InvokeAll(entries.Keys, new T(), arg);
+
+ var results = res.OrderBy(x => x.Key).Select(x => x.Value.Result);
+ var expectedResults = entries.OrderBy(x => x.Key).Select(x => x.Value + arg);
+
+ Assert.IsTrue(results.SequenceEqual(expectedResults));
+
+ var resultEntries = cache.GetAll(entries.Keys);
+
+ Assert.IsTrue(resultEntries.All(x => x.Value == x.Key + 1 + arg));
+
+ // Remove entries
+ res = cache.InvokeAll(entries.Keys, new T {Remove = true}, arg);
+
+ Assert.IsTrue(res.All(x => x.Value.Result == 0));
+ Assert.AreEqual(0, cache.GetAll(entries.Keys).Count);
+
+ // Non-existing entries
+ res = cache.InvokeAll(entries.Keys, new T {Exists = false}, arg);
+
+ Assert.IsTrue(res.All(x => x.Value.Result == arg));
+ Assert.IsTrue(cache.GetAll(entries.Keys).All(x => x.Value == arg));
+
+ // Test exceptions
+ var errKey = entries.Keys.Reverse().Take(5).Last();
+
+ TestInvokeAllException(cache, entries, new T { ThrowErr = true, ThrowOnKey = errKey }, arg, errKey);
+ TestInvokeAllException(cache, entries, new T { ThrowErrPortable = true, ThrowOnKey = errKey },
+ arg, errKey);
+ TestInvokeAllException(cache, entries, new T { ThrowErrNonSerializable = true, ThrowOnKey = errKey },
+ arg, errKey, "SerializationException");
+
+ }
+
+ private static void TestInvokeAllException<T>(ICache<int, int> cache, Dictionary<int, int> entries,
+ T processor, int arg, int errKey, string exceptionText = null) where T : AddArgCacheEntryProcessor
+ {
+ var res = cache.InvokeAll(entries.Keys, processor, arg);
+
+ foreach (var procRes in res)
+ {
+ if (procRes.Key == errKey)
+ // ReSharper disable once AccessToForEachVariableInClosure
+ AssertThrowsCacheEntryProcessorException(() => { var x = procRes.Value.Result; }, exceptionText);
+ else
+ Assert.Greater(procRes.Value.Result, 0);
+ }
+ }
+
+ /// <summary>
+ /// Test skip-store semantics.
+ /// </summary>
+ [Test]
+ public void TestSkipStore()
+ {
+ CacheProxyImpl<int, int> cache = (CacheProxyImpl<int, int>)Cache();
+
+ Assert.IsFalse(cache.SkipStore);
+
+ // Ensure correct flag set.
+
<TRUNCATED>