Skip to content

Add baseline version test #7627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions test/SharedFx.UnitTests/ConsoleReporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using McMaster.Extensions.CommandLineUtils;

namespace Microsoft.Extensions.Tools.Internal
{
public class ConsoleReporter : IReporter
{
private object _writeLock = new object();

public ConsoleReporter(IConsole console)
: this(console, verbose: false, quiet: false)
{ }

public ConsoleReporter(IConsole console, bool verbose, bool quiet)
{
Console = console;
IsVerbose = verbose;
IsQuiet = quiet;
}

protected IConsole Console { get; }
public bool IsVerbose { get; }
public bool IsQuiet { get; }

protected virtual void WriteLine(TextWriter writer, string message, ConsoleColor? color)
{
lock (_writeLock)
{
if (color.HasValue)
{
Console.ForegroundColor = color.Value;
}

writer.WriteLine(message);

if (color.HasValue)
{
Console.ResetColor();
}
}
}

public virtual void Error(string message)
=> WriteLine(Console.Error, message, ConsoleColor.Red);
public virtual void Warn(string message)
=> WriteLine(Console.Out, message, ConsoleColor.Yellow);

public virtual void Output(string message)
{
if (IsQuiet)
{
return;
}
WriteLine(Console.Out, message, color: null);
}

public virtual void Verbose(string message)
{
if (!IsVerbose)
{
return;
}

WriteLine(Console.Out, message, ConsoleColor.DarkGray);
}
}
}
65 changes: 65 additions & 0 deletions test/SharedFx.UnitTests/RetryHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using McMaster.Extensions.CommandLineUtils;

namespace TriageBuildFailures
{
internal static class RetryHelpers
{
/// <summary>
/// Constrain the exponential back-off to this many minutes.
/// </summary>
private const int MaxRetryMinutes = 15;

private static int TotalRetriesUsed;

public static int GetTotalRetriesUsed()
{
return TotalRetriesUsed;
}

public static async Task RetryAsync(Func<Task> action, IReporter reporter)
{
await RetryAsync<object>(
async () =>
{
await action();
return null;
},
reporter);
}

public static async Task<T> RetryAsync<T>(Func<Task<T>> action, IReporter reporter)
{
Exception firstException = null;

var retriesRemaining = 10;
var retryDelayInMinutes = 1;

while (retriesRemaining > 0)
{
try
{
return await action();
}
catch (Exception e)
{
firstException = firstException ?? e;
reporter.Output($"Exception thrown! {e.Message}");
reporter.Output($"Waiting {retryDelayInMinutes} minute(s) to retry ({retriesRemaining} left)...");
await Task.Delay(retryDelayInMinutes * 60 * 1000);

// Do exponential back-off, but limit it (1, 2, 4, 8, 15, 15, 15, ...)
// With MaxRetryMinutes=15 and MaxRetries=10, this will delay a maximum of 105 minutes
retryDelayInMinutes = Math.Min(2 * retryDelayInMinutes, MaxRetryMinutes);
retriesRemaining--;
TotalRetriesUsed++;
}
}
throw new InvalidOperationException("Max exception retries reached, giving up.", firstException);
}
}
}
5 changes: 5 additions & 0 deletions test/SharedFx.UnitTests/SharedFx.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<_Parameter1>MicrosoftNETCoreAppPackageVersion</_Parameter1>
<_Parameter2>$(RuntimeFrameworkVersion)</_Parameter2>
</AssemblyAttribute>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>PreviousAspNetCoreReleaseVersion</_Parameter1>
<_Parameter2>$(PreviousAspNetCoreReleaseVersion)</_Parameter2>
</AssemblyAttribute>
</ItemGroup>

<ItemGroup>
Expand All @@ -34,6 +38,7 @@
<PackageReference Include="xunit" Version="$(XunitPackageVersion)" />
<PackageReference Include="xunit.analyzers" Version="$(XunitAnalyzersPackageVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitRunnerVisualstudioPackageVersion)" />
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.2.2" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is test-only but have we used @natemcmaster's private packages elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mimicked here what we did in the internal repo.

</ItemGroup>

</Project>
63 changes: 63 additions & 0 deletions test/SharedFx.UnitTests/SharedFxTests.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,77 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using McMaster.Extensions.CommandLineUtils;
using Newtonsoft.Json.Linq;
using TriageBuildFailures;
using Xunit;

namespace Microsoft.AspNetCore
{
public class SharedFxTests
{

[Theory]
[MemberData(nameof(GetSharedFxConfig))]
public async Task BaselineTest(SharedFxConfig config)
{
var previousVersion = TestData.GetPreviousAspNetCoreReleaseVersion();
var url = new Uri($"https://dotnetcli.blob.core.windows.net/dotnet/aspnetcore/Runtime/" + previousVersion + "/aspnetcore-runtime-internal-" + previousVersion + "-win-x64.zip");
var zipName = "assemblies.zip";
var nugetAssemblyVersions = new Dictionary<string, Version>();
var root = TestData.GetDotNetRoot();
var dir = Path.Combine(root, "shared", config.Name, config.Version);

using (var testClient = new WebClient())
{
var reporter = new ConsoleReporter(PhysicalConsole.Singleton);
await RetryHelpers.RetryAsync(async () => await testClient.DownloadFileTaskAsync(url, zipName), reporter);
}

var zipPath = Path.Combine(AppContext.BaseDirectory, zipName);

if (!Directory.Exists(AppContext.BaseDirectory + "unzipped"))
{
ZipFile.ExtractToDirectory(AppContext.BaseDirectory, "unzipped");
}

var nugetAssembliesPath = Path.Combine(AppContext.BaseDirectory, "unzipped", "shared", config.Name, previousVersion);

var files = Directory.GetFiles(nugetAssembliesPath, "*.dll");
foreach (var file in files)
{
try
{
var assemblyVersion = AssemblyName.GetAssemblyName(file).Version;
var dllName = Path.GetFileName(file);
nugetAssemblyVersions.Add(dllName, assemblyVersion);
}
catch (BadImageFormatException) { }
}

files = Directory.GetFiles(dir, "*.dll");

Assert.All(files, file =>
{
try
{
var localAssemblyVersion = AssemblyName.GetAssemblyName(file).Version;
var dllName = Path.GetFileName(file);
Assert.True(nugetAssemblyVersions.ContainsKey(dllName), $"Expected {dllName} to be in the downloaded dlls");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and BTW just checking, are there are no xUnit asserts for these two asserts here? Usually Assert.True is frowned upon, unless there's no other reasonable choice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.Contains(nugetAssemblyVersions.Keys, ...) should work here. The only supposed loss would be the custom error message when it fails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could change to use the Assert.Contains api. The error message becomes slightly less clear. I'm indifferent.

Assert.True(localAssemblyVersion.CompareTo(nugetAssemblyVersions[dllName]) >= 0, $"Expected the local version of {dllName} to be greater than or equal to the already released version.");
}
catch (BadImageFormatException) { }

});
}

[Theory]
[MemberData(nameof(GetSharedFxConfig))]
public void ItContainsValidRuntimeConfigFile(SharedFxConfig config)
Expand Down
2 changes: 2 additions & 0 deletions test/SharedFx.UnitTests/TestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class TestData
{
public static string GetPackageVersion() => GetTestDataValue("PackageVersion");

public static string GetPreviousAspNetCoreReleaseVersion() => GetTestDataValue("PreviousAspNetCoreReleaseVersion");

public static string GetMicrosoftNETCoreAppPackageVersion() => GetTestDataValue("MicrosoftNETCoreAppPackageVersion");

public static string GetDotNetRoot() => GetTestDataValue("DotNetRoot");
Expand Down