Skip to content

Commit ee2a455

Browse files
committed
Improve reliability of ETag validation in event log acceptance tests
The test could fail if new events were written to the log between the initial request and the conditional poll. The validation now polls until the log stabilizes or a 304 Not Modified is received to avoid false positives caused by background activity.
1 parent f256b47 commit ee2a455

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

‎src/ServiceControl.AcceptanceTests/EventLogs/When_the_event_log_is_polled_with_an_etag.cs‎

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,9 @@ await Define<ScenarioContext>()
5252
return false;
5353
}
5454

55-
var current = await Poll(currentEtag);
55+
var current = await PollUntilTheLogGoesQuiet(currentEtag);
5656

57-
// The endpoint keeps writing startup events, so a 200 here means either the
58-
// validator went stale between the two requests, or the server ignored
59-
// If-None-Match. Only the second is a failure, and the ETag tells them apart.
60-
if (current.StatusCode == HttpStatusCode.OK && ReadEtag(current) != currentEtag)
57+
if (current == null)
6158
{
6259
return false;
6360
}
@@ -96,6 +93,35 @@ await Define<ScenarioContext>()
9693
static string ReadEtag(HttpResponseMessage response) =>
9794
response.Headers.TryGetValues("ETag", out var values) ? values.FirstOrDefault() : null;
9895

96+
// The endpoint keeps writing startup events, so a 200 carrying a *different* ETag only
97+
// means the log moved on between the two requests, and says nothing about conditional
98+
// GET support. Poll again with the ETag that response handed back, until either the log
99+
// stops changing (304, or a 200 repeating the validator we sent, which is the real
100+
// failure) or the attempts run out and the caller retries from a fresh read.
101+
async Task<HttpResponseMessage> PollUntilTheLogGoesQuiet(string etag)
102+
{
103+
for (var attempt = 0; attempt < MaxPollAttempts; attempt++)
104+
{
105+
var response = await Poll(etag);
106+
107+
if (response.StatusCode != HttpStatusCode.OK)
108+
{
109+
return response;
110+
}
111+
112+
var newEtag = ReadEtag(response);
113+
114+
if (string.IsNullOrEmpty(newEtag) || newEtag == etag)
115+
{
116+
return response;
117+
}
118+
119+
etag = newEtag;
120+
}
121+
122+
return null;
123+
}
124+
99125
Task<HttpResponseMessage> Poll(string ifNoneMatch)
100126
{
101127
var request = new HttpRequestMessage(HttpMethod.Get, "/api/eventlogitems/");
@@ -104,6 +130,8 @@ Task<HttpResponseMessage> Poll(string ifNoneMatch)
104130
return HttpClient.SendAsync(request);
105131
}
106132

133+
const int MaxPollAttempts = 5;
134+
107135
public class StartingEndpoint : EndpointConfigurationBuilder
108136
{
109137
public StartingEndpoint() =>

0 commit comments

Comments
 (0)