Skip to content

Commit

Permalink
fix(featureRuns): disallow stopping stopped run
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberhck committed Jul 11, 2020
1 parent 7ddae9f commit 1d210e0
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace Feature.Manager.Api.FeatureRuns.Exceptions
{
public class FeatureRunAlreadyStoppedException : Exception
{

}
}
11 changes: 10 additions & 1 deletion Feature.Manager.Api/FeatureRuns/FeatureRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task<FeatureRun> CreateFeatureRun(CreateFeatureRunRequest request)
try
{
var runs = await _featureRunRepository.GetRunsForFeatureByFeatId(request.FeatId);
if (runs.Any(x => x.EndAt == null))
if (runs.Any(x => x.EndAt == null || x.StopResult == StopResult.AllB))
{
throw new FeatureAlreadyRunningException();
}
Expand Down Expand Up @@ -82,13 +82,22 @@ public async Task<FeatureRun> StopFeatureRun(StopFeatureRunRequest request)
throw new FeatureRunNotFoundException();
}

if (result.EndAt?.ToUniversalTime() <= DateTime.UtcNow && result.StopResult != StopResult.AllB)
{
throw new FeatureRunAlreadyStoppedException();
}

if (!Enum.TryParse(request.StopResult, out StopResult stopResult))
{
throw new InvalidStopResultValueException();
}

return await _featureRunRepository.StopFeatureRun(request);
}
catch (FeatureRunAlreadyStoppedException)
{
throw;
}
catch (FeatureRunNotFoundException)
{
throw;
Expand Down
7 changes: 7 additions & 0 deletions Feature.Manager.Api/FeatureRuns/FeatureRunsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ public async Task<IActionResult> StopRun(StopFeatureRunRequest request)
var result = await _featureRunService.StopFeatureRun(request);
return Ok(result);
}
catch (FeatureRunAlreadyStoppedException)
{
return BadRequest(new ProblemDetails
{
Title = "Run Already stopped"
});
}
catch (InvalidStopResultValueException)
{
return BadRequest(new ProblemDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ public void Setup()
{
MakeFeatureRun(StopResult.AllB, "APP-5", DateTime.Now.Subtract(TimeSpan.FromHours(12)))
});
mock.Setup(x => x.GetRunsForFeatureByFeatId("APP-6")).ReturnsAsync(new List<FeatureRun>
{
MakeFeatureRun(StopResult.AllA, "APP-6", DateTime.Now.Subtract(TimeSpan.FromHours(12)))
});
mock.Setup(x => x.GetRunsForFeatureByFeatId("APP-19")).ReturnsAsync(new List<FeatureRun>());
_mock = mock;
var featureRepository = new Mock<IFeatureRepository>();
Expand Down Expand Up @@ -116,19 +120,35 @@ public async Task TestCannotCreateNewRunIfARunIsAlreadyRunning()
StartAt = DateTime.Now,
FeatId = "APP-2"
}));
Assert.ThrowsAsync<FeatureAlreadyRunningException>(() => _featureRunService.CreateFeatureRun(
new CreateFeatureRunRequest
{
Allocation = 100,
EndAt = DateTime.Now.Add(TimeSpan.FromDays(20)),
StartAt = DateTime.Now,
FeatId = "APP-5"
}));
}

[Test]
public async Task TestCreatesNewRunWhenNoFeaturesAreRunning()
{
var result = await _featureRunService.CreateFeatureRun(new CreateFeatureRunRequest
var app3 = await _featureRunService.CreateFeatureRun(new CreateFeatureRunRequest
{
Allocation = 100,
EndAt = DateTime.Now.Add(TimeSpan.FromDays(20)),
StartAt = DateTime.Now,
FeatId = "APP-3"
});
Assert.NotNull(result);
var app6 = await _featureRunService.CreateFeatureRun(new CreateFeatureRunRequest
{
Allocation = 100,
EndAt = DateTime.Now.Add(TimeSpan.FromDays(20)),
StartAt = DateTime.Now,
FeatId = "APP-6"
});
Assert.NotNull(app3);
Assert.NotNull(app6);
}

[Test]
Expand Down
70 changes: 70 additions & 0 deletions Feature.Manager.UnitTest/FeatureRuns/FeatureRunServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,46 @@ public void Setup()
FeatId = "APP-1",
RunToken = "RAND-UUID-TOKEN",
});
mock.Setup(x => x.GetById("stopped-run-all-b")).ReturnsAsync(new FeatureRun
{
Allocation = 100,
Id = "stopped-run-all-b",
EndAt = DateTime.Now.Subtract(TimeSpan.FromSeconds(5)),
StartAt = DateTime.Now.Subtract(TimeSpan.FromDays(2)),
StopResult = StopResult.AllB,
FeatId = "APP-1",
RunToken = "RAND-UUID-TOKEN",
});
mock.Setup(x => x.GetById("stopped-run-changed-settings")).ReturnsAsync(new FeatureRun
{
Allocation = 100,
Id = "stopped-run-changed-settings",
EndAt = DateTime.Now.Subtract(TimeSpan.FromSeconds(5)),
StartAt = DateTime.Now.Subtract(TimeSpan.FromDays(2)),
StopResult = StopResult.ChangeSettings,
FeatId = "APP-1",
RunToken = "RAND-UUID-TOKEN",
});
mock.Setup(x => x.GetById("stopped-run-all-a")).ReturnsAsync(new FeatureRun
{
Allocation = 100,
Id = "stopped-run-all-a",
EndAt = DateTime.Now.Subtract(TimeSpan.FromSeconds(5)),
StopResult = StopResult.AllA,
StartAt = DateTime.Now.Subtract(TimeSpan.FromDays(2)),
FeatId = "APP-1",
RunToken = "RAND-UUID-TOKEN",
});
mock.Setup(x => x.GetById("stopped-run-removed-from-code")).ReturnsAsync(new FeatureRun
{
Allocation = 100,
Id = "stopped-run-removed-from-code",
EndAt = DateTime.Now.Subtract(TimeSpan.FromSeconds(5)),
StopResult = StopResult.Removed,
StartAt = DateTime.Now.Subtract(TimeSpan.FromDays(2)),
FeatId = "APP-1",
RunToken = "RAND-UUID-TOKEN",
});
mock.Setup(x => x.GetById("RUN-UUID-3")).ThrowsAsync(new InvalidCastException());
mock.Setup(x => x.StopFeatureRun(It.IsAny<StopFeatureRunRequest>())).ReturnsAsync(
(StopFeatureRunRequest request) =>
Expand Down Expand Up @@ -199,5 +239,35 @@ public async Task TestGetRunningFeaturesHandlesException()
var systemUnderTest = new FeatureRunService(mock.Object, null);
Assert.ThrowsAsync<UnknownDbException>(() => systemUnderTest.GetRunningFeatures());
}

[Test]
public async Task StoppedRunsCantBeStoppedFurther()
{
Assert.ThrowsAsync<FeatureRunAlreadyStoppedException>(() => _featureRunService.StopFeatureRun(new StopFeatureRunRequest
{
RunId = "stopped-run-changed-settings",
StopResult = "AllB"
}));
Assert.ThrowsAsync<FeatureRunAlreadyStoppedException>(() => _featureRunService.StopFeatureRun(new StopFeatureRunRequest
{
RunId = "stopped-run-all-a",
StopResult = "AllB"
}));
Assert.ThrowsAsync<FeatureRunAlreadyStoppedException>(() => _featureRunService.StopFeatureRun(new StopFeatureRunRequest
{
RunId = "stopped-run-removed-from-code",
StopResult = "AllB"
}));
}

[Test]
public async Task StoppedAllBRunsCanBeChanged()
{
Assert.DoesNotThrowAsync(() => _featureRunService.StopFeatureRun(new StopFeatureRunRequest
{
RunId = "stopped-run-all-b",
StopResult = "AllA"
}));
}
}
}

0 comments on commit 1d210e0

Please sign in to comment.