PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Tests/Microsoft.NET.Build.Tests/ReferenceExeTests.cs

https://gitlab.com/dotnetfoundation/sdk
C# | 299 lines | 222 code | 67 blank | 10 comment | 7 complexity | 5cd8b867752d6628ed8f5c0e01e41cae MD5 | raw file
  1. // Copyright (c) .NET Foundation and contributors. All rights reserved.
  2. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  3. //
  4. using System.IO;
  5. using System.Linq;
  6. using System.Runtime.CompilerServices;
  7. using System.Xml.Linq;
  8. using FluentAssertions;
  9. using Microsoft.DotNet.Cli.Utils;
  10. using Microsoft.NET.TestFramework;
  11. using Microsoft.NET.TestFramework.Assertions;
  12. using Microsoft.NET.TestFramework.Commands;
  13. using Microsoft.NET.TestFramework.ProjectConstruction;
  14. using Xunit;
  15. using Xunit.Abstractions;
  16. namespace Microsoft.NET.Build.Tests
  17. {
  18. public class ReferenceExeTests : SdkTest
  19. {
  20. public ReferenceExeTests(ITestOutputHelper log) : base(log)
  21. {
  22. }
  23. private bool MainSelfContained { get; set; }
  24. private bool ReferencedSelfContained { get; set; }
  25. private bool TestWithPublish { get; set; } = false;
  26. private TestProject MainProject { get; set; }
  27. private TestProject ReferencedProject { get; set; }
  28. private void CreateProjects()
  29. {
  30. MainProject = new TestProject()
  31. {
  32. Name = "MainProject",
  33. TargetFrameworks = "net5.0",
  34. IsSdkProject = true,
  35. IsExe = true
  36. };
  37. MainProject.PackageReferences.Add(new TestPackageReference("Humanizer", "2.8.26"));
  38. MainProject.SourceFiles["Program.cs"] = @"using Humanizer; System.Console.WriteLine(""MainProject"".Humanize());";
  39. // By default we don't create the app host on Mac for FDD. For these tests, we want to create it everywhere
  40. MainProject.AdditionalProperties["UseAppHost"] = "true";
  41. if (MainSelfContained)
  42. {
  43. MainProject.RuntimeIdentifier = EnvironmentInfo.GetCompatibleRid();
  44. }
  45. ReferencedProject = new TestProject()
  46. {
  47. Name = "ReferencedProject",
  48. TargetFrameworks = "net5.0",
  49. IsSdkProject = true,
  50. IsExe = true,
  51. };
  52. ReferencedProject.AdditionalProperties["UseAppHost"] = "true";
  53. if (ReferencedSelfContained)
  54. {
  55. ReferencedProject.RuntimeIdentifier = EnvironmentInfo.GetCompatibleRid();
  56. }
  57. // Use a lower version of a library in the referenced project
  58. ReferencedProject.PackageReferences.Add(new TestPackageReference("Humanizer", "2.7.9"));
  59. ReferencedProject.SourceFiles["Program.cs"] = @"using Humanizer; System.Console.WriteLine(""ReferencedProject"".Humanize());";
  60. MainProject.ReferencedProjects.Add(ReferencedProject);
  61. }
  62. private void RunTest(string buildFailureCode = null, [CallerMemberName] string callingMethod = null)
  63. {
  64. var testProjectInstance = _testAssetsManager.CreateTestProject(MainProject, callingMethod: callingMethod, identifier: MainSelfContained.ToString() + "_" + ReferencedSelfContained.ToString());
  65. string outputDirectory;
  66. TestCommand buildOrPublishCommand;
  67. if (TestWithPublish)
  68. {
  69. var publishCommand = new PublishCommand(testProjectInstance);
  70. outputDirectory = publishCommand.GetOutputDirectory(MainProject.TargetFrameworks, runtimeIdentifier: MainProject.RuntimeIdentifier).FullName;
  71. buildOrPublishCommand = publishCommand;
  72. }
  73. else
  74. {
  75. var buildCommand = new BuildCommand(testProjectInstance);
  76. outputDirectory = buildCommand.GetOutputDirectory(MainProject.TargetFrameworks, runtimeIdentifier: MainProject.RuntimeIdentifier).FullName;
  77. buildOrPublishCommand = buildCommand;
  78. }
  79. if (buildFailureCode == null)
  80. {
  81. buildOrPublishCommand.Execute()
  82. .Should()
  83. .Pass();
  84. var mainExePath = Path.Combine(outputDirectory, MainProject.Name + Constants.ExeSuffix);
  85. var referencedExePath = Path.Combine(outputDirectory, ReferencedProject.Name + Constants.ExeSuffix);
  86. new RunExeCommand(Log, mainExePath)
  87. .Execute()
  88. .Should()
  89. .Pass()
  90. .And
  91. .HaveStdOut("Main project");
  92. var referencedExeResult = new RunExeCommand(Log, referencedExePath)
  93. .Execute();
  94. referencedExeResult
  95. .Should()
  96. .Pass()
  97. .And
  98. .HaveStdOut("Referenced project");
  99. }
  100. else
  101. {
  102. // Build should not succeed
  103. buildOrPublishCommand.Execute()
  104. .Should()
  105. .Fail()
  106. .And
  107. .HaveStdOutContaining(buildFailureCode);
  108. }
  109. }
  110. [Theory]
  111. [InlineData(false, false)]
  112. [InlineData(true, true)]
  113. public void ReferencedExeCanRun(bool mainSelfContained, bool referencedSelfContained)
  114. {
  115. MainSelfContained = mainSelfContained;
  116. ReferencedSelfContained = referencedSelfContained;
  117. CreateProjects();
  118. RunTest();
  119. }
  120. [Fact]
  121. public void ReferencedExeWithLowerTargetFrameworkCanRun()
  122. {
  123. MainSelfContained = false;
  124. ReferencedSelfContained = false;
  125. CreateProjects();
  126. ReferencedProject.TargetFrameworks = "netcoreapp3.1";
  127. ReferencedProject.AdditionalProperties["LangVersion"] = "9.0";
  128. RunTest();
  129. }
  130. // Having a self-contained and a framework-dependent app in the same folder is not supported (due to the way the host works).
  131. // The referenced app will fail to run. See here for more details: https://github.com/dotnet/sdk/pull/14488#issuecomment-725406998
  132. [Theory]
  133. [InlineData(true, false, "NETSDK1150")]
  134. [InlineData(false, true, "NETSDK1151")]
  135. public void ReferencedExeFailsToBuild(bool mainSelfContained, bool referencedSelfContained, string expectedFailureCode)
  136. {
  137. MainSelfContained = mainSelfContained;
  138. ReferencedSelfContained = referencedSelfContained;
  139. CreateProjects();
  140. RunTest(expectedFailureCode);
  141. }
  142. [Fact]
  143. public void ReferencedExeCanRunWhenReferencesExeWithSelfContainedMismatchForDifferentTargetFramework()
  144. {
  145. MainSelfContained = true;
  146. ReferencedSelfContained = false;
  147. CreateProjects();
  148. // Reference project which is self-contained for net5.0, not self-contained for net5.0-windows.
  149. ReferencedProject.TargetFrameworks = "net5.0;net5.0-windows";
  150. ReferencedProject.ProjectChanges.Add(project =>
  151. {
  152. var ns = project.Root.Name.Namespace;
  153. project.Root.Element(ns + "PropertyGroup")
  154. .Add(XElement.Parse(@"<RuntimeIdentifier Condition=""'$(TargetFramework)' == 'net5.0'"">" + EnvironmentInfo.GetCompatibleRid() + "</RuntimeIdentifier>"));
  155. });
  156. RunTest();
  157. }
  158. [Fact]
  159. public void ReferencedExeFailsToBuildWhenReferencesExeWithSelfContainedMismatchForSameTargetFramework()
  160. {
  161. MainSelfContained = true;
  162. ReferencedSelfContained = false;
  163. CreateProjects();
  164. // Reference project which is self-contained for net5.0-windows, not self-contained for net5.0.
  165. ReferencedProject.TargetFrameworks = "net5.0;net5.0-windows";
  166. ReferencedProject.ProjectChanges.Add(project =>
  167. {
  168. var ns = project.Root.Name.Namespace;
  169. project.Root.Element(ns + "PropertyGroup")
  170. .Add(XElement.Parse(@"<RuntimeIdentifier Condition=""'$(TargetFramework)' == 'net5.0-windows'"">" + EnvironmentInfo.GetCompatibleRid() + "</RuntimeIdentifier>"));
  171. });
  172. RunTest("NETSDK1150");
  173. }
  174. [Theory]
  175. [InlineData(false)]
  176. [InlineData(true)]
  177. public void ReferencedExeCanRunWhenPublished(bool selfContained)
  178. {
  179. MainSelfContained = selfContained;
  180. ReferencedSelfContained = selfContained;
  181. TestWithPublish = true;
  182. CreateProjects();
  183. RunTest();
  184. }
  185. [Fact]
  186. public void ReferencedExeCanRunWhenPublishedWithTrimming()
  187. {
  188. MainSelfContained = true;
  189. ReferencedSelfContained = true;
  190. TestWithPublish = true;
  191. CreateProjects();
  192. if (MainSelfContained)
  193. {
  194. MainProject.AdditionalProperties["PublishTrimmed"] = "True";
  195. }
  196. if (ReferencedSelfContained)
  197. {
  198. ReferencedProject.AdditionalProperties["PublishTrimmed"] = "True";
  199. }
  200. RunTest();
  201. }
  202. [Theory]
  203. [InlineData("xunit")]
  204. [InlineData("mstest")]
  205. public void TestProjectCanReferenceExe(string testTemplateName)
  206. {
  207. var testConsoleProject = new TestProject("ConsoleApp")
  208. {
  209. IsExe = true,
  210. TargetFrameworks = "net5.0",
  211. RuntimeIdentifier = EnvironmentInfo.GetCompatibleRid()
  212. };
  213. var testAsset = _testAssetsManager.CreateTestProject(testConsoleProject, identifier: testTemplateName);
  214. var testProjectDirectory = Path.Combine(testAsset.TestRoot, "TestProject");
  215. Directory.CreateDirectory(testProjectDirectory);
  216. new DotnetCommand(Log, "new", testTemplateName)
  217. .WithWorkingDirectory(testProjectDirectory)
  218. .Execute()
  219. .Should()
  220. .Pass();
  221. new DotnetCommand(Log, "add", "reference", ".." + Path.DirectorySeparatorChar + testConsoleProject.Name)
  222. .WithWorkingDirectory(testProjectDirectory)
  223. .Execute()
  224. .Should()
  225. .Pass();
  226. new BuildCommand(Log, testProjectDirectory)
  227. .Execute()
  228. .Should()
  229. .Pass();
  230. }
  231. }
  232. }