Welcome to mirror list, hosted at ThFree Co, Russian Federation.

IntegrationTestBase.cs « ILLink.Tasks.Tests « test - github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3027f4fcadfce008139bbfb6ba16d6195c1fe86a (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Xunit;
using Xunit.Abstractions;

namespace ILLink.Tests
{

	/// <summary>
	///   Represents a project. Each fixture contains setup code run
	///   once before all tests in the same test class. ProjectFixture
	///   is the base type for different specific project fixtures.
	/// </summary>
	public class ProjectFixture
	{
		private FixtureLogger logger;
		protected CommandHelper CommandHelper;

		protected void LogMessage (string message)
		{
			logger.LogMessage (message);
		}

		public ProjectFixture (IMessageSink diagnosticMessageSink)
		{
			logger = new FixtureLogger (diagnosticMessageSink);
			CommandHelper = new CommandHelper (logger);
		}

		protected void AddLinkerReference(string csproj)
		{
			var xdoc = XDocument.Load(csproj);
			var ns = xdoc.Root.GetDefaultNamespace();
			bool added = false;
			foreach (var el in xdoc.Root.Elements(ns + "ItemGroup")) {
				if (el.Elements(ns + "PackageReference").Any()) {
					el.Add(new XElement(ns+"PackageReference",
						new XAttribute("Include", TestContext.TasksPackageName),
						new XAttribute("Version", TestContext.TasksPackageVersion)));
					added = true;
					break;
				}
			}
			if (!added) {
				xdoc.Root.Add(new XElement(ns + "ItemGroup",
					new XElement(ns + "PackageReference",
						new XAttribute("Include", TestContext.TasksPackageName),
						new XAttribute("Version", TestContext.TasksPackageVersion))));
				added= true;
			}

			using (var fs = new FileStream(csproj, FileMode.Create)) {
				xdoc.Save(fs);
			}
		}

		static void AddLinkerRoots(string csproj, List<string> rootFiles)
		{
			var xdoc = XDocument.Load(csproj);
			var ns = xdoc.Root.GetDefaultNamespace();

			var rootsItemGroup = new XElement(ns+"ItemGroup");
			foreach (var rootFile in rootFiles) {
				rootsItemGroup.Add(new XElement(ns+"LinkerRootFiles",
					new XAttribute("Include", rootFile)));
			}

			var propertyGroup = xdoc.Root.Elements(ns + "PropertyGroup").First();
			propertyGroup.AddAfterSelf(rootsItemGroup);

			using (var fs = new FileStream(csproj, FileMode.Create)) {
				xdoc.Save(fs);
			}
		}

	}

	/// <summary>
	///   Contains logic shared by multiple test classes.
	/// </summary>
	public class IntegrationTestBase
	{
		private readonly TestLogger logger;
		protected readonly CommandHelper CommandHelper;

		public IntegrationTestBase(ITestOutputHelper output)
		{
			logger = new TestLogger(output);
			CommandHelper = new CommandHelper(logger);
		}

		private void LogMessage (string message)
		{
			logger.LogMessage (message);
		}

		/// <summary>
		///   Run the linker on the specified project. This assumes
		///   that the project already contains a reference to the
		///   linker task package.
		///   Optionally takes a list of root descriptor files.
		///   Returns the path to the built app, either the renamed
		///   host for self-contained publish, or the dll containing
		///   the entry point.
		/// </summary>
		public string BuildAndLink(string csproj, List<string> rootFiles = null, Dictionary<string, string> extraPublishArgs = null, bool selfContained = false)
		{
			string demoRoot = Path.GetDirectoryName(csproj);

			string publishArgs = $"publish -c {TestContext.Configuration} /v:n /p:ShowLinkerSizeComparison=true";
			if (selfContained) {
				publishArgs += $" -r {TestContext.RuntimeIdentifier}";
			}
			string rootFilesStr;
			if (rootFiles != null && rootFiles.Any()) {
				rootFilesStr = String.Join(";", rootFiles);
				publishArgs += $" /p:LinkerRootDescriptors={rootFilesStr}";
			}
			if (extraPublishArgs != null) {
				foreach (var item in extraPublishArgs) {
					publishArgs += $" /p:{item.Key}={item.Value}";
				}
			}
			int ret = CommandHelper.Dotnet(publishArgs, demoRoot);

			if (ret != 0) {
				LogMessage("publish failed, returning " + ret);
				Assert.True(false);
			}

			// detect the target framework for which the app was published
			string tfmDir = Path.Combine(demoRoot, "bin", TestContext.Configuration);
			string tfm = Directory.GetDirectories(tfmDir).Select(p => Path.GetFileName(p)).Single();
			string builtApp = Path.Combine(tfmDir, tfm);
			if (selfContained) {
				builtApp = Path.Combine(builtApp, TestContext.RuntimeIdentifier);
			}
			builtApp = Path.Combine(builtApp, "publish",
				Path.GetFileNameWithoutExtension(csproj));
			if (selfContained) {
				if (TestContext.RuntimeIdentifier.Contains("win")) {
					builtApp += ".exe";
				}
			} else {
				builtApp += ".dll";
			}
			Assert.True(File.Exists(builtApp));
			return builtApp;
		}

		public int RunApp(string target, out string processOutput, int timeout = Int32.MaxValue,
			string terminatingOutput = null, bool selfContained = false)
		{
			Assert.True(File.Exists(target));
			int ret;
			if (selfContained) {
				ret = CommandHelper.RunCommand(
					target, null,
					Directory.GetParent(target).FullName,
					null, out processOutput, timeout, terminatingOutput);
			} else {
				ret = CommandHelper.RunCommand(
					Path.GetFullPath(TestContext.DotnetToolPath),
					Path.GetFullPath(target),
					Directory.GetParent(target).FullName,
					null, out processOutput, timeout, terminatingOutput);
			}
			return ret;
		}
	}
}