Skip to content

Commit 7b9e17f

Browse files
authored
Merge pull request #387 from DataObjects-NET/6.0-fix-reprocessing-tests
Fix failing reprocessing tests on certain providers.
2 parents e7c8117 + f5ca6b4 commit 7b9e17f

File tree

3 files changed

+239
-231
lines changed

3 files changed

+239
-231
lines changed

Extensions/Xtensive.Orm.Reprocessing.Tests/Tests/Context.cs

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,58 @@
1212

1313
namespace Xtensive.Orm.Reprocessing.Tests.ReprocessingContext
1414
{
15-
public class Context
15+
public class Context : IDisposable
1616
{
1717
private readonly Domain domain;
18+
1819
public int Count;
1920
private AutoResetEvent wait1 = new AutoResetEvent(false);
2021
private AutoResetEvent wait2 = new AutoResetEvent(false);
2122

22-
public void Deadlock(bool first, IsolationLevel? isolationLevel, TransactionOpenMode? transactionOpenMode)
23+
public bool Disposed { get; private set; }
24+
25+
/// <summary>
26+
/// Root runner.
27+
/// </summary>
28+
public void Run(
29+
IsolationLevel? isolationLevel,
30+
TransactionOpenMode? transactionOpenMode,
31+
Action<bool, IsolationLevel?, TransactionOpenMode?> action)
2332
{
24-
TestContext.WriteLine("Context.DeadLock entered");
25-
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation).WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead)).WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New)).Execute(
33+
domain.Execute(
2634
session => {
35+
session.Remove(session.Query.All<Foo>());
36+
session.Remove(session.Query.All<Bar>());
37+
session.Remove(session.Query.All<Bar2>());
38+
_ = new Bar(session);
39+
_ = new Foo(session);
40+
});
41+
42+
Parallel.Invoke(
43+
() => action(true, isolationLevel, transactionOpenMode),
44+
() => action(false, isolationLevel, transactionOpenMode));
45+
}
46+
47+
#region Actions
48+
49+
// The actions that can be passed to root runner method (Run)
50+
// Some might be wrapped by other actons,
51+
// others used only directrly from runner method
52+
53+
public void Deadlock(bool first, IsolationLevel? isolationLevel, TransactionOpenMode? transactionOpenMode)
54+
{
55+
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation)
56+
.WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead))
57+
.WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New))
58+
.Execute(session => {
2759
_ = Interlocked.Increment(ref Count);
2860
_ = new Bar2(session, DateTime.Now, Guid.NewGuid()) { Name = Guid.NewGuid().ToString() };
2961
if (first) {
3062
_ = session.Query.All<Foo>().Lock(LockMode.Exclusive, LockBehavior.Wait).ToArray();
3163
if (wait1 != null) {
3264
_ = wait1.Set();
3365
_ = wait2.WaitOne();
66+
wait1.Dispose();
3467
wait1 = null;
3568
}
3669
_ = session.Query.All<Bar>().Lock(LockMode.Exclusive, LockBehavior.Wait).ToArray();
@@ -40,12 +73,12 @@ public void Deadlock(bool first, IsolationLevel? isolationLevel, TransactionOpen
4073
if (wait2 != null) {
4174
_ = wait2.Set();
4275
_ = wait1.WaitOne();
76+
wait2.Dispose();
4377
wait2 = null;
4478
}
4579
_ = session.Query.All<Foo>().Lock(LockMode.Exclusive, LockBehavior.Wait).ToArray();
4680
}
4781
});
48-
TestContext.WriteLine("Context.DeadLock left");
4982
}
5083

5184
public void External(
@@ -54,7 +87,6 @@ public void External(
5487
TransactionOpenMode? transactionOpenMode,
5588
Action<Session, bool, IsolationLevel?, TransactionOpenMode?> action)
5689
{
57-
TestContext.WriteLine("Context.External entered");
5890
using (var session = domain.OpenSession())
5991
using (var tran = isolationLevel == null ? null : session.OpenTransaction()) {
6092
if (tran != null) {
@@ -76,7 +108,6 @@ public void External(
76108
tran.Complete();
77109
}
78110
}
79-
TestContext.WriteLine("Context.External left");
80111
}
81112

82113
public void Parent(
@@ -86,7 +117,6 @@ public void Parent(
86117
IExecuteActionStrategy strategy,
87118
Action<bool, IsolationLevel?, TransactionOpenMode?> action)
88119
{
89-
TestContext.WriteLine("Context.Parent1 entered");
90120
domain.WithStrategy(strategy)
91121
.WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead))
92122
.WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New))
@@ -106,7 +136,6 @@ public void Parent(
106136
}
107137
action(first, isolationLevel, transactionOpenMode);
108138
});
109-
TestContext.WriteLine("Context.Parent1 left");
110139
}
111140

112141
public void Parent(
@@ -117,7 +146,6 @@ public void Parent(
117146
IExecuteActionStrategy strategy,
118147
Action<bool, IsolationLevel?, TransactionOpenMode?> action)
119148
{
120-
TestContext.WriteLine("Context.Parent2 entered");
121149
domain.WithStrategy(strategy)
122150
.WithSession(session)
123151
.WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead))
@@ -138,38 +166,15 @@ public void Parent(
138166
}
139167
action(first, isolationLevel, transactionOpenMode);
140168
});
141-
TestContext.WriteLine("Context.Parent2 left");
142-
}
143-
144-
public void Run(
145-
IsolationLevel? isolationLevel,
146-
TransactionOpenMode? transactionOpenMode,
147-
Action<bool, IsolationLevel?, TransactionOpenMode?> action)
148-
{
149-
TestContext.WriteLine("Context.Run entered");
150-
domain.Execute(
151-
session => {
152-
session.Remove(session.Query.All<Foo>());
153-
session.Remove(session.Query.All<Bar>());
154-
session.Remove(session.Query.All<Bar2>());
155-
_ = new Bar(session);
156-
_ = new Foo(session);
157-
});
158-
TestContext.WriteLine("Context.Run executed Domain.Execute");
159-
TestContext.WriteLine("Context.Run Parallel.Invoke started");
160-
Parallel.Invoke(
161-
() => action(true, isolationLevel, transactionOpenMode),
162-
() => action(false, isolationLevel, transactionOpenMode));
163-
TestContext.WriteLine("Context.Run Parallel.Invoke ended");
164-
TestContext.WriteLine("Context.Run left");
165169
}
166170

167171
public void UniqueConstraintViolation(
168172
bool first, IsolationLevel? isolationLevel, TransactionOpenMode? transactionOpenMode)
169173
{
170-
TestContext.WriteLine("Context.UniqueConstraintViolation entered");
171-
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation).WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead)).WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New)).Execute(
172-
session => {
174+
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation)
175+
.WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead))
176+
.WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New))
177+
.Execute(session => {
173178
_ = Interlocked.Increment(ref Count);
174179
session.EnsureTransactionIsStarted();
175180
_ = new Bar2(session, DateTime.Now, Guid.NewGuid()) { Name = Guid.NewGuid().ToString() };
@@ -179,27 +184,29 @@ public void UniqueConstraintViolation(
179184
if (wait1 != null && wait2 != null) {
180185
_ = wait1.Set();
181186
_ = wait2.WaitOne();
187+
wait1.Dispose();
182188
wait1 = null;
183189
}
184190
}
185191
else if (wait2 != null && wait2 != null) {
186192
_ = wait2.Set();
187193
_ = wait1.WaitOne();
194+
wait2.Dispose();
188195
wait2 = null;
189196
}
190197
_ = new Foo(session) { Name = name };
191198
}
192199
session.SaveChanges();
193200
});
194-
TestContext.WriteLine("Context.UniqueConstraintViolation left");
195201
}
196202

197203
public void UniqueConstraintViolationPrimaryKey(
198204
bool first, IsolationLevel? isolationLevel, TransactionOpenMode? transactionOpenMode)
199205
{
200-
TestContext.WriteLine("Context.UniqueConstraintViolationPrimaryKey entered");
201-
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation).WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead)).WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New)).Execute(
202-
session => {
206+
domain.WithStrategy(ExecuteActionStrategy.HandleUniqueConstraintViolation)
207+
.WithIsolationLevel(isolationLevel.GetValueOrDefault(IsolationLevel.RepeatableRead))
208+
.WithTransactionOpenMode(transactionOpenMode.GetValueOrDefault(TransactionOpenMode.New))
209+
.Execute(session => {
203210
_ = Interlocked.Increment(ref Count);
204211
session.EnsureTransactionIsStarted();
205212
_ = new Bar2(session, DateTime.Now, Guid.NewGuid()) { Name = Guid.NewGuid().ToString() };
@@ -211,25 +218,36 @@ public void UniqueConstraintViolationPrimaryKey(
211218
if (w1 != null && w2 != null) {
212219
_ = w1.Set();
213220
_ = w2.WaitOne();
221+
wait1.Dispose();
214222
wait1 = null;
215223
}
216224
}
217225
else if (w1 != null && w2 != null) {
218226
_ = w2.Set();
219227
_ = w1.WaitOne();
228+
wait2.Dispose();
220229
wait2 = null;
221230
}
222231
_ = new Foo(session, id) { Name = Guid.NewGuid().ToString() };
223232
}
224233
session.SaveChanges();
225234
});
226-
TestContext.WriteLine("Context.UniqueConstraintViolationPrimaryKey left");
227235
}
236+
#endregion
228237

229238
public Context(Domain domain)
230239
{
231240
this.domain = domain;
232241
}
242+
243+
public void Dispose()
244+
{
245+
if (Disposed)
246+
return;
247+
Disposed = true;
248+
wait1?.Dispose();
249+
wait2?.Dispose();
250+
}
233251
}
234252
}
235253

Extensions/Xtensive.Orm.Reprocessing.Tests/Tests/DeadlockReprocessing.cs

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,77 +10,77 @@
1010
using NUnit.Framework;
1111
using TestCommon.Model;
1212
using Xtensive.Orm.Reprocessing.Tests.ReprocessingContext;
13+
using Xtensive.Orm.Tests;
1314

1415
namespace Xtensive.Orm.Reprocessing.Tests
1516
{
16-
[TestFixture, Timeout(DefaultTestTimeout * 4)]
17+
[TestFixture]
1718
public class DeadlockReprocessing : ReprocessingBaseTest
1819
{
20+
protected override void CheckRequirements()
21+
{
22+
base.CheckRequirements();
23+
Require.ProviderIsNot(StorageProvider.Firebird, "Throws timeout operation instead of deadlock, which is not reprocessible.");
24+
}
25+
1926
[Test, Timeout(DefaultTestTimeout)]
2027
public void SimpleDeadlockTest()
2128
{
22-
Console.WriteLine("Test started");
23-
24-
var context = new Context(Domain);
25-
context.Run(IsolationLevel.Serializable, null, context.Deadlock);
26-
Assert.That(context.Count, Is.EqualTo(3));
27-
Assert.That(Bar2Count(), Is.EqualTo(2));
29+
using (var context = new Context(Domain)) {
30+
context.Run(IsolationLevel.Serializable, null, context.Deadlock);
31+
Assert.That(context.Count, Is.EqualTo(3));
32+
Assert.That(Bar2Count(), Is.EqualTo(2));
33+
}
2834
}
2935

3036
[Test, Timeout(DefaultTestTimeout)]
3137
public void NestedSerializableDeadlockTest()
3238
{
33-
Console.WriteLine("Test started");
34-
35-
var context = new Context(Domain);
36-
context.Run(
37-
IsolationLevel.Serializable,
38-
null,
39-
(b, level, open) => context.Parent(b, level, open, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock));
40-
Assert.That(context.Count, Is.EqualTo(3));
41-
Assert.That(Bar2Count(), Is.EqualTo(4));
39+
using (var context = new Context(Domain)) {
40+
context.Run(
41+
IsolationLevel.Serializable,
42+
null,
43+
(b, level, open) => context.Parent(b, level, open, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock));
44+
Assert.That(context.Count, Is.EqualTo(3));
45+
Assert.That(Bar2Count(), Is.EqualTo(4));
46+
}
4247
}
4348

4449
[Test, Timeout(DefaultTestTimeout)]
4550
public void NestedSnapshotDeadlockTest()
4651
{
47-
Console.WriteLine("Test started");
48-
49-
var context = new Context(Domain);
50-
context.Run(
51-
IsolationLevel.Snapshot,
52-
null,
53-
(b, level, open) => context.Parent(b, level, open, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock));
54-
Assert.That(context.Count, Is.EqualTo(3));
55-
Assert.That(Bar2Count(), Is.EqualTo(4));
52+
using (var context = new Context(Domain)) {
53+
context.Run(
54+
IsolationLevel.Snapshot,
55+
null,
56+
(b, level, open) => context.Parent(b, level, open, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock));
57+
Assert.That(context.Count, Is.EqualTo(3));
58+
Assert.That(Bar2Count(), Is.EqualTo(4));
59+
}
5660
}
5761

5862
[Test, Timeout(DefaultTestTimeout)]
5963
public void NestedNestedSerializableSerializableTest()
6064
{
61-
Console.WriteLine("Test started");
62-
6365
//nested nested serializable deadlock
64-
var context = new Context(Domain);
65-
context.Run(
66-
IsolationLevel.Serializable,
67-
null,
68-
(b, level, open) =>
69-
context.Parent(
70-
b,
71-
level,
72-
open,
73-
ExecuteActionStrategy.HandleReprocessableException,
74-
(b1, level1, open1) =>
75-
context.Parent(b1, level1, open1, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock)));
76-
Assert.That(context.Count, Is.EqualTo(3));
77-
Assert.That(Bar2Count(), Is.EqualTo(6));
66+
using (var context = new Context(Domain)) {
67+
context.Run(
68+
IsolationLevel.Serializable,
69+
null,
70+
(b, level, open) =>
71+
context.Parent(
72+
b,
73+
level,
74+
open,
75+
ExecuteActionStrategy.HandleReprocessableException,
76+
(b1, level1, open1) =>
77+
context.Parent(b1, level1, open1, ExecuteActionStrategy.HandleReprocessableException, context.Deadlock)));
78+
Assert.That(context.Count, Is.EqualTo(3));
79+
Assert.That(Bar2Count(), Is.EqualTo(6));
80+
}
7881
}
7982

80-
private int Bar2Count()
81-
{
82-
return Domain.Execute(session => session.Query.All<Bar2>().Count());
83-
}
83+
private int Bar2Count() => Domain.Execute(session => session.Query.All<Bar2>().Count());
8484
}
8585
}
8686

0 commit comments

Comments
 (0)