Merge branch 'main' into xakep139/log-source-gen-WPF-bug

This commit is contained in:
Nikita Balabaev 2024-05-22 22:00:11 +02:00
Родитель 75a0edec84 f580cdca8a
Коммит 10283f004d
9 изменённых файлов: 220 добавлений и 38 удалений

Просмотреть файл

@ -170,13 +170,13 @@
</Dependency>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.24225.1">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="8.0.0-beta.24266.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>67d23f4ba1813b315e7e33c71d18b63475f5c5f8</Sha>
<Sha>e6f70c7dd528f05cd28cec2a179d58c22e91d9ac</Sha>
</Dependency>
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="8.0.0-beta.24225.1">
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="8.0.0-beta.24266.3">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>67d23f4ba1813b315e7e33c71d18b63475f5c5f8</Sha>
<Sha>e6f70c7dd528f05cd28cec2a179d58c22e91d9ac</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>

Просмотреть файл

@ -1,6 +1,7 @@
parameters:
runAsPublic: false
sourceIndexPackageVersion: 1.0.1-20230228.2
sourceIndexUploadPackageVersion: 2.0.0-20240502.12
sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2
sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
@ -14,15 +15,15 @@ jobs:
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.condition }}
variables:
- name: SourceIndexPackageVersion
value: ${{ parameters.sourceIndexPackageVersion }}
- name: SourceIndexUploadPackageVersion
value: ${{ parameters.sourceIndexUploadPackageVersion }}
- name: SourceIndexProcessBinlogPackageVersion
value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
- name: SourceIndexPackageSource
value: ${{ parameters.sourceIndexPackageSource }}
- name: BinlogPath
value: ${{ parameters.binlogPath }}
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- group: source-dot-net stage1 variables
- template: /eng/common/templates-official/variables/pool-providers.yml
- template: /eng/common/templates/variables/pool-providers.yml
${{ if ne(parameters.pool, '') }}:
pool: ${{ parameters.pool }}
@ -33,24 +34,23 @@ jobs:
demands: ImageOverride -equals windows.vs2019.amd64.open
${{ if eq(variables['System.TeamProject'], 'internal') }}:
name: $(DncEngInternalBuildPool)
image: windows.vs2022.amd64
os: windows
demands: ImageOverride -equals windows.vs2019.amd64
steps:
- ${{ each preStep in parameters.preSteps }}:
- ${{ preStep }}
- task: UseDotNet@2
displayName: Use .NET Core SDK 6
displayName: Use .NET 8 SDK
inputs:
packageType: sdk
version: 6.0.x
version: 8.0.x
installationPath: $(Agent.TempDirectory)/dotnet
workingDirectory: $(Agent.TempDirectory)
- script: |
$(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: Download Tools
# Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
workingDirectory: $(Agent.TempDirectory)
@ -62,7 +62,24 @@ jobs:
displayName: Process Binlog into indexable sln
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name)
displayName: Upload stage1 artifacts to source index
env:
BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url)
- task: AzureCLI@2
displayName: Get stage 1 auth token
inputs:
azureSubscription: 'SourceDotNet Stage1 Publish'
addSpnToEnvironment: true
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId"
echo "##vso[task.setvariable variable=ARM_ID_TOKEN]$env:idToken"
echo "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId"
- script: |
echo "Client ID: $(ARM_CLIENT_ID)"
echo "ID Token: $(ARM_ID_TOKEN)"
echo "Tenant ID: $(ARM_TENANT_ID)"
az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN)
displayName: "Login to Azure"
- script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
displayName: Upload stage1 artifacts to source index

Просмотреть файл

@ -1,6 +1,7 @@
parameters:
runAsPublic: false
sourceIndexPackageVersion: 1.0.1-20230228.2
sourceIndexUploadPackageVersion: 2.0.0-20240502.12
sourceIndexProcessBinlogPackageVersion: 1.0.1-20240129.2
sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
preSteps: []
@ -14,14 +15,14 @@ jobs:
dependsOn: ${{ parameters.dependsOn }}
condition: ${{ parameters.condition }}
variables:
- name: SourceIndexPackageVersion
value: ${{ parameters.sourceIndexPackageVersion }}
- name: SourceIndexUploadPackageVersion
value: ${{ parameters.sourceIndexUploadPackageVersion }}
- name: SourceIndexProcessBinlogPackageVersion
value: ${{ parameters.sourceIndexProcessBinlogPackageVersion }}
- name: SourceIndexPackageSource
value: ${{ parameters.sourceIndexPackageSource }}
- name: BinlogPath
value: ${{ parameters.binlogPath }}
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- group: source-dot-net stage1 variables
- template: /eng/common/templates/variables/pool-providers.yml
${{ if ne(parameters.pool, '') }}:
@ -40,16 +41,16 @@ jobs:
- ${{ preStep }}
- task: UseDotNet@2
displayName: Use .NET Core SDK 6
displayName: Use .NET 8 SDK
inputs:
packageType: sdk
version: 6.0.x
version: 8.0.x
installationPath: $(Agent.TempDirectory)/dotnet
workingDirectory: $(Agent.TempDirectory)
- script: |
$(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(sourceIndexProcessBinlogPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
$(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(sourceIndexUploadPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: Download Tools
# Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
workingDirectory: $(Agent.TempDirectory)
@ -61,7 +62,24 @@ jobs:
displayName: Process Binlog into indexable sln
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name)
displayName: Upload stage1 artifacts to source index
env:
BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url)
- task: AzureCLI@2
displayName: Get stage 1 auth token
inputs:
azureSubscription: 'SourceDotNet Stage1 Publish'
addSpnToEnvironment: true
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
echo "##vso[task.setvariable variable=ARM_CLIENT_ID]$env:servicePrincipalId"
echo "##vso[task.setvariable variable=ARM_ID_TOKEN]$env:idToken"
echo "##vso[task.setvariable variable=ARM_TENANT_ID]$env:tenantId"
- script: |
echo "Client ID: $(ARM_CLIENT_ID)"
echo "ID Token: $(ARM_ID_TOKEN)"
echo "Tenant ID: $(ARM_TENANT_ID)"
az login --service-principal -u $(ARM_CLIENT_ID) --tenant $(ARM_TENANT_ID) --allow-no-subscriptions --federated-token $(ARM_ID_TOKEN)
displayName: "Login to Azure"
- script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
displayName: Upload stage1 artifacts to source index

Просмотреть файл

@ -51,7 +51,6 @@
<PackageVersion Include="System.IO.Hashing" Version="$(SystemIOHashingVersion)" />
<PackageVersion Include="System.Memory" Version="4.5.5" />
<PackageVersion Include="System.Net.Http.Json" Version="$(SystemNetHttpJsonVersion)" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
<PackageVersion Include="System.Text.Json" Version="$(SystemTextJsonVersion)" />

Просмотреть файл

@ -16,7 +16,7 @@
"msbuild-sdks": {
"Microsoft.Build.NoTargets": "3.7.0",
"Microsoft.Build.Traversal": "3.2.0",
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24225.1",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24225.1"
"Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24266.3",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24266.3"
}
}

Просмотреть файл

@ -37,7 +37,6 @@
<PackageReference Include="Microsoft.Bcl.TimeProvider" Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" />
<PackageReference Include="System.Collections.Immutable" Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))" />
<Reference Include="System.Net.Http" Condition="'$(TargetFramework)' == 'net462'" />
</ItemGroup>
<ItemGroup>

Просмотреть файл

@ -42,6 +42,102 @@ timeProvider.Advance(TimeSpan.FromSeconds(5));
myComponent.CheckState();
```
## Use ConfigureAwait(true) with FakeTimeProvider.Advance
The Advance method is used to simulate the passage of time. This can be useful in tests where you need to control the timing of asynchronous operations.
When awaiting a task in a test that uses `FakeTimeProvider`, it's important to use `ConfigureAwait(true)`.
Here's an example:
```cs
await provider.Delay(TimeSpan.FromSeconds(delay)).ConfigureAwait(true);
```
This ensures that the continuation of the awaited task (i.e., the code that comes after the await statement) runs in the original context.
For a more realistic example, consider the following test using Polly:
```cs
using Polly;
using Polly.Retry;
public class SomeService(TimeProvider timeProvider)
{
// Don't do this in real life, not thread safe
public int Tries { get; private set; }
private readonly ResiliencePipeline _retryPipeline = new ResiliencePipelineBuilder { TimeProvider = timeProvider }
.AddRetry(
new RetryStrategyOptions
{
ShouldHandle = new PredicateBuilder().Handle<InvalidOperationException>(),
Delay = TimeSpan.FromSeconds(1),
MaxRetryAttempts = 2,
BackoffType = DelayBackoffType.Linear,
})
.Build();
public async Task<int> PollyRetry(double taskDelay, double cancellationSeconds)
{
CancellationTokenSource cts = new(TimeSpan.FromSeconds(cancellationSeconds), timeProvider);
Tries = 0;
// get a context from the pool and return it when done
var context = ResilienceContextPool.Shared.Get(
// ensure execution continues on captured context
continueOnCapturedContext: true,
cancellationToken: cts.Token);
var result = await _retryPipeline.ExecuteAsync(
async _ =>
{
Tries++;
// Simulate a task that takes some time to complete
await Task.Delay(TimeSpan.FromSeconds(taskDelay), timeProvider).ConfigureAwait(true);
if (Tries <= 2)
{
throw new InvalidOperationException();
}
return Tries;
},
context);
ResilienceContextPool.Shared.Return(context);
return result;
}
}
using Microsoft.Extensions.Time.Testing;
public class SomeServiceTests
{
[Fact]
public void PollyRetry_ShouldHave2Tries()
{
var timeProvider = new FakeTimeProvider();
var someService = new SomeService(timeProvider);
// Act
var result = someService.PollyRetry(taskDelay: 1, cancellationSeconds: 6);
// Advancing the time more than one second should resolves the first execution delay.
timeProvider.Advance(TimeSpan.FromMilliseconds(1001));
// Advancing the time more than the retry delay time of 1s,
// and less then the task execution delay should start the second try
timeProvider.Advance(TimeSpan.FromMilliseconds(1050));
// Assert
result.IsCompleted.Should().BeFalse();
someService.Tries.Should().Be(2);
}
}
```
## Feedback & Contributing
We welcome feedback and contributions in [our GitHub repo](https://github.com/dotnet/extensions).

Просмотреть файл

@ -381,4 +381,57 @@ public class FakeTimeProviderTests
// Assert
Assert.Single(calls);
}
[Fact]
public void SimulateRetryPolicy()
{
// Arrange
var retries = 42;
var tries = 0;
var taskDelay = 0.5;
var delay = 1;
var provider = new FakeTimeProvider();
async Task<int> simulatedPollyRetry()
{
while (true)
{
try
{
// simulate task that takes some time to complete
await provider.Delay(TimeSpan.FromSeconds(taskDelay));
tries++;
if (tries <= retries)
{
// the task failed, trigger retry
throw new InvalidOperationException();
}
return tries;
}
catch (InvalidOperationException)
{
// ConfigureAwait(true) is required to ensure that tasks continue on the captured context
await provider.Delay(TimeSpan.FromSeconds(delay)).ConfigureAwait(true);
}
}
}
// Act
var result = simulatedPollyRetry();
for (int i = 0; i < retries; i++)
{
// advance time for simulated task delay
provider.Advance(TimeSpan.FromSeconds(taskDelay));
// advance time for retry delay
provider.Advance(TimeSpan.FromSeconds(delay));
}
// Assert
Assert.False(result.IsCompleted);
Assert.Equal(retries, tries);
}
}

Просмотреть файл

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.TimeProvider.Testing\Microsoft.Extensions.TimeProvider.Testing.csproj"/>
<ProjectReference Include="..\..\..\src\Libraries\Microsoft.Extensions.TimeProvider.Testing\Microsoft.Extensions.TimeProvider.Testing.csproj" />
</ItemGroup>
<ItemGroup>