Skip to content

Commit

Permalink
Switch StandaloneApp6x to pre-built test asset (#94590)
Browse files Browse the repository at this point in the history
- Add pre-built test asset for a self-contained net6.0 version of existing `HelloWorld` test asset
- Update `HostVersionCompatibility` tests to use the new test asset
  • Loading branch information
elinor-fung committed Nov 10, 2023
1 parent cc78af7 commit d170785
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 65 deletions.
3 changes: 1 addition & 2 deletions eng/Subsets.props
Expand Up @@ -489,8 +489,7 @@

<!-- Host.pretest subset (consumes live built libraries assets so needs to come after libraries) -->
<ItemGroup Condition="$(_subset.Contains('+host.pretest+'))">
<ProjectToBuild Include="$(InstallerProjectRoot)tests\Assets\Projects\AppWithSubDirs\AppWithSubDirs.csproj" Category="host" />
<ProjectToBuild Include="$(InstallerProjectRoot)tests\Assets\Projects\HelloWorld\HelloWorld.csproj" Category="host" />
<ProjectToBuild Include="$(InstallerProjectRoot)tests\Assets\Projects\**\*.csproj" Category="host" />
</ItemGroup>

<!-- Host.tests subset (consumes live built libraries assets so needs to come after libraries) -->
Expand Down
2 changes: 1 addition & 1 deletion src/installer/tests/Assets/Projects/Directory.Build.props
Expand Up @@ -4,7 +4,7 @@
<PropertyGroup>
<EnableDefaultItems>true</EnableDefaultItems>
<UseLocalTargetingRuntimePack>true</UseLocalTargetingRuntimePack>
<UseAppHost>false</UseAppHost>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<OutputPath>$(ArtifactsDir)tests\host\$(TargetOS).$(TargetArchitecture).$(Configuration)\$(MSBuildProjectName)</OutputPath>
</PropertyGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/installer/tests/Assets/Projects/Directory.Build.targets
Expand Up @@ -3,6 +3,10 @@

<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Build.targets, $(MSBuildThisFileDirectory)..))" />

<PropertyGroup>
<UseAppHost Condition="'$(UseAppHost)' == '' and '$(SelfContained)' != 'true'">false</UseAppHost>
</PropertyGroup>

<!-- Override target from targetingpacks.targets. Use Version instead of ProductVersion (written into runtimeconfig.json).
Host tests are run against the built shared framework that has the normal version (with suffixes) -->
<Target Name="UpdateRuntimeFrameworkVersion"
Expand Down
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>HelloWorld</AssemblyName>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
<SelfContained>true</SelfContained>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<UseLocalTargetingRuntimePack>false</UseLocalTargetingRuntimePack>

<!-- Set the RID when building on a platform where we support self-contained + apphost -->
<RuntimeIdentifier Condition="'$(TargetsLinux)' == 'true' or '$(TargetsOSX)' == 'true' or '$(TargetsWindows)' == 'true'">$(OutputRID)</RuntimeIdentifier>
</PropertyGroup>
</Project>
15 changes: 0 additions & 15 deletions src/installer/tests/Assets/TestProjects/StandaloneApp6x/Program.cs

This file was deleted.

This file was deleted.

Expand Up @@ -21,22 +21,23 @@ public HostVersionCompatibility(SharedTestState fixture)
[Fact]
public void LatestHost_OldRuntime_BackwardsCompatible_60()
{
LatestHost_OldRuntime_BackwardsCompatible(sharedTestState.Fixture60);
LatestHost_OldRuntime_BackwardsCompatible(sharedTestState.App60);
}

private void LatestHost_OldRuntime_BackwardsCompatible(TestProjectFixture previousVersionFixture)
private void LatestHost_OldRuntime_BackwardsCompatible(TestApp previousVersionApp)
{
TestProjectFixture fixture = previousVersionFixture.Copy();
string appExe = fixture.TestProject.AppExe;
TestApp app = previousVersionApp.Copy();
string appExe = app.AppExe;

Assert.NotEqual(fixture.Framework, RepoDirectoriesProvider.Default.Tfm);
Assert.NotEqual(fixture.RepoDirProvider.MicrosoftNETCoreAppVersion, RepoDirectoriesProvider.Default.MicrosoftNETCoreAppVersion);
RuntimeConfig appConfig = RuntimeConfig.FromFile(app.RuntimeConfigJson);
Assert.NotEqual(appConfig.Tfm, RepoDirectoriesProvider.Default.Tfm);
Assert.NotEqual(appConfig.GetIncludedFramework(Constants.MicrosoftNETCoreApp).Version, RepoDirectoriesProvider.Default.MicrosoftNETCoreAppVersion);

// Use the newer apphost
// This emulates the case when:
// 1) Newer runtime installed
// 2) Newer runtime uninstalled (installer preserves newer apphost)
fixture.TestProject.BuiltApp.CreateAppHost();
app.CreateAppHost();
Command.Create(appExe)
.EnableTracingAndCaptureOutputs()
.Execute()
Expand All @@ -48,7 +49,7 @@ private void LatestHost_OldRuntime_BackwardsCompatible(TestProjectFixture previo
// This emulates the case when:
// 1) Newer runtime installed
// 2) A roll-forward to the newer runtime did not occur
File.Copy(Binaries.HostFxr.FilePath, fixture.TestProject.HostFxrDll, true);
File.Copy(Binaries.HostFxr.FilePath, app.HostFxrDll, true);
Command.Create(appExe)
.EnableTracingAndCaptureOutputs()
.Execute()
Expand All @@ -60,28 +61,30 @@ private void LatestHost_OldRuntime_BackwardsCompatible(TestProjectFixture previo
[Fact]
public void OldHost_LatestRuntime_ForwardCompatible_60()
{
OldHost_LatestRuntime_ForwardCompatible(sharedTestState.Fixture60);
OldHost_LatestRuntime_ForwardCompatible(sharedTestState.App60);
}

private void OldHost_LatestRuntime_ForwardCompatible(TestProjectFixture previousVersionFixture)
private void OldHost_LatestRuntime_ForwardCompatible(TestApp previousVersionApp)
{
TestApp app = sharedTestState.AppLatest.Copy();
string appExe = app.AppExe;

Assert.NotEqual(RepoDirectoriesProvider.Default.Tfm, previousVersionFixture.Framework);
Assert.NotEqual(RepoDirectoriesProvider.Default.MicrosoftNETCoreAppVersion, previousVersionFixture.RepoDirProvider.MicrosoftNETCoreAppVersion);
RuntimeConfig previousAppConfig = RuntimeConfig.FromFile(previousVersionApp.RuntimeConfigJson);
string previousVersion = previousAppConfig.GetIncludedFramework(Constants.MicrosoftNETCoreApp).Version;
Assert.NotEqual(RepoDirectoriesProvider.Default.Tfm, previousAppConfig.Tfm);
Assert.NotEqual(RepoDirectoriesProvider.Default.MicrosoftNETCoreAppVersion, previousVersion);

// Use the older apphost
// This emulates the case when:
// 1) Newer runtime installed
// 2) App rolls forward to newer runtime
File.Copy(previousVersionFixture.TestProject.AppExe, appExe, true);
File.Copy(previousVersionApp.AppExe, appExe, true);
Command.Create(appExe)
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World")
.And.HaveStdErrContaining($"--- Invoked apphost [version: {previousVersionFixture.RepoDirProvider.MicrosoftNETCoreAppVersion}");
.And.HaveStdErrContaining($"--- Invoked apphost [version: {previousVersion}");

// Use the older apphost and hostfxr
// This emulates the case when:
Expand All @@ -90,53 +93,36 @@ private void OldHost_LatestRuntime_ForwardCompatible(TestProjectFixture previous
// Note that we don't have multi-level on hostfxr so we will always find the older\one-off hostfxr
if (OperatingSystem.IsWindows())
{
File.Copy(previousVersionFixture.TestProject.HostFxrDll, app.HostFxrDll, true);
File.Copy(previousVersionApp.HostFxrDll, app.HostFxrDll, true);
Command.Create(appExe)
.EnableTracingAndCaptureOutputs()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World")
.And.HaveStdErrContaining($"--- Invoked apphost [version: {previousVersionFixture.RepoDirProvider.MicrosoftNETCoreAppVersion}");
.And.HaveStdErrContaining($"--- Invoked apphost [version: {previousVersion}");
}
}

public class SharedTestState : IDisposable
{
private static RepoDirectoriesProvider RepoDirectories { get; set; }

public TestProjectFixture Fixture60 { get; }
public TestApp App60 { get; }
public TestApp AppLatest { get; }

private const string AppName = "HelloWorld";

public SharedTestState()
{
RepoDirectories = new RepoDirectoriesProvider();

Fixture60 = CreateTestFixture("StandaloneApp6x", "net6.0", "6.0");
App60 = TestApp.CreateFromBuiltAssets(AppName, Path.Combine("SelfContained", "net6.0"));

AppLatest = TestApp.CreateFromBuiltAssets(AppName);
AppLatest.PopulateSelfContained(TestApp.MockedComponent.None);
}

public void Dispose()
{
Fixture60.Dispose();
App60?.Dispose();
AppLatest?.Dispose();
}

private static TestProjectFixture CreateTestFixture(string testName, string netCoreAppFramework, string mnaVersion)
{
var repoDirectories = new RepoDirectoriesProvider(microsoftNETCoreAppVersion: mnaVersion);

// Use standalone instead of framework-dependent for ease of deployment.
var publishFixture = new TestProjectFixture(testName, repoDirectories, framework: netCoreAppFramework, assemblyName: AppName);
publishFixture
.EnsureRestoredForRid(publishFixture.CurrentRid)
.PublishProject(runtime: publishFixture.CurrentRid, selfContained: true, extraArgs: $"/p:AssemblyName={AppName}");

return publishFixture;
}
}
}
}
7 changes: 7 additions & 0 deletions src/installer/tests/TestUtils/RuntimeConfig.cs
Expand Up @@ -172,6 +172,8 @@ public static RuntimeConfig Path(string path)
return new RuntimeConfig(path);
}

public string Tfm => _tfm;

public Framework GetFramework(string name)
{
return _frameworks.FirstOrDefault(f => f.Name == name);
Expand Down Expand Up @@ -199,6 +201,11 @@ public RuntimeConfig RemoveFramework(string name)
return this;
}

public Framework GetIncludedFramework(string name)
{
return _includedFrameworks.FirstOrDefault(f => f.Name == name);
}

public RuntimeConfig WithIncludedFramework(Framework framework)
{
_includedFrameworks.Add(framework);
Expand Down
13 changes: 11 additions & 2 deletions src/installer/tests/TestUtils/TestApp.cs
Expand Up @@ -50,11 +50,20 @@ public static TestApp CreateEmpty(string name)
};
}

public static TestApp CreateFromBuiltAssets(string appName)
/// <summary>
/// Create a test app from pre-built output of <paramref name="appName"/>.
/// </summary>
/// <param name="appName">Name of pre-built app</param>
/// <param name="assetRelativePath">Path to asset - relative to the directory containing all pre-built assets</param>
/// <returns>
/// If <paramref name="assetRelativePath"/> is <c>null</c>, <paramref name="appName"/> is used as the relative path.
/// </returns>
public static TestApp CreateFromBuiltAssets(string appName, string assetRelativePath = null)
{
assetRelativePath = assetRelativePath ?? appName;
TestApp app = CreateEmpty(appName);
TestArtifact.CopyRecursive(
Path.Combine(RepoDirectoriesProvider.Default.TestAssetsOutput, appName),
Path.Combine(RepoDirectoriesProvider.Default.TestAssetsOutput, assetRelativePath),
app.Location);
return app;
}
Expand Down

0 comments on commit d170785

Please sign in to comment.