Skip to content

Commit f7e53bf

Browse files
mauroservientidanielmarbachandreasohlund
authored
Split When_sending_within_an_ambient_transaction into two distinct tests and improve done condition (#7695) (#7697)
* Split When_sending_within_an_ambient_transaction into two distinct tests and improve done condition * Improve naming * Typo --------- Remove attributes Co-authored-by: Daniel Marbach <daniel.marbach@openplace.net> Co-authored-by: Andreas Öhlund <andreas.ohlund@particular.net>
1 parent d904efc commit f7e53bf

2 files changed

Lines changed: 90 additions & 39 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
namespace NServiceBus.AcceptanceTests.Tx;
2+
3+
using System;
4+
using System.Threading.Tasks;
5+
using System.Transactions;
6+
using AcceptanceTesting;
7+
using AcceptanceTesting.Customization;
8+
using EndpointTemplates;
9+
using NUnit.Framework;
10+
11+
public class When_ambient_transaction_is_not_completed : NServiceBusAcceptanceTest
12+
{
13+
[Test]
14+
public async Task Should_not_deliver_enlisted_message()
15+
{
16+
Requires.DtcSupport();
17+
18+
var context = await Scenario.Define<Context>()
19+
.WithEndpoint<TransactionalEndpoint>(b => b.When(async session =>
20+
{
21+
using (new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
22+
{
23+
await session.Send(new MessageThatIsEnlisted());
24+
25+
// scope is not completed
26+
}
27+
28+
await session.Send(new MessageThatIsNotEnlisted());
29+
}))
30+
.Run();
31+
32+
using (Assert.EnterMultipleScope())
33+
{
34+
Assert.That(context.MessageThatIsEnlistedHandlerWasCalled, Is.False, "The transactional handler should not be called");
35+
Assert.That(context.MessageThatIsNotEnlistedHandlerWasCalled, Is.True, "The non-transactional handler should be called");
36+
}
37+
}
38+
39+
public class Context : ScenarioContext
40+
{
41+
public bool MessageThatIsEnlistedHandlerWasCalled { get; set; }
42+
public bool MessageThatIsNotEnlistedHandlerWasCalled { get; set; }
43+
}
44+
45+
public class TransactionalEndpoint : EndpointConfigurationBuilder
46+
{
47+
public TransactionalEndpoint() =>
48+
EndpointSetup<DefaultServer>(c =>
49+
{
50+
c.LimitMessageProcessingConcurrencyTo(1);
51+
var routing = c.ConfigureRouting();
52+
routing.RouteToEndpoint(typeof(MessageThatIsEnlisted), typeof(TransactionalEndpoint));
53+
routing.RouteToEndpoint(typeof(MessageThatIsNotEnlisted), typeof(TransactionalEndpoint));
54+
});
55+
56+
public class MessageThatIsEnlistedHandler(Context testContext) : IHandleMessages<MessageThatIsEnlisted>
57+
{
58+
public Task Handle(MessageThatIsEnlisted messageThatIsEnlisted, IMessageHandlerContext context)
59+
{
60+
testContext.MessageThatIsEnlistedHandlerWasCalled = true;
61+
testContext.MarkAsFailed(new InvalidOperationException($"'{nameof(MessageThatIsEnlistedHandler)}' should not be called because the surrounding transaction was rolled back."));
62+
return Task.CompletedTask;
63+
}
64+
}
65+
66+
public class MessageThatIsNotEnlistedHandler(Context testContext) : IHandleMessages<MessageThatIsNotEnlisted>
67+
{
68+
public Task Handle(MessageThatIsNotEnlisted messageThatIsNotEnlisted, IMessageHandlerContext context)
69+
{
70+
testContext.MessageThatIsNotEnlistedHandlerWasCalled = true;
71+
testContext.MarkAsCompleted();
72+
return Task.CompletedTask;
73+
}
74+
}
75+
}
76+
77+
public class MessageThatIsEnlisted : ICommand;
78+
79+
public class MessageThatIsNotEnlisted : ICommand;
80+
}

src/NServiceBus.AcceptanceTests/Tx/When_sending_within_an_ambient_transaction.cs renamed to src/NServiceBus.AcceptanceTests/Tx/When_sends_are_enlisted_in_ambient_transaction.cs

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,31 @@
77
using EndpointTemplates;
88
using NUnit.Framework;
99

10-
public class When_sending_within_an_ambient_transaction : NServiceBusAcceptanceTest
10+
public class When_sends_are_enlisted_in_ambient_transaction : NServiceBusAcceptanceTest
1111
{
1212
[Test]
13-
public async Task Should_not_deliver_them_until_the_commit_phase()
13+
public async Task Should_not_dispatch_messages_until_the_commit_phase()
1414
{
1515
Requires.DtcSupport();
1616

1717
var context = await Scenario.Define<Context>()
1818
.WithEndpoint<TransactionalEndpoint>(b => b.When(async (session, ctx) =>
1919
{
20-
using (var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
21-
{
22-
await session.Send(new MessageThatIsEnlisted
23-
{
24-
SequenceNumber = 1
25-
});
26-
await session.Send(new MessageThatIsEnlisted
27-
{
28-
SequenceNumber = 2
29-
});
30-
31-
//send another message as well so that we can check the order in the receiver
32-
using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
33-
{
34-
await session.Send(new MessageThatIsNotEnlisted());
35-
}
36-
37-
tx.Complete();
38-
}
39-
}))
40-
.Run();
41-
42-
Assert.That(context.SequenceNumberOfFirstMessage, Is.EqualTo(1), "The transport should preserve the order in which the transactional messages are delivered to the queuing system");
43-
}
20+
using var tx = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
21+
await session.Send(new MessageThatIsEnlisted { SequenceNumber = 1 });
22+
await session.Send(new MessageThatIsEnlisted { SequenceNumber = 2 });
4423

45-
[Test]
46-
public async Task Should_not_deliver_them_on_rollback()
47-
{
48-
Requires.DtcSupport();
49-
50-
var context = await Scenario.Define<Context>()
51-
.WithEndpoint<TransactionalEndpoint>(b => b.When(async session =>
52-
{
53-
using (new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
24+
//send another message that is not enlisted so that we can check the order in the receiver
25+
using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
5426
{
55-
await session.Send(new MessageThatIsEnlisted());
56-
//rollback
27+
await session.Send(new MessageThatIsNotEnlisted());
5728
}
5829

59-
await session.Send(new MessageThatIsNotEnlisted());
30+
tx.Complete();
6031
}))
6132
.Run();
6233

63-
Assert.That(context.MessageThatIsEnlistedHandlerWasCalled, Is.False, "The transactional handler should not be called");
34+
Assert.That(context.SequenceNumberOfFirstMessage, Is.EqualTo(1), "The transport should preserve the order in which the transactional messages are delivered to the queuing system");
6435
}
6536

6637
public class Context : ScenarioContext

0 commit comments

Comments
 (0)