Skip to content

Commit a9feeba

Browse files
committed
Merge pull request Azure#1792 from huangpf/dev
AzureCP PR - Fix Extension ID Issue #387
2 parents e7d9953 + c19a050 commit a9feeba

File tree

7 files changed

+202
-14
lines changed

7 files changed

+202
-14
lines changed

src/ResourceManager/Compute/Commands.Compute.Test/Commands.Compute.Test.csproj

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
<Compile Include="ScenarioTests\ComputeCloudExceptionTests.cs" />
169169
<Compile Include="ScenarioTests\DiagnosticsExtensionTests.cs" />
170170
<Compile Include="ScenarioTests\DscExtensionTests.cs" />
171+
<Compile Include="ScenarioTests\RunnerTests.cs" />
171172
<Compile Include="ScenarioTests\VirtualMachineBootDiagnosticsTests.cs" />
172173
<Compile Include="ScenarioTests\VMDynamicTests.cs" />
173174
<Compile Include="ScenarioTests\VirtualMachineProfileTests.cs" />
@@ -233,13 +234,7 @@
233234
<None Include="ScenarioTests\DummyConfig.ps1">
234235
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
235236
</None>
236-
<None Include="ScenarioTests\Generated\VirtualMachineDynamicTest1.ps1">
237-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
238-
</None>
239-
<None Include="ScenarioTests\Generated\VirtualMachineDynamicTest2.ps1">
240-
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
241-
</None>
242-
<None Include="ScenarioTests\Generated\VirtualMachineDynamicTest3.ps1">
237+
<None Include="ScenarioTests\RunnerTests.csv">
243238
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
244239
</None>
245240
<None Include="ScenarioTests\VirtualMachineBootDiagnosticsTests.ps1">
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using Microsoft.IdentityModel.Clients.ActiveDirectory;
5+
using Microsoft.Rest.ClientRuntime.Azure.TestFramework;
6+
using Xunit;
7+
8+
namespace Microsoft.Azure.Commands.Compute.Test.ScenarioTests
9+
{
10+
public class RunnerTests
11+
{
12+
[Fact]
13+
public void ExecuteRunnerTests()
14+
{
15+
var mode = Environment.GetEnvironmentVariable("AZURE_TEST_MODE");
16+
var csmAuth = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION");
17+
18+
if (mode == null || csmAuth == null || mode.ToLower() != "record")
19+
{
20+
return;
21+
}
22+
23+
Assert.False(string.IsNullOrEmpty(csmAuth));
24+
Assert.True(csmAuth.Contains("AADTenant"));
25+
26+
var envDictionary = TestUtilities.ParseConnectionString(csmAuth);
27+
var testEnv = new TestEnvironment(envDictionary);
28+
Assert.NotNull(testEnv.Tenant);
29+
Assert.NotNull(testEnv.SubscriptionId);
30+
Assert.NotNull(testEnv.ClientId);
31+
Assert.True(envDictionary.ContainsKey("ApplicationSecret"));
32+
33+
var authenticationContext = new AuthenticationContext("https://login.windows.net/" + testEnv.Tenant);
34+
var credential = new ClientCredential(testEnv.ClientId, envDictionary["ApplicationSecret"]);
35+
36+
var result = authenticationContext.AcquireToken("https://management.core.windows.net/", clientCredential: credential);
37+
38+
Assert.NotNull(result.AccessToken);
39+
envDictionary["RawToken"] = result.AccessToken;
40+
41+
FixCSMAuthEnvVariable(envDictionary);
42+
43+
Console.WriteLine(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"));
44+
45+
var testFile = File.ReadAllLines("ScenarioTests\\RunnerTests.csv");
46+
foreach (var line in testFile)
47+
{
48+
var tokens = line.Split(';');
49+
var className = tokens[0];
50+
var type = Type.GetType(className);
51+
var constructorInfo = type.GetConstructor(Type.EmptyTypes);
52+
for (int i = 1; i < tokens.Length; i++)
53+
{
54+
var method = tokens[i];
55+
var testClassInstance = constructorInfo.Invoke(new object[] {});
56+
var testMethod = type.GetMethod(method);
57+
58+
Console.WriteLine("Invoking method : " + testMethod);
59+
60+
testMethod.Invoke(testClassInstance, new object[] {});
61+
62+
Console.WriteLine("Method " + testMethod + " has finished");
63+
}
64+
}
65+
}
66+
67+
private void FixCSMAuthEnvVariable(IDictionary<string, string> envDictionary)
68+
{
69+
var str = string.Empty;
70+
foreach (var entry in envDictionary)
71+
{
72+
if (entry.Key != "AADClientId" && entry.Key != "ApplicationSecret")
73+
{
74+
str += string.Format("{0}={1};", entry.Key, entry.Value);
75+
}
76+
}
77+
78+
Environment.SetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION", str);
79+
}
80+
}
81+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft.Azure.Commands.Compute.Test.ScenarioTests.VMDynamicTests;RunVMDynamicTests

src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/VMDynamicTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using System;
16+
using System.IO;
1517
using Microsoft.Azure.Test.HttpRecorder;
1618
using Microsoft.WindowsAzure.Commands.ScenarioTest;
1719
using Xunit;
@@ -24,7 +26,7 @@ public partial class VMDynamicTests
2426
[Trait(Category.AcceptanceType, Category.CheckIn)]
2527
public void RunVMDynamicTests()
2628
{
27-
ComputeTestController.NewInstance.RunPsTest("Run-VMDynamicTests");
29+
ComputeTestController.NewInstance.RunPsTest("Run-VMDynamicTests -num_total_generated_tests 1");
2830
}
2931
}
3032
}

src/ServiceManagement/Common/Commands.ScenarioTest/Commands.ScenarioTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@
385385
<Compile Include="Resources\ResourceLocator.cs" />
386386
<Compile Include="Scheduler\SchedulerTests.cs" />
387387
<Compile Include="ServiceBusTests\ServiceBusAuthorizationRuleTests.cs" />
388+
<Compile Include="ServiceManagement\UnitTests.cs" />
388389
<Compile Include="ServiceManagement\ScenarioTests.cs" />
389390
<Compile Include="ServiceManagement\ServiceManagementTests.cs" />
390391
<Compile Include="StorageTests\StorageContainerTest.cs" />
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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 Microsoft.WindowsAzure.Commands.ServiceManagement.Extensions;
16+
using System;
17+
using Xunit;
18+
19+
namespace Microsoft.WindowsAzure.Commands.ScenarioTest
20+
{
21+
public partial class ServiceManagementTests
22+
{
23+
[Fact]
24+
[Trait(Category.Service, Category.ServiceManagement)]
25+
[Trait(Category.AcceptanceType, Category.CheckIn)]
26+
[Trait(Category.AcceptanceType, Category.BVT)]
27+
public void TestExtensionRoleNames()
28+
{
29+
var roleNames = new string[]
30+
{
31+
"test Role Name",
32+
"!!!!! _____ test Role Name ~~~",
33+
"testRoleName",
34+
" testRoleName",
35+
"testRoleName ",
36+
" testRoleName"
37+
};
38+
var expectedPrefixName = "testRoleName";
39+
var expectedExtensionId = "testRoleName-test-test-Ext-0";
40+
foreach (var roleName in roleNames)
41+
{
42+
ExtensionRole er = new ExtensionRole(roleName);
43+
Assert.Equal(er.RoleName, roleName.Trim());
44+
Assert.Equal(er.PrefixName, expectedPrefixName);
45+
Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId);
46+
}
47+
48+
var longRoleNames = new string[]
49+
{
50+
"A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789",
51+
" A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 ~~~"
52+
};
53+
54+
// PrefixName = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789
55+
// Extension Name = test
56+
// Slot = test
57+
// Index = 0
58+
// Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index}
59+
// Extenion ID's Max Length: 60 = 43 + 1 + 4 + 1 + 4 + 1 + 5
60+
// i.e. 'A123...E123' + '-' + 'test' + '-' + 'test' + '-' + 'Ext-0'
61+
// L=43 L=1 L=4 L=1 L=4 L=1 L=5
62+
expectedPrefixName = longRoleNames[0];
63+
expectedExtensionId = "A123456789B123456789C123456789D123456789E123-test-test-Ext-0";
64+
foreach (var roleName in longRoleNames)
65+
{
66+
ExtensionRole er = new ExtensionRole(roleName);
67+
Assert.Equal(er.RoleName, roleName.Trim());
68+
Assert.Equal(er.PrefixName, expectedPrefixName);
69+
Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId);
70+
}
71+
72+
73+
var longExtensionNames = longRoleNames;
74+
// PrefixName = Default
75+
// Extension Name = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789
76+
// Slot = test
77+
// Index = 1
78+
// Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index}
79+
// Extenion ID's Max Length: 60 = 1 + 1 + 47 + 1 + 4 + 1 + 5
80+
// i.e. 'D' + '-' + 'A123...456' + '-' + 'test' + '-' + 'Ext-0'
81+
// L=1 L=1 L=47 L=1 L=4 L=1 L=5
82+
expectedExtensionId = "D-A123456789B123456789C123456789D123456789E123456-test-Ext-1";
83+
foreach (var extensionName in longExtensionNames)
84+
{
85+
ExtensionRole er = new ExtensionRole();
86+
Assert.Equal(er.RoleName, string.Empty);
87+
Assert.Equal(er.PrefixName, "Default");
88+
Assert.Equal(er.GetExtensionId(extensionName, "test", 1), expectedExtensionId);
89+
}
90+
}
91+
}
92+
}

src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Common/ExtensionRole.cs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using System;
1616
using System.Text;
17+
using System.Text.RegularExpressions;
1718

1819
namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Extensions
1920
{
@@ -22,12 +23,21 @@ public class ExtensionRole
2223
protected const string DefaultExtensionIdPrefixStr = "Default";
2324
protected const string ExtensionIdSuffixTemplate = "-{0}-{1}-Ext-{2}";
2425
protected const int MaxExtensionIdLength = 60;
26+
protected const int MinRoleNamePartLength = 1;
27+
protected const int MaxSuffixLength = MaxExtensionIdLength - MinRoleNamePartLength;
2528

2629
public string RoleName { get; private set; }
2730
public string PrefixName { get; private set; }
2831
public ExtensionRoleType RoleType { get; private set; }
2932
public bool Default { get; private set; }
3033

34+
private static string RemoveDisallowedCharacters(string roleName)
35+
{
36+
// Remove characters that are not allowed in the extension id
37+
var disallowedCharactersRegex = new Regex(@"[^A-Za-z0-9\-]");
38+
return disallowedCharactersRegex.Replace(roleName, string.Empty);
39+
}
40+
3141
public ExtensionRole()
3242
{
3343
RoleName = string.Empty;
@@ -48,9 +58,7 @@ public ExtensionRole(string roleName)
4858
else
4959
{
5060
PrefixName = RoleName = roleName.Trim();
51-
PrefixName = PrefixName.Replace(".", string.Empty);
52-
PrefixName = PrefixName.Replace(" ", string.Empty);
53-
PrefixName = PrefixName.Replace("_", string.Empty);
61+
PrefixName = RemoveDisallowedCharacters(PrefixName);
5462
RoleType = ExtensionRoleType.NamedRoles;
5563
Default = false;
5664
}
@@ -63,13 +71,21 @@ public override string ToString()
6371

6472
public string GetExtensionId(string extensionName, string slot, int index)
6573
{
66-
var normalizedExtName = extensionName.Replace(".", string.Empty);
67-
normalizedExtName = normalizedExtName.Replace(" ", string.Empty);
68-
normalizedExtName = normalizedExtName.Replace("_", string.Empty);
74+
var normalizedExtName = RemoveDisallowedCharacters(extensionName);
6975

7076
var suffix = new StringBuilder();
77+
// Suffix format: -{extension_name_part}-{slot}-Ext-{index}
7178
suffix.AppendFormat(ExtensionIdSuffixTemplate, normalizedExtName, slot, index);
79+
if (suffix.Length > MaxSuffixLength)
80+
{
81+
// If the suffix is too long, truncate the {extension_name_part}
82+
int lenDiff = suffix.Length - MaxSuffixLength;
83+
int startIndex = 1; // Suffix starts with '-'
84+
suffix.Remove(startIndex + normalizedExtName.Length - lenDiff, lenDiff);
85+
}
7286

87+
// Calculate the prefix length by the difference between the suffix and the max ID length.
88+
// The difference should always be at least 1.
7389
int prefixSubStrLen = Math.Min(Math.Max(MaxExtensionIdLength - suffix.Length, 0), PrefixName.Length);
7490

7591
var result = new StringBuilder();

0 commit comments

Comments
 (0)