-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathItemDefinitionMetadataInTaskHost_Tests.cs
More file actions
109 lines (93 loc) · 4.53 KB
/
Copy pathItemDefinitionMetadataInTaskHost_Tests.cs
File metadata and controls
109 lines (93 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.Build.Execution;
using Microsoft.Build.UnitTests;
using Shouldly;
using Xunit;
#nullable disable
namespace Microsoft.Build.Engine.UnitTests.BackEnd
{
/// <summary>
/// Metadata inherited from an item definition, such as <c>%(Filename)</c>, is stored unexpanded and expanded
/// when it is read. These tests assert that a task observes the same value whether it runs in-proc or in a
/// task host.
/// Regression tests for https://github.com/dotnet/msbuild/issues/14763.
/// </summary>
public sealed class ItemDefinitionMetadataInTaskHost_Tests
{
private static string AssemblyLocation { get; } =
typeof(ItemDefinitionMetadataInTaskHost_Tests).Assembly.Location
?? Path.Combine(AppContext.BaseDirectory, "Microsoft.Build.Engine.UnitTests.dll");
private readonly ITestOutputHelper _output;
public ItemDefinitionMetadataInTaskHost_Tests(ITestOutputHelper output) => _output = output;
[Theory]
[InlineData(false)]
[InlineData(true)]
public void MetadataReferencingBuiltInMetadataIsExpandedForTheTask(bool useTaskHost)
{
Observe("%(Filename)", useTaskHost).ShouldBe("hello");
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void MetadataReferencingBuiltInMetadataFollowsReassignedItemSpec(bool useTaskHost)
{
Observe("%(Filename)", useTaskHost, newItemSpec: @"other\renamed.txt").ShouldBe("renamed");
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void MetadataOverriddenOnTheItemWinsOverTheItemDefinition(bool useTaskHost)
{
Observe("%(Filename)", useTaskHost, itemOverride: "explicit").ShouldBe("explicit");
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void EscapedMetadataReferenceIsNotExpanded(bool useTaskHost)
{
Observe("%25(Filename)", useTaskHost).ShouldBe("%(Filename)");
}
/// <summary>
/// Runs a task against an item whose definition carries <paramref name="definitionValue"/> and returns the
/// value the task itself observed, having asserted the task ran where the test intended.
/// </summary>
private string Observe(string definitionValue, bool useTaskHost, string newItemSpec = null, string itemOverride = null)
{
using TestEnvironment env = TestEnvironment.Create(_output);
string project = $"""
<Project>
<UsingTask TaskName="MetadataObservationTask" AssemblyFile="{AssemblyLocation}"{(useTaskHost ? @" TaskFactory=""TaskHostFactory""" : string.Empty)} />
<ItemDefinitionGroup>
<Thing>
<NameMeta>{definitionValue}</NameMeta>
</Thing>
</ItemDefinitionGroup>
<ItemGroup>
<Thing Include="folder\hello.txt">
{(itemOverride is null ? string.Empty : $"<NameMeta>{itemOverride}</NameMeta>")}
</Thing>
</ItemGroup>
<Target Name="Observe">
<MetadataObservationTask Items="@(Thing)" MetadataName="NameMeta" NewItemSpec="{newItemSpec}">
<Output PropertyName="ObservedValue" TaskParameter="ObservedValue" />
<Output PropertyName="TaskProcessId" TaskParameter="TaskProcessId" />
</MetadataObservationTask>
</Target>
</Project>
""";
ProjectInstance projectInstance = new(env.CreateFile("test.proj", project).Path);
BuildResult result = BuildManager.DefaultBuildManager.Build(
new BuildParameters { EnableNodeReuse = false },
new BuildRequestData(projectInstance, targetsToBuild: ["Observe"]));
result.OverallResult.ShouldBe(BuildResultCode.Success);
int taskProcessId = int.Parse(projectInstance.GetPropertyValue("TaskProcessId"));
bool ranOutOfProc = taskProcessId != Process.GetCurrentProcess().Id;
ranOutOfProc.ShouldBe(useTaskHost, $"the task was expected to run {(useTaskHost ? "in a task host" : "in-proc")}");
return projectInstance.GetPropertyValue("ObservedValue");
}
}
}