Skip to content

Commit 821f4d9

Browse files
committed
Consolidate done criteria
1 parent d1a7326 commit 821f4d9

File tree

1 file changed

+112
-123
lines changed

1 file changed

+112
-123
lines changed

src/ServiceControl.AcceptanceTests/Recoverability/MessageFailures/When_ingesting_failed_message_with_missing_headers.cs

Lines changed: 112 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,130 @@
1-
namespace ServiceControl.AcceptanceTests.Recoverability.MessageFailures
1+
namespace ServiceControl.AcceptanceTests.Recoverability.MessageFailures;
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
using AcceptanceTesting;
7+
using AcceptanceTesting.EndpointTemplates;
8+
using Infrastructure;
9+
using NServiceBus;
10+
using NServiceBus.AcceptanceTesting;
11+
using NServiceBus.Routing;
12+
using NServiceBus.Transport;
13+
using NUnit.Framework;
14+
using ServiceControl.MessageFailures.Api;
15+
16+
class When_ingesting_failed_message_with_missing_headers : AcceptanceTest
217
{
3-
using System;
4-
using System.Collections.Generic;
5-
using System.Threading.Tasks;
6-
using AcceptanceTesting;
7-
using AcceptanceTesting.EndpointTemplates;
8-
using Infrastructure;
9-
using NServiceBus;
10-
using NServiceBus.AcceptanceTesting;
11-
using NServiceBus.Routing;
12-
using NServiceBus.Transport;
13-
using NUnit.Framework;
14-
using ServiceControl.MessageFailures.Api;
15-
16-
class When_ingesting_failed_message_with_missing_headers : AcceptanceTest
18+
[Test]
19+
public async Task Should_be_ingested_when_minimal_required_headers_is_present()
1720
{
18-
[Test]
19-
public async Task Should_be_ingested_when_minimal_required_headers_is_present()
20-
{
21-
FailedMessageView failure = null;
22-
23-
var testStartTime = DateTime.UtcNow;
24-
25-
await Define<MyContext>(c =>
26-
{
27-
c.AddMinimalRequiredHeaders();
28-
})
29-
.WithEndpoint<FailingEndpoint>()
30-
.Done(async c =>
31-
{
32-
var result = await this.TryGet<FailedMessageView>($"/api/errors/last/{c.UniqueMessageId}");
33-
failure = result;
34-
return (c.UniqueMessageId != null) & result;
35-
})
36-
.Run();
37-
38-
Assert.That(failure, Is.Not.Null);
39-
Assert.That(failure.TimeSent, Is.Null);
40-
41-
//No failure time will result in utc now being used
42-
Assert.That(failure.TimeOfFailure, Is.GreaterThan(testStartTime));
43-
44-
// Both host and endpoint name is currently needed so this will be null since no host can be detected from the failed q header
45-
Assert.That(failure.ReceivingEndpoint, Is.Null);
46-
}
21+
var testStartTime = DateTime.UtcNow;
4722

48-
[Test]
49-
public async Task Should_include_headers_required_by_ServicePulse()
50-
{
51-
FailedMessageView failure = null;
52-
53-
var context = await Define<MyContext>(c =>
54-
{
55-
c.AddMinimalRequiredHeaders();
56-
57-
// This is needed for ServiceControl to be able to detect both endpoint (via failed q header) and host via the processing machine header
58-
// Missing endpoint or host will cause a null ref in ServicePulse
59-
c.Headers[Headers.ProcessingMachine] = "MyMachine";
60-
61-
c.Headers["NServiceBus.ExceptionInfo.ExceptionType"] = "SomeExceptionType";
62-
c.Headers["NServiceBus.ExceptionInfo.Message"] = "Some message";
63-
})
64-
.WithEndpoint<FailingEndpoint>()
65-
.Done(async c =>
66-
{
67-
var result = await this.TryGet<FailedMessageView>($"/api/errors/last/{c.UniqueMessageId}");
68-
failure = result;
69-
return (c.UniqueMessageId != null) & result;
70-
})
71-
.Run();
72-
73-
Assert.That(failure, Is.Not.Null);
74-
75-
// ServicePulse assumes that the receiving endpoint name is present
76-
Assert.That(failure.ReceivingEndpoint, Is.Not.Null);
77-
Assert.That(failure.ReceivingEndpoint.Name, Is.EqualTo(context.EndpointNameOfReceivingEndpoint));
78-
Assert.That(failure.ReceivingEndpoint.Host, Is.EqualTo("MyMachine"));
79-
80-
// ServicePulse needs both an exception type and description to render the UI in a resonable way
81-
Assert.That(failure.Exception.ExceptionType, Is.EqualTo("SomeExceptionType"));
82-
Assert.That(failure.Exception.Message, Is.EqualTo("Some message"));
83-
}
23+
var context = await Define<TestContext>(c => c.AddMinimalRequiredHeaders())
24+
.WithEndpoint<FailingEndpoint>()
25+
.Done(async c => await TryGetFailureFromApi(c))
26+
.Run();
8427

85-
[Test]
86-
public async Task TimeSent_should_not_be_casted()
87-
{
88-
FailedMessageView failure = null;
89-
90-
var sentTime = DateTime.Parse("2014-11-11T02:26:58.000462Z");
91-
92-
await Define<MyContext>(c =>
93-
{
94-
c.AddMinimalRequiredHeaders();
95-
c.Headers.Add("NServiceBus.TimeSent", DateTimeOffsetHelper.ToWireFormattedString(sentTime));
96-
})
97-
.WithEndpoint<FailingEndpoint>()
98-
.Done(async c =>
99-
{
100-
var result = await this.TryGet<FailedMessageView>($"/api/errors/last/{c.UniqueMessageId}");
101-
failure = result;
102-
return (c.UniqueMessageId != null) & result;
103-
})
104-
.Run();
105-
106-
Assert.That(failure, Is.Not.Null);
107-
Assert.That(failure.TimeSent, Is.EqualTo(sentTime));
108-
}
28+
var failure = context.Failure;
10929

110-
class MyContext : ScenarioContext
111-
{
112-
public string MessageId { get; } = Guid.NewGuid().ToString();
30+
Assert.That(failure, Is.Not.Null);
31+
Assert.That(failure.TimeSent, Is.Null);
11332

114-
public string EndpointNameOfReceivingEndpoint => "MyEndpoint";
33+
//No failure time will result in utc now being used
34+
Assert.That(failure.TimeOfFailure, Is.GreaterThan(testStartTime));
11535

116-
public string UniqueMessageId => DeterministicGuid.MakeId(MessageId, EndpointNameOfReceivingEndpoint).ToString();
36+
// Both host and endpoint name is currently needed so this will be null since no host can be detected from the failed q header
37+
Assert.That(failure.ReceivingEndpoint, Is.Null);
38+
}
11739

118-
public Dictionary<string, string> Headers { get; } = [];
40+
[Test]
41+
public async Task Should_include_headers_required_by_ServicePulse()
42+
{
43+
var context = await Define<TestContext>(c =>
44+
{
45+
c.AddMinimalRequiredHeaders();
46+
47+
// This is needed for ServiceControl to be able to detect both endpoint (via failed q header) and host via the processing machine header
48+
// Missing endpoint or host will cause a null ref in ServicePulse
49+
c.Headers[Headers.ProcessingMachine] = "MyMachine";
50+
51+
c.Headers["NServiceBus.ExceptionInfo.ExceptionType"] = "SomeExceptionType";
52+
c.Headers["NServiceBus.ExceptionInfo.Message"] = "Some message";
53+
})
54+
.WithEndpoint<FailingEndpoint>()
55+
.Done(async c => await TryGetFailureFromApi(c))
56+
.Run();
57+
58+
var failure = context.Failure;
59+
60+
Assert.That(failure, Is.Not.Null);
61+
62+
// ServicePulse assumes that the receiving endpoint name is present
63+
Assert.That(failure.ReceivingEndpoint, Is.Not.Null);
64+
Assert.That(failure.ReceivingEndpoint.Name, Is.EqualTo(context.EndpointNameOfReceivingEndpoint));
65+
Assert.That(failure.ReceivingEndpoint.Host, Is.EqualTo("MyMachine"));
66+
67+
// ServicePulse needs both an exception type and description to render the UI in a resonable way
68+
Assert.That(failure.Exception.ExceptionType, Is.EqualTo("SomeExceptionType"));
69+
Assert.That(failure.Exception.Message, Is.EqualTo("Some message"));
70+
}
71+
72+
[Test]
73+
public async Task TimeSent_should_not_be_casted()
74+
{
75+
var sentTime = DateTime.Parse("2014-11-11T02:26:58.000462Z");
11976

120-
public void AddMinimalRequiredHeaders()
77+
var context = await Define<TestContext>(c =>
12178
{
122-
Headers["NServiceBus.FailedQ"] = EndpointNameOfReceivingEndpoint;
123-
Headers[NServiceBus.Headers.MessageId] = MessageId;
124-
}
125-
}
79+
c.AddMinimalRequiredHeaders();
80+
c.Headers.Add("NServiceBus.TimeSent", DateTimeOffsetHelper.ToWireFormattedString(sentTime));
81+
})
82+
.WithEndpoint<FailingEndpoint>()
83+
.Done(async c => await TryGetFailureFromApi(c))
84+
.Run();
85+
86+
var failure = context.Failure;
87+
88+
Assert.That(failure, Is.Not.Null);
89+
Assert.That(failure.TimeSent, Is.EqualTo(sentTime));
90+
}
91+
92+
async Task<bool> TryGetFailureFromApi(TestContext context)
93+
{
94+
context.Failure = await this.TryGet<FailedMessageView>($"/api/errors/last/{context.UniqueMessageId}");
95+
return context.Failure != null;
96+
}
97+
98+
class TestContext : ScenarioContext
99+
{
100+
public string MessageId { get; } = Guid.NewGuid().ToString();
126101

127-
class FailingEndpoint : EndpointConfigurationBuilder
102+
public string EndpointNameOfReceivingEndpoint => "MyEndpoint";
103+
104+
public string UniqueMessageId => DeterministicGuid.MakeId(MessageId, EndpointNameOfReceivingEndpoint).ToString();
105+
106+
public Dictionary<string, string> Headers { get; } = [];
107+
108+
public FailedMessageView Failure { get; set; }
109+
110+
public void AddMinimalRequiredHeaders()
128111
{
129-
public FailingEndpoint() => EndpointSetup<DefaultServerWithoutAudit>(c => c.Recoverability().Delayed(x => x.NumberOfRetries(0)));
112+
Headers["NServiceBus.FailedQ"] = EndpointNameOfReceivingEndpoint;
113+
Headers[NServiceBus.Headers.MessageId] = MessageId;
114+
}
115+
}
116+
117+
class FailingEndpoint : EndpointConfigurationBuilder
118+
{
119+
public FailingEndpoint() => EndpointSetup<DefaultServerWithoutAudit>();
130120

131-
class SendFailedMessage : DispatchRawMessages<MyContext>
121+
class SendFailedMessage : DispatchRawMessages<TestContext>
122+
{
123+
protected override TransportOperations CreateMessage(TestContext context)
132124
{
133-
protected override TransportOperations CreateMessage(MyContext context)
134-
{
135-
var outgoingMessage = new OutgoingMessage(context.MessageId, context.Headers, Array.Empty<byte>());
125+
var outgoingMessage = new OutgoingMessage(context.MessageId, context.Headers, Array.Empty<byte>());
136126

137-
return new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag("error")));
138-
}
127+
return new TransportOperations(new TransportOperation(outgoingMessage, new UnicastAddressTag("error")));
139128
}
140129
}
141130
}

0 commit comments

Comments
 (0)