using System; using System.Diagnostics; using Xunit; using Xunit.Abstractions; namespace Centron.Tests.EndToEnd.Infrastructure { public abstract class PerformanceTest : EndToEndTest { protected PerformanceTest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } public override void Execute() { this.Prepare(); var watch = Stopwatch.StartNew(); this.Measure(); watch.Stop(); this.AssertResults(); bool FinishedInTime(double factor) { return this.AllowedDuration == null || watch.Elapsed.TotalSeconds <= this.AllowedDuration.Value.TotalSeconds * factor; } bool finishedPerfect = FinishedInTime(factor: 1.0); bool finishedGood = FinishedInTime(factor: 1.1); bool finishedBad = FinishedInTime(factor: 1.5); var status = finishedPerfect ? "PERFECT" : finishedGood ? "GOOD" : finishedBad ? "BAD" : string.Empty; if (string.IsNullOrWhiteSpace(status)) { this.TestOutputHelper.WriteLine($"{this.GetType().Name} did not finish in time. Max duration is {this.AllowedDuration?.ToString() ?? "(infinite)"}, but it took {watch.Elapsed}"); } else { this.TestOutputHelper.WriteLine($"{this.GetType().Name} did finish {status} in {watch.Elapsed}"); } } protected virtual TimeSpan? AllowedDuration { get; } protected virtual void Prepare() { } protected abstract void Measure(); protected virtual void AssertResults() { } } }