diff --git a/build.ps1 b/build.ps1 index bf7e10122..612cc0c1b 100644 --- a/build.ps1 +++ b/build.ps1 @@ -39,12 +39,9 @@ function Invoke-Tests() { foreach ($test in $(Get-ChildItem $testFolder | ? { $_.PsIsContainer })) { $csprojs = Get-ChildItem $test.FullName -Recurse | ? { $_.Extension -eq ".csproj" } foreach ($proj in $csprojs) { - $trx = "$($proj.BaseName).$(Get-Date -Format "yyyy-MM-dd.hh_mm_ss").trx" - $fullpath = Join-Path $testResults $trx - Write-Host "Testing $($proj.Name). Output: $trx" - dotnet test "$($proj.FullName)" --configuration $Configuration --logger "trx;LogFileName=$fullpath" --no-build + dotnet test "$($proj.FullName)" --configuration $Configuration --logger "trx" --no-build } } } diff --git a/build.sh b/build.sh index fbb4b2e20..6918e6c07 100755 --- a/build.sh +++ b/build.sh @@ -12,10 +12,11 @@ RootDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DotNetSDKPath=$RootDir"/.tools/dotnet/"$DotNetSDKVersion DotNetExe=$DotNetSDKPath"/dotnet" -TestResults=$RootDir"/TestResults" +BuildApps=true +RunTests=false usage() { - echo "Usage: build.sh [-c|--configuration ] [--downloadCatalog]" + echo "Usage: build.sh [-c|--configuration ] [--downloadCatalog] [--runTests] [--no-build]" } downloadCatalog() { @@ -39,6 +40,14 @@ downloadCatalog() { } installSDK() { + local dotnetPath=$(command -v dotnet) + + if [[ $dotnetPath != "" ]]; then + echo "dotnet is found on PATH. using that." + DotNetExe=$dotnetPath + return 0 + fi + if [[ -e $DotNetExe ]]; then echo $DotNetExe" exists. Skipping install..." return 0 @@ -53,33 +62,51 @@ installSDK() { curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current --install-dir $DotNetSDKPath } +tryGetTargetFramework() { + local file=$1 + local targetFramework=$(awk -F: '/.*netcoreapp[1-9]\.[0-9].*<\/TargetFramework(s)?>/ { print $0 }' $file | sed 's/.*\(netcoreapp[1-9]\.[0-9]\).*/\1/') + echo $targetFramework +} + build() { echo "Building ApiPort... Configuration: ["$Configuration"]" pushd src/ApiPort/ApiPort >/dev/null - $DotNetExe build ApiPort.csproj -f netcoreapp2.1 -c $Configuration - $DotNetExe build ApiPort.Offline.csproj -f netcoreapp2.1 -c $Configuration + + local targetFramework=$(tryGetTargetFramework ApiPort.props) + echo "Building for: $targetFramework" + + $DotNetExe build ApiPort.csproj -f $targetFramework -c $Configuration + $DotNetExe build ApiPort.Offline.csproj -f $targetFramework -c $Configuration popd >/dev/null } runTest() { ls $1/*.csproj | while read file; do - if awk -F: '/netcoreapp[1-9]\.[0-9]<\/TargetFramework>/ { found = 1 } END { if (found == 1) { exit 0 } else { exit 1 } }' $file; then - echo "Testing "$file - $DotNetExe test $file -c $Configuration --logger trx - else - # Can remove this when: https://github.com/dotnet/sdk/issues/335 is resolved + local targetFramework=$(tryGetTargetFramework $file) + + if [[ $targetFramework == "" ]]; then echo "Skipping "$file echo "--- Desktop .NET Framework testing is not currently supported on Unix." + else + echo "Testing "$file + $DotNetExe test $file -c $Configuration --logger trx --framework $targetFramework --results-directory $2 fi done +} - if [ ! -d $TestResults ]; then - mkdir $TestResults +findAndRunTests() { + local testResultsDirectory=$COMMON_TESTRESULTSDIRECTORY + + if [[ $testResultsDirectory == "" ]]; then + testResultsDirectory=$RootDir/TestResults + echo "Results directory not specified, using $testResultsDirectory." + else + echo "Using common one set by build agent." fi - find $RootDir/tests/ -type f -name "*.trx" | while read line; do - mv $line $TestResults/ + find tests/ -type d -name "*\.Tests" | while read file; do + runTest $file $testResultsDirectory done } @@ -94,6 +121,14 @@ while [[ $# -gt 0 ]]; do Configuration="$2" shift 2 ;; + "--runtests") + RunTests=true + shift + ;; + "--no-build") + BuildApps=false + shift + ;; "--downloadcatalog") downloadCatalog "true" exit 0 @@ -124,12 +159,17 @@ if [[ ! -e $DotNetExe ]]; then exit 2 fi -downloadCatalog +if [[ $BuildApps == "true" ]]; then + downloadCatalog + build +fi -build +if [[ $RunTests == "true" ]]; then + if [[$BuildApps != "true" ]]; then + echo "WARNING: Not building applications because --no-build is set." + fi -find tests/ -type d -name "*\.Tests" | while read file; do - runTest $file -done + findAndRunTests +fi echo "Finished!" diff --git a/src/ApiPort/ApiPort/ApiPort.props b/src/ApiPort/ApiPort/ApiPort.props index 310be3f2b..95a7508be 100644 --- a/src/ApiPort/ApiPort/ApiPort.props +++ b/src/ApiPort/ApiPort/ApiPort.props @@ -14,7 +14,7 @@ - win7-x64 + win7-x64;win7-x86 $(DefineConstants);FEATURE_SYSTEM_PROXY;FEATURE_NETWORK_CREDENTIAL diff --git a/src/lib/Microsoft.Fx.Portability/AssemblyFileComparer.cs b/src/lib/Microsoft.Fx.Portability/AssemblyFileComparer.cs index 0fd0ae132..3bf753045 100644 --- a/src/lib/Microsoft.Fx.Portability/AssemblyFileComparer.cs +++ b/src/lib/Microsoft.Fx.Portability/AssemblyFileComparer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Microsoft.Fx.Portability { @@ -21,7 +22,16 @@ public int Compare(IAssemblyFile x, IAssemblyFile y) return y == null ? 0 : -1; } - return string.Compare(x.Name, y?.Name, StringComparison.Ordinal); + // Filenames are case insensitive on Windows. + var comparison = StringComparison.OrdinalIgnoreCase; + +#if !NET461 + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + comparison = StringComparison.Ordinal; + } +#endif + return string.Compare(x.Name, y?.Name, comparison); } } } diff --git a/tests/ApiPort/ApiPort.Tests/AnalyzeOptionsTests.cs b/tests/ApiPort/ApiPort.Tests/AnalyzeOptionsTests.cs index d5eb37f44..72ee6463f 100644 --- a/tests/ApiPort/ApiPort.Tests/AnalyzeOptionsTests.cs +++ b/tests/ApiPort/ApiPort.Tests/AnalyzeOptionsTests.cs @@ -115,15 +115,22 @@ public static void TestAssemblyFlag_DirectoryAndFileName() { var directoryPath = Directory.GetCurrentDirectory(); var currentAssemblyPath = typeof(AnalyzeOptionsTests).GetTypeInfo().Assembly.Location; + var currentAssemblyDirectory = Path.GetDirectoryName(currentAssemblyPath); + + // The scenario tested is when an assembly is passed in twice, once explicitly and once as part of the folder + // Assert that we test this scenario. + if (!string.Equals(currentAssemblyDirectory, directoryPath, StringComparison.OrdinalIgnoreCase)) + { + Directory.SetCurrentDirectory(currentAssemblyDirectory); + directoryPath = Directory.GetCurrentDirectory(); + } var options = GetOptions($"analyze -f {directoryPath} -f {currentAssemblyPath}"); Assert.Equal(AppCommand.AnalyzeAssemblies, options.Command); Assert.NotEmpty(options.InputAssemblies); - // The scenario tested is when an assembly is passed in twice, once explicitly and once as part of the folder - // Assert that we test this scenario. - Assert.Equal(Path.GetDirectoryName(currentAssemblyPath), directoryPath, StringComparer.OrdinalIgnoreCase); + Assert.Equal(currentAssemblyDirectory, Directory.GetCurrentDirectory(), StringComparer.OrdinalIgnoreCase); foreach (var element in options.InputAssemblies) { diff --git a/tests/ApiPort/ApiPort.Tests/ApiPort.Tests.csproj b/tests/ApiPort/ApiPort.Tests/ApiPort.Tests.csproj index 4e0e347ff..d464b8b27 100644 --- a/tests/ApiPort/ApiPort.Tests/ApiPort.Tests.csproj +++ b/tests/ApiPort/ApiPort.Tests/ApiPort.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.1;net461 diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/Microsoft.Fx.Portability.Cci.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/Microsoft.Fx.Portability.Cci.Tests.csproj index 06dd2ced5..dab9a317e 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/Microsoft.Fx.Portability.Cci.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/Microsoft.Fx.Portability.Cci.Tests.csproj @@ -1,7 +1,7 @@  - net46 + netcoreapp2.1;net461 true true true diff --git a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs index 38f1fdd6c..66626ebdd 100644 --- a/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.Cci.Tests/TestAssembly.cs @@ -17,7 +17,15 @@ namespace Microsoft.Fx.Portability.Cci.Tests internal class TestAssembly { private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; - private static readonly string Mscorlib = typeof(object).GetTypeInfo().Assembly.Location; + private static readonly IEnumerable DefaultReferences = new[] + { + typeof(object).Assembly.Location, + typeof(Console).Assembly.Location, + + // Reference to System.Runtime.dll rather than System.Private.CoreLib on .NET Core + typeof(RuntimeReflectionExtensions).Assembly.Location + }.Distinct(); + private readonly string _path; private TestAssembly(string assemblyName, string text, IEnumerable referencePaths) @@ -56,7 +64,7 @@ public static string EmptyProject get { var text = GetText("EmptyProject.cs"); - return new TestAssembly("EmptyProject", text, new[] { Mscorlib }).Path; + return new TestAssembly("EmptyProject", text, DefaultReferences).Path; } } @@ -65,7 +73,8 @@ public static string WithGenericsAndReference get { var text = GetText("WithGenericsAndReference.cs"); - return new TestAssembly("WithGenericsAndReference", text, new[] { Mscorlib, EmptyProject }).Path; + var references = DefaultReferences.Concat(new[] { EmptyProject }); + return new TestAssembly("WithGenericsAndReference", text, references).Path; } } @@ -76,9 +85,9 @@ private static string GetText(string fileName) using (var stream = typeof(TestAssembly).GetTypeInfo().Assembly.GetManifestResourceStream(name)) { using (var reader = new StreamReader(stream)) - { - return reader.ReadToEnd(); - } + { + return reader.ReadToEnd(); + } } } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs index 24c2c00d3..2441aaed4 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/ManagedMetadataReaderTests.cs @@ -31,12 +31,10 @@ public ManagedMetadataReaderTests(ITestOutputHelper output) [InlineData("OpImplicitMethod2Parameter.cs", "M:Microsoft.Fx.Portability.MetadataReader.Tests.OpImplicit_Method_2Parameter`1.op_Implicit(`0,`0)")] [InlineData("OpExplicit.cs", "M:Microsoft.Fx.Portability.MetadataReader.Tests.Class2_OpExplicit`1.op_Explicit(Microsoft.Fx.Portability.MetadataReader.Tests.Class2_OpExplicit{`0})~Microsoft.Fx.Portability.MetadataReader.Tests.Class1_OpExplicit{`0}")] [InlineData("NestedGenericTypesWithInvalidNames.cs", "M:Microsoft.Fx.Portability.MetadataReader.Tests.OtherClass.d__0`1.System#Collections#Generic#IEnumerable{System#Tuple{T@System#Int32}}#GetEnumerator")] - [InlineData("modopt.il", "M:TestClass.Foo(System.Int32 optmod System.Runtime.CompilerServices.IsConst)")] - [InlineData("modopt.il", "M:TestClass.Bar(System.SByte optmod System.Runtime.CompilerServices.IsConst reqmod System.Runtime.CompilerServices.IsSignUnspecifiedByte*)")] [InlineData("NestedGenericTypes.cs", "M:OuterClass`2.InnerClass`2.InnerInnerClass.InnerInnerMethod(OuterClass{`3,`2}.InnerClass{System.Int32,`0}.InnerInnerClass)")] [InlineData("NestedGenericTypes.cs", "M:OuterClass`2.InnerClass`2.InnerMethod(OuterClass{`2,`2}.InnerClass{`1,`1})")] [InlineData("NestedGenericTypes.cs", "M:OuterClass`2.OuterMethod(`0,OuterClass{`1,`0}.InnerClass{`1,`0})")] - +#if FEATURE_ILASM // IL can, bizarrely, define non-generic types that take generic paratmers [InlineData("NonGenericTypesWithGenericParameters.il", "M:OuterClass.InnerClass.InnerMethod(OuterClass.InnerClass{`2,`2})")] [InlineData("NonGenericTypesWithGenericParameters.il", "M:OuterClass.OuterMethod(`0,OuterClass.InnerClass{`1,`0,System.Object,`0})")] @@ -45,7 +43,9 @@ public ManagedMetadataReaderTests(ITestOutputHelper output) // This is not possible to construct in C#, but was being encoded incorrectly by the metadata reader parser. [InlineData("NestedGenericTypes.il", "M:OuterClass`2.InnerClass`2.InnerMethod(OuterClass{`2,`2}.InnerClass`2)")] [InlineData("NestedGenericTypes.il", "M:OuterClass`2.OuterMethod(`0,OuterClass{`1,`0}.InnerClass{`1,`0})")] - + [InlineData("modopt.il", "M:TestClass.Foo(System.Int32 optmod System.Runtime.CompilerServices.IsConst)")] + [InlineData("modopt.il", "M:TestClass.Bar(System.SByte optmod System.Runtime.CompilerServices.IsConst reqmod System.Runtime.CompilerServices.IsSignUnspecifiedByte*)")] +#endif [Theory] public void TestForDocId(string source, string docid) { @@ -140,7 +140,9 @@ public void VerifyFilter() .OrderBy(x => x, StringComparer.Ordinal); var assemblyName = "FilterApis"; - var filter = new AssemblyNameFilter(assemblyName); + + // We want to recognize System.Console but not System.Uri. + var filter = new AssemblyNameFilter(assemblyName, new[] { "System.Console" }); var dependencyFinder = new ReflectionMetadataDependencyFinder(filter, new SystemObjectFinder(filter)); var assemblyToTest = TestAssembly.Create($"{assemblyName}.cs", _output); var progressReporter = Substitute.For(); @@ -240,6 +242,7 @@ public void ThrowsSystemObjectNotFoundException() Assert.IsType(exception.InnerException); } +#if FEATURE_ILASM [Fact] public void AssemblyWithNoReferencesIsSkipped() { @@ -257,6 +260,7 @@ public void AssemblyWithNoReferencesIsSkipped() Assert.Equal("NoReferences, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", assembly.AssemblyIdentity); } +#endif private static IEnumerable> EmptyProjectMemberDocId() { @@ -296,21 +300,37 @@ private static IEnumerable> EmptyProjectMemberDocId() private class AssemblyNameFilter : IDependencyFilter { + private static readonly HashSet SystemObjectAssemblies = new HashSet(StringComparer.Ordinal) + { + "mscorlib", + "netstandard", + "System.Private.CoreLib", + "System.Runtime" + }; + private readonly string _assemblyName; + private readonly HashSet _frameworkAssemblies; - public AssemblyNameFilter(string assemblyName) + public AssemblyNameFilter(string assemblyName, IEnumerable frameworkAssemblies) { - _assemblyName = assemblyName; + _assemblyName = assemblyName ?? throw new ArgumentNullException(nameof(assemblyName)); + _frameworkAssemblies = new HashSet( + frameworkAssemblies ?? Enumerable.Empty(), + StringComparer.Ordinal); } public bool IsFrameworkAssembly(AssemblyReferenceInformation assembly) { - var comparison = StringComparison.Ordinal; var name = assembly?.Name; - var result = string.Equals(_assemblyName, name, comparison) - || string.Equals("mscorlib", name, comparison) - || string.Equals("System.Runtime", name, comparison); + if (string.IsNullOrEmpty(name)) + { + return false; + } + + var result = string.Equals(_assemblyName, name, StringComparison.Ordinal) + || SystemObjectAssemblies.Contains(name) + || _frameworkAssemblies.Contains(name); return result; } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj index a8e92112c..d993528e8 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/Microsoft.Fx.Portability.MetadataReader.Tests.csproj @@ -1,11 +1,21 @@  - net46 + net461;netcoreapp2.1 true true true - win-x86 + + + + + win7-x86 + $(DefineConstants);FEATURE_ILASM diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs index c5b73b7df..4e3b4eb2b 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/SystemObjectFinderTests.cs @@ -18,6 +18,7 @@ public SystemObjectFinderTests(ITestOutputHelper output) _output = output; } +#if FEATURE_ILASM [Fact] public void MultipleMscorlibReferencesFound() { @@ -114,5 +115,6 @@ public void LookInFilePassedInAssembly(string name) } } } +#endif } } diff --git a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs index a565d205a..3f81c7ec0 100644 --- a/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs +++ b/tests/lib/Microsoft.Fx.Portability.MetadataReader.Tests/TestAssembly.cs @@ -63,10 +63,18 @@ public StringAssemblyFile(string name, string contents) private class CSharpCompileAssemblyFile : ResourceStreamAssemblyFile { private const string TFM = @"[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute("".NETFramework,Version=v4.5.1"", FrameworkDisplayName = "".NET Framework 4.5.1"")]"; - private static readonly IEnumerable References = new[] { typeof(object).GetTypeInfo().Assembly.Location, typeof(Uri).GetTypeInfo().Assembly.Location, typeof(Console).GetTypeInfo().Assembly.Location } - .Distinct() - .Select(r => MetadataReference.CreateFromFile(r)) - .ToList(); + private static readonly IEnumerable References = new[] + { + typeof(object).GetTypeInfo().Assembly.Location, + typeof(Uri).GetTypeInfo().Assembly.Location, + typeof(Console).GetTypeInfo().Assembly.Location, + + // Reference to System.Runtime.dll rather than System.Private.CoreLib on .NET Core + typeof(RuntimeReflectionExtensions).Assembly.Location + } + .Distinct() + .Select(r => MetadataReference.CreateFromFile(r)) + .ToList(); private readonly bool _allowUnsafe; private readonly IEnumerable _additionalReferences; diff --git a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/Microsoft.Fx.Portability.Offline.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/Microsoft.Fx.Portability.Offline.Tests.csproj index d9480a86e..434b5d007 100644 --- a/tests/lib/Microsoft.Fx.Portability.Offline.Tests/Microsoft.Fx.Portability.Offline.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.Offline.Tests/Microsoft.Fx.Portability.Offline.Tests.csproj @@ -1,13 +1,13 @@  - netcoreapp2.1 + netcoreapp2.1;net461 true diff --git a/tests/lib/Microsoft.Fx.Portability.Reports.Html.Tests/Microsoft.Fx.Portability.Reports.Html.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.Reports.Html.Tests/Microsoft.Fx.Portability.Reports.Html.Tests.csproj index e07a481bb..2680a07b3 100644 --- a/tests/lib/Microsoft.Fx.Portability.Reports.Html.Tests/Microsoft.Fx.Portability.Reports.Html.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.Reports.Html.Tests/Microsoft.Fx.Portability.Reports.Html.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1 + netcoreapp2.1 true diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs index a0a1a49c2..9b4771268 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs +++ b/tests/lib/Microsoft.Fx.Portability.Tests/BreakingChangeParserTests.cs @@ -372,9 +372,14 @@ private Stream GetBreakingChangeMarkdown(string resourceName) ... -```".Replace(Environment.NewLine, "\n", StringComparison.InvariantCulture) +```" +#if NET461 + .Replace(Environment.NewLine, "\n"), +#else + .Replace(Environment.NewLine, "\n", StringComparison.InvariantCulture), +#endif }; - #endregion +#endregion } } diff --git a/tests/lib/Microsoft.Fx.Portability.Tests/Microsoft.Fx.Portability.Tests.csproj b/tests/lib/Microsoft.Fx.Portability.Tests/Microsoft.Fx.Portability.Tests.csproj index 177264a2e..79be1dd4a 100644 --- a/tests/lib/Microsoft.Fx.Portability.Tests/Microsoft.Fx.Portability.Tests.csproj +++ b/tests/lib/Microsoft.Fx.Portability.Tests/Microsoft.Fx.Portability.Tests.csproj @@ -1,8 +1,9 @@  - netcoreapp2.1 + netcoreapp2.1;net461 true + $(DefineConstants);FEATURE_XML_SCHEMA false - $(DefineConstants);FEATURE_XML_SCHEMA