You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2016/12/28 10:57:22 UTC
ignite git commit: IGNITE-3430 .NET: Refactor transactional tests to
a separate class
Repository: ignite
Updated Branches:
refs/heads/master 06ef84606 -> 864af7eb4
IGNITE-3430 .NET: Refactor transactional tests to a separate class
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/864af7eb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/864af7eb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/864af7eb
Branch: refs/heads/master
Commit: 864af7eb48f19b8d6350332100f741fcdccdb5ad
Parents: 06ef846
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Wed Dec 28 13:55:26 2016 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Wed Dec 28 13:55:26 2016 +0300
----------------------------------------------------------------------
.../Apache.Ignite.Core.Tests.csproj | 1 +
.../Cache/CacheAbstractTest.cs | 625 -------------------
.../Cache/CacheAbstractTransactionalTest.cs | 556 +++++++++++++++++
.../Cache/CacheLocalAtomicTest.cs | 5 -
.../Cache/CacheLocalTest.cs | 6 +-
.../CachePartitionedAtomicNearEnabledTest.cs | 5 -
.../Cache/CachePartitionedAtomicTest.cs | 5 -
.../Cache/CachePartitionedNearEnabledTest.cs | 7 +-
.../Cache/CachePartitionedTest.cs | 7 +-
.../Cache/CacheReplicatedAtomicTest.cs | 5 -
.../Cache/CacheReplicatedTest.cs | 7 +-
11 files changed, 561 insertions(+), 668 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index f440c25..5948593 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -71,6 +71,7 @@
<Compile Include="Cache\CacheMetricsTest.cs" />
<Compile Include="Cache\CacheResultTest.cs" />
<Compile Include="Cache\CacheSwapSpaceTest.cs" />
+ <Compile Include="Cache\CacheAbstractTransactionalTest.cs" />
<Compile Include="Cache\Store\CacheStoreAdapterTest.cs" />
<Compile Include="Collections\MultiValueDictionaryTest.cs" />
<Compile Include="Collections\ReadOnlyCollectionTest.cs" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
index 821a179..250f974 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs
@@ -1917,621 +1917,6 @@ namespace Apache.Ignite.Core.Tests.Cache
}
/// <summary>
- /// Simple cache lock test (while <see cref="TestLock"/> is ignored).
- /// </summary>
- [Test]
- public void TestLockSimple()
- {
- if (!LockingEnabled())
- return;
-
- var cache = Cache();
-
- const int key = 7;
-
- Action<ICacheLock> checkLock = lck =>
- {
- using (lck)
- {
- Assert.Throws<InvalidOperationException>(lck.Exit); // can't exit if not entered
-
- lck.Enter();
-
- Assert.IsTrue(cache.IsLocalLocked(key, true));
- Assert.IsTrue(cache.IsLocalLocked(key, false));
-
- lck.Exit();
-
- Assert.IsFalse(cache.IsLocalLocked(key, true));
- Assert.IsFalse(cache.IsLocalLocked(key, false));
-
- Assert.IsTrue(lck.TryEnter());
-
- Assert.IsTrue(cache.IsLocalLocked(key, true));
- Assert.IsTrue(cache.IsLocalLocked(key, false));
-
- lck.Exit();
- }
-
- Assert.Throws<ObjectDisposedException>(lck.Enter); // Can't enter disposed lock
- };
-
- checkLock(cache.Lock(key));
- checkLock(cache.LockAll(new[] {key, 1, 2, 3}));
- }
-
- [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 that 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 task = tx.CommitAsync();
-
- task.Wait();
-
- Assert.IsTrue(task.IsCompleted);
- }
- 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).GetCluster().GetLocalNode().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);
- Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, tx.ThreadId);
-
- tx.AddMeta("myMeta", 42);
- Assert.AreEqual(42, tx.Meta<int>("myMeta"));
- Assert.AreEqual(42, tx.RemoveMeta<int>("myMeta"));
-
- tx.RollbackAsync().Wait();
-
- Assert.AreEqual(TransactionState.RolledBack, tx.State);
-
- try
- {
- tx.Commit();
- Assert.Fail();
- }
- catch (InvalidOperationException)
- {
- // Expected
- }
-
- tx = Transactions.TxStart();
-
- Assert.AreEqual(TransactionState.Active, tx.State);
-
- tx.CommitAsync().Wait();
-
- Assert.AreEqual(TransactionState.Committed, tx.State);
-
- var task = tx.RollbackAsync(); // Illegal, but should not fail here; will fail in task
-
- try
- {
- task.Wait();
- Assert.Fail();
- }
- catch (AggregateException)
- {
- // Expected
- }
- }
-
- /// <summary>
- /// Tests the transaction deadlock detection.
- /// </summary>
- [Test]
- public void TestTxDeadlockDetection()
- {
- if (!TxEnabled())
- return;
-
- var cache = Cache();
-
- var keys0 = Enumerable.Range(1, 100).ToArray();
-
- cache.PutAll(keys0.ToDictionary(x => x, x => x));
-
- var barrier = new Barrier(2);
-
- Action<int[]> increment = keys =>
- {
- using (var tx = Transactions.TxStart(TransactionConcurrency.Pessimistic,
- TransactionIsolation.RepeatableRead, TimeSpan.FromSeconds(0.5), 0))
- {
- foreach (var key in keys)
- cache[key]++;
-
- barrier.SignalAndWait(500);
-
- tx.Commit();
- }
- };
-
- // Increment keys within tx in different order to cause a deadlock.
- var aex = Assert.Throws<AggregateException>(() =>
- Task.WaitAll(Task.Factory.StartNew(() => increment(keys0)),
- Task.Factory.StartNew(() => increment(keys0.Reverse().ToArray()))));
-
- Assert.AreEqual(2, aex.InnerExceptions.Count);
-
- var deadlockEx = aex.InnerExceptions.OfType<TransactionDeadlockException>().First();
- Assert.IsTrue(deadlockEx.Message.Trim().StartsWith("Deadlock detected:"), deadlockEx.Message);
- }
-
- /// <summary>
/// Test thraed-locals leak.
/// </summary>
[Test]
@@ -3404,16 +2789,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected virtual bool TxEnabled()
- {
- return true;
- }
-
- protected bool LockingEnabled()
- {
- return TxEnabled();
- }
-
protected virtual bool LocalCache()
{
return false;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs
new file mode 100644
index 0000000..e836ba2
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs
@@ -0,0 +1,556 @@
+/*
+ * 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.Linq;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Transactions;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Transactional cache tests.
+ /// </summary>
+ public abstract class CacheAbstractTransactionalTest : CacheAbstractTest
+ {
+ /// <summary>
+ /// Simple cache lock test (while <see cref="TestLock"/> is ignored).
+ /// </summary>
+ [Test]
+ public void TestLockSimple()
+ {
+ var cache = Cache();
+
+ const int key = 7;
+
+ Action<ICacheLock> checkLock = lck =>
+ {
+ using (lck)
+ {
+ Assert.Throws<InvalidOperationException>(lck.Exit); // can't exit if not entered
+
+ lck.Enter();
+
+ Assert.IsTrue(cache.IsLocalLocked(key, true));
+ Assert.IsTrue(cache.IsLocalLocked(key, false));
+
+ lck.Exit();
+
+ Assert.IsFalse(cache.IsLocalLocked(key, true));
+ Assert.IsFalse(cache.IsLocalLocked(key, false));
+
+ Assert.IsTrue(lck.TryEnter());
+
+ Assert.IsTrue(cache.IsLocalLocked(key, true));
+ Assert.IsTrue(cache.IsLocalLocked(key, false));
+
+ lck.Exit();
+ }
+
+ Assert.Throws<ObjectDisposedException>(lck.Enter); // Can't enter disposed lock
+ };
+
+ checkLock(cache.Lock(key));
+ checkLock(cache.LockAll(new[] { key, 1, 2, 3 }));
+ }
+
+ /// <summary>
+ /// Tests cache locks.
+ /// </summary>
+ [Test]
+ [Ignore("IGNITE-835")]
+ public void TestLock()
+ {
+ 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 that 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();
+ }
+
+ /// <summary>
+ /// Tests that commit applies cache changes.
+ /// </summary>
+ [Test]
+ public void TestTxCommit([Values(true, false)] bool async)
+ {
+ var cache = Cache();
+
+ Assert.IsNull(Transactions.Tx);
+
+ using (var tx = Transactions.TxStart())
+ {
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ if (async)
+ {
+ var task = tx.CommitAsync();
+
+ task.Wait();
+
+ Assert.IsTrue(task.IsCompleted);
+ }
+ else
+ tx.Commit();
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+
+ Assert.IsNull(Transactions.Tx);
+ }
+
+ /// <summary>
+ /// Tests that rollback reverts cache changes.
+ /// </summary>
+ [Test]
+ public void TestTxRollback()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ Assert.IsNull(Transactions.Tx);
+
+ using (var tx = Transactions.TxStart())
+ {
+ cache.Put(1, 10);
+ cache.Put(2, 20);
+
+ tx.Rollback();
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+
+ Assert.IsNull(Transactions.Tx);
+ }
+
+ /// <summary>
+ /// Tests that Dispose without Commit reverts changes.
+ /// </summary>
+ [Test]
+ public void TestTxClose()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ Assert.IsNull(Transactions.Tx);
+
+ using (Transactions.TxStart())
+ {
+ cache.Put(1, 10);
+ cache.Put(2, 20);
+ }
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+
+ Assert.IsNull(Transactions.Tx);
+ }
+
+ /// <summary>
+ /// Tests all concurrency and isolation modes with and without timeout.
+ /// </summary>
+ [Test]
+ public void TestTxAllModes([Values(true, false)] bool withTimeout)
+ {
+ 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 + "]");
+
+ Assert.IsNull(Transactions.Tx);
+
+ using (var 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);
+
+ cache.Put(1, cntr);
+
+ tx.Commit();
+ }
+
+ Assert.IsNull(Transactions.Tx);
+
+ Assert.AreEqual(cntr, cache.Get(1));
+
+ cntr++;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests that transaction properties are applied and propagated properly.
+ /// </summary>
+ [Test]
+ public void TestTxAttributes()
+ {
+ 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).GetCluster().GetLocalNode().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);
+ }
+
+ /// <summary>
+ /// Tests <see cref="ITransaction.IsRollbackOnly"/> flag.
+ /// </summary>
+ [Test]
+ public void TestTxRollbackOnly()
+ {
+ var cache = Cache();
+
+ cache.Put(1, 1);
+ cache.Put(2, 2);
+
+ var 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);
+
+ var ex = Assert.Throws<TransactionRollbackException>(() => tx.Commit());
+ Assert.IsTrue(ex.Message.StartsWith("Invalid transaction state for prepare [state=MARKED_ROLLBACK"));
+
+ tx.Dispose();
+
+ Assert.AreEqual(TransactionState.RolledBack, tx.State);
+
+ Assert.IsTrue(tx.IsRollbackOnly);
+
+ Assert.AreEqual(1, cache.Get(1));
+ Assert.AreEqual(2, cache.Get(2));
+
+ Assert.IsNull(Transactions.Tx);
+ }
+
+ /// <summary>
+ /// Tests transaction metrics.
+ /// </summary>
+ [Test]
+ public void TestTxMetrics()
+ {
+ 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);
+ }
+
+ /// <summary>
+ /// Tests transaction state transitions.
+ /// </summary>
+ [Test]
+ public void TestTxStateAndExceptions()
+ {
+ var tx = Transactions.TxStart();
+
+ Assert.AreEqual(TransactionState.Active, tx.State);
+ Assert.AreEqual(Thread.CurrentThread.ManagedThreadId, tx.ThreadId);
+
+ tx.AddMeta("myMeta", 42);
+ Assert.AreEqual(42, tx.Meta<int>("myMeta"));
+ Assert.AreEqual(42, tx.RemoveMeta<int>("myMeta"));
+
+ tx.RollbackAsync().Wait();
+
+ Assert.AreEqual(TransactionState.RolledBack, tx.State);
+
+ Assert.Throws<InvalidOperationException>(() => tx.Commit());
+
+ tx = Transactions.TxStart();
+
+ Assert.AreEqual(TransactionState.Active, tx.State);
+
+ tx.CommitAsync().Wait();
+
+ Assert.AreEqual(TransactionState.Committed, tx.State);
+
+ var task = tx.RollbackAsync(); // Illegal, but should not fail here; will fail in task
+
+ Assert.Throws<AggregateException>(() => task.Wait());
+ }
+
+ /// <summary>
+ /// Tests the transaction deadlock detection.
+ /// </summary>
+ [Test]
+ public void TestTxDeadlockDetection()
+ {
+ var cache = Cache();
+
+ var keys0 = Enumerable.Range(1, 100).ToArray();
+
+ cache.PutAll(keys0.ToDictionary(x => x, x => x));
+
+ var barrier = new Barrier(2);
+
+ Action<int[]> increment = keys =>
+ {
+ using (var tx = Transactions.TxStart(TransactionConcurrency.Pessimistic,
+ TransactionIsolation.RepeatableRead, TimeSpan.FromSeconds(0.5), 0))
+ {
+ foreach (var key in keys)
+ cache[key]++;
+
+ barrier.SignalAndWait(500);
+
+ tx.Commit();
+ }
+ };
+
+ // Increment keys within tx in different order to cause a deadlock.
+ var aex = Assert.Throws<AggregateException>(() =>
+ Task.WaitAll(Task.Factory.StartNew(() => increment(keys0)),
+ Task.Factory.StartNew(() => increment(keys0.Reverse().ToArray()))));
+
+ Assert.AreEqual(2, aex.InnerExceptions.Count);
+
+ var deadlockEx = aex.InnerExceptions.OfType<TransactionDeadlockException>().First();
+ Assert.IsTrue(deadlockEx.Message.Trim().StartsWith("Deadlock detected:"), deadlockEx.Message);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
index b60c254..2c8c070 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalAtomicTest.cs
@@ -39,11 +39,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return false;
- }
-
protected override bool LocalCache()
{
return true;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
index 02cb987..000218b 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheLocalTest.cs
@@ -17,7 +17,7 @@
namespace Apache.Ignite.Core.Tests.Cache
{
- public class CacheLocalTest : CacheAbstractTest
+ public class CacheLocalTest : CacheAbstractTransactionalTest
{
protected override int CachePartitions()
{
@@ -39,10 +39,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return true;
- }
protected override bool LocalCache()
{
return true;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
index 4f6e7a0..77cc77f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicNearEnabledTest.cs
@@ -37,11 +37,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return true;
}
- protected override bool TxEnabled()
- {
- return false;
- }
-
protected override int Backups()
{
return 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
index ab59c64..e6f851e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedAtomicTest.cs
@@ -37,11 +37,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return false;
- }
-
protected override int Backups()
{
return 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
index 830698b..81d2e5a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedNearEnabledTest.cs
@@ -20,7 +20,7 @@ namespace Apache.Ignite.Core.Tests.Cache
using NUnit.Framework;
[Category(TestUtils.CategoryIntensive)]
- public class CachePartitionedNearEnabledTest : CacheAbstractTest
+ public class CachePartitionedNearEnabledTest : CacheAbstractTransactionalTest
{
protected override int GridCount()
{
@@ -37,11 +37,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return true;
}
- protected override bool TxEnabled()
- {
- return true;
- }
-
protected override int Backups()
{
return 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
index 02d3208..68546b9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CachePartitionedTest.cs
@@ -20,7 +20,7 @@ namespace Apache.Ignite.Core.Tests.Cache
using NUnit.Framework;
[Category(TestUtils.CategoryIntensive)]
- public class CachePartitionedTest : CacheAbstractTest
+ public class CachePartitionedTest : CacheAbstractTransactionalTest
{
protected override int GridCount()
{
@@ -37,11 +37,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return true;
- }
-
protected override int Backups()
{
return 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
index db6f5a5..bd31c77 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedAtomicTest.cs
@@ -42,11 +42,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return false;
- }
-
protected override int Backups()
{
return GridCount() - 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/864af7eb/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
index 7c70222..2d1c257 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheReplicatedTest.cs
@@ -20,7 +20,7 @@ namespace Apache.Ignite.Core.Tests.Cache
using NUnit.Framework;
[Category(TestUtils.CategoryIntensive)]
- public class CacheReplicatedTest : CacheAbstractTest
+ public class CacheReplicatedTest : CacheAbstractTransactionalTest
{
protected override int CachePartitions()
{
@@ -42,11 +42,6 @@ namespace Apache.Ignite.Core.Tests.Cache
return false;
}
- protected override bool TxEnabled()
- {
- return true;
- }
-
protected override int Backups()
{
return GridCount() - 1;