-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement ResiliencePipeline when using `IsLanguageForgeProjectDataLo…
…ader` (#1097) in case of a failure, the server will wait 60 seconds before trying again. Reduced connection timeouts to 5 seconds from 30.
- Loading branch information
Showing
8 changed files
with
194 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
backend/Testing/Services/IsLanguageForgeProjectDataLoaderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using LexBoxApi.GraphQL.CustomTypes; | ||
using Microsoft.Extensions.Time.Testing; | ||
using Polly; | ||
using Shouldly; | ||
|
||
namespace Testing.Services; | ||
|
||
public class IsLanguageForgeProjectDataLoaderTests | ||
{ | ||
private readonly FakeTimeProvider _timeProvider = new(); | ||
private readonly ResiliencePipeline<IReadOnlyDictionary<string, bool>> _pipeline; | ||
private static readonly TimeSpan BreakDuration = TimeSpan.FromSeconds(60); | ||
|
||
public IsLanguageForgeProjectDataLoaderTests() | ||
{ | ||
_pipeline = IsLanguageForgeProjectDataLoader.ConfigureResiliencePipeline(new() { TimeProvider = _timeProvider }, BreakDuration) | ||
.Build(); | ||
} | ||
|
||
private ValueTask<Outcome<Dictionary<string, bool>>> Execute(Exception? exception = null) | ||
{ | ||
ResilienceContext context = ResilienceContextPool.Shared.Get(); | ||
context.Properties.Set(IsLanguageForgeProjectDataLoader.ProjectCodesKey, new[] { "test" }); | ||
return _pipeline.ExecuteOutcomeAsync((context, state) => | ||
{ | ||
if (exception is not null) | ||
{ | ||
return Outcome.FromExceptionAsValueTask<Dictionary<string, bool>>(exception); | ||
} | ||
return Outcome.FromResultAsValueTask(new Dictionary<string, bool>() { { "test", true } }); | ||
}, | ||
context, | ||
this); | ||
} | ||
|
||
private void VerifyEmptyResult(Outcome<Dictionary<string, bool>> result) | ||
{ | ||
result.Exception.ShouldBeNull(); | ||
result.Result.ShouldBe(new Dictionary<string, bool>() { { "test", false } }); | ||
} | ||
|
||
private void VerifySuccessResult(Outcome<Dictionary<string, bool>> result) | ||
{ | ||
result.Exception.ShouldBeNull(); | ||
result.Result.ShouldBe(new Dictionary<string, bool>() { { "test", true } }); | ||
} | ||
|
||
[Fact] | ||
public async Task ResiliencePipelineWorksFine() | ||
{ | ||
var result = await Execute(); | ||
VerifySuccessResult(result); | ||
} | ||
|
||
[Fact] | ||
public async Task ResiliencePipelineReturnsEmptyResultWhenExceptionIsThrown() | ||
{ | ||
var result = await Execute(new Exception("test")); | ||
VerifyEmptyResult(result); | ||
} | ||
|
||
[Fact] | ||
public async Task CircuitBreaksAfter2Failures() | ||
{ | ||
for (int i = 0; i < 3; i++) | ||
{ | ||
await Execute(new Exception("test")); | ||
_timeProvider.Advance(TimeSpan.FromSeconds(21)); | ||
} | ||
//the circuit is open, now the fallback should be used | ||
var result = await Execute(); | ||
VerifyEmptyResult(result); | ||
} | ||
|
||
[Fact] | ||
public async Task CircuitBreaksAndReOpensAfterTimeout() | ||
{ | ||
for (int i = 0; i < 3; i++) | ||
{ | ||
await Execute(new Exception("test")); | ||
_timeProvider.Advance(TimeSpan.FromSeconds(21)); | ||
} | ||
//the circuit is open, now the fallback should be used | ||
VerifyEmptyResult(await Execute()); | ||
_timeProvider.Advance(BreakDuration + TimeSpan.FromSeconds(1)); | ||
VerifySuccessResult(await Execute()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters