Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using FluentAssertions;
using Microsoft.Build.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Xunit;

namespace Microsoft.NET.Build.Tasks.UnitTests
{
public class GivenAResolveFrameworkReferences
{
[Fact]
public void It_resolves_with_multiple_runtime_packs()
{
var task = new ResolveFrameworkReferences
{
FrameworkReferences = new[]
{
new MockTaskItem("Microsoft.NETCore.App", new Dictionary<string, string>()),
new MockTaskItem("Microsoft.Android", new Dictionary<string, string>()),
},

ResolvedTargetingPacks = new[]
{
new MockTaskItem("Microsoft.NETCore.App",
new Dictionary<string, string>()
{
{"NuGetPackageId", "Microsoft.NETCore.App.Ref"},
{"NuGetPackageVersion", "6.0.2"},
{"Path", "empty"},
}),
new MockTaskItem("Microsoft.Android",
new Dictionary<string, string>()
{
{"NuGetPackageId", "Microsoft.Android.Ref.32"},
{"NuGetPackageVersion", "32.0.300"},
{"Path", "empty"},
{"Profile", "Android"},
}),
},

ResolvedRuntimePacks = new[]
{
new MockTaskItem("Microsoft.NETCore.App.Runtime.Mono.android-arm",
new Dictionary<string, string>()
{
{"FrameworkName", "Microsoft.NetCore.App"},
{"NuGetPackageId", "Microsoft.NETCore.App.Runtime.Mono.android-arm"},
{"NuGetPackageVersion", "6.0.4"},
{"PackageDirectory", "empty"},
}),
new MockTaskItem("Microsoft.Android.Runtime.32",
new Dictionary<string, string>()
{
{"FrameworkName", "Microsoft.Android"},
{"NuGetPackageId", "Microsoft.Android.Runtime.32"},
{"NuGetPackageVersion", "32.0.300"},
{"PackageDirectory", "empty"},
}),
new MockTaskItem("Microsoft.Android.Runtime.32.android-arm",
new Dictionary<string, string>()
{
{"FrameworkName", "Microsoft.Android"},
{"NuGetPackageId", "Microsoft.Android.Runtime.32.android-arm"},
{"NuGetPackageVersion", "32.0.300"},
{"PackageDirectory", "empty"},
}),
},
};

task.Execute().Should().BeTrue();
task.ResolvedFrameworkReferences.Length.Should().Be(2);
task.ResolvedFrameworkReferences[0].GetMetadata("RuntimePackPath").Should().Be("empty");
task.ResolvedFrameworkReferences[0].GetMetadata("RuntimePackName").Should().Be("Microsoft.NETCore.App.Runtime.Mono.android-arm");
task.ResolvedFrameworkReferences[0].GetMetadata("RuntimePackVersion").Should().Be("6.0.4");
task.ResolvedFrameworkReferences[1].GetMetadata("RuntimePackPath").Should().Be("empty;empty");
task.ResolvedFrameworkReferences[1].GetMetadata("RuntimePackName").Should().Be("Microsoft.Android.Runtime.32;Microsoft.Android.Runtime.32.android-arm");
task.ResolvedFrameworkReferences[1].GetMetadata("RuntimePackVersion").Should().Be("32.0.300;32.0.300");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -317,5 +317,56 @@ public void Given_reference_to_NETCoreApp_It_should_not_resolve_runtime_pack()
task.RuntimePacks[0].ItemSpec.Should().Be("Microsoft.Windows.SDK.NET.Ref",
"it should not resolve runtime pack for Microsoft.NETCore.App");
}

[Fact]
public void It_resolves_FrameworkReference_with_multiple_runtime_patterns()
{
const string minimalRuntimeGraphPathContent =
"{\"runtimes\":{\"android\":{\"#import\":[\"linux\"]},\"linux\":{\"#import\":[]},\"android-arm\":{\"#import\":[\"android\"]},\"android-arm64\":{\"#import\":[\"android\"]}}}";
var runtimeGraphPathPath = Path.GetTempFileName();
File.WriteAllText(runtimeGraphPathPath, minimalRuntimeGraphPathContent);

var task = new ProcessFrameworkReferences
{
BuildEngine = new MockNeverCacheBuildEngine4(),
EnableTargetingPackDownload = true,
TargetFrameworkIdentifier = ".NETCoreApp",
TargetFrameworkVersion = "6.0",
TargetPlatformIdentifier = "Android",
RuntimeGraphPath = runtimeGraphPathPath,
RuntimeIdentifiers = new[]
{
"android-arm", "android-arm64"
},

FrameworkReferences = new[]
{
new MockTaskItem("Microsoft.Android", new Dictionary<string, string>()),
},

KnownFrameworkReferences = new[]
{
new MockTaskItem("Microsoft.Android",
new Dictionary<string, string>()
{
{"TargetFramework", "net6.0"},
{"RuntimeFrameworkName", "Microsoft.Android"},
{"LatestRuntimeFrameworkVersion", "32.0.300"},
{"TargetingPackName", "Microsoft.Android.Ref.32"},
{"TargetingPackVersion", "32.0.300"},
{"RuntimePackNamePatterns", "Microsoft.Android.Runtime.32;Microsoft.Android.Runtime.32.**RID**"},
{"RuntimePackRuntimeIdentifiers", "android-arm;android-arm64;android-x86;android-x64"},
{"Profile", "Android"},
}),
},
};

task.Execute().Should().BeTrue();
task.PackagesToDownload.Length.Should().Be(4);
task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.Android.Ref.32");
task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.Android.Runtime.32");
task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.Android.Runtime.32.android-arm");
task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.Android.Runtime.32.android-arm64");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ protected override void ExecuteCore()
}

var resolvedTargetingPacks = ResolvedTargetingPacks.ToDictionary(tp => tp.ItemSpec, StringComparer.OrdinalIgnoreCase);
var resolvedRuntimePacks = ResolvedRuntimePacks.ToDictionary(rp => rp.GetMetadata(MetadataKeys.FrameworkName), StringComparer.OrdinalIgnoreCase);

var resolvedFrameworkReferences = new List<TaskItem>(FrameworkReferences.Length);

Expand All @@ -48,13 +47,14 @@ protected override void ExecuteCore()
resolvedFrameworkReference.SetMetadata("TargetingPackVersion", targetingPack.GetMetadata(MetadataKeys.NuGetPackageVersion));
resolvedFrameworkReference.SetMetadata("Profile", targetingPack.GetMetadata("Profile"));

ITaskItem runtimePack;
if (resolvedRuntimePacks.TryGetValue(frameworkReference.ItemSpec, out runtimePack))
// Allow more than one runtime pack to be associated with this FrameworkReference
var matchingRuntimePacks = ResolvedRuntimePacks.Where(rp => rp.GetMetadata(MetadataKeys.FrameworkName).Equals(frameworkReference.ItemSpec, StringComparison.OrdinalIgnoreCase));
if (matchingRuntimePacks.Any())
{
resolvedFrameworkReference.SetMetadata("RuntimePackPath", runtimePack.GetMetadata(MetadataKeys.PackageDirectory));
resolvedFrameworkReference.SetMetadata("RuntimePackName", runtimePack.GetMetadata(MetadataKeys.NuGetPackageId));
resolvedFrameworkReference.SetMetadata("RuntimePackVersion", runtimePack.GetMetadata(MetadataKeys.NuGetPackageVersion));
}
resolvedFrameworkReference.SetMetadata("RuntimePackPath", string.Join (";", matchingRuntimePacks.Select (mrp => mrp.GetMetadata(MetadataKeys.PackageDirectory))));
resolvedFrameworkReference.SetMetadata("RuntimePackName", string.Join (";", matchingRuntimePacks.Select (mrp => mrp.GetMetadata(MetadataKeys.NuGetPackageId))));
resolvedFrameworkReference.SetMetadata("RuntimePackVersion", string.Join (";", matchingRuntimePacks.Select (mrp => mrp.GetMetadata(MetadataKeys.NuGetPackageVersion))));
Comment on lines +54 to +56
Copy link
Member

Choose a reason for hiding this comment

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

I don't see any changes in code that consumes these metadata values. Is that code going to be able to handle the multiple runtime packs?

Copy link
Member Author

Choose a reason for hiding this comment

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

I couldn't find any references in dotnet/sdk, aside from the tests that only make sure that this metadata is set. Maybe there are external usages that could break? Are you familiar with anything else that depends on these?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's used somewhere but I'm not sure. If it's really not used, then we don't even need to set the metadata at all (though it could be useful for debugging).

Copy link
Member Author

Choose a reason for hiding this comment

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

@dsplaisted are there any other folks we should loop in to determine whether we should remove this metadata or not? I'm not sure how to proceed.

}

resolvedFrameworkReferences.Add(resolvedFrameworkReference);
}
Expand Down