diff --git a/src/ResourceManager/Compute/Commands.Compute.Test/Commands.Compute.Test.csproj b/src/ResourceManager/Compute/Commands.Compute.Test/Commands.Compute.Test.csproj index 4ec67785cabd..8683842d8cc4 100644 --- a/src/ResourceManager/Compute/Commands.Compute.Test/Commands.Compute.Test.csproj +++ b/src/ResourceManager/Compute/Commands.Compute.Test/Commands.Compute.Test.csproj @@ -168,6 +168,7 @@ + @@ -233,13 +234,7 @@ Always - - Always - - - Always - - + Always diff --git a/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.cs b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.cs new file mode 100644 index 000000000000..5e62cb991c17 --- /dev/null +++ b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.IdentityModel.Clients.ActiveDirectory; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using Xunit; + +namespace Microsoft.Azure.Commands.Compute.Test.ScenarioTests +{ + public class RunnerTests + { + [Fact] + public void ExecuteRunnerTests() + { + var mode = Environment.GetEnvironmentVariable("AZURE_TEST_MODE"); + var csmAuth = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); + + if (mode == null || csmAuth == null || mode.ToLower() != "record") + { + return; + } + + Assert.False(string.IsNullOrEmpty(csmAuth)); + Assert.True(csmAuth.Contains("AADTenant")); + + var envDictionary = TestUtilities.ParseConnectionString(csmAuth); + var testEnv = new TestEnvironment(envDictionary); + Assert.NotNull(testEnv.Tenant); + Assert.NotNull(testEnv.SubscriptionId); + Assert.NotNull(testEnv.ClientId); + Assert.True(envDictionary.ContainsKey("ApplicationSecret")); + + var authenticationContext = new AuthenticationContext("https://login.windows.net/" + testEnv.Tenant); + var credential = new ClientCredential(testEnv.ClientId, envDictionary["ApplicationSecret"]); + + var result = authenticationContext.AcquireToken("https://management.core.windows.net/", clientCredential: credential); + + Assert.NotNull(result.AccessToken); + envDictionary["RawToken"] = result.AccessToken; + + FixCSMAuthEnvVariable(envDictionary); + + Console.WriteLine(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); + + var testFile = File.ReadAllLines("ScenarioTests\\RunnerTests.csv"); + foreach (var line in testFile) + { + var tokens = line.Split(';'); + var className = tokens[0]; + var type = Type.GetType(className); + var constructorInfo = type.GetConstructor(Type.EmptyTypes); + for (int i = 1; i < tokens.Length; i++) + { + var method = tokens[i]; + var testClassInstance = constructorInfo.Invoke(new object[] {}); + var testMethod = type.GetMethod(method); + + Console.WriteLine("Invoking method : " + testMethod); + + testMethod.Invoke(testClassInstance, new object[] {}); + + Console.WriteLine("Method " + testMethod + " has finished"); + } + } + } + + private void FixCSMAuthEnvVariable(IDictionary envDictionary) + { + var str = string.Empty; + foreach (var entry in envDictionary) + { + if (entry.Key != "AADClientId" && entry.Key != "ApplicationSecret") + { + str += string.Format("{0}={1};", entry.Key, entry.Value); + } + } + + Environment.SetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION", str); + } + } +} diff --git a/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.csv b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.csv new file mode 100644 index 000000000000..8c31d8680a86 --- /dev/null +++ b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/RunnerTests.csv @@ -0,0 +1 @@ +Microsoft.Azure.Commands.Compute.Test.ScenarioTests.VMDynamicTests;RunVMDynamicTests \ No newline at end of file diff --git a/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/VMDynamicTests.cs b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/VMDynamicTests.cs index 7ebe28708b0b..d22c639b10c6 100644 --- a/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/VMDynamicTests.cs +++ b/src/ResourceManager/Compute/Commands.Compute.Test/ScenarioTests/VMDynamicTests.cs @@ -12,6 +12,8 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using System; +using System.IO; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; @@ -24,7 +26,7 @@ public partial class VMDynamicTests [Trait(Category.AcceptanceType, Category.CheckIn)] public void RunVMDynamicTests() { - ComputeTestController.NewInstance.RunPsTest("Run-VMDynamicTests"); + ComputeTestController.NewInstance.RunPsTest("Run-VMDynamicTests -num_total_generated_tests 1"); } } } diff --git a/src/ServiceManagement/Common/Commands.ScenarioTest/Commands.ScenarioTest.csproj b/src/ServiceManagement/Common/Commands.ScenarioTest/Commands.ScenarioTest.csproj index 8620540d600a..be769ee999f0 100644 --- a/src/ServiceManagement/Common/Commands.ScenarioTest/Commands.ScenarioTest.csproj +++ b/src/ServiceManagement/Common/Commands.ScenarioTest/Commands.ScenarioTest.csproj @@ -385,6 +385,7 @@ + diff --git a/src/ServiceManagement/Common/Commands.ScenarioTest/ServiceManagement/UnitTests.cs b/src/ServiceManagement/Common/Commands.ScenarioTest/ServiceManagement/UnitTests.cs new file mode 100644 index 000000000000..9f2503c66ddb --- /dev/null +++ b/src/ServiceManagement/Common/Commands.ScenarioTest/ServiceManagement/UnitTests.cs @@ -0,0 +1,92 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.WindowsAzure.Commands.ServiceManagement.Extensions; +using System; +using Xunit; + +namespace Microsoft.WindowsAzure.Commands.ScenarioTest +{ + public partial class ServiceManagementTests + { + [Fact] + [Trait(Category.Service, Category.ServiceManagement)] + [Trait(Category.AcceptanceType, Category.CheckIn)] + [Trait(Category.AcceptanceType, Category.BVT)] + public void TestExtensionRoleNames() + { + var roleNames = new string[] + { + "test Role Name", + "!!!!! _____ test Role Name ~~~", + "testRoleName", + " testRoleName", + "testRoleName ", + " testRoleName" + }; + var expectedPrefixName = "testRoleName"; + var expectedExtensionId = "testRoleName-test-test-Ext-0"; + foreach (var roleName in roleNames) + { + ExtensionRole er = new ExtensionRole(roleName); + Assert.Equal(er.RoleName, roleName.Trim()); + Assert.Equal(er.PrefixName, expectedPrefixName); + Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId); + } + + var longRoleNames = new string[] + { + "A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789", + " A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 ~~~" + }; + + // PrefixName = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 + // Extension Name = test + // Slot = test + // Index = 0 + // Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index} + // Extenion ID's Max Length: 60 = 43 + 1 + 4 + 1 + 4 + 1 + 5 + // i.e. 'A123...E123' + '-' + 'test' + '-' + 'test' + '-' + 'Ext-0' + // L=43 L=1 L=4 L=1 L=4 L=1 L=5 + expectedPrefixName = longRoleNames[0]; + expectedExtensionId = "A123456789B123456789C123456789D123456789E123-test-test-Ext-0"; + foreach (var roleName in longRoleNames) + { + ExtensionRole er = new ExtensionRole(roleName); + Assert.Equal(er.RoleName, roleName.Trim()); + Assert.Equal(er.PrefixName, expectedPrefixName); + Assert.Equal(er.GetExtensionId("test", "test", 0), expectedExtensionId); + } + + + var longExtensionNames = longRoleNames; + // PrefixName = Default + // Extension Name = A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789 + // Slot = test + // Index = 1 + // Extension ID Format = {prefix_name_part}-{extension_name_part}-{slot}-Ext-{index} + // Extenion ID's Max Length: 60 = 1 + 1 + 47 + 1 + 4 + 1 + 5 + // i.e. 'D' + '-' + 'A123...456' + '-' + 'test' + '-' + 'Ext-0' + // L=1 L=1 L=47 L=1 L=4 L=1 L=5 + expectedExtensionId = "D-A123456789B123456789C123456789D123456789E123456-test-Ext-1"; + foreach (var extensionName in longExtensionNames) + { + ExtensionRole er = new ExtensionRole(); + Assert.Equal(er.RoleName, string.Empty); + Assert.Equal(er.PrefixName, "Default"); + Assert.Equal(er.GetExtensionId(extensionName, "test", 1), expectedExtensionId); + } + } + } +} diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Common/ExtensionRole.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Common/ExtensionRole.cs index d3fff4a56c93..aa57a26dcbde 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Common/ExtensionRole.cs +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Common/ExtensionRole.cs @@ -14,6 +14,7 @@ using System; using System.Text; +using System.Text.RegularExpressions; namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Extensions { @@ -22,12 +23,21 @@ public class ExtensionRole protected const string DefaultExtensionIdPrefixStr = "Default"; protected const string ExtensionIdSuffixTemplate = "-{0}-{1}-Ext-{2}"; protected const int MaxExtensionIdLength = 60; + protected const int MinRoleNamePartLength = 1; + protected const int MaxSuffixLength = MaxExtensionIdLength - MinRoleNamePartLength; public string RoleName { get; private set; } public string PrefixName { get; private set; } public ExtensionRoleType RoleType { get; private set; } public bool Default { get; private set; } + private static string RemoveDisallowedCharacters(string roleName) + { + // Remove characters that are not allowed in the extension id + var disallowedCharactersRegex = new Regex(@"[^A-Za-z0-9\-]"); + return disallowedCharactersRegex.Replace(roleName, string.Empty); + } + public ExtensionRole() { RoleName = string.Empty; @@ -48,9 +58,7 @@ public ExtensionRole(string roleName) else { PrefixName = RoleName = roleName.Trim(); - PrefixName = PrefixName.Replace(".", string.Empty); - PrefixName = PrefixName.Replace(" ", string.Empty); - PrefixName = PrefixName.Replace("_", string.Empty); + PrefixName = RemoveDisallowedCharacters(PrefixName); RoleType = ExtensionRoleType.NamedRoles; Default = false; } @@ -63,13 +71,21 @@ public override string ToString() public string GetExtensionId(string extensionName, string slot, int index) { - var normalizedExtName = extensionName.Replace(".", string.Empty); - normalizedExtName = normalizedExtName.Replace(" ", string.Empty); - normalizedExtName = normalizedExtName.Replace("_", string.Empty); + var normalizedExtName = RemoveDisallowedCharacters(extensionName); var suffix = new StringBuilder(); + // Suffix format: -{extension_name_part}-{slot}-Ext-{index} suffix.AppendFormat(ExtensionIdSuffixTemplate, normalizedExtName, slot, index); + if (suffix.Length > MaxSuffixLength) + { + // If the suffix is too long, truncate the {extension_name_part} + int lenDiff = suffix.Length - MaxSuffixLength; + int startIndex = 1; // Suffix starts with '-' + suffix.Remove(startIndex + normalizedExtName.Length - lenDiff, lenDiff); + } + // Calculate the prefix length by the difference between the suffix and the max ID length. + // The difference should always be at least 1. int prefixSubStrLen = Math.Min(Math.Max(MaxExtensionIdLength - suffix.Length, 0), PrefixName.Length); var result = new StringBuilder();