Skip to content

Commit 2001552

Browse files
author
Maddie Clayton
authored
Merge branch 'preview' into ade-status-fix
2 parents 721d3aa + 98667af commit 2001552

File tree

312 files changed

+56799
-579891
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

312 files changed

+56799
-579891
lines changed

build.proj

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
Condition=" '$(Scope)' == 'AzureStorage' "/>
6969
<CmdletSolutionsToBuild Include=".\src\Stack.sln"
7070
Condition=" '$(Stack)' == 'true' "/>
71-
71+
7272
<StaticAnalysis Include=".\tools\StaticAnalysis\StaticAnalysis.sln" />
7373
<LocalBuildTasks Include="$(LibraryToolsFolder)\BuildPackagesTask\Microsoft.Azure.Build.Tasks.sln" />
7474
<LocalBuildTasks Include="$(LibraryToolsFolder)\RepoTasks\RepoTasks.sln" Condition="'$(NetCore)' == 'false'"/>
@@ -204,26 +204,28 @@
204204
</FilesChangedTask>
205205

206206
<!-- Get the list of modules changed -->
207-
<FilterTask FilesChanged="@(FilesChanged)" MapFilePath=".\ModuleMappings.json">
208-
<Output TaskParameter="Output" ItemName="ModulesChanged"/>
209-
</FilterTask>
210-
<Message Text="Filtering help generation and StaticAnalysis by the following modules:"/>
211-
<Message Text="%(ModulesChanged.Identity)"/>
212-
<Message Text="Total: @(ModulesChanged->Count())"/>
213-
<Message Text=""/>
214-
215-
<!--Get the list of tests to be run based on files changed from a specified PullRequestNumber. Mapping between paths and test DLLs is used to produce the list.-->
216-
<FilterTask FilesChanged="@(FilesChanged)" MapFilePath=".\TestMappings.json">
217-
<Output TaskParameter="Output" ItemName="XUnitTests"/>
218-
</FilterTask>
219-
<Message Text="Using these test assemblies:"/>
220-
<Message Text="%(XUnitTests.Identity)"/>
221-
<Message Text="Total: @(XunitTests->Count())"/>
222-
<Message Text=""/>
207+
<FilterTask FilesChanged="@(FilesChanged)" MapFilePath=".\ModuleMappings.json">
208+
<Output TaskParameter="Output" ItemName="ModulesChanged"/>
209+
</FilterTask>
210+
<Message Text="Filtering help generation and StaticAnalysis by the following modules:"/>
211+
<Message Text="%(ModulesChanged.Identity)"/>
212+
<Message Text="Total: @(ModulesChanged->Count())"/>
213+
<Message Text=""/>
214+
215+
<!--Get the list of tests to be run based on files changed from a specified PullRequestNumber. Mapping between paths and test DLLs is used to produce the list.-->
216+
<FilterTask FilesChanged="@(FilesChanged)" MapFilePath=".\TestMappings.json">
217+
<Output TaskParameter="Output" ItemName="XUnitTests"/>
218+
</FilterTask>
219+
<Message Text="Using these test assemblies:"/>
220+
<Message Text="%(XUnitTests.Identity)"/>
221+
<Message Text="Total: @(XunitTests->Count())"/>
222+
<Message Text=""/>
223223
</Target>
224224

225225
<!-- Build all flavors of the Cmdlets -->
226226
<Target Name="Build" DependsOnTargets="RestoreNugetPackages;BuildMsBuildTask;FilterBuild">
227+
<CallTarget targets="ChangeLogCheck" ContinueOnError="false" />
228+
227229
<Message Importance="high" Text="Building Cmdlets..." />
228230

229231
<MakeDir Directories="$(PackageDirectory)" />
@@ -506,6 +508,17 @@
506508
<Error Text="StaticAnalysis has failed. Please follow the instructions on this doc: https://github.com/Azure/azure-powershell/blob/preview/documentation/Debugging-StaticAnalysis-Errors.md"/>
507509
</Target>
508510

511+
<Target Name="ChangeLogCheck">
512+
<Exec Command="&quot;$(PowerShellCommand)&quot; -NonInteractive -NoLogo -NoProfile -Command &quot;. $(LibraryToolsFolder)\CheckChangeLog.ps1 -FilesChanged '@(FilesChanged)' &quot;"
513+
ContinueOnError="false"
514+
Condition="'$(Latest)' == 'true'"/>
515+
<OnError ExecuteTargets="ChangeLogErrorMessage"/>
516+
</Target>
517+
518+
<Target Name="ChangeLogErrorMessage">
519+
<Error Text="Modified files were found with no update to their change log. Please add a snippet to the affected modules' change log."/>
520+
</Target>
521+
509522
<!-- Publish all packages -->
510523
<Target Name="Publish">
511524
<Error Condition=" '$(NuGetKey)' == '' " Text="You must provide the NuGetKey parameter to the build: /p:NuGetKey=YOUR_PUBLISHING_KEY" />

src/Common/Commands.Common.Authentication.Test/ClientFactoryHandlerTests.cs

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
using Microsoft.WindowsAzure.Commands.ScenarioTest;
2525
using Xunit;
2626
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
27+
using System.Linq;
28+
using Microsoft.Azure.Management.Internal.Resources;
29+
using System.Threading;
30+
using System.Threading.Tasks;
2731

2832
namespace Common.Authentication.Test
2933
{
@@ -51,7 +55,7 @@ public void DelegatingHandlersAreCloned()
5155
sub.SetTenant("common");
5256
AzureContext context = new AzureContext
5357
(
54-
sub,
58+
sub,
5559
account,
5660
AzureEnvironment.PublicEnvironments["AzureCloud"]
5761
);
@@ -65,7 +69,66 @@ public void DelegatingHandlersAreCloned()
6569
client = factory.CreateClient<StorageManagementClient>(context, AzureEnvironment.Endpoint.ServiceManagement);
6670
client = factory.CreateClient<StorageManagementClient>(context, AzureEnvironment.Endpoint.ServiceManagement);
6771
client = factory.CreateClient<StorageManagementClient>(context, AzureEnvironment.Endpoint.ServiceManagement);
68-
Assert.Equal(5, MockDelegatingHandler.cloneCount);
72+
Assert.Equal(5, MockDelegatingHandler.cloneCount);
73+
}
74+
75+
[Fact]
76+
[Trait(Category.AcceptanceType, Category.CheckIn)]
77+
public void AddsAppropriateRetryPolicy()
78+
{
79+
AzureSessionInitializer.InitializeAzureSession();
80+
string userAccount = "[email protected]";
81+
Guid subscriptionId = Guid.NewGuid();
82+
var account = new AzureAccount()
83+
{
84+
Id = userAccount,
85+
Type = AzureAccount.AccountType.User,
86+
};
87+
account.SetTenants("common");
88+
var sub = new AzureSubscription()
89+
{
90+
Id = subscriptionId.ToString(),
91+
};
92+
sub.SetAccount(userAccount);
93+
sub.SetEnvironment("AzureCloud");
94+
sub.SetTenant("common");
95+
AzureContext context = new AzureContext
96+
(
97+
sub,
98+
account,
99+
AzureEnvironment.PublicEnvironments["AzureCloud"]
100+
);
101+
AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(userAccount, Guid.NewGuid().ToString());
102+
var factory = new ClientFactory();
103+
factory.AddHandler(new RetryTestHandler());
104+
var client = factory.CreateClient<StorageManagementClient>(context, AzureEnvironment.Endpoint.ServiceManagement);
105+
var hyakHandler = EnsureHyakRetryPolicy(client);
106+
hyakHandler.MaxTries = 2;
107+
Assert.Throws<InvalidOperationException>(() => client.StorageAccounts.List());
108+
hyakHandler.MaxTries = 0;
109+
Assert.Throws<TaskCanceledException>(() => client.StorageAccounts.List());
110+
var autorestClient = factory.CreateArmClient<ResourceManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager);
111+
var autoRestHandler = EnsureAutoRestRetryPolicy(autorestClient);
112+
autoRestHandler.MaxTries = 2;
113+
var task = autorestClient.ResourceGroups.ListWithHttpMessagesAsync();
114+
Assert.Throws<InvalidOperationException>(() => task.ConfigureAwait(false).GetAwaiter().GetResult());
115+
autoRestHandler.MaxTries = 0;
116+
task = autorestClient.ResourceGroups.ListWithHttpMessagesAsync();
117+
Assert.Throws<TaskCanceledException>(() => task.ConfigureAwait(false).GetAwaiter().GetResult());
118+
}
119+
120+
private CancelRetryHandler EnsureHyakRetryPolicy<T>( Hyak.Common.ServiceClient<T> client) where T: Hyak.Common.ServiceClient<T>
121+
{
122+
var handler = client.GetHttpPipeline().First(h => h.GetType() == typeof(CancelRetryHandler)) as CancelRetryHandler;
123+
handler.WaitInterval = TimeSpan.Zero;
124+
return handler;
125+
}
126+
127+
private CancelRetryHandler EnsureAutoRestRetryPolicy<T>( Microsoft.Rest.ServiceClient<T> client) where T: Microsoft.Rest.ServiceClient<T>
128+
{
129+
var handler = client.HttpMessageHandlers.First(h => h is CancelRetryHandler)as CancelRetryHandler;
130+
handler.WaitInterval = TimeSpan.Zero;
131+
return handler;
69132
}
70133

71134
private class MockDelegatingHandler : DelegatingHandler, ICloneable
@@ -78,5 +141,28 @@ public object Clone()
78141
return this;
79142
}
80143
}
144+
145+
146+
private class RetryTestHandler : DelegatingHandler, ICloneable
147+
{
148+
private static int times = -1;
149+
150+
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
151+
{
152+
switch (Interlocked.Increment(ref times) % 3)
153+
{
154+
case 0:
155+
case 1:
156+
throw new TaskCanceledException();
157+
default:
158+
throw new InvalidOperationException();
159+
}
160+
}
161+
162+
public object Clone()
163+
{
164+
return new RetryTestHandler();
165+
}
166+
}
81167
}
82168
}

src/Common/Commands.Common.Authentication.Test/Commands.Common.Authentication.Test.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props')" />
4-
<Import Project="..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props')"/>
4+
<Import Project="..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props')" />
55
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
66
<PropertyGroup>
77
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -136,6 +136,10 @@
136136
<EmbeddedResource Include="Resources\ResourceLocator.cs" />
137137
</ItemGroup>
138138
<ItemGroup>
139+
<ProjectReference Include="..\..\ResourceManager\Common\Commands.ResourceManager.Common\Commands.ResourceManager.Common.csproj">
140+
<Project>{3819d8a7-c62c-4c47-8ddd-0332d9ce1252}</Project>
141+
<Name>Commands.ResourceManager.Common</Name>
142+
</ProjectReference>
139143
<ProjectReference Include="..\Commands.Common.Authentication.Abstractions\Commands.Common.Authentication.Abstractions.csproj">
140144
<Project>{70527617-7598-4aef-b5bd-db9186b8184b}</Project>
141145
<Name>Commands.Common.Authentication.Abstractions</Name>

src/Common/Commands.Common.Authentication/Commands.Common.Authentication.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
<Compile Include="ContextAutosaveSettings.cs" />
138138
<Compile Include="Extensions\CloudExceptionExtensions.cs" />
139139
<Compile Include="Factories\AuthenticationFactory.cs" />
140+
<Compile Include="Factories\CancelRetryHandler.cs" />
140141
<Compile Include="Factories\ClientFactory.cs" />
141142
<Compile Include="HttpClientOperationsFactory.cs" />
142143
<Compile Include="Utilities\HttpClientWithRetry.cs" />
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Linq;
17+
using System.Net.Http;
18+
using System.Threading;
19+
using System.Threading.Tasks;
20+
21+
namespace Microsoft.Azure.Commands.Common.Authentication.Factories
22+
{
23+
/// <summary>
24+
/// Class to enable automatic retry of TaskCanceledExsceptions.
25+
/// Note that this follows the calling pattern in PowerShell, which does not pass cancellation tokens from
26+
/// the base cmdlet
27+
/// </summary>
28+
public class CancelRetryHandler : DelegatingHandler, ICloneable
29+
{
30+
static readonly string[] TestModeLiveValues = { "Record", "None", "Live" };
31+
const string TestModeVariableKey = "Azure_Test_Mode";
32+
public CancelRetryHandler()
33+
{
34+
WaitInterval = TimeSpan.Zero;
35+
}
36+
public CancelRetryHandler(TimeSpan waitInterval, int maxTries)
37+
{
38+
WaitInterval = waitInterval;
39+
MaxTries = maxTries;
40+
}
41+
42+
public TimeSpan WaitInterval { get; set; } = TimeSpan.Zero;
43+
44+
public int MaxTries { get; set; } = 3;
45+
46+
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
47+
{
48+
int tries = 0;
49+
do
50+
{
51+
using (var source = new CancellationTokenSource())
52+
{
53+
try
54+
{
55+
return await base.SendAsync(request, source.Token).ConfigureAwait(false);
56+
}
57+
catch (TaskCanceledException) when (tries++ < MaxTries)
58+
{
59+
SleepIfRunningLive(WaitInterval);
60+
}
61+
}
62+
}
63+
while (true);
64+
}
65+
66+
void SleepIfRunningLive(TimeSpan timeSpan)
67+
{
68+
var testModeSetting = Environment.GetEnvironmentVariable(TestModeVariableKey);
69+
if (string.IsNullOrWhiteSpace(testModeSetting) || TestModeLiveValues.Any( v => string.Equals(v, testModeSetting, StringComparison.OrdinalIgnoreCase)))
70+
{
71+
Thread.Sleep(timeSpan);
72+
}
73+
}
74+
75+
public object Clone()
76+
{
77+
return new CancelRetryHandler(WaitInterval, MaxTries);
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)