Skip to content
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

Add tests for package #47

Merged
merged 4 commits into from
Aug 27, 2024
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
3 changes: 3 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<Project>
<PropertyGroup>
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>

<!-- Default to not packaging a project. Override per-project where dotnet sdk nuget packaging
is desired. -->
<IsPackable Condition="'$(IsPackable)' == ''">false</IsPackable>
Expand Down Expand Up @@ -36,6 +38,7 @@

<Target
Name="PreparePackageReleaseNotesFromFiles"
Condition="'$(IsPackable)' == 'true'"
BeforeTargets="GenerateNuspec">
<PropertyGroup>
<!-- This path will be relative to each executing project -->
Expand Down
6 changes: 6 additions & 0 deletions DotNet.ReproducibleBuilds.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNet.ReproducibleBuilds.Isolated", "src\DotNet.ReproducibleBuilds.Isolated\DotNet.ReproducibleBuilds.Isolated.csproj", "{BD88D2CB-4342-47A3-B0D1-07321E9A92C1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNet.ReproducibleBuilds.Tests", "tests\DotNet.ReproducibleBuilds.Tests\DotNet.ReproducibleBuilds.Tests.csproj", "{72BE4FA4-D190-44AF-B056-23AA79D1553A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -31,6 +33,10 @@ Global
{BD88D2CB-4342-47A3-B0D1-07321E9A92C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD88D2CB-4342-47A3-B0D1-07321E9A92C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD88D2CB-4342-47A3-B0D1-07321E9A92C1}.Release|Any CPU.Build.0 = Release|Any CPU
{72BE4FA4-D190-44AF-B056-23AA79D1553A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72BE4FA4-D190-44AF-B056-23AA79D1553A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72BE4FA4-D190-44AF-B056-23AA79D1553A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72BE4FA4-D190-44AF-B056-23AA79D1553A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 3 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ stages:
- script: dotnet nbgv cloud
displayName: Set Version

- script: dotnet test dirs.proj
displayName: Test

- script: dotnet pack dirs.proj
displayName: Create package(s)

Expand Down
9 changes: 9 additions & 0 deletions tests/DotNet.ReproducibleBuilds.Tests/BooleanExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Diagnostics.CodeAnalysis;

namespace DotNet.ReproducibleBuilds.Tests;

internal static class BooleanExtensions
{
public static string ToLowerInvariant(this bool value) => value.ToString().ToLowerInvariant();
public static string? ToLowerInvariant([NotNullIfNotNull(nameof(value))] this bool? value) => value?.ToString().ToLowerInvariant();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.0" />
<PackageReference Include="MSBuild.ProjectCreation" Version="12.0.1" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<None Include="$(RepoRoot)/src/DotNet.ReproducibleBuilds/*.props" CopyToOutputDirectory="PreserveNewest" />
<None Include="$(RepoRoot)/src/DotNet.ReproducibleBuilds/*.targets" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace DotNet.ReproducibleBuilds.Tests;

internal sealed class EnvironmentVariableSuppressor : IDisposable
{
private readonly string? _value;
private readonly string _name;

public EnvironmentVariableSuppressor(string name)
{
_name = name;
_value = Environment.GetEnvironmentVariable(name);
Environment.SetEnvironmentVariable(name, null);
}

public void Dispose()
{
Environment.SetEnvironmentVariable(_name, _value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace DotNet.ReproducibleBuilds.Tests;

internal static class FileSystemInfoExtensions
{
public static string Combine(this FileSystemInfo info, params string[] paths)
{
return Path.Combine([info.FullName, ..paths]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Microsoft.Build.Utilities.ProjectCreation;
using System.Runtime.CompilerServices;

namespace DotNet.ReproducibleBuilds.Tests;

internal static class MSBuildModuleInitializer
{
[ModuleInitializer]
internal static void InitializeMSBuild()
{
MSBuildAssemblyResolver.Register();
}
}
26 changes: 26 additions & 0 deletions tests/DotNet.ReproducibleBuilds.Tests/ProjectTemplates.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.Build.Utilities.ProjectCreation;

namespace DotNet.ReproducibleBuilds.Tests;

internal static class ProjectTemplates
{
private static readonly string ThisAssemblyDirectory = Path.GetDirectoryName(typeof(ProjectTemplates).Assembly.Location)!;

public static ProjectCreator ReproducibleBuildProject(this ProjectCreatorTemplates templates, FileInfo project)
{
DirectoryInfo directory = project.Directory ?? throw new ArgumentException("Project's path does not appear to have a parent.", nameof(project));

_ = ProjectCreator
.Create(path: directory.Combine("obj", $"{project.Name}.tests.g.props"))
.Import(Path.Combine(ThisAssemblyDirectory, "DotNet.ReproducibleBuilds.props"))
.Save();

_ = ProjectCreator
.Create(path: directory.Combine("obj", $"{project.Name}.tests.g.targets"))
.Import(Path.Combine(ThisAssemblyDirectory, "DotNet.ReproducibleBuilds.targets"))
.Save();

return templates
.SdkCsproj(path: project.FullName, targetFramework: "net8.0");
}
}
105 changes: 105 additions & 0 deletions tests/DotNet.ReproducibleBuilds.Tests/SourceLinkTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using FluentAssertions;
using Microsoft.Build.Utilities.ProjectCreation;

namespace DotNet.ReproducibleBuilds.Tests;

public class SourceLinkTests : TestBase
{
[Theory]
[InlineData(null, true)]
[InlineData(false, false)]
[InlineData(true, true)]
public void PublishRepositoryUrlIsSet(bool? publishRepositoryUrl, bool expected)
{
ProjectCreator.Templates
.ReproducibleBuildProject(GetRandomFile(".csproj"))
.PropertyGroup()
.Property("PublishRepositoryUrl", publishRepositoryUrl.ToLowerInvariant())
.Project
.GetPropertyValue("PublishRepositoryUrl")
.Should().Be(expected.ToLowerInvariant());
}

[Theory]
[InlineData(null, "embedded")]
[InlineData("embedded", "embedded")]
[InlineData("portable", "portable")]
public void DebugTypeIsSet(string? debugType, string expected)
{
ProjectCreator.Templates
.ReproducibleBuildProject(GetRandomFile(".csproj"))
.PropertyGroup()
.Property("DebugType", debugType)
.Project
.GetPropertyValue("DebugType")
.Should().Be(expected);
}

[Theory]
[InlineData(null, true)]
[InlineData(false, false)]
[InlineData(true, true)]
public void EmbedUntrackedSourcesIsSet(bool? embedUntrackedSources, bool expected)
{
ProjectCreator.Templates
.ReproducibleBuildProject(GetRandomFile(".csproj"))
.PropertyGroup()
.Property("PublishRepositoryUrl", embedUntrackedSources.ToLowerInvariant())
.Project
.GetPropertyValue("PublishRepositoryUrl")
.Should().Be(expected.ToLowerInvariant());
}

[Theory]
[InlineData("GITHUB_REF", "refs/pull/1234/merge", "pr1234")]
[InlineData("GITHUB_REF", "refs/heads/my-branch", "my-branch")]
[InlineData("GITHUB_REF", "refs/tags/v1.2.3", "v1.2.3")]

[InlineData("BUILD_SOURCEBRANCH", "refs/heads/my-branch", "my-branch")]
[InlineData("BUILD_SOURCEBRANCH", "refs/tags/v1.2.3", "v1.2.3")]

[InlineData("APPVEYOR_PULL_REQUEST_NUMBER", "1234", "pr1234")]
[InlineData("APPVEYOR_REPO_TAG_NAME", "refs/tags/v1.2.3", "refs/tags/v1.2.3")]
[InlineData("APPVEYOR_REPO_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]

[InlineData("TEAMCITY_BUILD_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]

[InlineData("TRAVIS_PULL_REQUEST", "1234", "pr1234")]
[InlineData("TRAVIS_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]

[InlineData("CIRCLE_PR_NUMBER", "1234", "pr1234")]
[InlineData("CIRCLE_TAG", "refs/heads/v1.2.3", "refs/heads/v1.2.3")]
[InlineData("CIRCLE_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]

[InlineData("CI_COMMIT_TAG", "refs/tags/v1.2.3", "refs/tags/v1.2.3")]
[InlineData("CI_MERGE_REQUEST_IID", "1234", "pr1234")]
[InlineData("CI_COMMIT_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]

[InlineData("BUDDY_EXECUTION_PULL_REQUEST_NO", "1234", "pr1234")]
[InlineData("BUDDY_EXECUTION_TAG", "refs/tags/v1.2.3", "refs/tags/v1.2.3")]
[InlineData("BUDDY_EXECUTION_BRANCH", "refs/heads/my-branch", "refs/heads/my-branch")]
public void RepositoryBranchIsSet(string ci, string original, string expected)
{
using EnvironmentVariableSuppressor hostSuppressor = new("BUILD_SOURCEBRANCH"); // Suppress our own CI provider variables (i.e. Azure DevOps)
using EnvironmentVariableSuppressor ciSuppressor = new(ci); // Suppress the mock CI provider (just in case).

// If RepositoryBranch is set, it should take precedence over the CI provider variables
ProjectCreator.Templates
.ReproducibleBuildProject(GetRandomFile(".csproj"))
.PropertyGroup()
.Property("RepositoryBranch", "explicitly-set")
.Property(ci, original)
.Project
.GetPropertyValue("RepositoryBranch")
.Should().Be("explicitly-set", "because explicitly setting `RepositoryBranch` should always win.");

// If RepositoryBranch is not set, it should be set from the CI provider property
ProjectCreator.Templates
.ReproducibleBuildProject(GetRandomFile(".csproj"))
.PropertyGroup()
.Property(ci, original)
.Project
.GetPropertyValue("RepositoryBranch")
.Should().Be(expected);
}
}
38 changes: 38 additions & 0 deletions tests/DotNet.ReproducibleBuilds.Tests/TestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace DotNet.ReproducibleBuilds.Tests;

public abstract class TestBase : IDisposable
{
protected TestBase()
{
TestRootPath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()));
}

public DirectoryInfo TestRootPath { get; }

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool isDisposing)
{
TestRootPath.Refresh();
if (TestRootPath.Exists)
{
try
{
TestRootPath.Delete(recursive: true);
}
catch (Exception)
{
// Ignored
}
}
}

protected FileInfo GetRandomFile(string? extension = null)
{
return new(TestRootPath.Combine($"{Path.GetRandomFileName()}{extension ?? string.Empty}"));
}
}