|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System.Runtime.CompilerServices;
using Microsoft.Extensions.DependencyModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Newtonsoft.Json.Linq;
using NuGet.Common;
using NuGet.Frameworks;
using NuGet.ProjectModel;
namespace Microsoft.NET.Publish.Tests
{
public class GivenThatAPublishedDepsJsonShouldContainVersionInformation : SdkTest
{
public GivenThatAPublishedDepsJsonShouldContainVersionInformation(ITestOutputHelper log) : base(log)
{
}
private TestProject GetTestProject()
{
var testProject = new TestProject()
{
Name = "DepsJsonVersions",
TargetFrameworks = "net6.0",
IsExe = true,
};
testProject.PackageReferences.Add(new TestPackageReference("System.Collections.Immutable", "8.0.0"));
testProject.PackageReferences.Add(new TestPackageReference("Libuv", "1.10.0"));
return testProject;
}
[Fact]
public void Versions_are_included_in_deps_json()
{
var testProject = GetTestProject();
var testAsset = _testAssetsManager.CreateTestProject(testProject);
var publishCommand = new PublishCommand(testAsset);
publishCommand.Execute()
.Should()
.Pass();
var publishDirectory = publishCommand.GetOutputDirectory(testProject.TargetFrameworks, runtimeIdentifier: testProject.RuntimeIdentifier);
publishDirectory.Should().HaveFile(testProject.Name + ".deps.json");
var depsFilePath = Path.Combine(publishDirectory.FullName, $"{testProject.Name}.deps.json");
CheckVersionsInDepsFile(depsFilePath);
}
// https://github.com/dotnet/sdk/issues/49665
// Failed to load /private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, error: dlopen(/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, 0x0001): tried: '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (no such file), '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
[PlatformSpecificFact(TestPlatforms.Any & ~TestPlatforms.OSX)]
public void Inbox_version_of_assembly_is_loaded_over_applocal_version()
{
var (coreDir, publishDir, immutableDir) = TestConflictResult();
immutableDir.Should().BeEquivalentTo(coreDir, "immutable collections library from Framework should win");
}
// https://github.com/dotnet/sdk/issues/49665
// Failed to load /private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, error: dlopen(/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, 0x0001): tried: '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (no such file), '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
[PlatformSpecificFact(TestPlatforms.Any & ~TestPlatforms.OSX)]
public void Inbox_version_is_loaded_if_runtime_file_versions_arent_in_deps()
{
static void testProjectChanges(TestProject testProject)
{
testProject.AdditionalProperties["IncludeFileVersionsInDependencyFile"] = "false";
}
var (coreDir, publishDir, immutableDir) = TestConflictResult(testProjectChanges);
immutableDir.Should().BeEquivalentTo(coreDir, "inbox immutable collections library from should win");
}
// https://github.com/dotnet/sdk/issues/49665
// Failed to load /private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, error: dlopen(/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib, 0x0001): tried: '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (no such file), '/private/tmp/helix/working/B3F609DC/p/d/shared/Microsoft.NETCore.App/8.0.0/libhostpolicy.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
[PlatformSpecificFact(TestPlatforms.Any & ~TestPlatforms.OSX)]
public void Local_version_of_assembly_with_higher_version_is_loaded_over_inbox_version()
{
static void publishFolderChanges(string publishFolder)
{
var depsJsonPath = Path.Combine(publishFolder, "DepsJsonVersions.deps.json");
var depsJson = JObject.Parse(File.ReadAllText(depsJsonPath));
var target = ((JProperty)depsJson["targets"].First).Value;
var file = target["System.Collections.Immutable/8.0.0"]["runtime"]["lib/net6.0/System.Collections.Immutable.dll"];
// Set fileVersion in deps.json to 9.0.0.0, which should be bigger than in box 4.6.x version
file["fileVersion"] = "9.0.0.0";
File.WriteAllText(depsJsonPath, depsJson.ToString());
}
var (coreDir, publishDir, immutableDir) = TestConflictResult(publishFolderChanges: publishFolderChanges);
immutableDir.Should().BeEquivalentTo(publishDir, "published immutable collections library from should win");
}
private (string coreDir, string publishDir, string immutableDir) TestConflictResult(
Action<TestProject> testProjectChanges = null,
Action<string> publishFolderChanges = null,
[CallerMemberName] string callingMethod = "")
{
var testProject = GetTestProject();
testProject.SourceFiles["Program.cs"] = @"
using System;
static class Program
{
public static void Main()
{
Console.WriteLine(typeof(object).Assembly.Location);
Console.WriteLine(typeof(System.Collections.Immutable.ImmutableList).Assembly.Location);
}
}
";
if (testProjectChanges != null)
{
testProjectChanges(testProject);
}
var testAsset = _testAssetsManager.CreateTestProject(testProject, callingMethod: callingMethod);
var publishCommand = new PublishCommand(testAsset);
publishCommand.Execute()
.Should()
.Pass();
var publishDirectory = publishCommand.GetOutputDirectory(testProject.TargetFrameworks, runtimeIdentifier: testProject.RuntimeIdentifier);
if (publishFolderChanges != null)
{
publishFolderChanges(publishDirectory.FullName);
}
// Assembly from package should be deployed, as it is newer than the in-box version for netcoreapp2.0,
// which is what the app targets
publishDirectory.Should().HaveFile("System.Collections.Immutable.dll");
var exePath = Path.Combine(publishDirectory.FullName, testProject.Name + ".dll");
string rollForwardVersion = "8.0.0";
var runAppCommand = new DotnetCommand(Log, "exec", "--fx-version", rollForwardVersion, exePath);
var runAppResult = runAppCommand
.Execute();
runAppResult
.Should()
.Pass();
var stdOutLines = runAppResult.StdOut.Split(Environment.NewLine);
string coreDir = Path.GetDirectoryName(stdOutLines[0]);
string immutableDir = Path.GetDirectoryName(stdOutLines[1]);
return (coreDir, publishDirectory.FullName, immutableDir);
}
void CheckVersionsInDepsFile(string depsFilePath)
{
DependencyContext dependencyContext;
using (var depsJsonFileStream = File.OpenRead(depsFilePath))
{
dependencyContext = new DependencyContextJsonReader().Read(depsJsonFileStream);
}
var libuvRuntimeLibrary = dependencyContext.RuntimeLibraries.Single(l => l.Name == "Libuv");
var libuvRuntimeFiles = libuvRuntimeLibrary.NativeLibraryGroups.SelectMany(rag => rag.RuntimeFiles).ToList();
libuvRuntimeFiles.Should().NotBeEmpty();
foreach (var runtimeFile in libuvRuntimeFiles)
{
runtimeFile.AssemblyVersion.Should().BeNull();
runtimeFile.FileVersion.Should().Be("0.0.0.0");
}
var immutableRuntimeLibrary = dependencyContext.RuntimeLibraries.Single(l => l.Name == "System.Collections.Immutable");
var immutableRuntimeFiles = immutableRuntimeLibrary.RuntimeAssemblyGroups.SelectMany(rag => rag.RuntimeFiles).ToList();
immutableRuntimeFiles.Should().NotBeEmpty();
foreach (var runtimeFile in immutableRuntimeFiles)
{
runtimeFile.AssemblyVersion.Should().Be("8.0.0.0");
runtimeFile.FileVersion.Should().Be("8.0.23.53103");
}
}
[Fact]
public void Versions_are_included_for_self_contained_apps()
{
Versions_are_included(build: false);
}
[Fact]
public void Versions_are_included_for_build()
{
Versions_are_included(build: true);
}
private void Versions_are_included(bool build, [CallerMemberName] string callingMethod = "")
{
var testProject = GetTestProject();
if (!EnvironmentInfo.SupportsTargetFramework(testProject.TargetFrameworks))
{
return;
}
testProject.RuntimeIdentifier = EnvironmentInfo.GetCompatibleRid(testProject.TargetFrameworks);
var testAsset = _testAssetsManager.CreateTestProject(testProject, callingMethod);
MSBuildCommand command;
if (build)
{
command = new BuildCommand(testAsset);
}
else
{
command = new PublishCommand(testAsset);
}
command.Execute()
.Should()
.Pass();
var outputDirectory = command.GetOutputDirectory(testProject.TargetFrameworks, runtimeIdentifier: testProject.RuntimeIdentifier);
outputDirectory.Should().HaveFile(testProject.Name + ".deps.json");
var depsFilePath = Path.Combine(outputDirectory.FullName, $"{testProject.Name}.deps.json");
CheckVersionsInDepsFile(depsFilePath);
}
}
}
|