Merge branch 'release/2.2'

This commit is contained in:
Nate McMaster 2018-08-29 21:44:45 -07:00
commit a8316cd7ab
No known key found for this signature in database
GPG Key ID: C6F361EAE0EB4089
35 changed files with 2794 additions and 0 deletions

View File

@ -0,0 +1,19 @@
trigger: none
queue:
name: DotNetCore-Windows
timeoutInMinutes: 120
steps:
- task: NodeTool@0
displayName: Install Node 10.x
inputs:
versionSpec: 10.x
- powershell: |
test/Cli.FunctionalTests/run-tests.ps1 -ci -ProdConManifestUrl $env:ProdConManifestUrl
condition: ne(variables['PB_SkipTests'], 'true')
displayName: Run E2E tests
- task: PublishTestResults@2
displayName: Publish test results
condition: always()
inputs:
testRunner: vstest
testResultsFiles: 'artifacts/logs/**/*.trx'

View File

@ -274,6 +274,7 @@
<PackageArtifact Include="Microsoft.Extensions.ObjectMethodExecutor.Sources" Category="noship" />
<PackageArtifact Include="Microsoft.Extensions.ObjectPool" Category="ship" AppMetapackage="true" AllMetapackage="true" />
<PackageArtifact Include="Microsoft.Extensions.Options.ConfigurationExtensions" Category="ship" AppMetapackage="true" AllMetapackage="true" />
<PackageArtifact Include="Microsoft.Extensions.Options.DataAnnotations" Category="ship" AppMetapackage="true" AllMetapackage="true" />
<PackageArtifact Include="Microsoft.Extensions.Options" Category="ship" AppMetapackage="true" AllMetapackage="true" />
<PackageArtifact Include="Microsoft.Extensions.ParameterDefaultValue.Sources" Category="noship" />
<PackageArtifact Include="Microsoft.Extensions.Primitives" Category="ship" AppMetapackage="true" AllMetapackage="true" />

View File

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Cli.FunctionalTests.Util;
using NUnit.Framework;
// Run all test cases in parallel
[assembly: Parallelizable(ParallelScope.Children)]
[SetUpFixture]
public class AssemblySetUp
{
public static string TempDir { get; private set; }
[OneTimeSetUp]
public void SetUp()
{
TempDir = IOUtil.GetTempDir();
}
[OneTimeTearDown]
public void TearDown()
{
IOUtil.DeleteDir(TempDir);
}
}

View File

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<RestoreSources>
https://api.nuget.org/v3/index.json;
$(DotNetRestoreSources)
</RestoreSources>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NuGet.Versioning" Version="4.7.0" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28016.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cli.FunctionalTests", "Cli.FunctionalTests.csproj", "{D44EA496-EF83-4D47-8C45-4DAF5A1B0070}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D44EA496-EF83-4D47-8C45-4DAF5A1B0070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D44EA496-EF83-4D47-8C45-4DAF5A1B0070}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D44EA496-EF83-4D47-8C45-4DAF5A1B0070}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D44EA496-EF83-4D47-8C45-4DAF5A1B0070}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {70432DA7-DCE4-4F73-A00C-E1AB180DDD6A}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,2 @@
<!-- Intentionally empty. -->
<Project />

View File

@ -0,0 +1,2 @@
<!-- Intentionally empty. -->
<Project />

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
</packageSources>
</configuration>

View File

@ -0,0 +1,57 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
namespace Cli.FunctionalTests
{
public class NuGetPackageSource
{
public static NuGetPackageSource None { get; } = new NuGetPackageSource
{
Name = nameof(None),
SourceArgumentLazy = new Lazy<string>(string.Empty),
};
public static NuGetPackageSource NuGetOrg { get; } = new NuGetPackageSource
{
Name = nameof(NuGetOrg),
SourceArgumentLazy = new Lazy<string>("--source https://api.nuget.org/v3/index.json"),
};
public static NuGetPackageSource DotNetCore { get; } = new NuGetPackageSource
{
Name = nameof(DotNetCore),
SourceArgumentLazy = new Lazy<string>("--source https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"),
};
public static NuGetPackageSource EnvironmentVariable { get; } = new NuGetPackageSource
{
Name = nameof(EnvironmentVariable),
SourceArgumentLazy = new Lazy<string>(() => GetSourceArgumentFromEnvironment()),
};
public static NuGetPackageSource EnvironmentVariableAndNuGetOrg { get; } = new NuGetPackageSource
{
Name = nameof(EnvironmentVariableAndNuGetOrg),
SourceArgumentLazy = new Lazy<string>(() => string.Join(" ", EnvironmentVariable.SourceArgument, NuGetOrg.SourceArgument)),
};
private NuGetPackageSource() { }
public string Name { get; private set; }
public string SourceArgument => SourceArgumentLazy.Value;
private Lazy<string> SourceArgumentLazy { get; set; }
public override string ToString() => Name;
private static string GetSourceArgumentFromEnvironment()
{
var sourceString = Environment.GetEnvironmentVariable("NUGET_PACKAGE_SOURCE") ??
throw new InvalidOperationException("Environment variable NUGET_PACKAGE_SOURCE is required but not set");
return string.Join(" ", sourceString.Split(',').Select(s => $"--source {s}"));
}
}
}

View File

@ -0,0 +1,5 @@
# Cli.FunctionalTests
This folder contains tests for ASP.NET Core scenarios in the .NET Core CLI.
This tests in this folder is meant to be kept in isolation from the rest of the repo, and are not invoked during the course of a regular build.

View File

@ -0,0 +1,55 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Cli.FunctionalTests
{
// https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
public class RuntimeIdentifier
{
public static RuntimeIdentifier None = new RuntimeIdentifier() {
Name = "none",
OSPlatforms = new[] { OSPlatform.Linux, OSPlatform.OSX, OSPlatform.Windows, },
};
public static RuntimeIdentifier Linux_x64 = new RuntimeIdentifier() {
Name = "linux-x64",
OSPlatforms = new[] { OSPlatform.Linux, },
ExecutableFileExtension = string.Empty,
};
public static RuntimeIdentifier OSX_x64 = new RuntimeIdentifier()
{
Name = "osx-x64",
OSPlatforms = new[] { OSPlatform.OSX, },
ExecutableFileExtension = string.Empty,
};
public static RuntimeIdentifier Win_x64 = new RuntimeIdentifier()
{
Name = "win-x64",
OSPlatforms = new[] { OSPlatform.Windows, },
ExecutableFileExtension = ".exe",
};
public static IEnumerable<RuntimeIdentifier> All = new[]
{
RuntimeIdentifier.None,
RuntimeIdentifier.Linux_x64,
RuntimeIdentifier.OSX_x64,
RuntimeIdentifier.Win_x64,
};
private RuntimeIdentifier() { }
public string Name { get; private set; }
public string RuntimeArgument => (this == None) ? string.Empty : $"--runtime {Name}";
public string Path => (this == None) ? string.Empty : Name;
public IEnumerable<OSPlatform> OSPlatforms { get; private set; }
public string ExecutableFileExtension { get; private set; }
public override string ToString() => Name;
}
}

View File

@ -0,0 +1,220 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using Cli.FunctionalTests.Templates;
using Cli.FunctionalTests.Util;
using NuGet.Versioning;
using NUnit.Framework;
namespace Cli.FunctionalTests
{
[TestFixture]
public class TemplateTests
{
[Test]
[TestCaseSource(nameof(RestoreData))]
public void _1_Restore(Template template)
{
var expected = template.ExpectedObjFilesAfterRestore;
var actual = template.ObjFilesAfterRestore;
CollectionAssert.AreEquivalent(expected, actual);
}
[Test]
[TestCaseSource(nameof(RestoreData))]
public void _2_RestoreIncremental(Template template)
{
var expected = template.ExpectedObjFilesAfterRestore;
var actual = template.ObjFilesAfterRestoreIncremental;
CollectionAssert.AreEquivalent(expected, actual);
}
[Test]
[TestCaseSource(nameof(BuildData))]
public void _3_Build(Template template)
{
var expectedObj = template.ExpectedObjFilesAfterBuild;
var actualObj = template.ObjFilesAfterBuild;
CollectionAssert.AreEquivalent(expectedObj, actualObj);
var expectedBin = template.ExpectedBinFilesAfterBuild;
var actualBin = template.BinFilesAfterBuild;
CollectionAssert.AreEquivalent(expectedBin, actualBin);
}
[Test]
[TestCaseSource(nameof(BuildData))]
public void _4_BuildIncremental(Template template)
{
var expectedObj = template.ExpectedObjFilesAfterBuild;
var actualObj = template.ObjFilesAfterBuildIncremental;
CollectionAssert.AreEquivalent(expectedObj, actualObj);
var expectedBin = template.ExpectedBinFilesAfterBuild;
var actualBin = template.BinFilesAfterBuildIncremental;
CollectionAssert.AreEquivalent(expectedBin, actualBin);
}
[Test]
[TestCaseSource(nameof(RunData))]
public void _5_Run(Template template)
{
var statusCode = template.HttpResponseAfterRun.StatusCode;
Assert.AreEqual(HttpStatusCode.OK, statusCode,
GetMessage(statusCode, template.ServerOutputAfterRun, template.ServerErrorAfterRun));
statusCode = template.HttpsResponseAfterRun.StatusCode;
Assert.AreEqual(HttpStatusCode.OK, statusCode,
GetMessage(statusCode, template.ServerOutputAfterRun, template.ServerErrorAfterRun));
}
[NonParallelizable]
[Test]
[TestCaseSource(nameof(RunNonParallelizableData))]
public void _5_RunNonParallelizable(Template template)
{
_5_Run(template);
}
[Test]
[TestCaseSource(nameof(PublishData))]
public void _6_Publish(Template template)
{
var expected = template.ExpectedFilesAfterPublish;
var actual = template.FilesAfterPublish;
CollectionAssert.AreEquivalent(expected, actual);
}
[Test]
[TestCaseSource(nameof(PublishData))]
public void _7_PublishIncremental(Template template)
{
var expected = template.ExpectedFilesAfterPublish;
var actual = template.FilesAfterPublishIncremental;
CollectionAssert.AreEquivalent(expected, actual);
}
[Test]
[TestCaseSource(nameof(ExecData))]
public void _8_Exec(Template template)
{
var statusCode = template.HttpResponseAfterExec.StatusCode;
Assert.AreEqual(HttpStatusCode.OK, statusCode,
GetMessage(statusCode, template.ServerOutputAfterExec, template.ServerErrorAfterExec));
statusCode = template.HttpsResponseAfterExec.StatusCode;
Assert.AreEqual(HttpStatusCode.OK, statusCode,
GetMessage(statusCode, template.ServerOutputAfterExec, template.ServerErrorAfterExec));
}
private static string GetMessage(HttpStatusCode statusCode, string serverOutput, string serverError)
{
return String.Join(Environment.NewLine,
$"StatusCode: {statusCode}",
string.Empty,
"ServerOutput",
"------------",
serverOutput,
string.Empty,
"ServerError",
"------------",
serverError);
}
private static IEnumerable<Template> GetTemplates(RuntimeIdentifier runtimeIdentifier)
{
// Offline restore is broken in SDK 2.1.301 (https://github.com/aspnet/Universe/issues/1220)
var offlinePackageSource = (DotNetUtil.SdkVersion == new SemanticVersion(2, 1, 301)) ?
NuGetPackageSource.NuGetOrg : NuGetPackageSource.None;
// Pre-release SDKs require a private nuget feed
var onlinePackageSource = DotNetUtil.RequiresPrivateFeed ?
NuGetPackageSource.EnvironmentVariableAndNuGetOrg : NuGetPackageSource.NuGetOrg;
if (runtimeIdentifier == RuntimeIdentifier.None)
{
// Framework-dependent
return new[]
{
Template.GetInstance<ClassLibraryTemplate>(NuGetPackageSource.None, runtimeIdentifier),
Template.GetInstance<ConsoleApplicationTemplate>(offlinePackageSource, runtimeIdentifier),
// Offline restore currently not supported for RazorClassLibrary template (https://github.com/aspnet/Universe/issues/1123)
Template.GetInstance<RazorClassLibraryTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<WebTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<RazorTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<MvcTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<AngularTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<ReactTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<ReactReduxTemplate>(offlinePackageSource, runtimeIdentifier),
Template.GetInstance<WebApiTemplate>(offlinePackageSource, runtimeIdentifier),
};
}
else
{
// Self-contained
return new[]
{
// ClassLibrary does not require a package source, even for self-contained deployments
Template.GetInstance<ClassLibraryTemplate>(NuGetPackageSource.None, runtimeIdentifier),
Template.GetInstance<ConsoleApplicationTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<RazorClassLibraryTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<WebTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<RazorTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<MvcTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<AngularTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<ReactTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<ReactReduxTemplate>(onlinePackageSource, runtimeIdentifier),
Template.GetInstance<WebApiTemplate>(onlinePackageSource, runtimeIdentifier),
};
}
}
private static readonly IEnumerable<Template> _restoreTemplates = RuntimeIdentifier.All.SelectMany(r => GetTemplates(r));
// Must call ToList() or similar on RestoreData to ensure TestCaseData instances can be compared to each other,
// which is required to use Except() in RunData.
public static IEnumerable<TestCaseData> RestoreData = _restoreTemplates.Select(t => new TestCaseData(t)).ToList();
public static IEnumerable<TestCaseData> BuildData => RestoreData;
public static IEnumerable<TestCaseData> PublishData => BuildData;
private static readonly IEnumerable<TestCaseData> _runData =
from tcd in BuildData
let t = (Template)tcd.Arguments[0]
// Only interested in verifying web applications
where (t.Type == TemplateType.WebApplication)
// "dotnet run" is only relevant for framework-dependent apps
where (t.RuntimeIdentifier == RuntimeIdentifier.None)
select tcd;
// On Linux, calling "dotnet run" on multiple React templates in parallel may fail since the default
// fs.inotify.max_user_watches is too low. One workaround is to increase fs.inotify.max_user_watches,
// but this means tests will fail on a default machine. A simpler workaround is to disable parallel
// execution for these tests.
public static IEnumerable<TestCaseData> RunNonParallelizableData =
from tcd in _runData
let t = (Template)tcd.Arguments[0]
where (t is ReactTemplate)
select tcd;
public static IEnumerable<TestCaseData> RunData = _runData.Except(RunNonParallelizableData);
public static IEnumerable<TestCaseData> ExecData =
from tcd in PublishData
let t = (Template)tcd.Arguments[0]
// Only interested in verifying web applications
where (t.Type == TemplateType.WebApplication)
// Can only run framework-dependent apps and self-contained apps matching the current platform
let runnable = t.RuntimeIdentifier.OSPlatforms.Any(p => RuntimeInformation.IsOSPlatform(p))
select (runnable ? tcd : tcd.Ignore($"RuntimeIdentifier '{t.RuntimeIdentifier}' cannot be executed on this platform"));
}
}

View File

@ -0,0 +1,67 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class AngularTemplate : SpaBaseTemplate
{
public AngularTemplate() { }
public override string Name => "angular";
protected override IEnumerable<string> NormalizeFilesAfterPublish(IEnumerable<string> filesAfterPublish)
{
// Remove generated hashes since they may vary by platform
return base.NormalizeFilesAfterPublish(filesAfterPublish)
.Select(f => Regex.Replace(f, @"\.[0-9a-f]{20}\.", ".[HASH]."));
}
private IDictionary<string, Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<string, Func<IEnumerable<string>>>()
{
{ "common", () => new[]
{
Path.Combine("wwwroot", "favicon.ico"),
Path.Combine("ClientApp", "dist", "3rdpartylicenses.txt"),
Path.Combine("ClientApp", "dist", "index.html"),
}
},
{ "netcoreapp2.1", () =>
_additionalFilesAfterPublish["common"]()
.Concat(new[]
{
Path.Combine("ClientApp", "dist", "glyphicons-halflings-regular.[HASH].woff2"),
Path.Combine("ClientApp", "dist", "glyphicons-halflings-regular.[HASH].svg"),
Path.Combine("ClientApp", "dist", "glyphicons-halflings-regular.[HASH].ttf"),
Path.Combine("ClientApp", "dist", "glyphicons-halflings-regular.[HASH].eot"),
Path.Combine("ClientApp", "dist", "glyphicons-halflings-regular.[HASH].woff"),
Path.Combine("ClientApp", "dist", $"inline.[HASH].bundle.js"),
Path.Combine("ClientApp", "dist", $"main.[HASH].bundle.js"),
Path.Combine("ClientApp", "dist", $"polyfills.[HASH].bundle.js"),
Path.Combine("ClientApp", "dist", $"styles.[HASH].bundle.css"),
})
},
{ "netcoreapp2.2", () =>
_additionalFilesAfterPublish["common"]()
.Concat(new[]
{
Path.Combine("ClientApp", "dist", $"runtime.[HASH].js"),
Path.Combine("ClientApp", "dist", $"main.[HASH].js"),
Path.Combine("ClientApp", "dist", $"polyfills.[HASH].js"),
Path.Combine("ClientApp", "dist", $"styles.[HASH].css"),
})
},
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(_additionalFilesAfterPublish[DotNetUtil.TargetFrameworkMoniker]());
}
}

View File

@ -0,0 +1,48 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Cli.FunctionalTests.Templates
{
public class ClassLibraryTemplate : Template
{
public ClassLibraryTemplate() { }
public override string Name => "classlib";
public override string OutputPath => Path.Combine("Debug", "netstandard2.0", RuntimeIdentifier.Path);
public override TemplateType Type => TemplateType.ClassLibrary;
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(new[]
{
$"{Name}.AssemblyInfo.cs",
$"{Name}.AssemblyInfoInputs.cache",
$"{Name}.assets.cache",
$"{Name}.csproj.CoreCompileInputs.cache",
$"{Name}.csproj.FileListAbsolute.txt",
$"{Name}.csprojAssemblyReference.cache",
$"{Name}.dll",
$"{Name}.pdb",
}.Select(p => Path.Combine(OutputPath, p)));
public override IEnumerable<string> ExpectedBinFilesAfterBuild => new[]
{
$"{Name}.deps.json",
$"{Name}.dll",
$"{Name}.pdb",
}.Select(p => Path.Combine(OutputPath, p));
public override IEnumerable<string> ExpectedFilesAfterPublish => new[]
{
$"{Name}.deps.json",
$"{Name}.dll",
$"{Name}.pdb",
};
}
}

View File

@ -0,0 +1,375 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class ConsoleApplicationTemplate : ClassLibraryTemplate
{
public ConsoleApplicationTemplate() { }
public override string Name => "console";
public override string OutputPath => Path.Combine("Debug", DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier.Path);
public override TemplateType Type => TemplateType.ConsoleApplication;
private IDictionary<RuntimeIdentifier, Func<IEnumerable<string>>> _additionalObjFilesAfterBuild =>
new Dictionary<RuntimeIdentifier, Func<IEnumerable<string>>>()
{
{ RuntimeIdentifier.None, () => Enumerable.Empty<string>() },
{ RuntimeIdentifier.Win_x64, () => new[]
{
Path.Combine(DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier.Path, "host", $"{Name}.exe"),
}
},
{ RuntimeIdentifier.Linux_x64, () => new[]
{
Path.Combine(DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier.Path, "host", $"{Name}"),
}
},
{ RuntimeIdentifier.OSX_x64, () => _additionalObjFilesAfterBuild[RuntimeIdentifier.Linux_x64]() },
};
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(_additionalObjFilesAfterBuild[RuntimeIdentifier]());
private IDictionary<RuntimeIdentifier, Func<IEnumerable<string>>> _additionalBinFilesAfterBuild =>
new Dictionary<RuntimeIdentifier, Func<IEnumerable<string>>>()
{
{ RuntimeIdentifier.None, () => new[]
{
$"{Name}.runtimeconfig.dev.json",
$"{Name}.runtimeconfig.json",
}.Select(p => Path.Combine(OutputPath, p))
},
{ RuntimeIdentifier.Win_x64, () =>
_additionalBinFilesAfterBuild[RuntimeIdentifier.None]()
.Concat(new[]
{
$"{Name}.exe",
"hostfxr.dll",
"hostpolicy.dll",
}.Select(p => Path.Combine(OutputPath, p)))
},
{ RuntimeIdentifier.Linux_x64, () =>
_additionalBinFilesAfterBuild[RuntimeIdentifier.None]()
.Concat(new[]
{
$"{Name}",
"libhostfxr.so",
"libhostpolicy.so",
}.Select(p => Path.Combine(OutputPath, p)))
},
{ RuntimeIdentifier.OSX_x64, () =>
_additionalBinFilesAfterBuild[RuntimeIdentifier.Linux_x64]()
.Select(f => Regex.Replace(f, ".so$", ".dylib"))
},
};
public override IEnumerable<string> ExpectedBinFilesAfterBuild =>
base.ExpectedBinFilesAfterBuild
.Concat(_additionalBinFilesAfterBuild[RuntimeIdentifier]());
protected override IEnumerable<string> NormalizeFilesAfterPublish(IEnumerable<string> filesAfterPublish)
{
// A few files included in self-contained deployments contain version numbers in the filename, which must
// be replaced so tests can pass on all versions.
return base.NormalizeFilesAfterPublish(filesAfterPublish)
.Select(f => Regex.Replace(f, @"_amd64_amd64_[0-9\.]+\.dll$", "_amd64_amd64_[VERSION].dll"));
}
private Func<IEnumerable<string>> _additionalFilesAfterPublishCommon = () => new[]
{
"Microsoft.CSharp.dll",
"Microsoft.VisualBasic.dll",
// It may seem unusual to include Microsoft.Win32 assemblies in all platforms, but it appears to be by design
// https://github.com/dotnet/corefx/issues/14896
"Microsoft.Win32.Primitives.dll",
"Microsoft.Win32.Registry.dll",
"mscorlib.dll",
"netstandard.dll",
"System.AppContext.dll",
"System.Buffers.dll",
"System.Collections.Concurrent.dll",
"System.Collections.dll",
"System.Collections.Immutable.dll",
"System.Collections.NonGeneric.dll",
"System.Collections.Specialized.dll",
"System.ComponentModel.Annotations.dll",
"System.ComponentModel.DataAnnotations.dll",
"System.ComponentModel.dll",
"System.ComponentModel.EventBasedAsync.dll",
"System.ComponentModel.Primitives.dll",
"System.ComponentModel.TypeConverter.dll",
"System.Configuration.dll",
"System.Console.dll",
"System.Core.dll",
"System.Data.Common.dll",
"System.Data.dll",
"System.Diagnostics.Contracts.dll",
"System.Diagnostics.Debug.dll",
"System.Diagnostics.DiagnosticSource.dll",
"System.Diagnostics.FileVersionInfo.dll",
"System.Diagnostics.Process.dll",
"System.Diagnostics.StackTrace.dll",
"System.Diagnostics.TextWriterTraceListener.dll",
"System.Diagnostics.Tools.dll",
"System.Diagnostics.TraceSource.dll",
"System.Diagnostics.Tracing.dll",
"System.dll",
"System.Drawing.dll",
"System.Drawing.Primitives.dll",
"System.Dynamic.Runtime.dll",
"System.Globalization.Calendars.dll",
"System.Globalization.dll",
"System.Globalization.Extensions.dll",
"System.IO.Compression.Brotli.dll",
"System.IO.Compression.dll",
"System.IO.Compression.FileSystem.dll",
"System.IO.Compression.ZipFile.dll",
"System.IO.dll",
"System.IO.FileSystem.AccessControl.dll",
"System.IO.FileSystem.dll",
"System.IO.FileSystem.DriveInfo.dll",
"System.IO.FileSystem.Primitives.dll",
"System.IO.FileSystem.Watcher.dll",
"System.IO.IsolatedStorage.dll",
"System.IO.MemoryMappedFiles.dll",
"System.IO.Pipes.AccessControl.dll",
"System.IO.Pipes.dll",
"System.IO.UnmanagedMemoryStream.dll",
"System.Linq.dll",
"System.Linq.Expressions.dll",
"System.Linq.Parallel.dll",
"System.Linq.Queryable.dll",
"System.Memory.dll",
"System.Net.dll",
"System.Net.Http.dll",
"System.Net.HttpListener.dll",
"System.Net.Mail.dll",
"System.Net.NameResolution.dll",
"System.Net.NetworkInformation.dll",
"System.Net.Ping.dll",
"System.Net.Primitives.dll",
"System.Net.Requests.dll",
"System.Net.Security.dll",
"System.Net.ServicePoint.dll",
"System.Net.Sockets.dll",
"System.Net.WebClient.dll",
"System.Net.WebHeaderCollection.dll",
"System.Net.WebProxy.dll",
"System.Net.WebSockets.Client.dll",
"System.Net.WebSockets.dll",
"System.Numerics.dll",
"System.Numerics.Vectors.dll",
"System.ObjectModel.dll",
"System.Private.CoreLib.dll",
"System.Private.DataContractSerialization.dll",
"System.Private.Uri.dll",
"System.Private.Xml.dll",
"System.Private.Xml.Linq.dll",
"System.Reflection.DispatchProxy.dll",
"System.Reflection.dll",
"System.Reflection.Emit.dll",
"System.Reflection.Emit.ILGeneration.dll",
"System.Reflection.Emit.Lightweight.dll",
"System.Reflection.Extensions.dll",
"System.Reflection.Metadata.dll",
"System.Reflection.Primitives.dll",
"System.Reflection.TypeExtensions.dll",
"System.Resources.Reader.dll",
"System.Resources.ResourceManager.dll",
"System.Resources.Writer.dll",
"System.Runtime.CompilerServices.VisualC.dll",
"System.Runtime.dll",
"System.Runtime.Extensions.dll",
"System.Runtime.Handles.dll",
"System.Runtime.InteropServices.dll",
"System.Runtime.InteropServices.RuntimeInformation.dll",
"System.Runtime.InteropServices.WindowsRuntime.dll",
"System.Runtime.Loader.dll",
"System.Runtime.Numerics.dll",
"System.Runtime.Serialization.dll",
"System.Runtime.Serialization.Formatters.dll",
"System.Runtime.Serialization.Json.dll",
"System.Runtime.Serialization.Primitives.dll",
"System.Runtime.Serialization.Xml.dll",
"System.Security.AccessControl.dll",
"System.Security.Claims.dll",
"System.Security.Cryptography.Algorithms.dll",
"System.Security.Cryptography.Cng.dll",
"System.Security.Cryptography.Csp.dll",
"System.Security.Cryptography.Encoding.dll",
"System.Security.Cryptography.OpenSsl.dll",
"System.Security.Cryptography.Primitives.dll",
"System.Security.Cryptography.X509Certificates.dll",
"System.Security.dll",
"System.Security.Principal.dll",
"System.Security.Principal.Windows.dll",
"System.Security.SecureString.dll",
"System.ServiceModel.Web.dll",
"System.ServiceProcess.dll",
"System.Text.Encoding.dll",
"System.Text.Encoding.Extensions.dll",
"System.Text.RegularExpressions.dll",
"System.Threading.dll",
"System.Threading.Overlapped.dll",
"System.Threading.Tasks.Dataflow.dll",
"System.Threading.Tasks.dll",
"System.Threading.Tasks.Extensions.dll",
"System.Threading.Tasks.Parallel.dll",
"System.Threading.Thread.dll",
"System.Threading.ThreadPool.dll",
"System.Threading.Timer.dll",
"System.Transactions.dll",
"System.Transactions.Local.dll",
"System.ValueTuple.dll",
"System.Web.dll",
"System.Web.HttpUtility.dll",
"System.Windows.dll",
"System.Xml.dll",
"System.Xml.Linq.dll",
"System.Xml.ReaderWriter.dll",
"System.Xml.Serialization.dll",
"System.Xml.XDocument.dll",
"System.Xml.XmlDocument.dll",
"System.Xml.XmlSerializer.dll",
"System.Xml.XPath.dll",
"System.Xml.XPath.XDocument.dll",
"WindowsBase.dll",
};
private IDictionary<RuntimeIdentifier, Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<RuntimeIdentifier, Func<IEnumerable<string>>>()
{
{ RuntimeIdentifier.None, () => new[]
{
$"{Name}.runtimeconfig.json",
}
},
{ RuntimeIdentifier.Win_x64, () =>
_additionalFilesAfterPublish[RuntimeIdentifier.None]()
.Concat(_additionalFilesAfterPublishCommon())
.Concat(new[]
{
$"{Name}.exe",
"api-ms-win-core-console-l1-1-0.dll",
"api-ms-win-core-datetime-l1-1-0.dll",
"api-ms-win-core-debug-l1-1-0.dll",
"api-ms-win-core-errorhandling-l1-1-0.dll",
"api-ms-win-core-file-l1-1-0.dll",
"api-ms-win-core-file-l1-2-0.dll",
"api-ms-win-core-file-l2-1-0.dll",
"api-ms-win-core-handle-l1-1-0.dll",
"api-ms-win-core-heap-l1-1-0.dll",
"api-ms-win-core-interlocked-l1-1-0.dll",
"api-ms-win-core-libraryloader-l1-1-0.dll",
"api-ms-win-core-localization-l1-2-0.dll",
"api-ms-win-core-memory-l1-1-0.dll",
"api-ms-win-core-namedpipe-l1-1-0.dll",
"api-ms-win-core-processenvironment-l1-1-0.dll",
"api-ms-win-core-processthreads-l1-1-0.dll",
"api-ms-win-core-processthreads-l1-1-1.dll",
"api-ms-win-core-profile-l1-1-0.dll",
"api-ms-win-core-rtlsupport-l1-1-0.dll",
"api-ms-win-core-string-l1-1-0.dll",
"api-ms-win-core-synch-l1-1-0.dll",
"api-ms-win-core-synch-l1-2-0.dll",
"api-ms-win-core-sysinfo-l1-1-0.dll",
"api-ms-win-core-timezone-l1-1-0.dll",
"api-ms-win-core-util-l1-1-0.dll",
"api-ms-win-crt-conio-l1-1-0.dll",
"api-ms-win-crt-convert-l1-1-0.dll",
"api-ms-win-crt-environment-l1-1-0.dll",
"api-ms-win-crt-filesystem-l1-1-0.dll",
"api-ms-win-crt-heap-l1-1-0.dll",
"api-ms-win-crt-locale-l1-1-0.dll",
"api-ms-win-crt-math-l1-1-0.dll",
"api-ms-win-crt-multibyte-l1-1-0.dll",
"api-ms-win-crt-private-l1-1-0.dll",
"api-ms-win-crt-process-l1-1-0.dll",
"api-ms-win-crt-runtime-l1-1-0.dll",
"api-ms-win-crt-stdio-l1-1-0.dll",
"api-ms-win-crt-string-l1-1-0.dll",
"api-ms-win-crt-time-l1-1-0.dll",
"api-ms-win-crt-utility-l1-1-0.dll",
"clrcompression.dll",
"clretwrc.dll",
"clrjit.dll",
"coreclr.dll",
"dbgshim.dll",
"hostfxr.dll",
"hostpolicy.dll",
"Microsoft.DiaSymReader.Native.amd64.dll",
"mscordaccore.dll",
"mscordaccore_amd64_amd64_[VERSION].dll",
"mscordbi.dll",
"mscorrc.debug.dll",
"mscorrc.dll",
"sos.dll",
"SOS.NETCore.dll",
"sos_amd64_amd64_[VERSION].dll",
"ucrtbase.dll",
})
},
{ RuntimeIdentifier.Linux_x64, () =>
_additionalFilesAfterPublish[RuntimeIdentifier.None]()
.Concat(_additionalFilesAfterPublishCommon())
.Concat(new[]
{
$"{Name}",
"createdump",
"libclrjit.so",
"libcoreclr.so",
"libcoreclrtraceptprovider.so",
"libdbgshim.so",
"libhostfxr.so",
"libhostpolicy.so",
"libmscordaccore.so",
"libmscordbi.so",
"libsos.so",
"libsosplugin.so",
"SOS.NETCore.dll",
"sosdocsunix.txt",
"System.Globalization.Native.so",
"System.IO.Compression.Native.a",
"System.IO.Compression.Native.so",
"System.Native.a",
"System.Native.so",
"System.Net.Http.Native.a",
"System.Net.Http.Native.so",
"System.Net.Security.Native.a",
"System.Net.Security.Native.so",
"System.Security.Cryptography.Native.OpenSsl.a",
"System.Security.Cryptography.Native.OpenSsl.so",
})
},
{ RuntimeIdentifier.OSX_x64, () =>
_additionalFilesAfterPublish[RuntimeIdentifier.Linux_x64]()
.Where(f => f != "createdump")
.Where(f => f != "libcoreclrtraceptprovider.so")
.Where(f => f != "libsosplugin.so")
.Select(f => Regex.Replace(f, ".so$", ".dylib"))
.Concat(new[]
{
"System.Security.Cryptography.Native.Apple.a",
"System.Security.Cryptography.Native.Apple.dylib",
})
}
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(_additionalFilesAfterPublish[RuntimeIdentifier]());
}
}

View File

@ -0,0 +1,49 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class MvcTemplate : RazorBootstrapJQueryTemplate
{
public MvcTemplate() { }
public override string Name => "mvc";
protected override string RazorPath => "Views";
private IDictionary<string, Func<IEnumerable<string>>> _additionalObjFilesAfterBuild =>
new Dictionary<string, Func<IEnumerable<string>>>()
{
{ "common", () => new[]
{
Path.Combine("Razor", RazorPath, "_ViewStart.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Home", "Index.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Home", "Privacy.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_CookieConsentPartial.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_Layout.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_ValidationScriptsPartial.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "Error.g.cshtml.cs"),
}
},
{ "netcoreapp2.1", () =>
_additionalObjFilesAfterBuild["common"]()
.Concat(new[]
{
Path.Combine("Razor", RazorPath, "Home", "About.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Home", "Contact.g.cshtml.cs"),
})
},
{ "netcoreapp2.2", () => _additionalObjFilesAfterBuild["common"]() },
};
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(_additionalObjFilesAfterBuild[DotNetUtil.TargetFrameworkMoniker]().Select(p => Path.Combine(OutputPath, p)));
}
}

View File

@ -0,0 +1,61 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public abstract class RazorApplicationBaseTemplate : WebTemplate
{
protected abstract string RazorPath { get; }
private IDictionary<RuntimeIdentifier, Func<IEnumerable<string>>> _additionalObjFilesAfterBuild =>
new Dictionary<RuntimeIdentifier, Func<IEnumerable<string>>>()
{
{ RuntimeIdentifier.None, () => new[]
{
Path.Combine("Razor", RazorPath, "_ViewImports.g.cshtml.cs"),
}.Select(p => Path.Combine(OutputPath, p))
},
{ RuntimeIdentifier.Win_x64, () =>
_additionalObjFilesAfterBuild[RuntimeIdentifier.None]()
.Concat(new[]
{
Path.Combine(DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier.Path, "host", $"{Name}.exe"),
})
},
{ RuntimeIdentifier.Linux_x64, () =>
_additionalObjFilesAfterBuild[RuntimeIdentifier.None]()
.Concat(new[]
{
Path.Combine(DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier.Path, "host", $"{Name}"),
})
},
{ RuntimeIdentifier.OSX_x64, () => _additionalObjFilesAfterBuild[RuntimeIdentifier.Linux_x64]() },
};
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(RazorUtil.GetExpectedObjFilesAfterBuild(this))
.Concat(_additionalObjFilesAfterBuild[RuntimeIdentifier]())
// Some files are duplicated in WebTemplate and RazorUtil, since they are needed by RazorClassLibraryTemplate
.Distinct();
public override IEnumerable<string> ExpectedBinFilesAfterBuild =>
base.ExpectedBinFilesAfterBuild
.Concat(RazorUtil.GetExpectedBinFilesAfterBuild(this));
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(RazorUtil.GetExpectedFilesAfterPublish(this))
.Concat(new[]
{
"appsettings.Development.json",
"appsettings.json",
});
}
}

View File

@ -0,0 +1,94 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public abstract class RazorBootstrapJQueryTemplate : RazorApplicationBaseTemplate
{
private IDictionary<string, Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<string, Func<IEnumerable<string>>>()
{
{ "common", () => new[]
{
Path.Combine("wwwroot", "favicon.ico"),
Path.Combine("wwwroot", "css", "site.css"),
Path.Combine("wwwroot", "css", "site.min.css"),
Path.Combine("wwwroot", "images", "banner1.svg"),
Path.Combine("wwwroot", "images", "banner2.svg"),
Path.Combine("wwwroot", "images", "banner3.svg"),
Path.Combine("wwwroot", "js", "site.js"),
Path.Combine("wwwroot", "js", "site.min.js"),
Path.Combine("wwwroot", "lib", "bootstrap", "LICENSE"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap.min.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap.min.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.js"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.min.js"),
Path.Combine("wwwroot", "lib", "jquery", ".bower.json"),
Path.Combine("wwwroot", "lib", "jquery", "LICENSE.txt"),
Path.Combine("wwwroot", "lib", "jquery", "dist", "jquery.js"),
Path.Combine("wwwroot", "lib", "jquery", "dist", "jquery.min.js"),
Path.Combine("wwwroot", "lib", "jquery", "dist", "jquery.min.map"),
Path.Combine("wwwroot", "lib", "jquery-validation", ".bower.json"),
Path.Combine("wwwroot", "lib", "jquery-validation", "LICENSE.md"),
Path.Combine("wwwroot", "lib", "jquery-validation", "dist", "additional-methods.js"),
Path.Combine("wwwroot", "lib", "jquery-validation", "dist", "additional-methods.min.js"),
Path.Combine("wwwroot", "lib", "jquery-validation", "dist", "jquery.validate.js"),
Path.Combine("wwwroot", "lib", "jquery-validation", "dist", "jquery.validate.min.js"),
Path.Combine("wwwroot", "lib", "jquery-validation-unobtrusive", "jquery.validate.unobtrusive.js"),
Path.Combine("wwwroot", "lib", "jquery-validation-unobtrusive", "jquery.validate.unobtrusive.min.js"),
Path.Combine("wwwroot", "lib", "jquery-validation-unobtrusive", "LICENSE.txt"),
}
},
{ "netcoreapp2.1", () =>
_additionalFilesAfterPublish["common"]()
.Concat(new[]
{
Path.Combine("wwwroot", "lib", "bootstrap", ".bower.json"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-theme.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-theme.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-theme.min.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-theme.min.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "fonts", "glyphicons-halflings-regular.eot"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "fonts", "glyphicons-halflings-regular.svg"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "fonts", "glyphicons-halflings-regular.ttf"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "fonts", "glyphicons-halflings-regular.woff"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "fonts", "glyphicons-halflings-regular.woff2"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "npm.js"),
Path.Combine("wwwroot", "lib", "jquery-validation-unobtrusive", ".bower.json"),
})
},
{ "netcoreapp2.2", () =>
_additionalFilesAfterPublish["common"]()
.Concat(new[]
{
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-grid.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-grid.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-grid.min.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-grid.min.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-reboot.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-reboot.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-reboot.min.css"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "css", "bootstrap-reboot.min.css.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.bundle.js"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.bundle.js.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.bundle.min.js"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.bundle.min.js.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.js.map"),
Path.Combine("wwwroot", "lib", "bootstrap", "dist", "js", "bootstrap.min.js.map"),
})
},
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(_additionalFilesAfterPublish[DotNetUtil.TargetFrameworkMoniker]());
}
}

View File

@ -0,0 +1,359 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Cli.FunctionalTests.Templates
{
public class RazorClassLibraryTemplate : ClassLibraryTemplate
{
public RazorClassLibraryTemplate() { }
public override string Name => "razorclasslib";
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(RazorUtil.GetExpectedObjFilesAfterBuild(this))
.Concat(new[]
{
Path.Combine("Razor", "Areas", "MyFeature", "Pages", "Page1.g.cshtml.cs"),
}.Select(p => Path.Combine(OutputPath, p)));
// We set PreserveCompilationContext=true for all project types in the Razor.Sdk. This results in an refs directory to be created
// in the build output directory which is undesirable. We should consider setting PreserveCompilationContext=true only if the
// app's an executable.
// https://github.com/aspnet/Razor/issues/2308
public override IEnumerable<string> ExpectedBinFilesAfterBuild =>
base.ExpectedBinFilesAfterBuild
.Concat(RazorUtil.GetExpectedBinFilesAfterBuild(this))
.Concat(new[]
{
Path.Combine("refs", "Microsoft.Win32.Primitives.dll"),
Path.Combine("refs", "mscorlib.dll"),
Path.Combine("refs", "netstandard.dll"),
Path.Combine("refs", "System.AppContext.dll"),
Path.Combine("refs", "System.Collections.Concurrent.dll"),
Path.Combine("refs", "System.Collections.dll"),
Path.Combine("refs", "System.Collections.NonGeneric.dll"),
Path.Combine("refs", "System.Collections.Specialized.dll"),
Path.Combine("refs", "System.ComponentModel.Composition.dll"),
Path.Combine("refs", "System.ComponentModel.dll"),
Path.Combine("refs", "System.ComponentModel.EventBasedAsync.dll"),
Path.Combine("refs", "System.ComponentModel.Primitives.dll"),
Path.Combine("refs", "System.ComponentModel.TypeConverter.dll"),
Path.Combine("refs", "System.Console.dll"),
Path.Combine("refs", "System.Core.dll"),
Path.Combine("refs", "System.Data.Common.dll"),
Path.Combine("refs", "System.Data.dll"),
Path.Combine("refs", "System.Diagnostics.Contracts.dll"),
Path.Combine("refs", "System.Diagnostics.Debug.dll"),
Path.Combine("refs", "System.Diagnostics.FileVersionInfo.dll"),
Path.Combine("refs", "System.Diagnostics.Process.dll"),
Path.Combine("refs", "System.Diagnostics.StackTrace.dll"),
Path.Combine("refs", "System.Diagnostics.TextWriterTraceListener.dll"),
Path.Combine("refs", "System.Diagnostics.Tools.dll"),
Path.Combine("refs", "System.Diagnostics.TraceSource.dll"),
Path.Combine("refs", "System.Diagnostics.Tracing.dll"),
Path.Combine("refs", "System.dll"),
Path.Combine("refs", "System.Drawing.dll"),
Path.Combine("refs", "System.Drawing.Primitives.dll"),
Path.Combine("refs", "System.Dynamic.Runtime.dll"),
Path.Combine("refs", "System.Globalization.Calendars.dll"),
Path.Combine("refs", "System.Globalization.dll"),
Path.Combine("refs", "System.Globalization.Extensions.dll"),
Path.Combine("refs", "System.IO.Compression.dll"),
Path.Combine("refs", "System.IO.Compression.FileSystem.dll"),
Path.Combine("refs", "System.IO.Compression.ZipFile.dll"),
Path.Combine("refs", "System.IO.dll"),
Path.Combine("refs", "System.IO.FileSystem.dll"),
Path.Combine("refs", "System.IO.FileSystem.DriveInfo.dll"),
Path.Combine("refs", "System.IO.FileSystem.Primitives.dll"),
Path.Combine("refs", "System.IO.FileSystem.Watcher.dll"),
Path.Combine("refs", "System.IO.IsolatedStorage.dll"),
Path.Combine("refs", "System.IO.MemoryMappedFiles.dll"),
Path.Combine("refs", "System.IO.Pipes.dll"),
Path.Combine("refs", "System.IO.UnmanagedMemoryStream.dll"),
Path.Combine("refs", "System.Linq.dll"),
Path.Combine("refs", "System.Linq.Expressions.dll"),
Path.Combine("refs", "System.Linq.Parallel.dll"),
Path.Combine("refs", "System.Linq.Queryable.dll"),
Path.Combine("refs", "System.Net.dll"),
Path.Combine("refs", "System.Net.Http.dll"),
Path.Combine("refs", "System.Net.NameResolution.dll"),
Path.Combine("refs", "System.Net.NetworkInformation.dll"),
Path.Combine("refs", "System.Net.Ping.dll"),
Path.Combine("refs", "System.Net.Primitives.dll"),
Path.Combine("refs", "System.Net.Requests.dll"),
Path.Combine("refs", "System.Net.Security.dll"),
Path.Combine("refs", "System.Net.Sockets.dll"),
Path.Combine("refs", "System.Net.WebHeaderCollection.dll"),
Path.Combine("refs", "System.Net.WebSockets.Client.dll"),
Path.Combine("refs", "System.Net.WebSockets.dll"),
Path.Combine("refs", "System.Numerics.dll"),
Path.Combine("refs", "System.ObjectModel.dll"),
Path.Combine("refs", "System.Reflection.dll"),
Path.Combine("refs", "System.Reflection.Extensions.dll"),
Path.Combine("refs", "System.Reflection.Primitives.dll"),
Path.Combine("refs", "System.Resources.Reader.dll"),
Path.Combine("refs", "System.Resources.ResourceManager.dll"),
Path.Combine("refs", "System.Resources.Writer.dll"),
Path.Combine("refs", "System.Runtime.CompilerServices.VisualC.dll"),
Path.Combine("refs", "System.Runtime.dll"),
Path.Combine("refs", "System.Runtime.Extensions.dll"),
Path.Combine("refs", "System.Runtime.Handles.dll"),
Path.Combine("refs", "System.Runtime.InteropServices.dll"),
Path.Combine("refs", "System.Runtime.InteropServices.RuntimeInformation.dll"),
Path.Combine("refs", "System.Runtime.Numerics.dll"),
Path.Combine("refs", "System.Runtime.Serialization.dll"),
Path.Combine("refs", "System.Runtime.Serialization.Formatters.dll"),
Path.Combine("refs", "System.Runtime.Serialization.Json.dll"),
Path.Combine("refs", "System.Runtime.Serialization.Primitives.dll"),
Path.Combine("refs", "System.Runtime.Serialization.Xml.dll"),
Path.Combine("refs", "System.Security.Claims.dll"),
Path.Combine("refs", "System.Security.Cryptography.Algorithms.dll"),
Path.Combine("refs", "System.Security.Cryptography.Csp.dll"),
Path.Combine("refs", "System.Security.Cryptography.Encoding.dll"),
Path.Combine("refs", "System.Security.Cryptography.Primitives.dll"),
Path.Combine("refs", "System.Security.Cryptography.X509Certificates.dll"),
Path.Combine("refs", "System.Security.Principal.dll"),
Path.Combine("refs", "System.Security.SecureString.dll"),
Path.Combine("refs", "System.ServiceModel.Web.dll"),
Path.Combine("refs", "System.Text.Encoding.dll"),
Path.Combine("refs", "System.Text.Encoding.Extensions.dll"),
Path.Combine("refs", "System.Text.RegularExpressions.dll"),
Path.Combine("refs", "System.Threading.dll"),
Path.Combine("refs", "System.Threading.Overlapped.dll"),
Path.Combine("refs", "System.Threading.Tasks.dll"),
Path.Combine("refs", "System.Threading.Tasks.Parallel.dll"),
Path.Combine("refs", "System.Threading.Thread.dll"),
Path.Combine("refs", "System.Threading.ThreadPool.dll"),
Path.Combine("refs", "System.Threading.Timer.dll"),
Path.Combine("refs", "System.Transactions.dll"),
Path.Combine("refs", "System.ValueTuple.dll"),
Path.Combine("refs", "System.Web.dll"),
Path.Combine("refs", "System.Windows.dll"),
Path.Combine("refs", "System.Xml.dll"),
Path.Combine("refs", "System.Xml.Linq.dll"),
Path.Combine("refs", "System.Xml.ReaderWriter.dll"),
Path.Combine("refs", "System.Xml.Serialization.dll"),
Path.Combine("refs", "System.Xml.XDocument.dll"),
Path.Combine("refs", "System.Xml.XmlDocument.dll"),
Path.Combine("refs", "System.Xml.XmlSerializer.dll"),
Path.Combine("refs", "System.Xml.XPath.dll"),
Path.Combine("refs", "System.Xml.XPath.XDocument.dll"),
}.Select(p => Path.Combine(OutputPath, p)));
private IEnumerable<string> _additionalFilesAfterPublishCommon = new[]
{
"Microsoft.AspNetCore.Antiforgery.dll",
"Microsoft.AspNetCore.Authentication.Abstractions.dll",
"Microsoft.AspNetCore.Authentication.Core.dll",
"Microsoft.AspNetCore.Authorization.dll",
"Microsoft.AspNetCore.Authorization.Policy.dll",
"Microsoft.AspNetCore.Cors.dll",
"Microsoft.AspNetCore.Cryptography.Internal.dll",
"Microsoft.AspNetCore.DataProtection.Abstractions.dll",
"Microsoft.AspNetCore.DataProtection.dll",
"Microsoft.AspNetCore.Diagnostics.Abstractions.dll",
"Microsoft.AspNetCore.Hosting.Abstractions.dll",
"Microsoft.AspNetCore.Hosting.Server.Abstractions.dll",
"Microsoft.AspNetCore.Html.Abstractions.dll",
"Microsoft.AspNetCore.Http.Abstractions.dll",
"Microsoft.AspNetCore.Http.dll",
"Microsoft.AspNetCore.Http.Extensions.dll",
"Microsoft.AspNetCore.Http.Features.dll",
"Microsoft.AspNetCore.JsonPatch.dll",
"Microsoft.AspNetCore.Localization.dll",
"Microsoft.AspNetCore.Mvc.Abstractions.dll",
"Microsoft.AspNetCore.Mvc.ApiExplorer.dll",
"Microsoft.AspNetCore.Mvc.Core.dll",
"Microsoft.AspNetCore.Mvc.Cors.dll",
"Microsoft.AspNetCore.Mvc.DataAnnotations.dll",
"Microsoft.AspNetCore.Mvc.dll",
"Microsoft.AspNetCore.Mvc.Formatters.Json.dll",
"Microsoft.AspNetCore.Mvc.Localization.dll",
"Microsoft.AspNetCore.Mvc.Razor.dll",
"Microsoft.AspNetCore.Mvc.Razor.Extensions.dll",
"Microsoft.AspNetCore.Mvc.RazorPages.dll",
"Microsoft.AspNetCore.Mvc.TagHelpers.dll",
"Microsoft.AspNetCore.Mvc.ViewFeatures.dll",
"Microsoft.AspNetCore.Razor.dll",
"Microsoft.AspNetCore.Razor.Language.dll",
"Microsoft.AspNetCore.Razor.Runtime.dll",
"Microsoft.AspNetCore.ResponseCaching.Abstractions.dll",
"Microsoft.AspNetCore.Routing.Abstractions.dll",
"Microsoft.AspNetCore.Routing.dll",
"Microsoft.AspNetCore.WebUtilities.dll",
"Microsoft.CodeAnalysis.CSharp.dll",
"Microsoft.CodeAnalysis.dll",
"Microsoft.CodeAnalysis.Razor.dll",
"Microsoft.CSharp.dll",
"Microsoft.DotNet.PlatformAbstractions.dll",
"Microsoft.Extensions.Caching.Abstractions.dll",
"Microsoft.Extensions.Caching.Memory.dll",
"Microsoft.Extensions.Configuration.Abstractions.dll",
"Microsoft.Extensions.DependencyInjection.Abstractions.dll",
"Microsoft.Extensions.DependencyInjection.dll",
"Microsoft.Extensions.DependencyModel.dll",
"Microsoft.Extensions.FileProviders.Abstractions.dll",
"Microsoft.Extensions.FileProviders.Composite.dll",
"Microsoft.Extensions.FileSystemGlobbing.dll",
"Microsoft.Extensions.Hosting.Abstractions.dll",
"Microsoft.Extensions.Localization.Abstractions.dll",
"Microsoft.Extensions.Localization.dll",
"Microsoft.Extensions.Logging.Abstractions.dll",
"Microsoft.Extensions.ObjectPool.dll",
"Microsoft.Extensions.Options.dll",
"Microsoft.Extensions.Primitives.dll",
"Microsoft.Extensions.WebEncoders.dll",
"Microsoft.Net.Http.Headers.dll",
"Microsoft.Win32.Registry.dll",
"Newtonsoft.Json.Bson.dll",
"Newtonsoft.Json.dll",
"System.AppContext.dll",
"System.Buffers.dll",
"System.Collections.Concurrent.dll",
"System.Collections.Immutable.dll",
"System.ComponentModel.Annotations.dll",
"System.Diagnostics.DiagnosticSource.dll",
"System.Diagnostics.StackTrace.dll",
"System.Dynamic.Runtime.dll",
"System.IO.FileSystem.Primitives.dll",
"System.Linq.dll",
"System.Linq.Expressions.dll",
"System.Memory.dll",
"System.Numerics.Vectors.dll",
"System.ObjectModel.dll",
"System.Reflection.Emit.dll",
"System.Reflection.Emit.ILGeneration.dll",
"System.Reflection.Emit.Lightweight.dll",
"System.Reflection.Metadata.dll",
"System.Reflection.TypeExtensions.dll",
"System.Runtime.CompilerServices.Unsafe.dll",
"System.Runtime.Numerics.dll",
"System.Security.AccessControl.dll",
"System.Security.Cryptography.Cng.dll",
"System.Security.Cryptography.OpenSsl.dll",
"System.Security.Cryptography.Pkcs.dll",
"System.Security.Cryptography.Primitives.dll",
"System.Security.Cryptography.Xml.dll",
"System.Security.Permissions.dll",
"System.Security.Principal.Windows.dll",
"System.Text.Encodings.Web.dll",
"System.Text.RegularExpressions.dll",
"System.Threading.dll",
"System.Threading.Tasks.Extensions.dll",
"System.Threading.Tasks.Parallel.dll",
"System.Threading.Thread.dll",
"System.ValueTuple.dll",
"System.Xml.ReaderWriter.dll",
"System.Xml.XDocument.dll",
"System.Xml.XmlDocument.dll",
"System.Xml.XPath.dll",
"System.Xml.XPath.XDocument.dll",
};
private IEnumerable<string> _additionalFilesAfterPublishSelfContained = new[]
{
"System.Collections.dll",
"System.Console.dll",
"System.Diagnostics.Debug.dll",
"System.Diagnostics.FileVersionInfo.dll",
"System.Diagnostics.Tools.dll",
"System.Diagnostics.Tracing.dll",
"System.Globalization.Calendars.dll",
"System.Globalization.dll",
"System.IO.Compression.dll",
"System.IO.dll",
"System.IO.FileSystem.dll",
"System.Reflection.dll",
"System.Reflection.Extensions.dll",
"System.Reflection.Primitives.dll",
"System.Resources.ResourceManager.dll",
"System.Runtime.dll",
"System.Runtime.Extensions.dll",
"System.Runtime.Handles.dll",
"System.Runtime.InteropServices.dll",
"System.Runtime.InteropServices.RuntimeInformation.dll",
"System.Security.Cryptography.Algorithms.dll",
"System.Security.Cryptography.Csp.dll",
"System.Security.Cryptography.Encoding.dll",
"System.Security.Cryptography.X509Certificates.dll",
"System.Text.Encoding.CodePages.dll",
"System.Text.Encoding.dll",
"System.Text.Encoding.Extensions.dll",
"System.Threading.Tasks.dll",
};
private IDictionary<RuntimeIdentifier, Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<RuntimeIdentifier, Func<IEnumerable<string>>>()
{
{ RuntimeIdentifier.None, () =>
_additionalFilesAfterPublishCommon
.Concat(new[]
{
Path.Combine("runtimes", "debian.8-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "fedora.23-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "fedora.24-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "opensuse.13.2-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "opensuse.42.1-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "osx", "lib", "netstandard1.6", "System.Security.Cryptography.Algorithms.dll"),
Path.Combine("runtimes", "osx.10.10-x64", "native", "System.Security.Cryptography.Native.Apple.dylib"),
Path.Combine("runtimes", "osx.10.10-x64", "native", "System.Security.Cryptography.Native.OpenSsl.dylib"),
Path.Combine("runtimes", "rhel.7-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "ubuntu.14.04-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "ubuntu.16.04-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "ubuntu.16.10-x64", "native", "System.Security.Cryptography.Native.OpenSsl.so"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.1", "System.Runtime.InteropServices.RuntimeInformation.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.3", "System.Diagnostics.FileVersionInfo.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.3", "System.IO.Compression.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.3", "System.Security.Cryptography.Csp.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.3", "System.Security.Cryptography.Encoding.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.3", "System.Text.Encoding.CodePages.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.6", "System.Security.Cryptography.Algorithms.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.6", "System.Security.Cryptography.OpenSsl.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard1.6", "System.Security.Cryptography.X509Certificates.dll"),
Path.Combine("runtimes", "unix", "lib", "netstandard2.0", "Microsoft.Win32.Registry.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.1", "System.Runtime.InteropServices.RuntimeInformation.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Diagnostics.FileVersionInfo.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.IO.Compression.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Security.AccessControl.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Security.Cryptography.Csp.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Security.Cryptography.Encoding.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Security.Principal.Windows.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.3", "System.Text.Encoding.CodePages.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.6", "System.Security.Cryptography.Algorithms.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.6", "System.Security.Cryptography.Cng.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard1.6", "System.Security.Cryptography.X509Certificates.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard2.0", "Microsoft.Win32.Registry.dll"),
Path.Combine("runtimes", "win", "lib", "netstandard2.0", "System.Security.Cryptography.Pkcs.dll"),
})
},
{ RuntimeIdentifier.Win_x64, () =>
_additionalFilesAfterPublishCommon
.Concat(_additionalFilesAfterPublishSelfContained)
.Concat(new[]
{
"System.Threading.Overlapped.dll",
})
},
{ RuntimeIdentifier.Linux_x64, () =>
_additionalFilesAfterPublishCommon
.Concat(_additionalFilesAfterPublishSelfContained)
.Concat(new[]
{
"System.Private.Uri.dll",
})
},
{ RuntimeIdentifier.OSX_x64, () => _additionalFilesAfterPublish[RuntimeIdentifier.Linux_x64]() },
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(RazorUtil.GetExpectedFilesAfterPublish(this))
.Concat(_additionalFilesAfterPublish[RuntimeIdentifier]());
}
}

View File

@ -0,0 +1,49 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class RazorTemplate : RazorBootstrapJQueryTemplate
{
public RazorTemplate() { }
public override string Name => "razor";
protected override string RazorPath => "Pages";
private IDictionary<string, Func<IEnumerable<string>>> _additionalObjFilesAfterBuild =>
new Dictionary<string, Func<IEnumerable<string>>>()
{
{ "common", () => new[]
{
Path.Combine("Razor", RazorPath, "_ViewStart.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Error.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Index.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Privacy.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_CookieConsentPartial.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_Layout.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Shared", "_ValidationScriptsPartial.g.cshtml.cs"),
}
},
{ "netcoreapp2.1", () =>
_additionalObjFilesAfterBuild["common"]()
.Concat(new[]
{
Path.Combine("Razor", RazorPath, "About.g.cshtml.cs"),
Path.Combine("Razor", RazorPath, "Contact.g.cshtml.cs"),
})
},
{ "netcoreapp2.2", () => _additionalObjFilesAfterBuild["common"]() },
};
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(_additionalObjFilesAfterBuild[DotNetUtil.TargetFrameworkMoniker]().Select(p => Path.Combine(OutputPath, p)));
}
}

View File

@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Cli.FunctionalTests.Templates
{
public static class RazorUtil
{
public static IEnumerable<string> GetExpectedObjFilesAfterBuild(Template template) => new[]
{
// Added between 2.1.300-rc1 and 2.1.300-rtm (https://github.com/aspnet/Razor/pull/2316)
$"{template.Name}.csproj.CopyComplete",
$"{template.Name}.RazorAssemblyInfo.cache",
$"{template.Name}.RazorAssemblyInfo.cs",
$"{template.Name}.RazorCoreGenerate.cache",
$"{template.Name}.RazorTargetAssemblyInfo.cache",
$"{template.Name}.RazorTargetAssemblyInfo.cs",
$"{template.Name}.TagHelpers.input.cache",
$"{template.Name}.TagHelpers.output.cache",
$"{template.Name}.Views.dll",
$"{template.Name}.Views.pdb",
}.Select(p => Path.Combine(template.OutputPath, p));
public static IEnumerable<string> GetExpectedBinFilesAfterBuild(Template template) => new[]
{
$"{template.Name}.Views.dll",
$"{template.Name}.Views.pdb",
}.Select(p => Path.Combine(template.OutputPath, p));
public static IEnumerable<string> GetExpectedFilesAfterPublish(Template template) => new[]
{
$"{template.Name}.Views.dll",
$"{template.Name}.Views.pdb",
};
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Cli.FunctionalTests.Templates
{
public class ReactReduxTemplate : ReactTemplate
{
public ReactReduxTemplate() { }
public override string Name => "reactredux";
}
}

View File

@ -0,0 +1,60 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class ReactTemplate : SpaBaseTemplate
{
public ReactTemplate() { }
public override string Name => "react";
protected override IEnumerable<string> NormalizeFilesAfterPublish(IEnumerable<string> filesAfterPublish)
{
// Remove generated hashes since they may vary by platform
return base.NormalizeFilesAfterPublish(filesAfterPublish)
.Select(f => Regex.Replace(f, @"\.[0-9a-f]{8}\.", ".[HASH]."));
}
private IDictionary<string, Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<string, Func<IEnumerable<string>>>()
{
{ "common", () => new[]
{
Path.Combine("ClientApp", "build", "asset-manifest.json"),
Path.Combine("ClientApp", "build", "favicon.ico"),
Path.Combine("ClientApp", "build", "index.html"),
Path.Combine("ClientApp", "build", "manifest.json"),
Path.Combine("ClientApp", "build", "service-worker.js"),
Path.Combine("ClientApp", "build", "static", "css", "main.[HASH].css"),
Path.Combine("ClientApp", "build", "static", "css", "main.[HASH].css.map"),
Path.Combine("ClientApp", "build", "static", "js", "main.[HASH].js"),
Path.Combine("ClientApp", "build", "static", "js", "main.[HASH].js.map"),
}
},
{ "netcoreapp2.1", () =>
_additionalFilesAfterPublish["common"]()
.Concat(new[]
{
Path.Combine("ClientApp", "build", "static", "media", "glyphicons-halflings-regular.[HASH].woff2"),
Path.Combine("ClientApp", "build", "static", "media", "glyphicons-halflings-regular.[HASH].svg"),
Path.Combine("ClientApp", "build", "static", "media", "glyphicons-halflings-regular.[HASH].ttf"),
Path.Combine("ClientApp", "build", "static", "media", "glyphicons-halflings-regular.[HASH].eot"),
Path.Combine("ClientApp", "build", "static", "media", "glyphicons-halflings-regular.[HASH].woff"),
})
},
{ "netcoreapp2.2", () => _additionalFilesAfterPublish["common"]() },
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(_additionalFilesAfterPublish[DotNetUtil.TargetFrameworkMoniker]());
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Cli.FunctionalTests.Templates
{
public abstract class SpaBaseTemplate : RazorApplicationBaseTemplate
{
protected override string RazorPath => "Pages";
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(new[]
{
Path.Combine("Razor", RazorPath, "Error.g.cshtml.cs"),
}.Select(p => Path.Combine(OutputPath, p)));
}
}

View File

@ -0,0 +1,248 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public abstract class Template
{
private static readonly TimeSpan _sleepBetweenOutputContains = TimeSpan.FromMilliseconds(100);
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler()
{
// Allow self-signed certs
ServerCertificateCustomValidationCallback = (m, c, ch, p) => true
})
{
// Prevent failures due to slow requests when running many tests in parallel
Timeout = Timeout.InfiniteTimeSpan,
};
private static ConcurrentDictionary<(Type Type, NuGetPackageSource NuGetPackageSource, RuntimeIdentifier RuntimeIdentifier), Template> _templates =
new ConcurrentDictionary<(Type Type, NuGetPackageSource NuGetPackageSource, RuntimeIdentifier RuntimeIdentifier), Template>();
public static T GetInstance<T>(NuGetPackageSource nuGetPackageSource, RuntimeIdentifier runtimeIdentifier) where T : Template, new()
{
return (T)_templates.GetOrAdd((typeof(T), nuGetPackageSource, runtimeIdentifier),
(k) => new T() { NuGetPackageSource = nuGetPackageSource, RuntimeIdentifier = runtimeIdentifier });
}
private Lazy<IEnumerable<string>> _objFilesAfterRestore;
private Lazy<IEnumerable<string>> _objFilesAfterRestoreIncremental;
private Lazy<(IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles)> _filesAfterBuild;
private Lazy<(IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles)> _filesAfterBuildIncremental;
private Lazy<IEnumerable<string>> _filesAfterPublish;
private Lazy<IEnumerable<string>> _filesAfterPublishIncremental;
private Lazy<(HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError )> _httpResponsesAfterRun;
private Lazy<(HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError)> _httpResponsesAfterExec;
public NuGetPackageSource NuGetPackageSource { get; private set; }
public RuntimeIdentifier RuntimeIdentifier { get; private set; }
protected Template()
{
_objFilesAfterRestore = new Lazy<IEnumerable<string>>(
GetObjFilesAfterRestore, LazyThreadSafetyMode.ExecutionAndPublication);
_objFilesAfterRestoreIncremental = new Lazy<IEnumerable<string>>(
GetObjFilesAfterRestoreIncremental, LazyThreadSafetyMode.ExecutionAndPublication);
_filesAfterBuild = new Lazy<(IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles)>(
GetFilesAfterBuild, LazyThreadSafetyMode.ExecutionAndPublication);
_filesAfterBuildIncremental = new Lazy<(IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles)>(
GetFilesAfterBuildIncremental, LazyThreadSafetyMode.ExecutionAndPublication);
_filesAfterPublish = new Lazy<IEnumerable<string>>(
GetFilesAfterPublish, LazyThreadSafetyMode.ExecutionAndPublication);
_filesAfterPublishIncremental = new Lazy<IEnumerable<string>>(
GetFilesAfterPublishIncremental, LazyThreadSafetyMode.ExecutionAndPublication);
_httpResponsesAfterRun = new Lazy<(HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError)>(
GetHttpResponsesAfterRun, LazyThreadSafetyMode.ExecutionAndPublication);
_httpResponsesAfterExec = new Lazy<(HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError)>(
GetHttpResponsesAfterExec, LazyThreadSafetyMode.ExecutionAndPublication);
}
public override string ToString() => $"{Name}, source: {NuGetPackageSource}, rid: {RuntimeIdentifier}, sdk: {DotNetUtil.SdkVersion}, runtime: {DotNetUtil.RuntimeVersion}";
private string TempDir => Path.Combine(AssemblySetUp.TempDir, Name, NuGetPackageSource.Name, RuntimeIdentifier.Name );
public abstract string Name { get; }
public abstract string OutputPath { get; }
public abstract TemplateType Type { get; }
public virtual string RelativeUrl => string.Empty;
public IEnumerable<string> ObjFilesAfterRestore => _objFilesAfterRestore.Value;
public IEnumerable<string> ObjFilesAfterRestoreIncremental => _objFilesAfterRestoreIncremental.Value;
public IEnumerable<string> ObjFilesAfterBuild => _filesAfterBuild.Value.ObjFiles;
public IEnumerable<string> BinFilesAfterBuild => _filesAfterBuild.Value.BinFiles;
public IEnumerable<string> ObjFilesAfterBuildIncremental => _filesAfterBuildIncremental.Value.ObjFiles;
public IEnumerable<string> BinFilesAfterBuildIncremental => _filesAfterBuildIncremental.Value.BinFiles;
public IEnumerable<string> FilesAfterPublish => NormalizeFilesAfterPublish(_filesAfterPublish.Value);
public IEnumerable<string> FilesAfterPublishIncremental => NormalizeFilesAfterPublish(_filesAfterPublishIncremental.Value);
public HttpResponseMessage HttpResponseAfterRun => _httpResponsesAfterRun.Value.Http;
public HttpResponseMessage HttpsResponseAfterRun => _httpResponsesAfterRun.Value.Https;
public string ServerOutputAfterRun => _httpResponsesAfterRun.Value.ServerOutput;
public string ServerErrorAfterRun => _httpResponsesAfterRun.Value.ServerError;
public HttpResponseMessage HttpResponseAfterExec => _httpResponsesAfterExec.Value.Http;
public HttpResponseMessage HttpsResponseAfterExec => _httpResponsesAfterExec.Value.Https;
public string ServerOutputAfterExec => _httpResponsesAfterExec.Value.ServerOutput;
public string ServerErrorAfterExec => _httpResponsesAfterExec.Value.ServerError;
public virtual IEnumerable<string> ExpectedObjFilesAfterRestore => new[]
{
$"{Name}.csproj.nuget.cache",
$"{Name}.csproj.nuget.g.props",
$"{Name}.csproj.nuget.g.targets",
"project.assets.json",
};
public virtual IEnumerable<string> ExpectedObjFilesAfterBuild => ExpectedObjFilesAfterRestore;
public abstract IEnumerable<string> ExpectedBinFilesAfterBuild { get; }
public abstract IEnumerable<string> ExpectedFilesAfterPublish { get; }
// Hook for subclasses to modify template immediately after "dotnet new". Typically used
// for temporary workarounds (e.g. changing TFM in csproj).
protected virtual void AfterNew(string tempDir) { }
// Hook for subclasses to normalize files after publish (e.g. replacing hash codes)
protected virtual IEnumerable<string> NormalizeFilesAfterPublish(IEnumerable<string> filesAfterPublish)
{
return filesAfterPublish;
}
private IEnumerable<string> GetObjFilesAfterRestore()
{
Directory.CreateDirectory(TempDir);
DotNetUtil.New(Name, TempDir);
AfterNew(TempDir);
DotNetUtil.Restore(TempDir, NuGetPackageSource, RuntimeIdentifier);
return IOUtil.GetFiles(Path.Combine(TempDir, "obj"));
}
private IEnumerable<string> GetObjFilesAfterRestoreIncremental()
{
// RestoreIncremental depends on Restore
_ = ObjFilesAfterRestore;
DotNetUtil.Restore(TempDir, NuGetPackageSource, RuntimeIdentifier);
return IOUtil.GetFiles(Path.Combine(TempDir, "obj"));
}
private (IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles) GetFilesAfterBuild()
{
// Build depends on RestoreIncremental
_ = ObjFilesAfterRestoreIncremental;
DotNetUtil.Build(TempDir, NuGetPackageSource, RuntimeIdentifier);
return (IOUtil.GetFiles(Path.Combine(TempDir, "obj")), IOUtil.GetFiles(Path.Combine(TempDir, "bin")));
}
private (IEnumerable<string> ObjFiles, IEnumerable<string> BinFiles) GetFilesAfterBuildIncremental()
{
// BuildIncremental depends on Build
_ = ObjFilesAfterBuild;
DotNetUtil.Build(TempDir, NuGetPackageSource, RuntimeIdentifier);
return (IOUtil.GetFiles(Path.Combine(TempDir, "obj")), IOUtil.GetFiles(Path.Combine(TempDir, "bin")));
}
private IEnumerable<string> GetFilesAfterPublish()
{
// Publish depends on BuildIncremental
_ = BinFilesAfterBuildIncremental;
DotNetUtil.Publish(TempDir, RuntimeIdentifier);
return IOUtil.GetFiles(Path.Combine(TempDir, DotNetUtil.PublishOutput));
}
private IEnumerable<string> GetFilesAfterPublishIncremental()
{
// PublishIncremental depends on Publish
_ = FilesAfterPublish;
DotNetUtil.Publish(TempDir, RuntimeIdentifier);
return IOUtil.GetFiles(Path.Combine(TempDir, DotNetUtil.PublishOutput));
}
private (HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError) GetHttpResponsesAfterRun()
{
// Run depends on BuildIncremental
_ = BinFilesAfterBuildIncremental;
return GetHttpResponses(DotNetUtil.Run(TempDir, RuntimeIdentifier));
}
private (HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError) GetHttpResponsesAfterExec()
{
// Exec depends on PublishIncremental
_ = FilesAfterPublishIncremental;
return GetHttpResponses(DotNetUtil.Exec(TempDir, Name, RuntimeIdentifier));
}
private (HttpResponseMessage Http, HttpResponseMessage Https, string ServerOutput, string ServerError) GetHttpResponses(
(Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) process)
{
try
{
var (httpUrl, httpsUrl) = ScrapeUrls(process);
return (
Get(new Uri(new Uri(httpUrl), RelativeUrl)),
Get(new Uri(new Uri(httpsUrl), RelativeUrl)),
process.OutputBuilder.ToString(),
process.ErrorBuilder.ToString()
);
}
finally
{
DotNetUtil.StopProcess(process, throwOnError: false);
}
}
private (string HttpUrl, string HttpsUrl) ScrapeUrls(
(Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) process)
{
// Extract URLs from output
while (true)
{
var output = process.OutputBuilder.ToString();
if (output.Contains("Application started"))
{
var httpUrl = Regex.Match(output, @"Now listening on: (http:\S*)").Groups[1].Value;
var httpsUrl = Regex.Match(output, @"Now listening on: (https:\S*)").Groups[1].Value;
return (httpUrl, httpsUrl);
}
else if (process.Process.HasExited)
{
var startInfo = process.Process.StartInfo;
throw new InvalidOperationException(
$"Failed to start process '{startInfo.FileName} {startInfo.Arguments}'" + Environment.NewLine + output);
}
else
{
Thread.Sleep(_sleepBetweenOutputContains);
}
}
}
private HttpResponseMessage Get(Uri requestUri)
{
return _httpClient.GetAsync(requestUri).Result;
}
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Cli.FunctionalTests.Templates
{
public enum TemplateType
{
ClassLibrary,
ConsoleApplication,
WebApplication,
}
}

View File

@ -0,0 +1,25 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
namespace Cli.FunctionalTests.Templates
{
public class WebApiTemplate : WebTemplate
{
public WebApiTemplate() { }
public override string Name => "webapi";
public override string RelativeUrl => "/api/values";
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(new[]
{
"appsettings.Development.json",
"appsettings.json",
});
}
}

View File

@ -0,0 +1,251 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cli.FunctionalTests.Util;
namespace Cli.FunctionalTests.Templates
{
public class WebTemplate : ConsoleApplicationTemplate
{
public WebTemplate() { }
public override string Name => "web";
public override TemplateType Type => TemplateType.WebApplication;
public override IEnumerable<string> ExpectedObjFilesAfterBuild =>
base.ExpectedObjFilesAfterBuild
.Concat(new[]
{
$"{Name}.RazorAssemblyInfo.cache",
$"{Name}.RazorAssemblyInfo.cs",
$"{Name}.RazorTargetAssemblyInfo.cache",
}.Select(p => Path.Combine(OutputPath, p)));
private IDictionary<(string TargetFrameworkMoniker, RuntimeIdentifier), Func<IEnumerable<string>>> _additionalFilesAfterPublish =>
new Dictionary<(string TargetFrameworkMoniker, RuntimeIdentifier), Func<IEnumerable<string>>>()
{
{ ("netcoreapp2.1", RuntimeIdentifier.None), () => new[]
{
// Publish includes all *.config and *.json files (https://github.com/aspnet/websdk/issues/334)
"NuGet.config",
"web.config",
}
},
{ ("netcoreapp2.1", RuntimeIdentifier.Linux_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.1", RuntimeIdentifier.None)]()
.Concat(new[]
{
"Microsoft.AspNetCore.Antiforgery.dll",
"Microsoft.AspNetCore.Authentication.Abstractions.dll",
"Microsoft.AspNetCore.Authentication.Cookies.dll",
"Microsoft.AspNetCore.Authentication.Core.dll",
"Microsoft.AspNetCore.Authentication.dll",
"Microsoft.AspNetCore.Authentication.Facebook.dll",
"Microsoft.AspNetCore.Authentication.Google.dll",
"Microsoft.AspNetCore.Authentication.JwtBearer.dll",
"Microsoft.AspNetCore.Authentication.MicrosoftAccount.dll",
"Microsoft.AspNetCore.Authentication.OAuth.dll",
"Microsoft.AspNetCore.Authentication.OpenIdConnect.dll",
"Microsoft.AspNetCore.Authentication.Twitter.dll",
"Microsoft.AspNetCore.Authentication.WsFederation.dll",
"Microsoft.AspNetCore.Authorization.dll",
"Microsoft.AspNetCore.Authorization.Policy.dll",
"Microsoft.AspNetCore.Connections.Abstractions.dll",
"Microsoft.AspNetCore.CookiePolicy.dll",
"Microsoft.AspNetCore.Cors.dll",
"Microsoft.AspNetCore.Cryptography.Internal.dll",
"Microsoft.AspNetCore.Cryptography.KeyDerivation.dll",
"Microsoft.AspNetCore.DataProtection.Abstractions.dll",
"Microsoft.AspNetCore.DataProtection.dll",
"Microsoft.AspNetCore.DataProtection.Extensions.dll",
"Microsoft.AspNetCore.Diagnostics.Abstractions.dll",
"Microsoft.AspNetCore.Diagnostics.dll",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.dll",
"Microsoft.AspNetCore.dll",
"Microsoft.AspNetCore.HostFiltering.dll",
"Microsoft.AspNetCore.Hosting.Abstractions.dll",
"Microsoft.AspNetCore.Hosting.dll",
"Microsoft.AspNetCore.Hosting.Server.Abstractions.dll",
"Microsoft.AspNetCore.Html.Abstractions.dll",
"Microsoft.AspNetCore.Http.Abstractions.dll",
"Microsoft.AspNetCore.Http.Connections.Common.dll",
"Microsoft.AspNetCore.Http.Connections.dll",
"Microsoft.AspNetCore.Http.dll",
"Microsoft.AspNetCore.Http.Extensions.dll",
"Microsoft.AspNetCore.Http.Features.dll",
"Microsoft.AspNetCore.HttpOverrides.dll",
"Microsoft.AspNetCore.HttpsPolicy.dll",
"Microsoft.AspNetCore.Identity.dll",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll",
"Microsoft.AspNetCore.Identity.UI.dll",
"Microsoft.AspNetCore.Identity.UI.Views.dll",
"Microsoft.AspNetCore.JsonPatch.dll",
"Microsoft.AspNetCore.Localization.dll",
"Microsoft.AspNetCore.Localization.Routing.dll",
"Microsoft.AspNetCore.MiddlewareAnalysis.dll",
"Microsoft.AspNetCore.Mvc.Abstractions.dll",
"Microsoft.AspNetCore.Mvc.ApiExplorer.dll",
"Microsoft.AspNetCore.Mvc.Core.dll",
"Microsoft.AspNetCore.Mvc.Cors.dll",
"Microsoft.AspNetCore.Mvc.DataAnnotations.dll",
"Microsoft.AspNetCore.Mvc.dll",
"Microsoft.AspNetCore.Mvc.Formatters.Json.dll",
"Microsoft.AspNetCore.Mvc.Formatters.Xml.dll",
"Microsoft.AspNetCore.Mvc.Localization.dll",
"Microsoft.AspNetCore.Mvc.Razor.dll",
"Microsoft.AspNetCore.Mvc.Razor.Extensions.dll",
"Microsoft.AspNetCore.Mvc.RazorPages.dll",
"Microsoft.AspNetCore.Mvc.TagHelpers.dll",
"Microsoft.AspNetCore.Mvc.ViewFeatures.dll",
"Microsoft.AspNetCore.NodeServices.dll",
"Microsoft.AspNetCore.Owin.dll",
"Microsoft.AspNetCore.Razor.dll",
"Microsoft.AspNetCore.Razor.Language.dll",
"Microsoft.AspNetCore.Razor.Runtime.dll",
"Microsoft.AspNetCore.ResponseCaching.Abstractions.dll",
"Microsoft.AspNetCore.ResponseCaching.dll",
"Microsoft.AspNetCore.ResponseCompression.dll",
"Microsoft.AspNetCore.Rewrite.dll",
"Microsoft.AspNetCore.Routing.Abstractions.dll",
"Microsoft.AspNetCore.Routing.dll",
"Microsoft.AspNetCore.Server.HttpSys.dll",
"Microsoft.AspNetCore.Server.IISIntegration.dll",
"Microsoft.AspNetCore.Server.Kestrel.Core.dll",
"Microsoft.AspNetCore.Server.Kestrel.dll",
"Microsoft.AspNetCore.Server.Kestrel.Https.dll",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll",
"Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll",
"Microsoft.AspNetCore.Session.dll",
"Microsoft.AspNetCore.SignalR.Common.dll",
"Microsoft.AspNetCore.SignalR.Core.dll",
"Microsoft.AspNetCore.SignalR.dll",
"Microsoft.AspNetCore.SignalR.Protocols.Json.dll",
"Microsoft.AspNetCore.SpaServices.dll",
"Microsoft.AspNetCore.SpaServices.Extensions.dll",
"Microsoft.AspNetCore.StaticFiles.dll",
"Microsoft.AspNetCore.WebSockets.dll",
"Microsoft.AspNetCore.WebUtilities.dll",
"Microsoft.CodeAnalysis.CSharp.dll",
"Microsoft.CodeAnalysis.dll",
"Microsoft.CodeAnalysis.Razor.dll",
"Microsoft.DotNet.PlatformAbstractions.dll",
"Microsoft.EntityFrameworkCore.Abstractions.dll",
"Microsoft.EntityFrameworkCore.Design.dll",
"Microsoft.EntityFrameworkCore.dll",
"Microsoft.EntityFrameworkCore.InMemory.dll",
"Microsoft.EntityFrameworkCore.Relational.dll",
"Microsoft.EntityFrameworkCore.SqlServer.dll",
"Microsoft.Extensions.Caching.Abstractions.dll",
"Microsoft.Extensions.Caching.Memory.dll",
"Microsoft.Extensions.Caching.SqlServer.dll",
"Microsoft.Extensions.Configuration.Abstractions.dll",
"Microsoft.Extensions.Configuration.Binder.dll",
"Microsoft.Extensions.Configuration.CommandLine.dll",
"Microsoft.Extensions.Configuration.dll",
"Microsoft.Extensions.Configuration.EnvironmentVariables.dll",
"Microsoft.Extensions.Configuration.FileExtensions.dll",
"Microsoft.Extensions.Configuration.Ini.dll",
"Microsoft.Extensions.Configuration.Json.dll",
"Microsoft.Extensions.Configuration.KeyPerFile.dll",
"Microsoft.Extensions.Configuration.UserSecrets.dll",
"Microsoft.Extensions.Configuration.Xml.dll",
"Microsoft.Extensions.DependencyInjection.Abstractions.dll",
"Microsoft.Extensions.DependencyInjection.dll",
"Microsoft.Extensions.DependencyModel.dll",
"Microsoft.Extensions.DiagnosticAdapter.dll",
"Microsoft.Extensions.FileProviders.Abstractions.dll",
"Microsoft.Extensions.FileProviders.Composite.dll",
"Microsoft.Extensions.FileProviders.Embedded.dll",
"Microsoft.Extensions.FileProviders.Physical.dll",
"Microsoft.Extensions.FileSystemGlobbing.dll",
"Microsoft.Extensions.Hosting.Abstractions.dll",
"Microsoft.Extensions.Hosting.dll",
"Microsoft.Extensions.Http.dll",
"Microsoft.Extensions.Identity.Core.dll",
"Microsoft.Extensions.Identity.Stores.dll",
"Microsoft.Extensions.Localization.Abstractions.dll",
"Microsoft.Extensions.Localization.dll",
"Microsoft.Extensions.Logging.Abstractions.dll",
"Microsoft.Extensions.Logging.Configuration.dll",
"Microsoft.Extensions.Logging.Console.dll",
"Microsoft.Extensions.Logging.Debug.dll",
"Microsoft.Extensions.Logging.dll",
"Microsoft.Extensions.Logging.EventSource.dll",
"Microsoft.Extensions.Logging.TraceSource.dll",
"Microsoft.Extensions.ObjectPool.dll",
"Microsoft.Extensions.Options.ConfigurationExtensions.dll",
"Microsoft.Extensions.Options.dll",
"Microsoft.Extensions.Primitives.dll",
"Microsoft.Extensions.WebEncoders.dll",
"Microsoft.IdentityModel.Logging.dll",
"Microsoft.IdentityModel.Protocols.dll",
"Microsoft.IdentityModel.Protocols.OpenIdConnect.dll",
"Microsoft.IdentityModel.Protocols.WsFederation.dll",
"Microsoft.IdentityModel.Tokens.dll",
"Microsoft.IdentityModel.Tokens.Saml.dll",
"Microsoft.IdentityModel.Xml.dll",
"Microsoft.Net.Http.Headers.dll",
"Newtonsoft.Json.Bson.dll",
"Newtonsoft.Json.dll",
"Remotion.Linq.dll",
"System.Data.SqlClient.dll",
"System.IdentityModel.Tokens.Jwt.dll",
"System.Interactive.Async.dll",
"System.IO.Pipelines.dll",
"System.Net.Http.Formatting.dll",
"System.Net.WebSockets.WebSocketProtocol.dll",
"System.Runtime.CompilerServices.Unsafe.dll",
"System.Security.Cryptography.Pkcs.dll",
"System.Security.Cryptography.Xml.dll",
"System.Security.Permissions.dll",
"System.Text.Encoding.CodePages.dll",
"System.Text.Encodings.Web.dll",
"System.Threading.Channels.dll",
})
},
{ ("netcoreapp2.1", RuntimeIdentifier.OSX_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.1", RuntimeIdentifier.Linux_x64)]()
},
{ ("netcoreapp2.1", RuntimeIdentifier.Win_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.1", RuntimeIdentifier.Linux_x64)]()
.Concat(new[]
{
"sni.dll",
})
},
{ ("netcoreapp2.2", RuntimeIdentifier.None), () =>
_additionalFilesAfterPublish[("netcoreapp2.1", RuntimeIdentifier.None)]()
},
{ ("netcoreapp2.2", RuntimeIdentifier.Linux_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.1", RuntimeIdentifier.Linux_x64)]()
.Concat(new[]
{
"Microsoft.AspNetCore.Diagnostics.HealthChecks.dll",
"Microsoft.AspNetCore.Server.IIS.dll",
"Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions.dll",
"Microsoft.Extensions.Diagnostics.HealthChecks.dll",
})
},
{ ("netcoreapp2.2", RuntimeIdentifier.OSX_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.2", RuntimeIdentifier.Linux_x64)]()
},
{ ("netcoreapp2.2", RuntimeIdentifier.Win_x64), () =>
_additionalFilesAfterPublish[("netcoreapp2.2", RuntimeIdentifier.Linux_x64)]()
.Concat(new[]
{
"aspnetcorev2_inprocess.dll",
"sni.dll",
})
},
};
public override IEnumerable<string> ExpectedFilesAfterPublish =>
base.ExpectedFilesAfterPublish
.Concat(_additionalFilesAfterPublish[(DotNetUtil.TargetFrameworkMoniker, RuntimeIdentifier)]());
}
}

View File

@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text;
namespace Cli.FunctionalTests.Util
{
public class ConcurrentStringBuilder
{
private StringBuilder _stringBuilder = new StringBuilder();
private object _lock = new object();
public void AppendLine()
{
lock (_lock)
{
_stringBuilder.AppendLine();
}
}
public void AppendLine(string data)
{
lock (_lock)
{
_stringBuilder.AppendLine(data);
}
}
public override string ToString()
{
lock (_lock)
{
return _stringBuilder.ToString();
}
}
}
}

View File

@ -0,0 +1,243 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.Extensions.Internal;
using Newtonsoft.Json;
using NuGet.Versioning;
namespace Cli.FunctionalTests.Util
{
internal static class DotNetUtil
{
private const string _clearPackageSourcesNuGetConfig =
@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<packageSources>
<clear />
</packageSources>
</configuration>
";
// Bind to dynamic port 0 to avoid port conflicts during parallel tests
private const string _urls = "--urls http://127.0.0.1:0;https://127.0.0.1:0";
// Must publish to folder under "bin" or "obj" to prevent double-copying publish output during incremental publish
public static string PublishOutput => Path.Combine("bin", "pub");
private static readonly Lazy<(SemanticVersion SdkVersion, SemanticVersion RuntimeVersion)> _versions =
new Lazy<(SemanticVersion SdkVersion, SemanticVersion RuntimeVersion)>(GetVersions, LazyThreadSafetyMode.PublicationOnly);
public static SemanticVersion SdkVersion => _versions.Value.SdkVersion;
public static SemanticVersion RuntimeVersion => _versions.Value.RuntimeVersion;
private static readonly Lazy<bool> _requiresPrivateFeed = new Lazy<bool>(GetRequiresPrivateFeed, LazyThreadSafetyMode.PublicationOnly);
public static bool RequiresPrivateFeed => _requiresPrivateFeed.Value;
public static string TargetFrameworkMoniker => $"netcoreapp{RuntimeVersion.Major}.{RuntimeVersion.Minor}";
private static readonly HttpClient _httpClient = new HttpClient();
private static readonly IEnumerable<KeyValuePair<string, string>> _globalEnvironment = new KeyValuePair<string, string>[] {
// Ignore globally-installed .NET Core components
new KeyValuePair<string, string>("DOTNET_MULTILEVEL_LOOKUP", "false"),
};
private static (SemanticVersion SdkVersion, SemanticVersion RuntimeVersion) GetVersions()
{
var info = RunDotNet("--info", workingDirectory: null);
var sdkVersionString = Regex.Match(info, @"Version:\s*(\S+)").Groups[1].Value;
var sdkVersion = SemanticVersion.Parse(sdkVersionString);
// Select highest version of Microsoft.NETCore.App which matches major and minor version of SDK
var runtimeVersionPattern = $@"Microsoft.NETCore.App\s*({sdkVersion.Major}.{sdkVersion.Minor}\S+)";
var runtimeVersionString = Regex.Match(info, runtimeVersionPattern, RegexOptions.RightToLeft).Groups[1].Value;
var runtimeVersion = SemanticVersion.Parse(runtimeVersionString);
// Supported version range is [2.1.300,2.2.100] (inclusive)
if (sdkVersion >= new SemanticVersion(2, 1, 300) && sdkVersion <= new SemanticVersion(2, 2, 100))
{
return (sdkVersion, runtimeVersion);
}
else
{
throw new InvalidOperationException($"Unsupported SDK version: {sdkVersion}");
}
}
// Private feed is required if nuget.org doesn't contain the matching version of Microsoft.NETCore.App
private static bool GetRequiresPrivateFeed()
{
var versionString = _httpClient.GetStringAsync("https://api.nuget.org/v3-flatcontainer/microsoft.netcore.app/index.json").Result;
var definition = new { Versions = Enumerable.Empty<string>() };
var versions = JsonConvert.DeserializeAnonymousType(versionString, definition);
return !versions.Versions.Contains(RuntimeVersion.ToString());
}
private static IEnumerable<KeyValuePair<string, string>> GetEnvironment(NuGetPackageSource nuGetPackageSource)
{
// Set NUGET_PACKAGES to an initially-empty, distinct folder for each NuGetPackageSource. This ensures packages are loaded
// from either NuGetFallbackFolder or configured sources, and *not* loaded from the default per-user global-packages folder.
//
// [5/7/2018] NUGET_PACKAGES cannot be set to a folder under the application due to https://github.com/dotnet/cli/issues/9216.
yield return new KeyValuePair<string, string>("NUGET_PACKAGES", Path.Combine(AssemblySetUp.TempDir, nuGetPackageSource.Name));
}
public static string New(string template, string workingDirectory)
{
// Clear all packages sources by default. May be overridden by NuGetPackageSource parameter.
File.WriteAllText(Path.Combine(workingDirectory, "NuGet.config"), _clearPackageSourcesNuGetConfig);
// Pass "--debug:ephemeral-hive" to build template contents in-memory, rather than using the default
// "%UserProfile%\.templateengine" cache, which may be out-of-date when testing newer builds with the same version.
return RunDotNet($"new {template} --name {template} --output . --no-restore --debug:ephemeral-hive", workingDirectory);
}
public static string Restore(string workingDirectory, NuGetPackageSource packageSource, RuntimeIdentifier runtimeIdentifier)
{
return RunDotNet($"restore /warnaserror --no-cache {packageSource.SourceArgument} {runtimeIdentifier.RuntimeArgument}",
workingDirectory, GetEnvironment(packageSource));
}
public static string Build(string workingDirectory, NuGetPackageSource packageSource, RuntimeIdentifier runtimeIdentifier)
{
// "dotnet build" cannot use "--no-restore" if the app is self-contained and the SDK contains a patched runtime
// https://github.com/dotnet/sdk/issues/2312, https://github.com/dotnet/cli/issues/9514
bool restoreRequired = (runtimeIdentifier != RuntimeIdentifier.None) && (DotNetUtil.RuntimeVersion.Patch > 0);
var restoreArgument = restoreRequired ? $"--no-cache {packageSource.SourceArgument}" : "--no-restore";
return RunDotNet($"build /warnaserror {restoreArgument} {runtimeIdentifier.RuntimeArgument}", workingDirectory, GetEnvironment(packageSource));
}
public static (Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) Run(
string workingDirectory, RuntimeIdentifier runtimeIdentifier)
{
return StartDotNet($"run --no-build {_urls} {runtimeIdentifier.RuntimeArgument}", workingDirectory);
}
public static string Publish(string workingDirectory, RuntimeIdentifier runtimeIdentifier)
{
return RunDotNet($"publish --no-build -o {PublishOutput} {runtimeIdentifier.RuntimeArgument}", workingDirectory);
}
internal static (Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) Exec(
string workingDirectory, string name, RuntimeIdentifier runtimeIdentifier)
{
if (runtimeIdentifier == RuntimeIdentifier.None)
{
var path = Path.Combine(PublishOutput, $"{name}.dll");
return StartDotNet($"exec {path} {_urls}", workingDirectory);
}
else
{
var file = (runtimeIdentifier == RuntimeIdentifier.Win_x64) ? $"{name}.exe" : name;
var path = Path.Combine(workingDirectory, PublishOutput, file);
return StartProcess(path, _urls, workingDirectory);
}
}
private static string RunDotNet(string arguments, string workingDirectory,
IEnumerable<KeyValuePair<string, string>> environment = null, bool throwOnError = true)
{
var p = StartDotNet(arguments, workingDirectory, environment);
return WaitForExit(p, throwOnError: throwOnError);
}
private static (Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) StartDotNet(
string arguments, string workingDirectory, IEnumerable<KeyValuePair<string, string>> environment = null)
{
var env = _globalEnvironment.Concat(environment ?? Enumerable.Empty<KeyValuePair<string, string>>());
return StartProcess("dotnet", arguments, workingDirectory, env);
}
private static (Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) StartProcess(
string filename, string arguments, string workingDirectory, IEnumerable<KeyValuePair<string, string>> environment = null)
{
var process = new Process()
{
StartInfo =
{
FileName = filename,
Arguments = arguments,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = workingDirectory,
},
};
if (environment != null)
{
foreach (var kvp in environment)
{
process.StartInfo.Environment.Add(kvp);
}
}
var outputBuilder = new ConcurrentStringBuilder();
process.OutputDataReceived += (_, e) =>
{
outputBuilder.AppendLine(e.Data);
};
var errorBuilder = new ConcurrentStringBuilder();
process.ErrorDataReceived += (_, e) =>
{
errorBuilder.AppendLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
return (process, outputBuilder, errorBuilder);
}
public static string StopProcess((Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) process,
bool throwOnError = true)
{
if (!process.Process.HasExited)
{
process.Process.KillTree();
}
return WaitForExit(process, throwOnError: throwOnError);
}
public static string WaitForExit((Process Process, ConcurrentStringBuilder OutputBuilder, ConcurrentStringBuilder ErrorBuilder) process,
bool throwOnError = true)
{
// Workaround issue where WaitForExit() blocks until child processes are killed, which is problematic
// for the dotnet.exe NodeReuse child processes. I'm not sure why this is problematic for dotnet.exe child processes
// but not for MSBuild.exe child processes. The workaround is to specify a large timeout.
// https://stackoverflow.com/a/37983587/102052
process.Process.WaitForExit(int.MaxValue);
if (throwOnError && process.Process.ExitCode != 0)
{
var sb = new ConcurrentStringBuilder();
sb.AppendLine($"Command {process.Process.StartInfo.FileName} {process.Process.StartInfo.Arguments} returned exit code {process.Process.ExitCode}");
sb.AppendLine();
sb.AppendLine(process.OutputBuilder.ToString());
throw new InvalidOperationException(sb.ToString());
}
return process.OutputBuilder.ToString();
}
}
}

View File

@ -0,0 +1,85 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
namespace Cli.FunctionalTests.Util
{
internal static class IOUtil
{
public static void ReplaceInFile(string path, string oldValue, string newValue)
{
File.WriteAllText(path, File.ReadAllText(path).Replace(oldValue, newValue));
}
public static IEnumerable<string> GetFiles(string path)
{
return Directory.GetFiles(path, "*", SearchOption.AllDirectories)
.Select(p => Path.GetRelativePath(path, p));
}
public static IEnumerable<string> GetDirectories(string path)
{
return Directory.GetDirectories(path, "*", SearchOption.AllDirectories)
.Select(p => Path.GetRelativePath(path, p));
}
public static string GetTempDir()
{
var temp = Path.GetTempFileName();
File.Delete(temp);
Directory.CreateDirectory(temp);
return temp;
}
public static void DeleteFileIfExists(string path)
{
if (File.Exists(path))
{
File.Delete(path);
}
}
public static void DeleteDir(string path)
{
// If delete fails (e.g. due to a file in use), retry once every second up to 20 times.
for (var i = 0; i < 20; i++)
{
try
{
var dir = new DirectoryInfo(path) { Attributes = FileAttributes.Normal };
foreach (var info in dir.GetFileSystemInfos("*", SearchOption.AllDirectories))
{
info.Attributes = FileAttributes.Normal;
}
dir.Delete(recursive: true);
break;
}
catch (DirectoryNotFoundException)
{
break;
}
catch (FileNotFoundException)
{
break;
}
catch (Exception)
{
if (i < 19)
{
Thread.Sleep(TimeSpan.FromSeconds(1));
}
else
{
throw;
}
}
}
}
}
}

View File

@ -0,0 +1,113 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Microsoft.Extensions.Internal
{
internal static class ProcessExtensions
{
private static readonly bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(30);
public static void KillTree(this Process process)
{
process.KillTree(_defaultTimeout);
}
public static void KillTree(this Process process, TimeSpan timeout)
{
string stdout;
if (_isWindows)
{
RunProcessAndWaitForExit(
"taskkill",
$"/T /F /PID {process.Id}",
timeout,
out stdout);
}
else
{
var children = new HashSet<int>();
GetAllChildIdsUnix(process.Id, children, timeout);
foreach (var childId in children)
{
KillProcessUnix(childId, timeout);
}
KillProcessUnix(process.Id, timeout);
}
}
private static void GetAllChildIdsUnix(int parentId, ISet<int> children, TimeSpan timeout)
{
string stdout;
var exitCode = RunProcessAndWaitForExit(
"pgrep",
$"-P {parentId}",
timeout,
out stdout);
if (exitCode == 0 && !string.IsNullOrEmpty(stdout))
{
using (var reader = new StringReader(stdout))
{
while (true)
{
var text = reader.ReadLine();
if (text == null)
{
return;
}
int id;
if (int.TryParse(text, out id))
{
children.Add(id);
// Recursively get the children
GetAllChildIdsUnix(id, children, timeout);
}
}
}
}
}
private static void KillProcessUnix(int processId, TimeSpan timeout)
{
string stdout;
RunProcessAndWaitForExit(
"kill",
$"-TERM {processId}",
timeout,
out stdout);
}
private static int RunProcessAndWaitForExit(string fileName, string arguments, TimeSpan timeout, out string stdout)
{
var startInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(startInfo);
stdout = null;
if (process.WaitForExit((int)timeout.TotalMilliseconds))
{
stdout = process.StandardOutput.ReadToEnd();
}
else
{
process.Kill();
}
return process.ExitCode;
}
}
}

View File

@ -0,0 +1,104 @@
<#
.SYNOPSIS
This script runs the tests in this project on complete build of the .NET Core CLI
.PARAMETER ci
This is a CI build
.PARAMETER AccessTokenSuffix
The access token for Azure blobs
.PARAMETER AssetRootUrl
The blob feed for the .NET Core CLI. If not specified, it will determined automatically if possible.
.PARAMETER RestoreSources
A list of additional NuGet feeds. If not specified, it will determined automatically if possible.
.PARAMETER ProdConManifestUrl
The prodcon build.xml file
.PARAMETER ProcConChannel
The prodcon channel to use if a build.xml file isn't set.
#>
param(
[switch]$ci,
$AssetRootUrl = $env:PB_AccessRootUrl,
$AccessTokenSuffix = $env:PB_AccessTokenSuffix,
$RestoreSources = $env:PB_RestoreSources,
$ProdConManifestUrl,
$ProcConChannel = 'master'
)
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version 1
$repoRoot = Resolve-Path "$PSScriptRoot/../../"
Import-Module "$repoRoot/scripts/common.psm1" -Scope Local -Force
Push-Location $PSScriptRoot
try {
New-Item -Type Directory "$PSScriptRoot/obj/" -ErrorAction Ignore | Out-Null
$sdkVersion = ''
if (-not $ci -or $ProdConManifestUrl) {
if (-not $ProdConManifestUrl) {
Write-Host -ForegroundColor Magenta "Running tests for the latest ProdCon build"
$ProdConManifestUrl = "https://raw.githubusercontent.com/dotnet/versions/master/build-info/dotnet/product/cli/$ProcConChannel/build.xml"
}
[xml] $prodConManifest = Invoke-RestMethod $ProdConManifestUrl
$RestoreSources = $prodConManifest.OrchestratedBuild.Endpoint `
| ? { $_.Type -eq 'BlobFeed' } `
| select -first 1 -ExpandProperty Url
$AssetRootUrl = $RestoreSources -replace '/index.json', '/assets'
$sdkVersion = $prodConManifest.OrchestratedBuild.Build `
| ? { $_.Name -eq 'cli' } `
| select -first 1 -ExpandProperty ProductVersion
}
else {
if (-not $AssetRootUrl) {
Write-Error "Missing required parameter: AssetRootUrl"
}
$AssetRootUrl = $AssetRootUrl.TrimEnd('/')
[xml] $cli = Invoke-RestMethod "$AssetRootUrl/orchestration-metadata/manifests/cli.xml${AccessTokenSuffix}"
$sdkVersion = $cli.Build.ProductVersion
}
Write-Host "sdkVersion: $sdkVersion"
Write-Host "AssetRootUrl: $AssetRootUrl"
Write-Host "RestoreSources: $RestoreSources"
@{ sdk = @{ version = $sdkVersion } } | ConvertTo-Json | Set-Content "$PSScriptRoot/global.json"
$dotnetRoot = "$repoRoot/.dotnet"
$dotnet = "$dotnetRoot/dotnet.exe"
if (-not (Test-Path "$dotnetRoot/sdk/$sdkVersion/dotnet.dll")) {
Remove-Item -Recurse -Force $dotnetRoot -ErrorAction Ignore | Out-Null
$cliUrl = "$AssetRootUrl/Sdk/$sdkVersion/dotnet-sdk-$sdkVersion-win-x64.zip"
Write-Host "Downloading $cliUrl"
Invoke-WebRequest -UseBasicParsing "${cliUrl}${AccessTokenSuffix}" -OutFile "$PSScriptRoot/obj/dotnet.zip"
Expand-Archive "$PSScriptRoot/obj/dotnet.zip" -DestinationPath $dotnetRoot
}
# Set a clean test environment
$env:DOTNET_ROOT = $dotnetRoot
$env:DOTNET_MULTILEVEL_LOOKUP = 0
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 0
$env:MSBuildSdksPath = ''
$env:PATH = "$dotnetRoot;$env:PATH"
Invoke-Block { & $dotnet test `
--logger "console;verbosity=detailed" `
--logger "trx;LogFileName=$repoRoot/artifacts/logs/e2etests.trx" `
"-p:DotNetRestoreSources=$RestoreSources" `
"-bl:$repoRoot/artifacts/logs/e2etests.binlog" }
}
finally {
Pop-Location
}

View File

@ -0,0 +1,3 @@
#!/bin/sh
dotnet test --logger "console;verbosity=detailed" "$@"