Merge branch 'master' into merge/release/5.0-preview3-to-master

This commit is contained in:
Ryan Nowak 2020-04-03 13:13:40 -07:00 committed by GitHub
commit 66ae2ba817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
210 changed files with 7531 additions and 1447 deletions

View File

@ -71,6 +71,7 @@ variables:
# The following extra properties are not set when testing. Use with final build.[cmd,sh] of asset-producing jobs.
- name: _PublishArgs
value: /p:Publish=true
/p:GenerateChecksums=true
/p:DotNetPublishBlobFeedKey=$(dotnetfeed-storage-access-key-1)
/p:DotNetPublishBlobFeedUrl=https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json
/p:DotNetPublishToBlobFeed=$(_DotNetPublishToBlobFeed)
@ -594,7 +595,7 @@ stages:
parameters:
condition: ne(variables['SkipTests'], 'true')
jobName: MacOS_Test
jobDisplayName: "Test: macOS 10.13"
jobDisplayName: "Test: macOS 10.14"
agentOs: macOS
isTestingJob: true
buildArgs: --all --test "/p:RunTemplateTests=false /p:SkipHelixReadyTests=true" $(_InternalRuntimeDownloadArgs)

12
.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

6
CODE-OF-CONDUCT.md Normal file
View File

@ -0,0 +1,6 @@
# Code of Conduct
This project has adopted the code of conduct defined by the Contributor Covenant
to clarify expected behavior in our community.
For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).

View File

@ -179,7 +179,6 @@
<ArchiveExtension>.tar.gz</ArchiveExtension>
<ArchiveExtension Condition="'$(TargetOsName)' == 'win'">.zip</ArchiveExtension>
<ChecksumExtension>.sha512</ChecksumExtension>
</PropertyGroup>
<Import Project="eng\Workarounds.props" />

View File

@ -105,6 +105,14 @@
<SkipTests Condition="'$(SkipHelixReadyTests)' == 'true' AND '$(BuildHelixPayload)' == 'true'">true</SkipTests>
</PropertyGroup>
<PropertyGroup>
<PackageThirdPartyNoticesFile Condition="'$(PackageThirdPartyNoticesFile)' == ''">$(RepoRoot)THIRD-PARTY-NOTICES.TXT</PackageThirdPartyNoticesFile>
</PropertyGroup>
<ItemGroup Condition="'$(IsPackable)' == 'true'">
<None Include="$(PackageThirdPartyNoticesFile)" Pack="true" PackagePath="." />
</ItemGroup>
<ItemGroup Condition="'$(Language)' == 'C#' AND '$(IsReferenceAssemblyProject)' == 'true'">
<Compile Include="$(SharedSourceRoot)ReferenceAssemblyInfo.cs" LinkBase="Properties" />
</ItemGroup>

View File

@ -9,7 +9,7 @@ Follow the [Getting Started](https://docs.microsoft.com/aspnet/core/getting-star
Also check out the [.NET Homepage](https://www.microsoft.com/net) for released versions of .NET, getting started guides, and learning resources.
See the [Issue Management Policies](https://github.com/dotnet/aspnetcore/blob/anurse/issue-policies/docs/IssueManagementPolicies.md) document for more information on how we handle incoming issues.
See the [Issue Management Policies](https://github.com/dotnet/aspnetcore/blob/master/docs/IssueManagementPolicies.md) document for more information on how we handle incoming issues.
## How to Engage, Contribute, and Give Feedback
@ -37,4 +37,4 @@ These are some other repos for related projects:
## Code of conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
See [CODE-OF-CONDUCT](./CODE-OF-CONDUCT.md)

33
eng/AfterSigning.targets Normal file
View File

@ -0,0 +1,33 @@
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" Condition="'$(GenerateChecksums)' == 'true'" />
<PropertyGroup Condition="'$(GenerateChecksums)' == 'true'">
<!-- The one use of ArtifactsDir in Publish.proj adds an additional slash, confusing itself. -->
<ArtifactsDir Condition=" HasTrailingSlash('$(ArtifactsDir)') ">$(ArtifactsDir.Substring(0, $([MSBuild]::Subtract($(ArtifactsDir.Length), 1))))</ArtifactsDir>
<!-- $(InstallersOutputPath) is not defined. Root Directory.Build.props is not imported. -->
<InstallersOutputPath>$(ArtifactsDir)\installers\</InstallersOutputPath>
</PropertyGroup>
<Target Name="PopulateGenerateChecksumItems"
Condition="'$(GenerateChecksums)' == 'true'"
AfterTargets="Build"
BeforeTargets="GenerateChecksums" >
<ItemGroup>
<InstallerFiles Include="$(InstallersOutputPath)**\*.msi" />
<InstallerFiles Include="$(InstallersOutputPath)**\*.exe" />
<InstallerFiles Include="$(InstallersOutputPath)**\*.zip" />
<InstallerFiles Include="$(InstallersOutputPath)**\*.tar.gz" />
<InstallerFiles Include="$(InstallersOutputPath)**\*.wixlib" />
<InstallerFiles Include="$(InstallersOutputPath)**\*.rpm" />
<GenerateChecksumItems Include="%(InstallerFiles.Identity)" >
<DestinationPath>%(FullPath).sha512</DestinationPath>
</GenerateChecksumItems>
</ItemGroup>
</Target>
<Import Project="Sdk.targets" Sdk="Microsoft.DotNet.Arcade.Sdk" Condition="'$(GenerateChecksums)' == 'true'" />
</Project>

View File

@ -6,12 +6,12 @@
</PropertyGroup>
<!-- Package: AspNetCoreRuntime.3.0.x64-->
<PropertyGroup Condition=" '$(PackageId)' == 'AspNetCoreRuntime.3.0.x64' ">
<BaselinePackageVersion>3.0.2</BaselinePackageVersion>
<BaselinePackageVersion>3.0.3</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'AspNetCoreRuntime.3.0.x64' AND '$(TargetFramework)' == 'net461' " />
<!-- Package: AspNetCoreRuntime.3.0.x86-->
<PropertyGroup Condition=" '$(PackageId)' == 'AspNetCoreRuntime.3.0.x86' ">
<BaselinePackageVersion>3.0.2</BaselinePackageVersion>
<BaselinePackageVersion>3.0.3</BaselinePackageVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(PackageId)' == 'AspNetCoreRuntime.3.0.x86' AND '$(TargetFramework)' == 'net461' " />
<!-- Package: dotnet-sql-cache-->

View File

@ -5,8 +5,8 @@ Update this list when preparing for a new patch.
-->
<Baseline Version="3.1.3">
<Package Id="AspNetCoreRuntime.3.0.x64" Version="3.0.2" />
<Package Id="AspNetCoreRuntime.3.0.x86" Version="3.0.2" />
<Package Id="AspNetCoreRuntime.3.0.x64" Version="3.0.3" />
<Package Id="AspNetCoreRuntime.3.0.x86" Version="3.0.3" />
<Package Id="dotnet-sql-cache" Version="3.1.3" />
<Package Id="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="3.1.3" />
<Package Id="Microsoft.AspNetCore.App.Runtime.win-x64" Version="3.1.3" />

View File

@ -152,6 +152,7 @@
$(RepoRoot)src\SiteExtensions\LoggingAggregate\test\**\*.csproj;
$(RepoRoot)src\Shared\**\*.*proj;
$(RepoRoot)src\Tools\**\*.*proj;
$(RepoRoot)src\Logging.AzureAppServices\**\src\*.csproj;
$(RepoRoot)src\Middleware\**\*.csproj;
$(RepoRoot)src\Razor\**\*.*proj;
$(RepoRoot)src\Mvc\**\*.*proj;
@ -191,6 +192,7 @@
$(RepoRoot)src\Security\**\src\*.csproj;
$(RepoRoot)src\SiteExtensions\**\src\*.csproj;
$(RepoRoot)src\Tools\**\src\*.csproj;
$(RepoRoot)src\Logging.AzureAppServices\**\src\*.csproj;
$(RepoRoot)src\Middleware\**\src\*.csproj;
$(RepoRoot)src\Razor\**\src\*.csproj;
$(RepoRoot)src\Mvc\**\src\*.csproj;

View File

@ -29,7 +29,6 @@ and are generated based on the last package release.
<LatestPackageReference Include="Microsoft.CodeAnalysis.Razor" Version="$(MicrosoftCodeAnalysisRazorPackageVersion)" />
<LatestPackageReference Include="Microsoft.CSharp" Version="$(MicrosoftCSharpPackageVersion)" />
<LatestPackageReference Include="Microsoft.DotNet.GenAPI" Version="$(MicrosoftDotNetGenApiPackageVersion)" />
<LatestPackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="$(MicrosoftDotNetPlatformAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="$(MicrosoftExtensionsCachingAbstractionsPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(MicrosoftExtensionsCachingMemoryPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsPackageVersion)" />
@ -120,8 +119,6 @@ and are generated based on the last package release.
<LatestPackageReference Include="Microsoft.EntityFrameworkCore" Version="$(MicrosoftEntityFrameworkCorePackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="$(MicrosoftExtensionsCachingSqlServerPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="$(MicrosoftExtensionsCachingStackExchangeRedisPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.AzureAppServices" Version="$(MicrosoftExtensionsLoggingAzureAppServicesPackageVersion)" />
<LatestPackageReference Include="Microsoft.Extensions.Logging.Testing" Version="$(MicrosoftExtensionsLoggingTestingPackageVersion)" />
<LatestPackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="$(MicrosoftIdentityModelClientsActiveDirectoryPackageVersion)" />
<LatestPackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="$(MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion)" />
<LatestPackageReference Include="Microsoft.IdentityModel.Protocols.WsFederation" Version="$(MicrosoftIdentityModelProtocolsWsFederationPackageVersion)" />

View File

@ -32,6 +32,7 @@
<ProjectReferenceProvider Include="Microsoft.Extensions.ApiDescription.Server" ProjectPath="$(RepoRoot)src\Tools\Extensions.ApiDescription.Server\src\Microsoft.Extensions.ApiDescription.Server.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.DeveloperCertificates.XPlat" ProjectPath="$(RepoRoot)src\Tools\FirstRunCertGenerator\src\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj" />
<ProjectReferenceProvider Include="GetDocument.Insider" ProjectPath="$(RepoRoot)src\Tools\GetDocumentInsider\src\GetDocumentInsider.csproj" />
<ProjectReferenceProvider Include="Microsoft.Extensions.Logging.AzureAppServices" ProjectPath="$(RepoRoot)src\Logging.AzureAppServices\src\Microsoft.Extensions.Logging.AzureAppServices.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.ConcurrencyLimiter" ProjectPath="$(RepoRoot)src\Middleware\ConcurrencyLimiter\src\Microsoft.AspNetCore.ConcurrencyLimiter.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" ProjectPath="$(RepoRoot)src\Middleware\Diagnostics.EntityFrameworkCore\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj" />
<ProjectReferenceProvider Include="Microsoft.AspNetCore.HeaderPropagation" ProjectPath="$(RepoRoot)src\Middleware\HeaderPropagation\src\Microsoft.AspNetCore.HeaderPropagation.csproj" />

View File

@ -1,7 +1,7 @@
<Project>
<PropertyGroup Condition=" HasTrailingSlash('$(ArtifactsDir)') ">
<PropertyGroup>
<!-- The one use of ArtifactsDir in Publish.proj adds an additional slash, confusing itself. -->
<ArtifactsDir>$(ArtifactsDir.Substring(0, $([MSBuild]::Subtract($(ArtifactsDir.Length), 1))))</ArtifactsDir>
<ArtifactsDir Condition=" HasTrailingSlash('$(ArtifactsDir)') ">$(ArtifactsDir.Substring(0, $([MSBuild]::Subtract($(ArtifactsDir.Length), 1))))</ArtifactsDir>
<PublishDependsOnTargets>$(PublishDependsOnTargets);_PublishInstallersAndChecksums</PublishDependsOnTargets>
@ -50,12 +50,10 @@
<!-- Do not push .nupkg files from Linux and macOS builds. They'll be packed up separately and signed on Windows. -->
<ItemsToPushToBlobFeed Remove="@(ItemsToPushToBlobFeed)" Condition="'$(OS)' != 'Windows_NT'" />
<!-- Skip publishing checksums for now - the checksums for the .zip files don't match (https://github.com/dotnet/aspnetcore/issues/18792)
<ItemsToPushToBlobFeed Include="@(_ChecksumsToPublish)">
<PublishFlatContainer>true</PublishFlatContainer>
<RelativeBlobPath>$(_UploadPathRoot)/Runtime/$(_PackageVersion)/%(Filename)%(Extension)</RelativeBlobPath>
</ItemsToPushToBlobFeed>
-->
<ItemsToPushToBlobFeed Include="@(_InstallersToPublish)">
<IsShipping>true</IsShipping>

View File

@ -13,320 +13,312 @@
<Uri>https://github.com/dotnet/blazor</Uri>
<Sha>dd7fb4d3931d556458f62642c2edfc59f6295bfb</Sha>
</Dependency>
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="5.0.0-preview.3.20202.16">
<Dependency Name="Microsoft.AspNetCore.Razor.Language" Version="5.0.0-preview.4.20201.4">
<Uri>https://github.com/dotnet/aspnetcore-tooling</Uri>
<Sha>46133a42cbf5af76e4f98a0b5221d55d342067a0</Sha>
<Sha>4ec71cb57e45db101bbd4ffcf64dafa1711de0af</Sha>
</Dependency>
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="5.0.0-preview.3.20202.16">
<Dependency Name="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="5.0.0-preview.4.20201.4">
<Uri>https://github.com/dotnet/aspnetcore-tooling</Uri>
<Sha>46133a42cbf5af76e4f98a0b5221d55d342067a0</Sha>
<Sha>4ec71cb57e45db101bbd4ffcf64dafa1711de0af</Sha>
</Dependency>
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="5.0.0-preview.3.20202.16">
<Dependency Name="Microsoft.CodeAnalysis.Razor" Version="5.0.0-preview.4.20201.4">
<Uri>https://github.com/dotnet/aspnetcore-tooling</Uri>
<Sha>46133a42cbf5af76e4f98a0b5221d55d342067a0</Sha>
<Sha>4ec71cb57e45db101bbd4ffcf64dafa1711de0af</Sha>
</Dependency>
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="5.0.0-preview.3.20202.16">
<Dependency Name="Microsoft.NET.Sdk.Razor" Version="5.0.0-preview.4.20201.4">
<Uri>https://github.com/dotnet/aspnetcore-tooling</Uri>
<Sha>46133a42cbf5af76e4f98a0b5221d55d342067a0</Sha>
<Sha>4ec71cb57e45db101bbd4ffcf64dafa1711de0af</Sha>
</Dependency>
<Dependency Name="dotnet-ef" Version="5.0.0-preview.3.20181.2">
<Dependency Name="dotnet-ef" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore.Relational" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore.Tools" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.3.20181.2">
<Dependency Name="Microsoft.EntityFrameworkCore" Version="5.0.0-preview.4.20203.1">
<Uri>https://github.com/dotnet/efcore</Uri>
<Sha>7a6aa0a4f513c28b5a0501a2db8880885def2236</Sha>
<Sha>b0636ed8050797d0a9c16da8b98c2eea7d7e1f16</Sha>
</Dependency>
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.AspNetCore.Analyzer.Testing" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Caching.Memory" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Caching.SqlServer" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.Binder" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.CommandLine" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.Ini" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.Json" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.UserSecrets" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration.Xml" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Configuration" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.DependencyInjection" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.DiagnosticAdapter" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.FileProviders.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.FileProviders.Composite" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.FileSystemGlobbing" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Hosting" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Http" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.AzureAppServices" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.Configuration" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.Console" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.Debug" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.EventSource" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.EventLog" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.TraceSource" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging.Testing" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Logging" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Options.DataAnnotations" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Options" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Microsoft.Internal.Extensions.Refs" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.Primitives" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
</Dependency>
<Dependency Name="Microsoft.Internal.Extensions.Refs" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
</Dependency>
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="Microsoft.Win32.Registry" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="Microsoft.Win32.SystemEvents" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.ComponentModel.Annotations" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Diagnostics.EventLog" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Drawing.Common" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Drawing.Common" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.IO.Pipelines" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.IO.Pipelines" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Net.Http.WinHttpHandler" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Net.WebSockets.WebSocketProtocol" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Reflection.Metadata" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Runtime.CompilerServices.Unsafe" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Security.Cryptography.Cng" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Security.Cryptography.Pkcs" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Security.Cryptography.Xml" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Security.Permissions" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Security.Permissions" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Security.Principal.Windows" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.ServiceProcess.ServiceController" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Text.Encodings.Web" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Text.Json" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Text.Json" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Threading.Channels" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Threading.Channels" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="System.Windows.Extensions" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="System.Windows.Extensions" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.3-runtime.20202.4" CoherentParentDependency="Microsoft.Extensions.Logging">
<Dependency Name="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.4-runtime.20201.1" CoherentParentDependency="Microsoft.Extensions.Logging">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.Extensions.Logging">
<Dependency Name="Microsoft.NETCore.App.Ref" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.Extensions.Logging">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<!--
Win-x64 is used here because we have picked an arbitrary runtime identifier to flow the version of the latest NETCore.App runtime.
All Runtime.$rid packages should have the same version.
-->
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.Extensions.Logging">
<Dependency Name="Microsoft.NETCore.App.Runtime.win-x64" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.Extensions.Logging">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.Extensions.Logging">
<Dependency Name="Microsoft.NETCore.App.Internal" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.Extensions.Logging">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<!-- Listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-preview.3.20202.4" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Dependency Name="Microsoft.NETCore.Platforms" Version="5.0.0-preview.4.20201.1" CoherentParentDependency="Microsoft.NETCore.App.Runtime.win-x64">
<Uri>https://github.com/dotnet/runtime</Uri>
<Sha>2b487f31064fe07d3b3398a7432edd1fa5777796</Sha>
<Sha>e1fa5d7648d46f067e265211fc2c695d409fe788</Sha>
</Dependency>
<Dependency Name="Internal.AspNetCore.Analyzers" Version="5.0.0-preview.3.20202.8" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Dependency Name="Internal.AspNetCore.Analyzers" Version="5.0.0-preview.4.20201.2" CoherentParentDependency="Microsoft.AspNetCore.Razor.Language">
<Uri>https://github.com/dotnet/extensions</Uri>
<Sha>ec073cff7d938e94cea1b239e9d8934627239a8a</Sha>
<Sha>03c40031d618f923aa88da125cb078aabde9ebb1</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.GenAPI" Version="5.0.0-beta.20180.5">
<Uri>https://github.com/dotnet/arcade</Uri>
@ -340,9 +332,9 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>09bb9d929120b402348c9a0e9c8c951e824059aa</Sha>
</Dependency>
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.6.0-3.20177.6" CoherentParentDependency="Microsoft.Extensions.Logging">
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="3.6.0-3.20201.6" CoherentParentDependency="Microsoft.Extensions.Logging">
<Uri>https://github.com/dotnet/roslyn</Uri>
<Sha>c9f2423cb5a2ab1ee8de0ef10e536d7672b1a2ea</Sha>
<Sha>8167e4880190407325d6cf7282f6bb62267abc56</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>

View File

@ -9,7 +9,7 @@
<AspNetCoreMajorVersion>5</AspNetCoreMajorVersion>
<AspNetCoreMinorVersion>0</AspNetCoreMinorVersion>
<AspNetCorePatchVersion>0</AspNetCorePatchVersion>
<PreReleaseVersionIteration>3</PreReleaseVersionIteration>
<PreReleaseVersionIteration>4</PreReleaseVersionIteration>
<!--
When StabilizePackageVersion is set to 'true', this branch will produce stable outputs for 'Shipping' packages
-->
@ -64,92 +64,90 @@
<!-- Packages from dotnet/arcade -->
<MicrosoftDotNetGenAPIPackageVersion>5.0.0-beta.20180.5</MicrosoftDotNetGenAPIPackageVersion>
<!-- Packages from dotnet/roslyn -->
<MicrosoftNetCompilersToolsetPackageVersion>3.6.0-3.20177.6</MicrosoftNetCompilersToolsetPackageVersion>
<MicrosoftNetCompilersToolsetPackageVersion>3.6.0-3.20201.6</MicrosoftNetCompilersToolsetPackageVersion>
<!-- Packages from dotnet/core-setup -->
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.3-runtime.20202.4</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.3.20202.4</MicrosoftNETCoreAppInternalPackageVersion>
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.3.20202.4</MicrosoftNETCoreAppRefPackageVersion>
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.3.20202.4</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
<MicrosoftExtensionsDependencyModelPackageVersion>5.0.0-preview.4-runtime.20201.1</MicrosoftExtensionsDependencyModelPackageVersion>
<MicrosoftNETCoreAppInternalPackageVersion>5.0.0-preview.4.20201.1</MicrosoftNETCoreAppInternalPackageVersion>
<MicrosoftNETCoreAppRefPackageVersion>5.0.0-preview.4.20201.1</MicrosoftNETCoreAppRefPackageVersion>
<MicrosoftNETCoreAppRuntimewinx64PackageVersion>5.0.0-preview.4.20201.1</MicrosoftNETCoreAppRuntimewinx64PackageVersion>
<!-- Packages from dotnet/corefx -->
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.3.20202.4</MicrosoftWin32RegistryPackageVersion>
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.3.20202.4</MicrosoftWin32SystemEventsPackageVersion>
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.3.20202.4</SystemComponentModelAnnotationsPackageVersion>
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.3.20202.4</SystemDiagnosticsEventLogPackageVersion>
<SystemDrawingCommonPackageVersion>5.0.0-preview.3.20202.4</SystemDrawingCommonPackageVersion>
<SystemIOPipelinesPackageVersion>5.0.0-preview.3.20202.4</SystemIOPipelinesPackageVersion>
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.3.20202.4</SystemNetHttpWinHttpHandlerPackageVersion>
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.3.20202.4</SystemNetWebSocketsWebSocketProtocolPackageVersion>
<SystemReflectionMetadataPackageVersion>5.0.0-preview.3.20202.4</SystemReflectionMetadataPackageVersion>
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.3.20202.4</SystemRuntimeCompilerServicesUnsafePackageVersion>
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.3.20202.4</SystemSecurityCryptographyCngPackageVersion>
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.3.20202.4</SystemSecurityCryptographyPkcsPackageVersion>
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.3.20202.4</SystemSecurityCryptographyXmlPackageVersion>
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.3.20202.4</SystemSecurityPermissionsPackageVersion>
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.3.20202.4</SystemSecurityPrincipalWindowsPackageVersion>
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.3.20202.4</SystemServiceProcessServiceControllerPackageVersion>
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.3.20202.4</SystemTextEncodingsWebPackageVersion>
<SystemTextJsonPackageVersion>5.0.0-preview.3.20202.4</SystemTextJsonPackageVersion>
<SystemThreadingChannelsPackageVersion>5.0.0-preview.3.20202.4</SystemThreadingChannelsPackageVersion>
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.3.20202.4</SystemWindowsExtensionsPackageVersion>
<MicrosoftWin32RegistryPackageVersion>5.0.0-preview.4.20201.1</MicrosoftWin32RegistryPackageVersion>
<MicrosoftWin32SystemEventsPackageVersion>5.0.0-preview.4.20201.1</MicrosoftWin32SystemEventsPackageVersion>
<SystemComponentModelAnnotationsPackageVersion>5.0.0-preview.4.20201.1</SystemComponentModelAnnotationsPackageVersion>
<SystemDiagnosticsEventLogPackageVersion>5.0.0-preview.4.20201.1</SystemDiagnosticsEventLogPackageVersion>
<SystemDrawingCommonPackageVersion>5.0.0-preview.4.20201.1</SystemDrawingCommonPackageVersion>
<SystemIOPipelinesPackageVersion>5.0.0-preview.4.20201.1</SystemIOPipelinesPackageVersion>
<SystemNetHttpWinHttpHandlerPackageVersion>5.0.0-preview.4.20201.1</SystemNetHttpWinHttpHandlerPackageVersion>
<SystemNetWebSocketsWebSocketProtocolPackageVersion>5.0.0-preview.4.20201.1</SystemNetWebSocketsWebSocketProtocolPackageVersion>
<SystemReflectionMetadataPackageVersion>5.0.0-preview.4.20201.1</SystemReflectionMetadataPackageVersion>
<SystemRuntimeCompilerServicesUnsafePackageVersion>5.0.0-preview.4.20201.1</SystemRuntimeCompilerServicesUnsafePackageVersion>
<SystemSecurityCryptographyCngPackageVersion>5.0.0-preview.4.20201.1</SystemSecurityCryptographyCngPackageVersion>
<SystemSecurityCryptographyPkcsPackageVersion>5.0.0-preview.4.20201.1</SystemSecurityCryptographyPkcsPackageVersion>
<SystemSecurityCryptographyXmlPackageVersion>5.0.0-preview.4.20201.1</SystemSecurityCryptographyXmlPackageVersion>
<SystemSecurityPermissionsPackageVersion>5.0.0-preview.4.20201.1</SystemSecurityPermissionsPackageVersion>
<SystemSecurityPrincipalWindowsPackageVersion>5.0.0-preview.4.20201.1</SystemSecurityPrincipalWindowsPackageVersion>
<SystemServiceProcessServiceControllerPackageVersion>5.0.0-preview.4.20201.1</SystemServiceProcessServiceControllerPackageVersion>
<SystemTextEncodingsWebPackageVersion>5.0.0-preview.4.20201.1</SystemTextEncodingsWebPackageVersion>
<SystemTextJsonPackageVersion>5.0.0-preview.4.20201.1</SystemTextJsonPackageVersion>
<SystemThreadingChannelsPackageVersion>5.0.0-preview.4.20201.1</SystemThreadingChannelsPackageVersion>
<SystemWindowsExtensionsPackageVersion>5.0.0-preview.4.20201.1</SystemWindowsExtensionsPackageVersion>
<!-- Only listed explicitly to workaround https://github.com/dotnet/cli/issues/10528 -->
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-preview.3.20202.4</MicrosoftNETCorePlatformsPackageVersion>
<MicrosoftNETCorePlatformsPackageVersion>5.0.0-preview.4.20201.1</MicrosoftNETCorePlatformsPackageVersion>
<!-- Packages from dotnet/blazor -->
<MicrosoftAspNetCoreBlazorMonoPackageVersion>3.2.0-preview1.20067.1</MicrosoftAspNetCoreBlazorMonoPackageVersion>
<!-- Packages from dotnet/extensions -->
<InternalAspNetCoreAnalyzersPackageVersion>5.0.0-preview.3.20202.8</InternalAspNetCoreAnalyzersPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>5.0.0-preview.3.20202.8</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsCachingAbstractionsPackageVersion>
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsCachingMemoryPackageVersion>
<MicrosoftExtensionsCachingSqlServerPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsCachingSqlServerPackageVersion>
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationBinderPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationIniPackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsConfigurationXmlPackageVersion>
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsHostingAbstractionsPackageVersion>
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsHostingPackageVersion>
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsHttpPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingAzureAppServicesPackageVersion>
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingConfigurationPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingEventSourcePackageVersion>
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingEventLogPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.3.20202.8</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftInternalExtensionsRefsPackageVersion>5.0.0-preview.3.20202.8</MicrosoftInternalExtensionsRefsPackageVersion>
<InternalAspNetCoreAnalyzersPackageVersion>5.0.0-preview.4.20201.2</InternalAspNetCoreAnalyzersPackageVersion>
<MicrosoftAspNetCoreAnalyzerTestingPackageVersion>5.0.0-preview.4.20201.2</MicrosoftAspNetCoreAnalyzerTestingPackageVersion>
<MicrosoftExtensionsCachingAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsCachingAbstractionsPackageVersion>
<MicrosoftExtensionsCachingMemoryPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsCachingMemoryPackageVersion>
<MicrosoftExtensionsCachingSqlServerPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsCachingSqlServerPackageVersion>
<MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsCachingStackExchangeRedisPackageVersion>
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
<MicrosoftExtensionsConfigurationBinderPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationBinderPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
<MicrosoftExtensionsConfigurationIniPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationIniPackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
<MicrosoftExtensionsConfigurationXmlPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsConfigurationXmlPackageVersion>
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsDiagnosticAdapterPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsDiagnosticAdapterPackageVersion>
<MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsFileProvidersAbstractionsPackageVersion>
<MicrosoftExtensionsFileProvidersCompositePackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsFileProvidersCompositePackageVersion>
<MicrosoftExtensionsFileProvidersPhysicalPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsFileProvidersPhysicalPackageVersion>
<MicrosoftExtensionsFileSystemGlobbingPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsFileSystemGlobbingPackageVersion>
<MicrosoftExtensionsHostingAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsHostingAbstractionsPackageVersion>
<MicrosoftExtensionsHostingPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsHostingPackageVersion>
<MicrosoftExtensionsHttpPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsHttpPackageVersion>
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
<MicrosoftExtensionsLoggingConfigurationPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingConfigurationPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingEventSourcePackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingEventSourcePackageVersion>
<MicrosoftExtensionsLoggingEventLogPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingEventLogPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTraceSourcePackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsLoggingTraceSourcePackageVersion>
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
<MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsOptionsDataAnnotationsPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsPrimitivesPackageVersion>5.0.0-preview.4.20201.2</MicrosoftExtensionsPrimitivesPackageVersion>
<MicrosoftInternalExtensionsRefsPackageVersion>5.0.0-preview.4.20201.2</MicrosoftInternalExtensionsRefsPackageVersion>
<!-- Packages from dotnet/efcore -->
<dotnetefPackageVersion>5.0.0-preview.3.20181.2</dotnetefPackageVersion>
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.3.20181.2</MicrosoftEntityFrameworkCorePackageVersion>
<dotnetefPackageVersion>5.0.0-preview.4.20203.1</dotnetefPackageVersion>
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
<MicrosoftEntityFrameworkCoreSqlitePackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCoreSqlitePackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftEntityFrameworkCoreToolsPackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>5.0.0-preview.4.20203.1</MicrosoftEntityFrameworkCorePackageVersion>
<!-- Packages from dotnet/aspnetcore-tooling -->
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>5.0.0-preview.3.20202.16</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>5.0.0-preview.3.20202.16</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>5.0.0-preview.3.20202.16</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>5.0.0-preview.3.20202.16</MicrosoftNETSdkRazorPackageVersion>
<MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>5.0.0-preview.4.20201.4</MicrosoftAspNetCoreMvcRazorExtensionsPackageVersion>
<MicrosoftAspNetCoreRazorLanguagePackageVersion>5.0.0-preview.4.20201.4</MicrosoftAspNetCoreRazorLanguagePackageVersion>
<MicrosoftCodeAnalysisRazorPackageVersion>5.0.0-preview.4.20201.4</MicrosoftCodeAnalysisRazorPackageVersion>
<MicrosoftNETSdkRazorPackageVersion>5.0.0-preview.4.20201.4</MicrosoftNETSdkRazorPackageVersion>
</PropertyGroup>
<!--

View File

@ -0,0 +1,2 @@
<Project>
</Project>

View File

@ -0,0 +1,2 @@
<Project>
</Project>

View File

@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace RunTests
{
public class ProcessResult
{
public ProcessResult(string standardOutput, string standardError, int exitCode)
{
StandardOutput = standardOutput;
StandardError = standardError;
ExitCode = exitCode;
}
public string StandardOutput { get; }
public string StandardError { get; }
public int ExitCode { get; }
}
}

View File

@ -0,0 +1,158 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
#nullable enable
namespace RunTests
{
public static class ProcessUtil
{
[DllImport("libc", SetLastError = true, EntryPoint = "kill")]
private static extern int sys_kill(int pid, int sig);
public static async Task<ProcessResult> RunAsync(
string filename,
string arguments,
string? workingDirectory = null,
bool throwOnError = true,
IDictionary<string, string?>? environmentVariables = null,
Action<string>? outputDataReceived = null,
Action<string>? errorDataReceived = null,
Action<int>? onStart = null,
CancellationToken cancellationToken = default)
{
Console.WriteLine($"Running '{filename} {arguments}'");
using var process = new Process()
{
StartInfo =
{
FileName = filename,
Arguments = arguments,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
},
EnableRaisingEvents = true
};
if (workingDirectory != null)
{
process.StartInfo.WorkingDirectory = workingDirectory;
}
if (environmentVariables != null)
{
foreach (var kvp in environmentVariables)
{
process.StartInfo.Environment.Add(kvp);
}
}
var outputBuilder = new StringBuilder();
process.OutputDataReceived += (_, e) =>
{
if (e.Data != null)
{
if (outputDataReceived != null)
{
outputDataReceived.Invoke(e.Data);
}
else
{
outputBuilder.AppendLine(e.Data);
}
}
};
var errorBuilder = new StringBuilder();
process.ErrorDataReceived += (_, e) =>
{
if (e.Data != null)
{
if (errorDataReceived != null)
{
errorDataReceived.Invoke(e.Data);
}
else
{
errorBuilder.AppendLine(e.Data);
}
}
};
var processLifetimeTask = new TaskCompletionSource<ProcessResult>();
process.Exited += (_, e) =>
{
Console.WriteLine($"'{process.StartInfo.FileName} {process.StartInfo.Arguments}' completed with exit code '{process.ExitCode}'");
if (throwOnError && process.ExitCode != 0)
{
processLifetimeTask.TrySetException(new InvalidOperationException($"Command {filename} {arguments} returned exit code {process.ExitCode}"));
}
else
{
processLifetimeTask.TrySetResult(new ProcessResult(outputBuilder.ToString(), errorBuilder.ToString(), process.ExitCode));
}
};
process.Start();
onStart?.Invoke(process.Id);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
var cancelledTcs = new TaskCompletionSource<object?>();
await using var _ = cancellationToken.Register(() => cancelledTcs.TrySetResult(null));
var result = await Task.WhenAny(processLifetimeTask.Task, cancelledTcs.Task);
if (result == cancelledTcs.Task)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
sys_kill(process.Id, sig: 2); // SIGINT
var cancel = new CancellationTokenSource();
await Task.WhenAny(processLifetimeTask.Task, Task.Delay(TimeSpan.FromSeconds(5), cancel.Token));
cancel.Cancel();
}
if (!process.HasExited)
{
process.CloseMainWindow();
if (!process.HasExited)
{
process.Kill();
}
}
}
return await processLifetimeTask.Task;
}
public static void KillProcess(int pid)
{
try
{
using var process = Process.GetProcessById(pid);
process?.Kill();
}
catch (ArgumentException) { }
catch (InvalidOperationException) { }
}
}
}

View File

@ -0,0 +1,54 @@
// 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.CommandLine;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace RunTests
{
class Program
{
static async Task Main(string[] args)
{
try
{
var runner = new TestRunner(RunTestsOptions.Parse(args));
var keepGoing = runner.SetupEnvironment();
if (keepGoing)
{
keepGoing = await runner.InstallAspNetAppIfNeededAsync();
}
runner.DisplayContents();
if (keepGoing)
{
if (!await runner.CheckTestDiscoveryAsync())
{
Console.WriteLine("RunTest stopping due to test discovery failure.");
Environment.Exit(1);
return;
}
var exitCode = await runner.RunTestsAsync();
runner.UploadResults();
Console.WriteLine($"Completed Helix job with exit code '{exitCode}'");
Environment.Exit(exitCode);
}
Console.WriteLine("Tests were not run due to previous failures. Exit code=1");
Environment.Exit(1);
}
catch (Exception e)
{
Console.WriteLine($"RunTests uncaught exception: {e.ToString()}");
Environment.Exit(1);
}
}
}
}

View File

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20158.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,81 @@
// 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.CommandLine;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace RunTests
{
public class RunTestsOptions
{
public static RunTestsOptions Parse(string[] args)
{
var command = new RootCommand()
{
new Option(
aliases: new string[] { "--target", "-t" },
description: "The test dll to run")
{ Argument = new Argument<string>(), Required = true },
new Option(
aliases: new string[] { "--sdk" },
description: "The version of the sdk being used")
{ Argument = new Argument<string>(), Required = true },
new Option(
aliases: new string[] { "--runtime" },
description: "The version of the runtime being used")
{ Argument = new Argument<string>(), Required = true },
new Option(
aliases: new string[] { "--queue" },
description: "The name of the Helix queue being run on")
{ Argument = new Argument<string>(), Required = true },
new Option(
aliases: new string[] { "--arch" },
description: "The architecture being run on")
{ Argument = new Argument<string>(), Required = true },
new Option(
aliases: new string[] { "--quarantined" },
description: "Whether quarantined tests should run or not")
{ Argument = new Argument<bool>(), Required = true },
new Option(
aliases: new string[] { "--ef" },
description: "The version of the EF tool to use")
{ Argument = new Argument<string>(), Required = true },
};
var parseResult = command.Parse(args);
var options = new RunTestsOptions();
options.Target = parseResult.ValueForOption<string>("--target");
options.SdkVersion = parseResult.ValueForOption<string>("--sdk");
options.RuntimeVersion = parseResult.ValueForOption<string>("--runtime");
options.HelixQueue = parseResult.ValueForOption<string>("--queue");
options.Architecture = parseResult.ValueForOption<string>("--arch");
options.Quarantined = parseResult.ValueForOption<bool>("--quarantined");
options.EfVersion = parseResult.ValueForOption<string>("--ef");
options.HELIX_WORKITEM_ROOT = Environment.GetEnvironmentVariable("HELIX_WORKITEM_ROOT");
options.Path = Environment.GetEnvironmentVariable("PATH");
options.DotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
return options;
}
public string Target { get; set;}
public string SdkVersion { get; set;}
public string RuntimeVersion { get; set;}
public string HelixQueue { get; set;}
public string Architecture { get; set;}
public bool Quarantined { get; set;}
public string EfVersion { get; set;}
public string HELIX_WORKITEM_ROOT { get; set;}
public string DotnetRoot { get; set; }
public string Path { get; set; }
}
}

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.CommandLine;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace RunTests
{
public class TestRunner
{
public TestRunner(RunTestsOptions options)
{
Options = options;
EnvironmentVariables = new Dictionary<string, string>();
}
public RunTestsOptions Options { get; set; }
public Dictionary<string, string> EnvironmentVariables { get; set; }
public bool SetupEnvironment()
{
try
{
// Rename default.NuGet.config to NuGet.config if there is not a custom one from the project
// We use a local NuGet.config file to avoid polluting global machine state and avoid relying on global machine state
if (!File.Exists("NuGet.config"))
{
File.Copy("default.NuGet.config", "NuGet.config");
}
EnvironmentVariables.Add("PATH", Options.Path);
EnvironmentVariables.Add("DOTNET_ROOT", Options.DotnetRoot);
EnvironmentVariables.Add("helix", Options.HelixQueue);
Console.WriteLine($"Current Directory: {Options.HELIX_WORKITEM_ROOT}");
var helixDir = Options.HELIX_WORKITEM_ROOT;
Console.WriteLine($"Setting HELIX_DIR: {helixDir}");
EnvironmentVariables.Add("HELIX_DIR", helixDir);
EnvironmentVariables.Add("NUGET_FALLBACK_PACKAGES", helixDir);
var nugetRestore = Path.Combine(helixDir, "nugetRestore");
EnvironmentVariables.Add("NUGET_RESTORE", nugetRestore);
var dotnetEFFullPath = Path.Combine(nugetRestore, $"dotnet-ef/{Options.EfVersion}/tools/netcoreapp3.1/any/dotnet-ef.exe");
Console.WriteLine($"Set DotNetEfFullPath: {dotnetEFFullPath}");
EnvironmentVariables.Add("DotNetEfFullPath", dotnetEFFullPath);
Console.WriteLine($"Creating nuget restore directory: {nugetRestore}");
Directory.CreateDirectory(nugetRestore);
// Rename default.runner.json to xunit.runner.json if there is not a custom one from the project
if (!File.Exists("xunit.runner.json"))
{
File.Copy("default.runner.json", "xunit.runner.json");
}
return true;
}
catch (Exception e)
{
Console.WriteLine($"Exception in SetupEnvironment: {e.ToString()}");
return false;
}
}
public void DisplayContents()
{
try
{
Console.WriteLine();
Console.WriteLine("Displaying directory contents:");
foreach (var file in Directory.EnumerateFiles("./"))
{
Console.WriteLine(Path.GetFileName(file));
}
foreach (var file in Directory.EnumerateDirectories("./"))
{
Console.WriteLine(Path.GetFileName(file));
}
Console.WriteLine();
}
catch (Exception e)
{
Console.WriteLine($"Exception in DisplayInitialState: {e.ToString()}");
}
}
public async Task<bool> InstallAspNetAppIfNeededAsync()
{
try
{
Console.WriteLine("Checking for Microsoft.AspNetCore.App/");
if (Directory.Exists("Microsoft.AspNetCore.App"))
{
var appRuntimePath = $"{Options.DotnetRoot}/shared/Microsoft.AspNetCore.App/{Options.RuntimeVersion}";
Console.WriteLine($"Found Microsoft.AspNetCore.App/, copying to {appRuntimePath}");
foreach (var file in Directory.EnumerateFiles("Microsoft.AspNetCore.App", "*.*", SearchOption.AllDirectories))
{
File.Copy(file, Path.Combine(appRuntimePath, file), overwrite: true);
}
Console.WriteLine($"Adding current directory to nuget sources: {Options.HELIX_WORKITEM_ROOT}");
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"nuget add source {Options.HELIX_WORKITEM_ROOT} --configfile NuGet.config",
environmentVariables: EnvironmentVariables);
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
"nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json --configfile NuGet.config",
environmentVariables: EnvironmentVariables);
// Write nuget sources to console, useful for debugging purposes
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
"nuget list source",
environmentVariables: EnvironmentVariables,
outputDataReceived: Console.WriteLine,
errorDataReceived: Console.WriteLine);
await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"tool install dotnet-ef --global --version {Options.EfVersion}",
environmentVariables: EnvironmentVariables);
// ';' is the path separator on Windows, and ':' on Unix
Options.Path += RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ";" : ":";
Options.Path += $"{Environment.GetEnvironmentVariable("DOTNET_CLI_HOME")}/.dotnet/tools";
EnvironmentVariables["PATH"] = Options.Path;
}
else
{
Console.WriteLine($"No app runtime found, skipping...");
}
return true;
}
catch (Exception e)
{
Console.WriteLine($"Exception in InstallAspNetAppIfNeeded: {e.ToString()}");
return false;
}
}
public async Task<bool> CheckTestDiscoveryAsync()
{
try
{
// Run test discovery so we know if there are tests to run
var discoveryResult = await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
$"vstest {Options.Target} -lt",
environmentVariables: EnvironmentVariables);
if (discoveryResult.StandardOutput.Contains("Exception thrown"))
{
Console.WriteLine("Exception thrown during test discovery.");
Console.WriteLine(discoveryResult.StandardOutput);
return false;
}
return true;
}
catch (Exception e)
{
Console.WriteLine($"Exception in CheckTestDiscovery: {e.ToString()}");
return false;
}
}
public async Task<int> RunTestsAsync()
{
var exitCode = 0;
try
{
var commonTestArgs = $"vstest {Options.Target} --logger:xunit --logger:\"console;verbosity=normal\" --blame";
if (Options.Quarantined)
{
Console.WriteLine("Running quarantined tests.");
// Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
var result = await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
commonTestArgs + " --TestCaseFilter:\"Quarantined=true\"",
environmentVariables: EnvironmentVariables,
outputDataReceived: Console.WriteLine,
errorDataReceived: Console.WriteLine,
throwOnError: false);
if (result.ExitCode != 0)
{
Console.WriteLine($"Failure in quarantined tests. Exit code: {result.ExitCode}.");
}
}
else
{
Console.WriteLine("Running non-quarantined tests.");
// Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
var result = await ProcessUtil.RunAsync($"{Options.DotnetRoot}/dotnet",
commonTestArgs + " --TestCaseFilter:\"Quarantined!=true\"",
environmentVariables: EnvironmentVariables,
outputDataReceived: Console.WriteLine,
errorDataReceived: Console.Error.WriteLine,
throwOnError: false);
if (result.ExitCode != 0)
{
Console.WriteLine($"Failure in non-quarantined tests. Exit code: {result.ExitCode}.");
exitCode = result.ExitCode;
}
}
}
catch (Exception e)
{
Console.WriteLine($"Exception in RunTests: {e.ToString()}");
exitCode = 1;
}
return exitCode;
}
public void UploadResults()
{
// 'testResults.xml' is the file Helix looks for when processing test results
Console.WriteLine("Trying to upload results...");
if (File.Exists("TestResults/TestResults.xml"))
{
Console.WriteLine("Copying TestResults/TestResults.xml to ./testResults.xml");
File.Copy("TestResults/TestResults.xml", "testResults.xml");
}
else
{
Console.WriteLine("No test results found.");
}
var HELIX_WORKITEM_UPLOAD_ROOT = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT");
Console.WriteLine($"Copying artifacts/log/ to {HELIX_WORKITEM_UPLOAD_ROOT}/");
if (Directory.Exists("artifacts/log"))
{
foreach (var file in Directory.EnumerateFiles("artifacts/log", "*.log", SearchOption.AllDirectories))
{
// Combine the directory name + log name for the copied log file name to avoid overwriting duplicate test names in different test projects
var logName = $"{Path.GetFileName(Path.GetDirectoryName(file))}_{Path.GetFileName(file)}";
Console.WriteLine($"Copying: {file} to {Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, logName)}");
// Need to copy to HELIX_WORKITEM_UPLOAD_ROOT and HELIX_WORKITEM_UPLOAD_ROOT/../ in order for Azure Devops attachments to link properly and for Helix to store the logs
File.Copy(file, Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, logName));
File.Copy(file, Path.Combine(HELIX_WORKITEM_UPLOAD_ROOT, "..", logName));
}
}
else
{
Console.WriteLine("No logs found in artifacts/log");
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@ -3,13 +3,9 @@ REM Need delayed expansion !PATH! so parens in the path don't mess up the parens
setlocal enabledelayedexpansion
REM Use '$' as a variable name prefix to avoid MSBuild variable collisions with these variables
set $target=%1
set $sdkVersion=%2
set $runtimeVersion=%3
set $helixQueue=%4
set $arch=%5
set $quarantined=%6
set $efVersion=%7
set DOTNET_HOME=%HELIX_CORRELATION_PAYLOAD%\sdk
set DOTNET_ROOT=%DOTNET_HOME%\%$arch%
@ -23,84 +19,14 @@ echo "Installing SDK"
powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -useb 'https://dot.net/v1/dotnet-install.ps1'))) -Architecture %$arch% -Version %$sdkVersion% -InstallDir %DOTNET_ROOT%"
echo "Installing Runtime"
powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -useb 'https://dot.net/v1/dotnet-install.ps1'))) -Architecture %$arch% -Runtime dotnet -Version %$runtimeVersion% -InstallDir %DOTNET_ROOT%"
echo "Checking for Microsoft.AspNetCore.App"
if EXIST ".\Microsoft.AspNetCore.App" (
echo "Found Microsoft.AspNetCore.App, copying to %DOTNET_ROOT%\shared\Microsoft.AspNetCore.App\%runtimeVersion%"
xcopy /i /y ".\Microsoft.AspNetCore.App" %DOTNET_ROOT%\shared\Microsoft.AspNetCore.App\%runtimeVersion%\
echo "Adding current directory to nuget sources: %HELIX_WORKITEM_ROOT%"
dotnet nuget add source %HELIX_WORKITEM_ROOT%
dotnet nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json
dotnet nuget list source
dotnet tool install dotnet-ef --global --version %$efVersion%
set PATH=!PATH!;%DOTNET_CLI_HOME%\.dotnet\tools
)
echo "Current Directory: %HELIX_WORKITEM_ROOT%"
set HELIX=%$helixQueue%
set HELIX_DIR=%HELIX_WORKITEM_ROOT%
set NUGET_FALLBACK_PACKAGES=%HELIX_DIR%
set NUGET_RESTORE=%HELIX_DIR%\nugetRestore
set DotNetEfFullPath=%HELIX_DIR%\nugetRestore\dotnet-ef\%$efVersion%\tools\netcoreapp3.1\any\dotnet-ef.exe
echo "Set DotNetEfFullPath: %DotNetEfFullPath%"
echo "Setting HELIX_DIR: %HELIX_DIR%"
echo Creating nuget restore directory: %NUGET_RESTORE%
mkdir %NUGET_RESTORE%
mkdir logs
REM "Rename default.runner.json to xunit.runner.json if there is not a custom one from the project"
if not EXIST ".\xunit.runner.json" (
copy default.runner.json xunit.runner.json
)
dir
%DOTNET_ROOT%\dotnet vstest %$target% -lt >discovered.txt
find /c "Exception thrown" discovered.txt
REM "ERRORLEVEL is not %ERRORLEVEL%" https://blogs.msdn.microsoft.com/oldnewthing/20080926-00/?p=20743/
if not errorlevel 1 (
echo Exception thrown during test discovery. 1>&2
type discovered.txt 1>&2
exit /b 1
)
set exit_code=0
if %$quarantined%==True (
set %$quarantined=true
echo "Restore for RunTests..."
dotnet restore RunTests\RunTests.csproj --source https://api.nuget.org/v3/index.json --ignore-failed-sources
echo "Running tests..."
dotnet run --project RunTests\RunTests.csproj -- --target %1 --sdk %2 --runtime %3 --queue %4 --arch %5 --quarantined %6 --ef %7
if errorlevel 1 (
set exit_code=1
)
REM Disable "!Foo!" expansions because they break the filter syntax
setlocal disabledelayedexpansion
set NONQUARANTINE_FILTER="Quarantined!=true"
set QUARANTINE_FILTER="Quarantined=true"
if %$quarantined%==true (
echo Running quarantined tests.
%DOTNET_ROOT%\dotnet vstest %$target% --logger:xunit --logger:"console;verbosity=normal" --blame --TestCaseFilter:%QUARANTINE_FILTER%
if errorlevel 1 (
echo Failure in quarantined test 1>&2
REM DO NOT EXIT and DO NOT SET EXIT_CODE to 1
)
) else (
REM Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
echo Running non-quarantined tests.
%DOTNET_ROOT%\dotnet vstest %$target% --logger:xunit --logger:"console;verbosity=normal" --blame --TestCaseFilter:%NONQUARANTINE_FILTER%
if errorlevel 1 (
echo Failure in non-quarantined test 1>&2
set exit_code=1
REM DO NOT EXIT
)
)
echo "Copying TestResults\TestResults.xml to ."
copy TestResults\TestResults.xml testResults.xml
echo "Copying artifacts/logs to %HELIX_WORKITEM_UPLOAD_ROOT%\..\"
for /R artifacts/log %%f in (*.log) do (
echo "Copying: %%f"
copy "%%f" %HELIX_WORKITEM_UPLOAD_ROOT%\..\
copy "%%f" %HELIX_WORKITEM_UPLOAD_ROOT%\
)
echo "Finished running tests: exit_code=%exit_code%"
exit /b %exit_code%

View File

@ -1,12 +1,7 @@
#!/usr/bin/env bash
test_binary_path="$1"
dotnet_sdk_version="$2"
dotnet_runtime_version="$3"
helix_queue_name="$4"
target_arch="$5"
quarantined="$6"
efVersion="$7"
RESET="\033[0m"
RED="\033[0;31m"
@ -30,19 +25,6 @@ export DOTNET_CLI_HOME="$DIR/.home$RANDOM"
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
# Used by SkipOnHelix attribute
export helix="$helix_queue_name"
export HELIX_DIR="$DIR"
export NUGET_FALLBACK_PACKAGES="$DIR"
export DotNetEfFullPath=$DIR\nugetRestore\dotnet-ef\$efVersion\tools\netcoreapp3.1\any\dotnet-ef.dll
echo "Set DotNetEfFullPath: $DotNetEfFullPath"
export NUGET_RESTORE="$DIR/nugetRestore"
echo "Creating nugetRestore directory: $NUGET_RESTORE"
mkdir $NUGET_RESTORE
mkdir logs
ls -laR
RESET="\033[0m"
RED="\033[0;31m"
YELLOW="\033[0;33m"
@ -93,29 +75,6 @@ if [ $? -ne 0 ]; then
done
fi
# Copy over any local shared fx if found
if [ -d "Microsoft.AspNetCore.App" ]
then
echo "Found Microsoft.AspNetCore.App directory, copying to $DOTNET_ROOT/shared/Microsoft.AspNetCore.App/$dotnet_runtime_version."
cp -r Microsoft.AspNetCore.App $DOTNET_ROOT/shared/Microsoft.AspNetCore.App/$dotnet_runtime_version
echo "Adding current directory to nuget sources: $DIR"
dotnet nuget add source $DIR
dotnet nuget add source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json
dotnet nuget list source
dotnet tool install dotnet-ef --global --version $efVersion
# Ensure tools are on on PATH
export PATH="$PATH:$DOTNET_CLI_HOME/.dotnet/tools"
fi
# Rename default.runner.json to xunit.runner.json if there is not a custom one from the project
if [ ! -f "xunit.runner.json" ]
then
cp default.runner.json xunit.runner.json
fi
if [ -e /proc/self/coredump_filter ]; then
# Include memory in private and shared file-backed mappings in the dump.
# This ensures that we can see disassembly from our shared libraries when
@ -123,40 +82,14 @@ if [ -e /proc/self/coredump_filter ]; then
echo -n 0x3F > /proc/self/coredump_filter
fi
# dontet-install.sh seems to affect the Linux filesystem and causes test flakiness unless we sync the filesystem before running tests
sync
$DOTNET_ROOT/dotnet vstest $test_binary_path -lt >discovered.txt
if grep -q "Exception thrown" discovered.txt; then
echo -e "${RED}Exception thrown during test discovery${RESET}".
cat discovered.txt
exit 1
fi
exit_code=0
# Filter syntax: https://github.com/Microsoft/vstest-docs/blob/master/docs/filter.md
NONQUARANTINE_FILTER="Quarantined!=true"
QUARANTINE_FILTER="Quarantined=true"
if [ "$quarantined" == true ]; then
echo "Running all tests including quarantined."
$DOTNET_ROOT/dotnet vstest $test_binary_path --logger:xunit --logger:"console;verbosity=normal" --blame --TestCaseFilter:"$QUARANTINE_FILTER"
if [ $? != 0 ]; then
echo "Quarantined tests failed!" 1>&2
# DO NOT EXIT
fi
else
echo "Running non-quarantined tests."
$DOTNET_ROOT/dotnet vstest $test_binary_path --logger:xunit --logger:"console;verbosity=normal" --blame --TestCaseFilter:"$NONQUARANTINE_FILTER"
exit_code=$?
if [ $exit_code != 0 ]; then
echo "Non-quarantined tests failed!" 1>&2
# DO NOT EXIT
fi
fi
echo "Copying TestResults/TestResults to ."
cp TestResults/TestResults.xml testResults.xml
echo "Copying artifacts/logs to $HELIX_WORKITEM_UPLOAD_ROOT/"
cp `find . -name \*.log` $HELIX_WORKITEM_UPLOAD_ROOT/../
cp `find . -name \*.log` $HELIX_WORKITEM_UPLOAD_ROOT/
echo "Restore for RunTests..."
$DOTNET_ROOT/dotnet restore RunTests/RunTests.csproj --source https://api.nuget.org/v3/index.json --ignore-failed-sources
echo "Running tests..."
$DOTNET_ROOT/dotnet run --project RunTests/RunTests.csproj -- --target $1 --sdk $2 --runtime $3 --queue $4 --arch $5 --quarantined $6 --ef $7
exit_code = $?
echo "Finished tests...exit_code=$exit_code"
exit $exit_code

View File

@ -7,11 +7,8 @@
],
"add": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.Net.Component.4.7.TargetingPack",
"Microsoft.VisualStudio.Component.FSharp.MSBuild",
"Microsoft.VisualStudio.Component.NuGet",
"Microsoft.VisualStudio.Component.NuGet.BuildTools",

View File

@ -7,11 +7,8 @@
],
"add": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.Net.Component.4.7.TargetingPack",
"Microsoft.VisualStudio.Component.FSharp.MSBuild",
"Microsoft.VisualStudio.Component.NuGet",
"Microsoft.VisualStudio.Component.NuGet.BuildTools",

View File

@ -7,12 +7,8 @@
],
"add": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.Net.Component.4.7.TargetingPack",
"Microsoft.VisualStudio.Component.Azure.Storage.Emulator",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",

View File

@ -7,12 +7,8 @@
],
"add": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.Net.Component.4.7.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.Net.Component.4.7.TargetingPack",
"Microsoft.VisualStudio.Component.Azure.Storage.Emulator",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",

View File

@ -22,6 +22,7 @@
<ItemGroup Condition="'$(IsRequiredCheck)' == 'true' AND '$(TargetArchitecture)' == 'x64'">
<HelixAvailableTargetQueue Include="Ubuntu.1604.Amd64.Open" Platform="Linux" />
<HelixAvailableTargetQueue Include="Windows.10.Amd64.Open" Platform="Windows" />
<HelixAvailableTargetQueue Include="OSX.1014.Amd64.Open" Platform="Linux" />
</ItemGroup>
<!-- daily scheduled only queues -->

12
eng/tools/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

12
src/Analyzers/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

12
src/Antiforgery/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

12
src/Azure/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

12
src/Components/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -10,6 +10,12 @@
<Reference Include="Mono.WebAssembly.Interop" />
<Reference Include="Microsoft.AspNetCore.Components.Web" />
<Reference Include="Microsoft.Extensions.Options" />
<!--
Supress a "BUILD001: Reference to 'Microsoft.Extensions.Configuration' was removed since the last stable release
of this package." warning.
-->
<SuppressBaselineReference Include="Microsoft.Extensions.Configuration" />
</ItemGroup>
<ItemGroup>

View File

@ -24,6 +24,7 @@
<NuspecProperty Include="componentsversion=$(ComponentsPackageVersion)" />
<NuspecProperty Include="razorversion=$(MicrosoftAspNetCoreRazorDesignPackageVersion)" />
<NuspecProperty Include="blazormonoversion=$(MicrosoftAspNetCoreBlazorMonoPackageVersion)" />
<NuspecProperty Include="PackageThirdPartyNoticesFile=$(PackageThirdPartyNoticesFile)" />
</ItemGroup>
<ItemGroup>

View File

@ -8,7 +8,7 @@
</metadata>
<files>
$CommonFileElements$
<file src="..\..\..\THIRD-PARTY-NOTICES.txt" />
<file src="$PackageThirdPartyNoticesFile$" target=".\THIRD-PARTY-NOTICES.txt" />
<file src="build\**" target="build" />
<file src="targets\**" target="targets" />
<file src="$taskskDir$\**" target="tools/" />

View File

@ -34,6 +34,7 @@
<NuspecProperty Include="publishDir=$(PublishDir)" />
<NuspecProperty Include="componentsrootdir=..\..\..\" />
<NuspecProperty Include="blazorversion=$(PackageVersion)" />
<NuspecProperty Include="PackageThirdPartyNoticesFile=$(PackageThirdPartyNoticesFile)" />
</ItemGroup>
</Project>

View File

@ -7,6 +7,6 @@
$CommonFileElements$
<file src="build\**" target="build" />
<file src="$publishDir$**\*" target="tools" />
<file src="$componentsrootdir$THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
<file src="$PackageThirdPartyNoticesFile$" target=".\THIRD-PARTY-NOTICES.txt" />
</files>
</package>

View File

@ -58,6 +58,7 @@
<NuspecProperty Condition="'$(DotNetBuildFromSource)' != 'true'" Include="systemComponentModelAnnotationsPackageVersion=$(SystemComponentModelAnnotationsPackageVersion)" />
<NuspecProperty Include="AssemblyName=$(AssemblyName)" />
<NuspecProperty Include="OutputPath=$(OutputPath)" />
<NuspecProperty Include="PackageThirdPartyNoticesFile=$(PackageThirdPartyNoticesFile)" />
</ItemGroup>
</Project>

View File

@ -21,6 +21,6 @@
<file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
<file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
<file src="$PackageThirdPartyNoticesFile$" target=".\THIRD-PARTY-NOTICES.txt" />
</files>
</package>

View File

@ -15,6 +15,6 @@
<file src="$OutputPath$**\$AssemblyName$.dll" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.pdb" target="lib\" />
<file src="$OutputPath$**\$AssemblyName$.xml" target="lib\" />
<file src="..\..\THIRD-PARTY-NOTICES.txt" target=".\THIRD-PARTY-NOTICES.txt" />
<file src="$PackageThirdPartyNoticesFile$" target=".\THIRD-PARTY-NOTICES.txt" />
</files>
</package>

View File

@ -20,6 +20,8 @@
<!-- So we can use the tool from source within the repo without having to pack -->
<BlazorToolsDir>$(MSBuildThisFileDirectory)Blazor\Build\src\bin\$(Configuration)\$(DefaultNetCoreTargetFramework)\</BlazorToolsDir>
<PackageThirdPartyNoticesFile>$(MSBuildThisFileDirectory)THIRD-PARTY-NOTICES.txt</PackageThirdPartyNoticesFile>
</PropertyGroup>
<PropertyGroup>

View File

@ -24,8 +24,6 @@
</Target>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)THIRD-PARTY-NOTICES.txt" Pack="true" PackagePath="." />
<!-- Add a project dependency without reference output assemblies to enforce build order -->
<!-- Applying workaround for https://github.com/microsoft/msbuild/issues/2661 and https://github.com/dotnet/sdk/issues/952 -->
<ProjectReference

View File

@ -14,8 +14,8 @@
<Reference Include="Microsoft.AspNetCore.Mvc" />
<Reference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" />
<Reference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" />
<Reference Include="Microsoft.AspNetCore.Testing" />
<Reference Include="Microsoft.Extensions.Hosting" />
<Reference Include="Microsoft.Extensions.Logging.Testing" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.DataProtection
[ConditionalFact]
[X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")]
public void System_UsesProvidedDirectoryAndCertificate()
{
var filePath = Path.Combine(GetTestFilesPath(), "TestCert.pfx");
@ -165,7 +165,6 @@ namespace Microsoft.AspNetCore.DataProtection
[ConditionalFact]
[X509StoreIsAvailable(StoreName.My, StoreLocation.CurrentUser)]
[SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/6720")]
public void System_UsesProvidedCertificateNotFromStore()
{
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))

View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -67,7 +67,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<!-- There is no way to suppress the .dev.runtimeconfig.json generation. -->
<ProjectRuntimeConfigDevFilePath>$(IntermediateOutputPath)ignoreme.dev.runtimeconfig.json</ProjectRuntimeConfigDevFilePath>
<VersionFileIntermediateOutputPath>$(IntermediateOutputPath).version</VersionFileIntermediateOutputPath>
<VersionFileIntermediateOutputPath>$(IntermediateOutputPath)$(SharedFxName).versions.txt</VersionFileIntermediateOutputPath>
<!-- The project representing the shared framework doesn't produce a .NET assembly or symbols. -->
<DebugType>none</DebugType>
@ -156,12 +156,6 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<RedistArchiveOutputPath>$(InstallersOutputPath)$(RedistArchiveOutputFileName)</RedistArchiveOutputPath>
</PropertyGroup>
<ItemGroup Condition="'$(DotNetBuildFromSource)' != 'true'">
<GenerateChecksumItems Include="$(RedistArchiveOutputPath)">
<DestinationPath>$(RedistArchiveOutputPath)$(ChecksumExtension)</DestinationPath>
</GenerateChecksumItems>
</ItemGroup>
<!-- Target chain -->
<PropertyGroup>
<ResolveReferencesDependsOn>
@ -501,4 +495,13 @@ This package is an internal implementation of the .NET Core SDK and is not meant
</ItemGroup>
</Target>
<Target Name="IncludeVersionFile"
DependsOnTargets="GenerateSharedFxVersionsFiles"
BeforeTargets="_GetPackageFiles">
<ItemGroup>
<None Include="$(VersionFileIntermediateOutputPath)" Pack="true" PackagePath="." />
</ItemGroup>
</Target>
</Project>

View File

@ -36,6 +36,10 @@
<_Parameter1>TargetingPackLayoutRoot</_Parameter1>
<_Parameter2>$(TargetingPackLayoutRoot)</_Parameter2>
</AssemblyAttribute>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>IsTargetingPackBuilding</_Parameter1>
<_Parameter2>$(IsTargetingPackBuilding)</_Parameter2>
</AssemblyAttribute>
<AssemblyAttribute Include="Microsoft.AspNetCore.TestData">
<_Parameter1>VerifyAncmBinary</_Parameter1>
<_Parameter2>$(VerifyAncmBinary)</_Parameter2>

View File

@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore
[Fact]
public void ItContainsVersionFile()
{
var versionFile = Path.Combine(_sharedFxRoot, ".version");
var versionFile = Path.Combine(_sharedFxRoot, "Microsoft.AspNetCore.App.versions.txt");
AssertEx.FileExists(versionFile);
var lines = File.ReadAllLines(versionFile);
Assert.Equal(2, lines.Length);

View File

@ -20,17 +20,24 @@ namespace Microsoft.AspNetCore
private readonly string _expectedRid;
private readonly string _targetingPackRoot;
private readonly ITestOutputHelper _output;
private readonly bool _isTargetingPackBuilding;
public TargetingPackTests(ITestOutputHelper output)
{
_output = output;
_expectedRid = TestData.GetSharedFxRuntimeIdentifier();
_targetingPackRoot = Path.Combine(TestData.GetTestDataValue("TargetingPackLayoutRoot"), "packs", "Microsoft.AspNetCore.App.Ref", TestData.GetTestDataValue("TargetingPackVersion"));
_isTargetingPackBuilding = bool.Parse(TestData.GetTestDataValue("IsTargetingPackBuilding"));
}
[Fact]
public void AssembliesAreReferenceAssemblies()
{
if (!_isTargetingPackBuilding)
{
return;
}
IEnumerable<string> dlls = Directory.GetFiles(_targetingPackRoot, "*.dll", SearchOption.AllDirectories);
Assert.NotEmpty(dlls);
@ -58,6 +65,11 @@ namespace Microsoft.AspNetCore
[Fact]
public void PlatformManifestListsAllFiles()
{
if (!_isTargetingPackBuilding)
{
return;
}
var platformManifestPath = Path.Combine(_targetingPackRoot, "data", "PlatformManifest.txt");
var expectedAssemblies = TestData.GetSharedFxDependencies()
.Split(';', StringSplitOptions.RemoveEmptyEntries)

12
src/Grpc/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -125,7 +125,8 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
description: "A timeout occurred while running check.",
duration: duration,
exception: ex,
data: null);
data: null,
tags: registration.Tags);
Log.HealthCheckError(_logger, registration, ex, duration);
}
@ -139,7 +140,8 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
description: ex.Message,
duration: duration,
exception: ex,
data: null);
data: null,
tags: registration.Tags);
Log.HealthCheckError(_logger, registration, ex, duration);
}

View File

@ -113,6 +113,47 @@ namespace Microsoft.Extensions.Diagnostics.HealthChecks
});
}
[Fact]
public async Task CheckAsync_TagsArePresentInHealthReportEntryIfExceptionOccurs()
{
const string ExceptionMessage = "exception-message";
const string OperationCancelledMessage = "operation-cancelled-message";
var exceptionTags = new[] { "unhealthy-check-tag" };
var operationExceptionTags = new[] { "degraded-check-tag" };
// Arrange
var service = CreateHealthChecksService(b =>
{
b.AddAsyncCheck("ExceptionCheck", _ => throw new Exception(ExceptionMessage), exceptionTags);
b.AddAsyncCheck("OperationExceptionCheck", _ => throw new OperationCanceledException(OperationCancelledMessage), operationExceptionTags);
});
// Act
var results = await service.CheckHealthAsync();
// Assert
Assert.Collection(
results.Entries.OrderBy(kvp => kvp.Key),
actual =>
{
Assert.Equal("ExceptionCheck", actual.Key);
Assert.Equal(ExceptionMessage, actual.Value.Description);
Assert.Equal(HealthStatus.Unhealthy, actual.Value.Status);
Assert.Equal(ExceptionMessage, actual.Value.Exception.Message);
Assert.Empty(actual.Value.Data);
Assert.Equal(actual.Value.Tags, exceptionTags);
},
actual =>
{
Assert.Equal("OperationExceptionCheck", actual.Key);
Assert.Equal("A timeout occurred while running check.", actual.Value.Description);
Assert.Equal(HealthStatus.Unhealthy, actual.Value.Status);
Assert.Equal(OperationCancelledMessage, actual.Value.Exception.Message);
Assert.Empty(actual.Value.Data);
Assert.Equal(actual.Value.Tags, operationExceptionTags);
});
}
[Fact]
public async Task CheckAsync_RunsFilteredChecksAndAggregatesResultsAsync()
{

12
src/Hosting/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -23,7 +23,6 @@
<Reference Include="Microsoft.Extensions.FileProviders.Embedded" />
<Reference Include="Microsoft.Extensions.Logging" />
<Reference Include="Microsoft.Extensions.Logging.Console" />
<Reference Include="Microsoft.Extensions.Logging.Testing" />
<Reference Include="Microsoft.NETCore.Windows.ApiSets" />
<Reference Include="Serilog.Extensions.Logging" />
<Reference Include="Serilog.Sinks.File" />

View File

@ -115,10 +115,25 @@ namespace Microsoft.AspNetCore.TestHost
// This could throw an error if there was a pending server read. Needs to
// happen before completing the response so the response returns the error.
var requestBodyInProgress = RequestBodyReadInProgress();
if (requestBodyInProgress)
{
// If request is still in progress then abort it.
CancelRequestBody();
}
// Matches Kestrel server: response is completed before request is drained
await CompleteResponseAsync();
await CompleteRequestAsync(requestBodyInProgress);
if (!requestBodyInProgress)
{
// Writer was already completed in send request callback.
await _requestPipe.Reader.CompleteAsync();
// Don't wait for request to drain. It could block indefinitely. In a real server
// we would wait for a timeout and then kill the socket.
// Potential future improvement: add logging that the request timed out
}
_application.DisposeContext(_testContext, exception: null);
}
catch (Exception ex)
@ -165,24 +180,6 @@ namespace Microsoft.AspNetCore.TestHost
CancelRequestBody();
}
private async Task CompleteRequestAsync(bool requestBodyInProgress)
{
if (requestBodyInProgress)
{
// If request is still in progress then abort it.
CancelRequestBody();
}
else
{
// Writer was already completed in send request callback.
await _requestPipe.Reader.CompleteAsync();
}
// Don't wait for request to drain. It could block indefinitely. In a real server
// we would wait for a timeout and then kill the socket.
// Potential future improvement: add logging that the request timed out
}
private bool RequestBodyReadInProgress()
{
try

12
src/Http/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Http.Extensions
public partial class QueryBuilder : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
public QueryBuilder() { }
public QueryBuilder(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> parameters) { }
public QueryBuilder(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> parameters) { }
public void Add(string key, System.Collections.Generic.IEnumerable<string> values) { }
public void Add(string key, string value) { }

View File

@ -3,8 +3,10 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNetCore.Http.Extensions
{
@ -23,6 +25,12 @@ namespace Microsoft.AspNetCore.Http.Extensions
_params = new List<KeyValuePair<string, string>>(parameters);
}
public QueryBuilder(IEnumerable<KeyValuePair<string, StringValues>> parameters)
: this(parameters.SelectMany(kvp => kvp.Value, (kvp, v) => KeyValuePair.Create(kvp.Key, v)))
{
}
public void Add(string key, IEnumerable<string> values)
{
foreach (var value in values)
@ -78,4 +86,4 @@ namespace Microsoft.AspNetCore.Http.Extensions
return _params.GetEnumerator();
}
}
}
}

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Primitives;
using Xunit;
namespace Microsoft.AspNetCore.Http.Extensions
@ -70,6 +71,18 @@ namespace Microsoft.AspNetCore.Http.Extensions
Assert.Equal("?key1=value1&key2=value2&key3=value3", builder.ToString());
}
[Fact]
public void AddMultipleValuesViaConstructor_WithStringValues()
{
var builder = new QueryBuilder(new[]
{
new KeyValuePair<string, StringValues>("key1", new StringValues(new [] { "value1", string.Empty, "value3" })),
new KeyValuePair<string, StringValues>("key2", string.Empty),
new KeyValuePair<string, StringValues>("key3", StringValues.Empty)
});
Assert.Equal("?key1=value1&key1=&key1=value3&key2=", builder.ToString());
}
[Fact]
public void AddMultipleValuesViaInitializer_AddedInOrder()
{
@ -95,4 +108,4 @@ namespace Microsoft.AspNetCore.Http.Extensions
Assert.Equal("?key1=value1&key2=value2&key3=value3", builder1.ToString());
}
}
}
}

View File

@ -216,6 +216,8 @@ namespace Microsoft.AspNetCore.WebUtilities
public static partial class QueryHelpers
{
public static string AddQueryString(string uri, System.Collections.Generic.IDictionary<string, string> queryString) { throw null; }
public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> queryString) { throw null; }
public static string AddQueryString(string uri, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> queryString) { throw null; }
public static string AddQueryString(string uri, string name, string value) { throw null; }
public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> ParseNullableQuery(string queryString) { throw null; }
public static System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> ParseQuery(string queryString) { throw null; }

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using Microsoft.Extensions.Primitives;
@ -46,10 +47,10 @@ namespace Microsoft.AspNetCore.WebUtilities
}
/// <summary>
/// Append the given query keys and values to the uri.
/// Append the given query keys and values to the URI.
/// </summary>
/// <param name="uri">The base uri.</param>
/// <param name="queryString">A collection of name value query pairs to append.</param>
/// <param name="uri">The base URI.</param>
/// <param name="queryString">A dictionary of query keys and values to append.</param>
/// <returns>The combined result.</returns>
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
@ -68,7 +69,38 @@ namespace Microsoft.AspNetCore.WebUtilities
return AddQueryString(uri, (IEnumerable<KeyValuePair<string, string>>)queryString);
}
private static string AddQueryString(
/// <summary>
/// Append the given query keys and values to the URI.
/// </summary>
/// <param name="uri">The base URI.</param>
/// <param name="queryString">A collection of query names and values to append.</param>
/// <returns>The combined result.</returns>
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
public static string AddQueryString(string uri, IEnumerable<KeyValuePair<string, StringValues>> queryString)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
if (queryString == null)
{
throw new ArgumentNullException(nameof(queryString));
}
return AddQueryString(uri, queryString.SelectMany(kvp => kvp.Value, (kvp, v) => KeyValuePair.Create(kvp.Key, v)));
}
/// <summary>
/// Append the given query keys and values to the URI.
/// </summary>
/// <param name="uri">The base URI.</param>
/// <param name="queryString">A collection of name value query pairs to append.</param>
/// <returns>The combined result.</returns>
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
public static string AddQueryString(
string uri,
IEnumerable<KeyValuePair<string, string>> queryString)
{

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Primitives;
using Xunit;
namespace Microsoft.AspNetCore.WebUtilities
@ -119,5 +120,37 @@ namespace Microsoft.AspNetCore.WebUtilities
var result = QueryHelpers.AddQueryString(uri, queryStrings);
Assert.Equal(expectedUri, result);
}
[Theory]
[InlineData("http://contoso.com/", "http://contoso.com/?param1=value1&param1=&param1=value3&param2=")]
[InlineData("http://contoso.com/someaction", "http://contoso.com/someaction?param1=value1&param1=&param1=value3&param2=")]
[InlineData("http://contoso.com/someaction?param2=1", "http://contoso.com/someaction?param2=1&param1=value1&param1=&param1=value3&param2=")]
[InlineData("http://contoso.com/some#action", "http://contoso.com/some?param1=value1&param1=&param1=value3&param2=#action")]
[InlineData("http://contoso.com/some?param2=1#action", "http://contoso.com/some?param2=1&param1=value1&param1=&param1=value3&param2=#action")]
[InlineData("http://contoso.com/#action", "http://contoso.com/?param1=value1&param1=&param1=value3&param2=#action")]
[InlineData(
"http://contoso.com/someaction?q=test#anchor?value",
"http://contoso.com/someaction?q=test&param1=value1&param1=&param1=value3&param2=#anchor?value")]
[InlineData(
"http://contoso.com/someaction#anchor?stuff",
"http://contoso.com/someaction?param1=value1&param1=&param1=value3&param2=#anchor?stuff")]
[InlineData(
"http://contoso.com/someaction?name?something",
"http://contoso.com/someaction?name?something&param1=value1&param1=&param1=value3&param2=")]
[InlineData(
"http://contoso.com/someaction#name#something",
"http://contoso.com/someaction?param1=value1&param1=&param1=value3&param2=#name#something")]
public void AddQueryStringWithEnumerableOfKeysAndStringValues(string uri, string expectedUri)
{
var queryStrings = new Dictionary<string, StringValues>()
{
{ "param1", new StringValues(new [] { "value1", string.Empty, "value3" }) },
{ "param2", string.Empty },
{ "param3", StringValues.Empty }
};
var result = QueryHelpers.AddQueryString(uri, queryStrings);
Assert.Equal(expectedUri, result);
}
}
}

12
src/Identity/.vsconfig Normal file
View File

@ -0,0 +1,12 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -23,6 +23,7 @@
</GetCurrentProjectStaticWebAssetsDependsOn>
<IdentityUIFrameworkVersion Condition="'$(IdentityUIFrameworkVersion)' == ''">Bootstrap4</IdentityUIFrameworkVersion>
<PackageThirdPartyNoticesFile>$(MSBuildThisFileDirectory)THIRD-PARTY-NOTICES.TXT</PackageThirdPartyNoticesFile>
</PropertyGroup>
@ -32,7 +33,6 @@
<None Include="build\*" Pack="true" PackagePath="build\" />
<None Include="buildMultiTargeting\*" Pack="true" PackagePath="buildMultiTargeting\" />
<None Include="buildTransitive\*" Pack="true" PackagePath="buildTransitive\" />
<None Include="THIRD-PARTY-NOTICES.txt" Pack="true" PackagePath="/THIRD-PARTY-NOTICES.txt" />
</ItemGroup>
<ItemGroup>

View File

@ -40,6 +40,7 @@ namespace Microsoft.AspNetCore.Identity.Test
[Theory]
[MemberData(nameof(ScriptWithIntegrityData))]
[QuarantinedTest]
public async Task IdentityUI_ScriptTags_SubresourceIntegrityCheck(ScriptTag scriptTag)
{
var integrity = await GetShaIntegrity(scriptTag);

View File

@ -0,0 +1,16 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -0,0 +1,16 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -0,0 +1,16 @@
{
"version": "1.0",
"components": [
"Microsoft.Net.Component.4.6.1.TargetingPack",
"Microsoft.Net.Component.4.7.2.SDK",
"Microsoft.Net.Component.4.7.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.ATL",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows10SDK.17134",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NetCoreTools",
"Microsoft.VisualStudio.Workload.NetWeb",
"Microsoft.VisualStudio.Workload.VisualStudioExtension"
]
}

View File

@ -64,7 +64,7 @@
<Target Name="CopyToArtifactsDirectory"
Condition=" '$(IsShipping)' == 'true' AND '$(SkipCopyToArtifactsDirectory)' != 'true' "
AfterTargets="Build" BeforeTargets="GenerateChecksums">
BeforeTargets="Build">
<Copy SourceFiles="$(TargetPath)" DestinationFiles="$(InstallersOutputPath)$(PackageFileName)" />
<ItemGroup>
<_cabs Include="$(TargetDir)**/*.cab" />
@ -72,10 +72,4 @@
<Copy SourceFiles="@(_cabs)" DestinationFolder="$(InstallersOutputPath)" />
</Target>
<ItemGroup Condition=" '$(IsShipping)' == 'true' AND '$(SkipCopyToArtifactsDirectory)' != 'true' ">
<GenerateChecksumItems Include="$(InstallersOutputPath)$(PackageFileName)">
<DestinationPath>$(InstallersOutputPath)$(PackageFileName)$(ChecksumExtension)</DestinationPath>
</GenerateChecksumItems>
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
<PropertyGroup>
<!-- These projects depend on a 3rd party source -->
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,98 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging.AzureAppServices;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Options;
using static Microsoft.Extensions.DependencyInjection.ServiceDescriptor;
namespace Microsoft.Extensions.Logging
{
/// <summary>
/// Extension methods for adding Azure diagnostics logger.
/// </summary>
public static class AzureAppServicesLoggerFactoryExtensions
{
/// <summary>
/// Adds an Azure Web Apps diagnostics logger.
/// </summary>
/// <param name="builder">The extension method argument</param>
public static ILoggingBuilder AddAzureWebAppDiagnostics(this ILoggingBuilder builder)
{
var context = WebAppContext.Default;
// Only add the provider if we're in Azure WebApp. That cannot change once the apps started
return AddAzureWebAppDiagnostics(builder, context);
}
internal static ILoggingBuilder AddAzureWebAppDiagnostics(this ILoggingBuilder builder, IWebAppContext context)
{
if (!context.IsRunningInAzureWebApp)
{
return builder;
}
builder.AddConfiguration();
var config = SiteConfigurationProvider.GetAzureLoggingConfiguration(context);
var services = builder.Services;
var addedFileLogger = TryAddEnumerable(services, Singleton<ILoggerProvider, FileLoggerProvider>());
var addedBlobLogger = TryAddEnumerable(services, Singleton<ILoggerProvider, BlobLoggerProvider>());
if (addedFileLogger || addedBlobLogger)
{
services.AddSingleton(context);
services.AddSingleton<IOptionsChangeTokenSource<LoggerFilterOptions>>(
new ConfigurationChangeTokenSource<LoggerFilterOptions>(config));
}
if (addedFileLogger)
{
services.AddSingleton<IConfigureOptions<LoggerFilterOptions>>(CreateFileFilterConfigureOptions(config));
services.AddSingleton<IConfigureOptions<AzureFileLoggerOptions>>(new FileLoggerConfigureOptions(config, context));
services.AddSingleton<IOptionsChangeTokenSource<AzureFileLoggerOptions>>(
new ConfigurationChangeTokenSource<AzureFileLoggerOptions>(config));
LoggerProviderOptions.RegisterProviderOptions<AzureFileLoggerOptions, FileLoggerProvider>(builder.Services);
}
if (addedBlobLogger)
{
services.AddSingleton<IConfigureOptions<LoggerFilterOptions>>(CreateBlobFilterConfigureOptions(config));
services.AddSingleton<IConfigureOptions<AzureBlobLoggerOptions>>(new BlobLoggerConfigureOptions(config, context));
services.AddSingleton<IOptionsChangeTokenSource<AzureBlobLoggerOptions>>(
new ConfigurationChangeTokenSource<AzureBlobLoggerOptions>(config));
LoggerProviderOptions.RegisterProviderOptions<AzureBlobLoggerOptions, BlobLoggerProvider>(builder.Services);
}
return builder;
}
private static bool TryAddEnumerable(IServiceCollection collection, ServiceDescriptor descriptor)
{
var beforeCount = collection.Count;
collection.TryAddEnumerable(descriptor);
return beforeCount != collection.Count;
}
private static ConfigurationBasedLevelSwitcher CreateBlobFilterConfigureOptions(IConfiguration config)
{
return new ConfigurationBasedLevelSwitcher(
configuration: config,
provider: typeof(BlobLoggerProvider),
levelKey: "AzureBlobTraceLevel");
}
private static ConfigurationBasedLevelSwitcher CreateFileFilterConfigureOptions(IConfiguration config)
{
return new ConfigurationBasedLevelSwitcher(
configuration: config,
provider: typeof(FileLoggerProvider),
levelKey: "AzureDriveTraceLevel");
}
}
}

View File

@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Options for Azure diagnostics blob logging.
/// </summary>
public class AzureBlobLoggerOptions: BatchingLoggerOptions
{
private string _blobName = "applicationLog.txt";
/// <summary>
/// Gets or sets the last section of log blob name.
/// Defaults to <c>"applicationLog.txt"</c>.
/// </summary>
public string BlobName
{
get { return _blobName; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException(nameof(value), $"{nameof(BlobName)} must be non-empty string.");
}
_blobName = value;
}
}
internal string ContainerUrl { get; set; }
internal string ApplicationName { get; set; }
internal string ApplicationInstanceId { get; set; }
}
}

View File

@ -0,0 +1,73 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Options for Azure diagnostics file logging.
/// </summary>
public class AzureFileLoggerOptions: BatchingLoggerOptions
{
private int? _fileSizeLimit = 10 * 1024 * 1024;
private int? _retainedFileCountLimit = 2;
private string _fileName = "diagnostics-";
/// <summary>
/// Gets or sets a strictly positive value representing the maximum log size in bytes or null for no limit.
/// Once the log is full, no more messages will be appended.
/// Defaults to <c>10MB</c>.
/// </summary>
public int? FileSizeLimit
{
get { return _fileSizeLimit; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FileSizeLimit)} must be positive.");
}
_fileSizeLimit = value;
}
}
/// <summary>
/// Gets or sets a strictly positive value representing the maximum retained file count or null for no limit.
/// Defaults to <c>2</c>.
/// </summary>
public int? RetainedFileCountLimit
{
get { return _retainedFileCountLimit; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(RetainedFileCountLimit)} must be positive.");
}
_retainedFileCountLimit = value;
}
}
/// <summary>
/// Gets or sets a string representing the prefix of the file name used to store the logging information.
/// The current date, in the format YYYYMMDD will be added after the given value.
/// Defaults to <c>diagnostics-</c>.
/// </summary>
public string FileName
{
get { return _fileName; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException(nameof(value));
}
_fileName = value;
}
}
internal string LogDirectory { get; set; }
}
}

View File

@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class BatchLoggerConfigureOptions : IConfigureOptions<BatchingLoggerOptions>
{
private readonly IConfiguration _configuration;
private readonly string _isEnabledKey;
public BatchLoggerConfigureOptions(IConfiguration configuration, string isEnabledKey)
{
_configuration = configuration;
_isEnabledKey = isEnabledKey;
}
public void Configure(BatchingLoggerOptions options)
{
options.IsEnabled = TextToBoolean(_configuration.GetSection(_isEnabledKey)?.Value);
}
private static bool TextToBoolean(string text)
{
if (string.IsNullOrEmpty(text) ||
!bool.TryParse(text, out var result))
{
result = false;
}
return result;
}
}
}

View File

@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class BatchingLogger : ILogger
{
private readonly BatchingLoggerProvider _provider;
private readonly string _category;
public BatchingLogger(BatchingLoggerProvider loggerProvider, string categoryName)
{
_provider = loggerProvider;
_category = categoryName;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return _provider.IsEnabled;
}
public void Log<TState>(DateTimeOffset timestamp, LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
var builder = new StringBuilder();
builder.Append(timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"));
builder.Append(" [");
builder.Append(logLevel.ToString());
builder.Append("] ");
builder.Append(_category);
var scopeProvider = _provider.ScopeProvider;
if (scopeProvider != null)
{
scopeProvider.ForEachScope((scope, stringBuilder) =>
{
stringBuilder.Append(" => ").Append(scope);
}, builder);
builder.AppendLine(":");
}
else
{
builder.Append(": ");
}
builder.AppendLine(formatter(state, exception));
if (exception != null)
{
builder.AppendLine(exception.ToString());
}
_provider.AddMessage(timestamp, builder.ToString());
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
Log(DateTimeOffset.Now, logLevel, eventId, state, exception, formatter);
}
}
}

View File

@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Options for a logger which batches up log messages.
/// </summary>
public class BatchingLoggerOptions
{
private int? _batchSize;
private int? _backgroundQueueSize = 1000;
private TimeSpan _flushPeriod = TimeSpan.FromSeconds(1);
/// <summary>
/// Gets or sets the period after which logs will be flushed to the store.
/// </summary>
public TimeSpan FlushPeriod
{
get { return _flushPeriod; }
set
{
if (value <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(FlushPeriod)} must be positive.");
}
_flushPeriod = value;
}
}
/// <summary>
/// Gets or sets the maximum size of the background log message queue or null for no limit.
/// After maximum queue size is reached log event sink would start blocking.
/// Defaults to <c>1000</c>.
/// </summary>
public int? BackgroundQueueSize
{
get { return _backgroundQueueSize; }
set
{
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(BackgroundQueueSize)} must be non-negative.");
}
_backgroundQueueSize = value;
}
}
/// <summary>
/// Gets or sets a maximum number of events to include in a single batch or null for no limit.
/// </summary>
/// Defaults to <c>null</c>.
public int? BatchSize
{
get { return _batchSize; }
set
{
if (value <= 0)
{
throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(BatchSize)} must be positive.");
}
_batchSize = value;
}
}
/// <summary>
/// Gets or sets value indicating if logger accepts and queues writes.
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Gets or sets a value indicating whether scopes should be included in the message.
/// Defaults to <c>false</c>.
/// </summary>
public bool IncludeScopes { get; set; } = false;
}
}

View File

@ -0,0 +1,208 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// A provider of <see cref="BatchingLogger"/> instances.
/// </summary>
public abstract class BatchingLoggerProvider : ILoggerProvider, ISupportExternalScope
{
private readonly List<LogMessage> _currentBatch = new List<LogMessage>();
private readonly TimeSpan _interval;
private readonly int? _queueSize;
private readonly int? _batchSize;
private readonly IDisposable _optionsChangeToken;
private int _messagesDropped;
private BlockingCollection<LogMessage> _messageQueue;
private Task _outputTask;
private CancellationTokenSource _cancellationTokenSource;
private bool _includeScopes;
private IExternalScopeProvider _scopeProvider;
internal IExternalScopeProvider ScopeProvider => _includeScopes ? _scopeProvider : null;
internal BatchingLoggerProvider(IOptionsMonitor<BatchingLoggerOptions> options)
{
// NOTE: Only IsEnabled is monitored
var loggerOptions = options.CurrentValue;
if (loggerOptions.BatchSize <= 0)
{
throw new ArgumentOutOfRangeException(nameof(loggerOptions.BatchSize), $"{nameof(loggerOptions.BatchSize)} must be a positive number.");
}
if (loggerOptions.FlushPeriod <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(nameof(loggerOptions.FlushPeriod), $"{nameof(loggerOptions.FlushPeriod)} must be longer than zero.");
}
_interval = loggerOptions.FlushPeriod;
_batchSize = loggerOptions.BatchSize;
_queueSize = loggerOptions.BackgroundQueueSize;
_optionsChangeToken = options.OnChange(UpdateOptions);
UpdateOptions(options.CurrentValue);
}
/// <summary>
/// Checks if the queue is enabled.
/// </summary>
public bool IsEnabled { get; private set; }
private void UpdateOptions(BatchingLoggerOptions options)
{
var oldIsEnabled = IsEnabled;
IsEnabled = options.IsEnabled;
_includeScopes = options.IncludeScopes;
if (oldIsEnabled != IsEnabled)
{
if (IsEnabled)
{
Start();
}
else
{
Stop();
}
}
}
internal abstract Task WriteMessagesAsync(IEnumerable<LogMessage> messages, CancellationToken token);
private async Task ProcessLogQueue()
{
while (!_cancellationTokenSource.IsCancellationRequested)
{
var limit = _batchSize ?? int.MaxValue;
while (limit > 0 && _messageQueue.TryTake(out var message))
{
_currentBatch.Add(message);
limit--;
}
var messagesDropped = Interlocked.Exchange(ref _messagesDropped, 0);
if (messagesDropped != 0)
{
_currentBatch.Add(new LogMessage(DateTimeOffset.Now, $"{messagesDropped} message(s) dropped because of queue size limit. Increase the queue size or decrease logging verbosity to avoid this.{Environment.NewLine}"));
}
if (_currentBatch.Count > 0)
{
try
{
await WriteMessagesAsync(_currentBatch, _cancellationTokenSource.Token);
}
catch
{
// ignored
}
_currentBatch.Clear();
}
else
{
await IntervalAsync(_interval, _cancellationTokenSource.Token);
}
}
}
/// <summary>
/// Wait for the given <see cref="TimeSpan"/>.
/// </summary>
/// <param name="interval">The amount of time to wait.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the delay.</param>
/// <returns>A <see cref="Task"/> which completes when the <paramref name="interval"/> has passed or the <paramref name="cancellationToken"/> has been canceled.</returns>
protected virtual Task IntervalAsync(TimeSpan interval, CancellationToken cancellationToken)
{
return Task.Delay(interval, cancellationToken);
}
internal void AddMessage(DateTimeOffset timestamp, string message)
{
if (!_messageQueue.IsAddingCompleted)
{
try
{
if (!_messageQueue.TryAdd(new LogMessage(timestamp, message), millisecondsTimeout: 0, cancellationToken: _cancellationTokenSource.Token))
{
Interlocked.Increment(ref _messagesDropped);
}
}
catch
{
//cancellation token canceled or CompleteAdding called
}
}
}
private void Start()
{
_messageQueue = _queueSize == null ?
new BlockingCollection<LogMessage>(new ConcurrentQueue<LogMessage>()) :
new BlockingCollection<LogMessage>(new ConcurrentQueue<LogMessage>(), _queueSize.Value);
_cancellationTokenSource = new CancellationTokenSource();
_outputTask = Task.Run(ProcessLogQueue);
}
private void Stop()
{
_cancellationTokenSource.Cancel();
_messageQueue.CompleteAdding();
try
{
_outputTask.Wait(_interval);
}
catch (TaskCanceledException)
{
}
catch (AggregateException ex) when (ex.InnerExceptions.Count == 1 && ex.InnerExceptions[0] is TaskCanceledException)
{
}
}
/// <inheritdoc/>
public void Dispose()
{
_optionsChangeToken?.Dispose();
if (IsEnabled)
{
Stop();
}
}
/// <summary>
/// Creates a <see cref="BatchingLogger"/> with the given <paramref name="categoryName"/>.
/// </summary>
/// <param name="categoryName">The name of the category to create this logger with.</param>
/// <returns>The <see cref="BatchingLogger"/> that was created.</returns>
public ILogger CreateLogger(string categoryName)
{
return new BatchingLogger(this, categoryName);
}
/// <summary>
/// Sets the scope on this provider.
/// </summary>
/// <param name="scopeProvider">Provides the scope.</param>
void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider)
{
_scopeProvider = scopeProvider;
}
}
}

View File

@ -0,0 +1,97 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <inheritdoc />
internal class BlobAppendReferenceWrapper : ICloudAppendBlob
{
private readonly Uri _fullUri;
private readonly HttpClient _client;
private readonly Uri _appendUri;
public BlobAppendReferenceWrapper(string containerUrl, string name, HttpClient client)
{
var uriBuilder = new UriBuilder(containerUrl);
uriBuilder.Path += "/" + name;
_fullUri = uriBuilder.Uri;
AppendBlockQuery(uriBuilder);
_appendUri = uriBuilder.Uri;
_client = client;
}
/// <inheritdoc />
public async Task AppendAsync(ArraySegment<byte> data, CancellationToken cancellationToken)
{
Task<HttpResponseMessage> AppendDataAsync()
{
var message = new HttpRequestMessage(HttpMethod.Put, _appendUri)
{
Content = new ByteArrayContent(data.Array, data.Offset, data.Count)
};
AddCommonHeaders(message);
return _client.SendAsync(message, cancellationToken);
}
var response = await AppendDataAsync();
if (response.StatusCode == HttpStatusCode.NotFound)
{
// If no blob exists try creating it
var message = new HttpRequestMessage(HttpMethod.Put, _fullUri)
{
// Set Content-Length to 0 to create "Append Blob"
Content = new ByteArrayContent(Array.Empty<byte>()),
Headers =
{
{ "If-None-Match", "*" }
}
};
AddCommonHeaders(message);
response = await _client.SendAsync(message, cancellationToken);
// If result is 2** or 412 try to append again
if (response.IsSuccessStatusCode ||
response.StatusCode == HttpStatusCode.PreconditionFailed)
{
// Retry sending data after blob creation
response = await AppendDataAsync();
}
}
response.EnsureSuccessStatusCode();
}
private static void AddCommonHeaders(HttpRequestMessage message)
{
message.Headers.Add("x-ms-blob-type", "AppendBlob");
message.Headers.Add("x-ms-version", "2016-05-31");
message.Headers.Date = DateTimeOffset.UtcNow;
}
private static void AppendBlockQuery(UriBuilder uriBuilder)
{
// See https://msdn.microsoft.com/en-us/library/system.uribuilder.query.aspx for:
// Note: Do not append a string directly to Query property.
// If the length of Query is greater than 1, retrieve the property value
// as a string, remove the leading question mark, append the new query string,
// and set the property with the combined string.
var queryToAppend = "comp=appendblock";
if (uriBuilder.Query != null && uriBuilder.Query.Length > 1)
uriBuilder.Query = uriBuilder.Query.Substring(1) + "&" + queryToAppend;
else
uriBuilder.Query = queryToAppend;
}
}
}

View File

@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class BlobLoggerConfigureOptions : BatchLoggerConfigureOptions, IConfigureOptions<AzureBlobLoggerOptions>
{
private readonly IConfiguration _configuration;
private readonly IWebAppContext _context;
public BlobLoggerConfigureOptions(IConfiguration configuration, IWebAppContext context)
: base(configuration, "AzureBlobEnabled")
{
_configuration = configuration;
_context = context;
}
public void Configure(AzureBlobLoggerOptions options)
{
base.Configure(options);
options.ContainerUrl = _configuration.GetSection("APPSETTING_DIAGNOSTICS_AZUREBLOBCONTAINERSASURL")?.Value;
options.ApplicationName = _context.SiteName;
options.ApplicationInstanceId = _context.SiteInstanceId;
}
}
}

View File

@ -0,0 +1,92 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// The <see cref="ILoggerProvider"/> implementation that stores messages by appending them to Azure Blob in batches.
/// </summary>
[ProviderAlias("AzureAppServicesBlob")]
public class BlobLoggerProvider : BatchingLoggerProvider
{
private readonly string _appName;
private readonly string _fileName;
private readonly Func<string, ICloudAppendBlob> _blobReferenceFactory;
private readonly HttpClient _httpClient;
/// <summary>
/// Creates a new instance of <see cref="BlobLoggerProvider"/>
/// </summary>
/// <param name="options">The options to use when creating a provider.</param>
public BlobLoggerProvider(IOptionsMonitor<AzureBlobLoggerOptions> options)
: this(options, null)
{
_blobReferenceFactory = name => new BlobAppendReferenceWrapper(
options.CurrentValue.ContainerUrl,
name,
_httpClient);
}
/// <summary>
/// Creates a new instance of <see cref="BlobLoggerProvider"/>
/// </summary>
/// <param name="blobReferenceFactory">The container to store logs to.</param>
/// <param name="options">Options to be used in creating a logger.</param>
internal BlobLoggerProvider(
IOptionsMonitor<AzureBlobLoggerOptions> options,
Func<string, ICloudAppendBlob> blobReferenceFactory) :
base(options)
{
var value = options.CurrentValue;
_appName = value.ApplicationName;
_fileName = value.ApplicationInstanceId + "_" + value.BlobName;
_blobReferenceFactory = blobReferenceFactory;
_httpClient = new HttpClient();
}
internal override async Task WriteMessagesAsync(IEnumerable<LogMessage> messages, CancellationToken cancellationToken)
{
var eventGroups = messages.GroupBy(GetBlobKey);
foreach (var eventGroup in eventGroups)
{
var key = eventGroup.Key;
var blobName = $"{_appName}/{key.Year}/{key.Month:00}/{key.Day:00}/{key.Hour:00}/{_fileName}";
var blob = _blobReferenceFactory(blobName);
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
{
foreach (var logEvent in eventGroup)
{
writer.Write(logEvent.Message);
}
await writer.FlushAsync();
var tryGetBuffer = stream.TryGetBuffer(out var buffer);
Debug.Assert(tryGetBuffer);
await blob.AppendAsync(buffer, cancellationToken);
}
}
}
private (int Year, int Month, int Day, int Hour) GetBlobKey(LogMessage e)
{
return (e.Timestamp.Year,
e.Timestamp.Month,
e.Timestamp.Day,
e.Timestamp.Hour);
}
}
}

View File

@ -0,0 +1,51 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class ConfigurationBasedLevelSwitcher: IConfigureOptions<LoggerFilterOptions>
{
private readonly IConfiguration _configuration;
private readonly Type _provider;
private readonly string _levelKey;
public ConfigurationBasedLevelSwitcher(IConfiguration configuration, Type provider, string levelKey)
{
_configuration = configuration;
_provider = provider;
_levelKey = levelKey;
}
public void Configure(LoggerFilterOptions options)
{
options.Rules.Add(new LoggerFilterRule(_provider.FullName, null, GetLogLevel(), null));
}
private LogLevel GetLogLevel()
{
return TextToLogLevel(_configuration.GetSection(_levelKey)?.Value);
}
private static LogLevel TextToLogLevel(string text)
{
switch (text?.ToUpperInvariant())
{
case "ERROR":
return LogLevel.Error;
case "WARNING":
return LogLevel.Warning;
case "INFORMATION":
return LogLevel.Information;
case "VERBOSE":
return LogLevel.Trace;
default:
return LogLevel.None;
}
}
}
}

View File

@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class FileLoggerConfigureOptions : BatchLoggerConfigureOptions, IConfigureOptions<AzureFileLoggerOptions>
{
private readonly IWebAppContext _context;
public FileLoggerConfigureOptions(IConfiguration configuration, IWebAppContext context)
: base(configuration, "AzureDriveEnabled")
{
_context = context;
}
public void Configure(AzureFileLoggerOptions options)
{
base.Configure(options);
options.LogDirectory = Path.Combine(_context.HomeFolder, "LogFiles", "Application");
}
}
}

View File

@ -0,0 +1,89 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// A <see cref="BatchingLoggerProvider"/> which writes out to a file.
/// </summary>
[ProviderAlias("AzureAppServicesFile")]
public class FileLoggerProvider : BatchingLoggerProvider
{
private readonly string _path;
private readonly string _fileName;
private readonly int? _maxFileSize;
private readonly int? _maxRetainedFiles;
/// <summary>
/// Creates a new instance of <see cref="FileLoggerProvider"/>.
/// </summary>
/// <param name="options">The options to use when creating a provider.</param>
public FileLoggerProvider(IOptionsMonitor<AzureFileLoggerOptions> options) : base(options)
{
var loggerOptions = options.CurrentValue;
_path = loggerOptions.LogDirectory;
_fileName = loggerOptions.FileName;
_maxFileSize = loggerOptions.FileSizeLimit;
_maxRetainedFiles = loggerOptions.RetainedFileCountLimit;
}
internal override async Task WriteMessagesAsync(IEnumerable<LogMessage> messages, CancellationToken cancellationToken)
{
Directory.CreateDirectory(_path);
foreach (var group in messages.GroupBy(GetGrouping))
{
var fullName = GetFullName(group.Key);
var fileInfo = new FileInfo(fullName);
if (_maxFileSize > 0 && fileInfo.Exists && fileInfo.Length > _maxFileSize)
{
return;
}
using (var streamWriter = File.AppendText(fullName))
{
foreach (var item in group)
{
await streamWriter.WriteAsync(item.Message);
}
}
}
RollFiles();
}
private string GetFullName((int Year, int Month, int Day) group)
{
return Path.Combine(_path, $"{_fileName}{group.Year:0000}{group.Month:00}{group.Day:00}.txt");
}
private (int Year, int Month, int Day) GetGrouping(LogMessage message)
{
return (message.Timestamp.Year, message.Timestamp.Month, message.Timestamp.Day);
}
private void RollFiles()
{
if (_maxRetainedFiles > 0)
{
var files = new DirectoryInfo(_path)
.GetFiles(_fileName + "*")
.OrderByDescending(f => f.Name)
.Skip(_maxRetainedFiles.Value);
foreach (var item in files)
{
item.Delete();
}
}
}
}
}

View File

@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Represents an append blob, a type of blob where blocks of data are always committed to the end of the blob.
/// </summary>
internal interface ICloudAppendBlob
{
/// <summary>
/// Initiates an asynchronous operation to open a stream for writing to the blob.
/// </summary>
/// <returns>A <see cref="T:System.Threading.Tasks.Task`1" /> object of type <see cref="Stream" /> that represents the asynchronous operation.</returns>
Task AppendAsync(ArraySegment<byte> data, CancellationToken cancellationToken);
}
}

View File

@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Represents an Azure WebApp context
/// </summary>
internal interface IWebAppContext
{
/// <summary>
/// Gets the path to the home folder if running in Azure WebApp
/// </summary>
string HomeFolder { get; }
/// <summary>
/// Gets the name of site if running in Azure WebApp
/// </summary>
string SiteName { get; }
/// <summary>
/// Gets the id of site if running in Azure WebApp
/// </summary>
string SiteInstanceId { get; }
/// <summary>
/// Gets a value indicating whether or new we're in an Azure WebApp
/// </summary>
bool IsRunningInAzureWebApp { get; }
}
}

View File

@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal readonly struct LogMessage
{
public LogMessage(DateTimeOffset timestamp, string message)
{
Timestamp = timestamp;
Message = message;
}
public DateTimeOffset Timestamp { get; }
public string Message { get; }
}
}

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Logger implementation to support Azure App Services 'Diagnostics logs' and 'Log stream' features.</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<IsPackable>true</IsPackable>
<IsShipping>true</IsShipping>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.Extensions.Logging.AzureAppServices.Tests" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
<Reference Include="Microsoft.Extensions.Configuration.Json" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" />
<Reference Include="Microsoft.Extensions.Logging.Configuration" />
<Reference Include="Microsoft.Extensions.Logging" />
<Reference Include="System.ValueTuple" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

View File

@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using Microsoft.Extensions.Configuration;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
internal class SiteConfigurationProvider
{
public static IConfiguration GetAzureLoggingConfiguration(IWebAppContext context)
{
var settingsFolder = Path.Combine(context.HomeFolder, "site", "diagnostics");
var settingsFile = Path.Combine(settingsFolder, "settings.json");
return new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile(settingsFile, optional: true, reloadOnChange: true)
.Build();
}
}
}

View File

@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.Extensions.Logging.AzureAppServices
{
/// <summary>
/// Represents the default implementation of <see cref="IWebAppContext"/>.
/// </summary>
internal class WebAppContext : IWebAppContext
{
/// <summary>
/// Gets the default instance of the WebApp context.
/// </summary>
public static WebAppContext Default { get; } = new WebAppContext();
private WebAppContext() { }
/// <inheritdoc />
public string HomeFolder { get; } = Environment.GetEnvironmentVariable("HOME");
/// <inheritdoc />
public string SiteName { get; } = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");
/// <inheritdoc />
public string SiteInstanceId { get; } = Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID");
/// <inheritdoc />
public bool IsRunningInAzureWebApp => !string.IsNullOrEmpty(HomeFolder) &&
!string.IsNullOrEmpty(SiteName);
}
}

View File

@ -0,0 +1,186 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.Logging.AzureAppServices.Test
{
public class AzureAppendBlobTests
{
public string _containerUrl = "https://host/container?query=1";
public string _blobName = "blob/path";
[Fact]
public async Task SendsDataAsStream()
{
var testMessageHandler = new TestMessageHandler(async message =>
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1&comp=appendblock", message.RequestUri.ToString());
Assert.Equal(new byte[] { 0, 2, 3 }, await message.Content.ReadAsByteArrayAsync());
AssertDefaultHeaders(message);
return new HttpResponseMessage(HttpStatusCode.OK);
});
var blob = new BlobAppendReferenceWrapper(_containerUrl, _blobName, new HttpClient(testMessageHandler));
await blob.AppendAsync(new ArraySegment<byte>(new byte[] { 0, 2, 3 }), CancellationToken.None);
}
private static void AssertDefaultHeaders(HttpRequestMessage message)
{
Assert.Equal(new[] {"AppendBlob"}, message.Headers.GetValues("x-ms-blob-type"));
Assert.Equal(new[] {"2016-05-31"}, message.Headers.GetValues("x-ms-version"));
Assert.NotNull(message.Headers.Date);
}
[Theory]
[InlineData(HttpStatusCode.Created)]
[InlineData(HttpStatusCode.PreconditionFailed)]
public async Task CreatesBlobIfNotExist(HttpStatusCode createStatusCode)
{
var stage = 0;
var testMessageHandler = new TestMessageHandler(async message =>
{
// First PUT request
if (stage == 0)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1&comp=appendblock", message.RequestUri.ToString());
Assert.Equal(new byte[] { 0, 2, 3 }, await message.Content.ReadAsByteArrayAsync());
Assert.Equal(3, message.Content.Headers.ContentLength);
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
// Create request
if (stage == 1)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1", message.RequestUri.ToString());
Assert.Equal(0, message.Content.Headers.ContentLength);
Assert.Equal(new[] { "*" }, message.Headers.GetValues("If-None-Match"));
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(createStatusCode);
}
// First PUT request
if (stage == 2)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1&comp=appendblock", message.RequestUri.ToString());
Assert.Equal(new byte[] { 0, 2, 3 }, await message.Content.ReadAsByteArrayAsync());
Assert.Equal(3, message.Content.Headers.ContentLength);
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(HttpStatusCode.Created);
}
throw new NotImplementedException();
});
var blob = new BlobAppendReferenceWrapper(_containerUrl, _blobName, new HttpClient(testMessageHandler));
await blob.AppendAsync(new ArraySegment<byte>(new byte[] { 0, 2, 3 }), CancellationToken.None);
Assert.Equal(3, stage);
}
[Fact]
public async Task ThrowsForUnknownStatus()
{
var stage = 0;
var testMessageHandler = new TestMessageHandler(async message =>
{
// First PUT request
if (stage == 0)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1&comp=appendblock", message.RequestUri.ToString());
Assert.Equal(new byte[] { 0, 2, 3 }, await message.Content.ReadAsByteArrayAsync());
Assert.Equal(3, message.Content.Headers.ContentLength);
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
throw new NotImplementedException();
});
var blob = new BlobAppendReferenceWrapper(_containerUrl, _blobName, new HttpClient(testMessageHandler));
await Assert.ThrowsAsync<HttpRequestException>(() => blob.AppendAsync(new ArraySegment<byte>(new byte[] { 0, 2, 3 }), CancellationToken.None));
Assert.Equal(1, stage);
}
[Fact]
public async Task ThrowsForUnknownStatusDuringCreation()
{
var stage = 0;
var testMessageHandler = new TestMessageHandler(async message =>
{
// First PUT request
if (stage == 0)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1&comp=appendblock", message.RequestUri.ToString());
Assert.Equal(new byte[] { 0, 2, 3 }, await message.Content.ReadAsByteArrayAsync());
Assert.Equal(3, message.Content.Headers.ContentLength);
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
// Create request
if (stage == 1)
{
Assert.Equal(HttpMethod.Put, message.Method);
Assert.Equal("https://host/container/blob/path?query=1", message.RequestUri.ToString());
Assert.Equal(0, message.Content.Headers.ContentLength);
Assert.Equal(new[] { "*" }, message.Headers.GetValues("If-None-Match"));
AssertDefaultHeaders(message);
stage++;
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
throw new NotImplementedException();
});
var blob = new BlobAppendReferenceWrapper(_containerUrl, _blobName, new HttpClient(testMessageHandler));
await Assert.ThrowsAsync<HttpRequestException>(() => blob.AppendAsync(new ArraySegment<byte>(new byte[] { 0, 2, 3 }), CancellationToken.None));
Assert.Equal(2, stage);
}
private class TestMessageHandler : HttpMessageHandler
{
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>> _callback;
public TestMessageHandler(Func<HttpRequestMessage, Task<HttpResponseMessage>> callback)
{
_callback = callback;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await _callback(request);
}
}
}
}

View File

@ -0,0 +1,98 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Xunit;
namespace Microsoft.Extensions.Logging.AzureAppServices.Test
{
public class AzureBlobSinkTests
{
DateTimeOffset _timestampOne = new DateTimeOffset(2016, 05, 04, 03, 02, 01, TimeSpan.Zero);
[Fact]
public async Task WritesMessagesInBatches()
{
var blob = new Mock<ICloudAppendBlob>();
var buffers = new List<byte[]>();
blob.Setup(b => b.AppendAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<CancellationToken>()))
.Callback((ArraySegment<byte> s, CancellationToken ct) => buffers.Add(ToArray(s)))
.Returns(Task.CompletedTask);
var sink = new TestBlobSink(name => blob.Object);
var logger = (BatchingLogger)sink.CreateLogger("Cat");
await sink.IntervalControl.Pause;
for (int i = 0; i < 5; i++)
{
logger.Log(_timestampOne, LogLevel.Information, 0, "Text " + i, null, (state, ex) => state);
}
sink.IntervalControl.Resume();
await sink.IntervalControl.Pause;
Assert.Single(buffers);
Assert.Equal(
"2016-05-04 03:02:01.000 +00:00 [Information] Cat: Text 0" + Environment.NewLine +
"2016-05-04 03:02:01.000 +00:00 [Information] Cat: Text 1" + Environment.NewLine +
"2016-05-04 03:02:01.000 +00:00 [Information] Cat: Text 2" + Environment.NewLine +
"2016-05-04 03:02:01.000 +00:00 [Information] Cat: Text 3" + Environment.NewLine +
"2016-05-04 03:02:01.000 +00:00 [Information] Cat: Text 4" + Environment.NewLine,
Encoding.UTF8.GetString(buffers[0]));
}
[Fact]
public async Task GroupsByHour()
{
var blob = new Mock<ICloudAppendBlob>();
var buffers = new List<byte[]>();
var names = new List<string>();
blob.Setup(b => b.AppendAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<CancellationToken>()))
.Callback((ArraySegment<byte> s, CancellationToken ct) => buffers.Add(ToArray(s)))
.Returns(Task.CompletedTask);
var sink = new TestBlobSink(name =>
{
names.Add(name);
return blob.Object;
});
var logger = (BatchingLogger)sink.CreateLogger("Cat");
await sink.IntervalControl.Pause;
var startDate = _timestampOne;
for (int i = 0; i < 3; i++)
{
logger.Log(startDate, LogLevel.Information, 0, "Text " + i, null, (state, ex) => state);
startDate = startDate.AddHours(1);
}
sink.IntervalControl.Resume();
await sink.IntervalControl.Pause;
Assert.Equal(3, buffers.Count);
Assert.Equal("appname/2016/05/04/03/42_filename", names[0]);
Assert.Equal("appname/2016/05/04/04/42_filename", names[1]);
Assert.Equal("appname/2016/05/04/05/42_filename", names[2]);
}
private byte[] ToArray(ArraySegment<byte> inputStream)
{
return inputStream.Array
.Skip(inputStream.Offset)
.Take(inputStream.Count)
.ToArray();
}
}
}

View File

@ -0,0 +1,70 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using Moq;
using Xunit;
namespace Microsoft.Extensions.Logging.AzureAppServices.Test
{
public class AzureDiagnosticsConfigurationProviderTests
{
[Fact]
public void NoConfigFile()
{
var tempFolder = Path.Combine(Path.GetTempPath(), "AzureWebAppLoggerThisFolderShouldNotExist");
var contextMock = new Mock<IWebAppContext>();
contextMock.SetupGet(c => c.HomeFolder)
.Returns(tempFolder);
var config = SiteConfigurationProvider.GetAzureLoggingConfiguration(contextMock.Object);
Assert.NotNull(config);
}
[Fact]
public void ReadsSettingsFileAndEnvironment()
{
var tempFolder = Path.Combine(Path.GetTempPath(), "WebAppLoggerConfigurationDisabledInSettingsFile");
try
{
var settingsFolder = Path.Combine(tempFolder, "site", "diagnostics");
var settingsFile = Path.Combine(settingsFolder, "settings.json");
if (!Directory.Exists(settingsFolder))
{
Directory.CreateDirectory(settingsFolder);
}
Environment.SetEnvironmentVariable("RANDOM_ENVIRONMENT_VARIABLE", "USEFUL_VALUE");
File.WriteAllText(settingsFile, @"{ ""key"":""test value"" }");
var contextMock = new Mock<IWebAppContext>();
contextMock.SetupGet(c => c.HomeFolder)
.Returns(tempFolder);
var config = SiteConfigurationProvider.GetAzureLoggingConfiguration(contextMock.Object);
Assert.Equal("test value", config["key"]);
Assert.Equal("USEFUL_VALUE", config["RANDOM_ENVIRONMENT_VARIABLE"]);
}
finally
{
if (Directory.Exists(tempFolder))
{
try
{
Directory.Delete(tempFolder, recursive: true);
}
catch
{
// Don't break the test if temp folder deletion fails.
}
}
}
}
}
}

View File

@ -0,0 +1,136 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.Logging.AzureAppServices.Test
{
public class BatchingLoggerProviderTests
{
private DateTimeOffset _timestampOne = new DateTimeOffset(2016, 05, 04, 03, 02, 01, TimeSpan.Zero);
private string _nl = Environment.NewLine;
private Regex _timeStampRegex = new Regex(@"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} .\d{2}:\d{2} ");
[Fact]
public async Task LogsInIntervals()
{
var provider = new TestBatchingLoggingProvider();
var logger = (BatchingLogger)provider.CreateLogger("Cat");
await provider.IntervalControl.Pause;
logger.Log(_timestampOne, LogLevel.Information, 0, "Info message", null, (state, ex) => state);
logger.Log(_timestampOne.AddHours(1), LogLevel.Error, 0, "Error message", null, (state, ex) => state);
provider.IntervalControl.Resume();
await provider.IntervalControl.Pause;
Assert.Equal("2016-05-04 03:02:01.000 +00:00 [Information] Cat: Info message" + _nl, provider.Batches[0][0].Message);
Assert.Equal("2016-05-04 04:02:01.000 +00:00 [Error] Cat: Error message" + _nl, provider.Batches[0][1].Message);
}
[Fact]
public async Task IncludesScopes()
{
var provider = new TestBatchingLoggingProvider(includeScopes: true);
var factory = new LoggerFactory(new [] { provider });
var logger = factory.CreateLogger("Cat");
await provider.IntervalControl.Pause;
using (logger.BeginScope("Scope"))
{
using (logger.BeginScope("Scope2"))
{
logger.Log(LogLevel.Information, 0, "Info message", null, (state, ex) => state);
}
}
provider.IntervalControl.Resume();
await provider.IntervalControl.Pause;
Assert.Matches(_timeStampRegex, provider.Batches[0][0].Message);
Assert.EndsWith(
" [Information] Cat => Scope => Scope2:" + _nl +
"Info message" + _nl,
provider.Batches[0][0].Message);
}
[Fact]
public async Task RespectsBatchSize()
{
var provider = new TestBatchingLoggingProvider(maxBatchSize: 1);
var logger = (BatchingLogger)provider.CreateLogger("Cat");
await provider.IntervalControl.Pause;
logger.Log(_timestampOne, LogLevel.Information, 0, "Info message", null, (state, ex) => state);
logger.Log(_timestampOne.AddHours(1), LogLevel.Error, 0, "Error message", null, (state, ex) => state);
provider.IntervalControl.Resume();
await provider.IntervalControl.Pause;
Assert.Equal(2, provider.Batches.Count);
Assert.Single(provider.Batches[0]);
Assert.Equal("2016-05-04 03:02:01.000 +00:00 [Information] Cat: Info message" + _nl, provider.Batches[0][0].Message);
Assert.Single(provider.Batches[1]);
Assert.Equal("2016-05-04 04:02:01.000 +00:00 [Error] Cat: Error message" + _nl, provider.Batches[1][0].Message);
}
[Fact]
public async Task DropsMessagesWhenReachingMaxQueue()
{
var provider = new TestBatchingLoggingProvider(maxQueueSize: 1);
var logger = (BatchingLogger)provider.CreateLogger("Cat");
await provider.IntervalControl.Pause;
logger.Log(_timestampOne, LogLevel.Information, 0, "Info message", null, (state, ex) => state);
logger.Log(_timestampOne.AddHours(1), LogLevel.Error, 0, "Error message", null, (state, ex) => state);
provider.IntervalControl.Resume();
await provider.IntervalControl.Pause;
Assert.Equal(2, provider.Batches[0].Length);
Assert.Equal("2016-05-04 03:02:01.000 +00:00 [Information] Cat: Info message" + _nl, provider.Batches[0][0].Message);
Assert.Equal("1 message(s) dropped because of queue size limit. Increase the queue size or decrease logging verbosity to avoid this." + _nl, provider.Batches[0][1].Message);
}
private class TestBatchingLoggingProvider: BatchingLoggerProvider
{
public List<LogMessage[]> Batches { get; } = new List<LogMessage[]>();
public ManualIntervalControl IntervalControl { get; } = new ManualIntervalControl();
public TestBatchingLoggingProvider(TimeSpan? interval = null, int? maxBatchSize = null, int? maxQueueSize = null, bool includeScopes = false)
: base(new OptionsWrapperMonitor<BatchingLoggerOptions>(new BatchingLoggerOptions
{
FlushPeriod = interval ?? TimeSpan.FromSeconds(1),
BatchSize = maxBatchSize,
BackgroundQueueSize = maxQueueSize,
IsEnabled = true,
IncludeScopes = includeScopes
}))
{
}
internal override Task WriteMessagesAsync(IEnumerable<LogMessage> messages, CancellationToken token)
{
Batches.Add(messages.ToArray());
return Task.CompletedTask;
}
protected override Task IntervalAsync(TimeSpan interval, CancellationToken cancellationToken)
{
return IntervalControl.IntervalAsync();
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More