Skip to content

Commit d9601b2

Browse files
committed
Adding tests
1 parent f5631aa commit d9601b2

File tree

2 files changed

+156
-1
lines changed

2 files changed

+156
-1
lines changed

src/ServiceControl.AcceptanceTesting/HttpExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public static async Task<ManyResult<T>> TryGetMany<T>(this IAcceptanceTestInfras
4747
return ManyResult<T>.Empty;
4848
}
4949

50-
return ManyResult<T>.New(true, response);
50+
return ManyResult<T>.New(true, response.Where(m => condition(m)).ToList());
5151
}
5252

5353
public static async Task<HttpStatusCode> Patch<T>(this IAcceptanceTestInfrastructureProvider provider, string url, T payload = null) where T : class
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
namespace ServiceControl.MultiInstance.AcceptanceTests.Recoverability
2+
{
3+
using System;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using AcceptanceTesting;
7+
using AcceptanceTesting.EndpointTemplates;
8+
using MessageFailures;
9+
using MessageFailures.Api;
10+
using NServiceBus;
11+
using NServiceBus.AcceptanceTesting;
12+
using NServiceBus.Settings;
13+
using NUnit.Framework;
14+
using ServiceControl.Infrastructure;
15+
using TestSupport;
16+
17+
class WhenRetryingSameMessageMultipleTimes : AcceptanceTest
18+
{
19+
[Test]
20+
public async Task WithNoEdit()
21+
{
22+
await Define<MyContext>()
23+
.WithEndpoint<FailureEndpoint>(b => b.When(bus => bus.SendLocal(new MyMessage())).DoNotFailOnErrorMessages())
24+
.Done(async c =>
25+
{
26+
if (c.RetryCount < 3)
27+
{
28+
var result = await GetFailedMessage(c, ServiceControlInstanceName, FailedMessageStatus.Unresolved);
29+
if (result.HasResult)
30+
{
31+
if (result.Item.ProcessingAttempts.Count == c.RetryCount + 1)
32+
{
33+
await this.Post<object>($"/api/errors/{result.Item.UniqueMessageId}/retry", null, null,
34+
ServiceControlInstanceName);
35+
c.RetryCount++;
36+
}
37+
}
38+
39+
return false;
40+
}
41+
42+
return await GetFailedMessage(c, ServiceControlInstanceName, FailedMessageStatus.Resolved);
43+
})
44+
.Run(TimeSpan.FromMinutes(2));
45+
}
46+
47+
[Test]
48+
public async Task WithEdit()
49+
{
50+
CustomServiceControlPrimarySettings = s => { s.AllowMessageEditing = true; };
51+
52+
await Define<MyContext>()
53+
.WithEndpoint<FailureEndpoint>(b =>
54+
b.When(bus => bus.SendLocal(new MyMessage())).DoNotFailOnErrorMessages())
55+
.Done(async c =>
56+
{
57+
if (c.RetryCount < 3)
58+
{
59+
var results = await GetAllFailedMessage(ServiceControlInstanceName, FailedMessageStatus.Unresolved);
60+
if (!results.HasResult)
61+
{
62+
return false;
63+
}
64+
65+
var result = results.Items.Single();
66+
67+
c.MessageId = result.MessageId;
68+
69+
var failedMessage = await GetFailedMessage(c, ServiceControlInstanceName, FailedMessageStatus.Unresolved);
70+
if (!failedMessage.HasResult)
71+
{
72+
return false;
73+
}
74+
75+
await this.Post<object>($"/api/edit/{failedMessage.Item.UniqueMessageId}",
76+
new
77+
{
78+
MessageBody = $"{{ \"Name\": \"John{c.RetryCount}\" }}",
79+
MessageHeaders = failedMessage.Item.ProcessingAttempts[^1].Headers
80+
}, null,
81+
ServiceControlInstanceName);
82+
c.RetryCount++;
83+
84+
return false;
85+
}
86+
87+
return !(await GetAllFailedMessage(ServiceControlInstanceName, FailedMessageStatus.Unresolved)).HasResult;
88+
})
89+
.Run(TimeSpan.FromMinutes(2));
90+
}
91+
92+
Task<SingleResult<FailedMessage>> GetFailedMessage(MyContext c, string instance, FailedMessageStatus expectedStatus)
93+
{
94+
if (c.MessageId == null)
95+
{
96+
return Task.FromResult(SingleResult<FailedMessage>.Empty);
97+
}
98+
99+
return this.TryGet<FailedMessage>("/api/errors/" + c.UniqueMessageId, f => f.Status == expectedStatus, instance);
100+
}
101+
102+
Task<ManyResult<FailedMessageView>> GetAllFailedMessage(string instance, FailedMessageStatus expectedStatus)
103+
{
104+
return this.TryGetMany<FailedMessageView>("/api/errors", f => f.Status == expectedStatus, instance);
105+
}
106+
107+
public class FailureEndpoint : EndpointConfigurationBuilder
108+
{
109+
public FailureEndpoint() => EndpointSetup<DefaultServerWithoutAudit>(c => { c.NoRetries(); });
110+
111+
public class MyMessageHandler : IHandleMessages<MyMessage>
112+
{
113+
readonly MyContext testContext;
114+
readonly IReadOnlySettings settings;
115+
116+
public MyMessageHandler(MyContext testContext, IReadOnlySettings settings)
117+
{
118+
this.testContext = testContext;
119+
this.settings = settings;
120+
}
121+
122+
public Task Handle(MyMessage message, IMessageHandlerContext context)
123+
{
124+
testContext.MessageId = context.MessageId.Replace(@"\", "-");
125+
testContext.EndpointNameOfReceivingEndpoint = settings.EndpointName();
126+
Console.Out.WriteLine("Handling message");
127+
128+
if (testContext.RetryCount < 3)
129+
{
130+
Console.Out.WriteLine("Throwing exception for MyMessage");
131+
throw new Exception("Simulated exception");
132+
}
133+
134+
return Task.CompletedTask;
135+
}
136+
}
137+
}
138+
139+
140+
public class MyMessage : ICommand
141+
{
142+
public string Name { get; set; }
143+
}
144+
145+
public class MyContext : ScenarioContext
146+
{
147+
public string MessageId { get; set; }
148+
149+
public string EndpointNameOfReceivingEndpoint { get; set; }
150+
151+
public string UniqueMessageId => DeterministicGuid.MakeId(MessageId, EndpointNameOfReceivingEndpoint).ToString();
152+
public int RetryCount { get; set; }
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)