First Commit - Migrating from GH repo
5bc5fa08
Varad
committed
21 changed files
Cache.cs
/Cache.cs+24
/Cache.cs
Add comment 1 Plus  using Newtonsoft.Json.Linq;
Add comment 2 Plus  using System.Collections.Generic;
Add comment 3 Plus  
Add comment 4 Plus  public static class Cache
Add comment 5 Plus  {
Add comment 6 Plus   public static void Initialize(string clientId, string servicePrincipalPassword, string tenantId, string loaderioKey)
Add comment 7 Plus   {
Add comment 8 Plus   FunctionappDomainToDetails = new Dictionary<string, JObject>();
Add comment 9 Plus   Scenarios = new List<JObject>();
Add comment 10 Plus   ScenariosSplitByOSAndSKU = new Dictionary<string, List<JObject>>();
Add comment 11 Plus   ClientId = clientId;
Add comment 12 Plus   ServicePrincipalPassword = servicePrincipalPassword;
Add comment 13 Plus   TenantId = tenantId;
Add comment 14 Plus   LoaderioKey = loaderioKey;
Add comment 15 Plus   }
Add comment 16 Plus  
Add comment 17 Plus   public static IDictionary<string, JObject> FunctionappDomainToDetails;
Add comment 18 Plus   public static List<JObject> Scenarios;
Add comment 19 Plus   public static IDictionary<string, List<JObject>> ScenariosSplitByOSAndSKU;
Add comment 20 Plus   public static string ClientId;
Add comment 21 Plus   public static string ServicePrincipalPassword;
Add comment 22 Plus   public static string TenantId;
Add comment 23 Plus   public static string LoaderioKey;
Add comment 24 Plus  }
Function1.cs
/Function1.cs+119
/Function1.cs
Add comment 1 Plus  using System;
Add comment 2 Plus  using System.Collections.Generic;
Add comment 3 Plus  using System.IO;
Add comment 4 Plus  using System.Threading.Tasks;
Add comment 5 Plus  using Microsoft.Azure.WebJobs;
Add comment 6 Plus  using Microsoft.Azure.WebJobs.Extensions.DurableTask;
Add comment 7 Plus  using Microsoft.Extensions.Configuration;
Add comment 8 Plus  using Microsoft.Extensions.Logging;
Add comment 9 Plus  using Newtonsoft.Json.Linq;
Add comment 10 Plus  
Add comment 11 Plus  namespace TestScheduler
Add comment 12 Plus  {
Add comment 13 Plus   public class Function1
Add comment 14 Plus   {
Add comment 15 Plus   private readonly ILogger _logger;
Add comment 16 Plus  
Add comment 17 Plus   public Function1(ILoggerFactory loggerFactory)
Add comment 18 Plus   {
Add comment 19 Plus   _logger = loggerFactory.CreateLogger("Microsoft.Azure.WebJobs.LoaderioTestScheduler");
Add comment 20 Plus   }
Add comment 21 Plus  
Add comment 22 Plus   [FunctionName("Function1")]
Add comment 23 Plus   public void Run(
Add comment 24 Plus   Microsoft.Azure.WebJobs.ExecutionContext context,
Add comment 25 Plus   [TimerTrigger("0 */8 * * *")]TimerInfo timeInfo,
Add comment 26 Plus   [DurableClient] IDurableOrchestrationClient starter,
Add comment 27 Plus   ILogger log)
Add comment 28 Plus   {
Add comment 29 Plus   _logger.LogInformation($"C# Timer trigger function executing at: {DateTime.UtcNow}");
Add comment 30 Plus  
Add comment 31 Plus   var config = new ConfigurationBuilder()
Add comment 32 Plus   .SetBasePath(context.FunctionAppDirectory)
Add comment 33 Plus   .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
Add comment 34 Plus   .AddEnvironmentVariables()
Add comment 35 Plus   .Build();
Add comment 36 Plus  
Add comment 37 Plus   string clientId = config["ClientId"];
Add comment 38 Plus   string servicePrincipalPassword = config["ServicePrincipalPassword"];
Add comment 39 Plus   string loaderioKey = config["LoaderioAPIKey"];
Add comment 40 Plus   string loaderioTestURL = config["LoaderioTestsURL"];
Add comment 41 Plus   string tenantId = config["TenantId"];
Add comment 42 Plus   var masterOrchestrationsInGroups = new List<Task>();
Add comment 43 Plus  
Add comment 44 Plus   ClearAndPopulateCache(loaderioTestURL, clientId, servicePrincipalPassword, tenantId, loaderioKey);
Add comment 45 Plus  
Add comment 46 Plus   // Start Master orchestration for each group
Add comment 47 Plus   foreach (string key in Cache.ScenariosSplitByOSAndSKU.Keys)
Add comment 48 Plus   {
Add comment 49 Plus   try
Add comment 50 Plus   {
Add comment 51 Plus   _logger.LogInformation($"Enqueuing master orchestration for group {key}");
Add comment 52 Plus   // masterOrchestrationsInGroups.Add(starter.StartNewAsync(orchestratorFunctionName: "MasterOrchestration", input: key));
Add comment 53 Plus   masterOrchestrationsInGroups.Add(starter.StartNewAsync(orchestratorFunctionName: "MasterOrchestration", input: new MasterOrchestrationInput(key, Cache.ScenariosSplitByOSAndSKU[key], clientId, servicePrincipalPassword, tenantId, loaderioKey)));
Add comment 54 Plus   }
Add comment 55 Plus   catch (Exception ex)
Add comment 56 Plus   {
Add comment 57 Plus   _logger.LogError(ex, $"Error while processing group key {key}");
Add comment 58 Plus   }
Add comment 59 Plus   }
Add comment 60 Plus  
Add comment 61 Plus   _logger.LogInformation($"C# Timer trigger function completed at: {DateTime.UtcNow}");
Add comment 62 Plus   }
Add comment 63 Plus  
Add comment 64 Plus   private void ClearAndPopulateCache(string loaderioTestsUrl, string clientId, string servicePrincipalPassword, string tenantId, string loaderioKey)
Add comment 65 Plus   {
Add comment 66 Plus   try
Add comment 67 Plus   {
Add comment 68 Plus   using (StreamReader file = new StreamReader(Helpers.GetLoaderioTests(loaderioTestsUrl)))
Add comment 69 Plus   {
Add comment 70 Plus   string line = null;
Add comment 71 Plus   Cache.Initialize(clientId, servicePrincipalPassword, tenantId, loaderioKey);
Add comment 72 Plus  
Add comment 73 Plus   while ((line = file.ReadLine()) != null)
Add comment 74 Plus   {
Add comment 75 Plus   try
Add comment 76 Plus   {
Add comment 77 Plus   JObject testGroup = JObject.Parse(line);
Add comment 78 Plus   string appName = testGroup.Value<string>("AppName");
Add comment 79 Plus   string domain = $"{appName}.azurewebsites.net";
Add comment 80 Plus  
Add comment 81 Plus   // Split
Add comment 82 Plus   string[] SplitAppName = appName.Split('-');
Add comment 83 Plus   string key = $"{SplitAppName[1].ToLower()}-{SplitAppName[2].ToLower()}"; // {SKU}-{OS}
Add comment 84 Plus   if(appName.Contains("euap", StringComparison.OrdinalIgnoreCase))
Add comment 85 Plus   {
Add comment 86 Plus   key = "euap"; // EUAP apps belong to separate group
Add comment 87 Plus   }
Add comment 88 Plus   if(!Cache.ScenariosSplitByOSAndSKU.ContainsKey(key))
Add comment 89 Plus   {
Add comment 90 Plus   Cache.ScenariosSplitByOSAndSKU.Add(key, new List<JObject>());
Add comment 91 Plus   }
Add comment 92 Plus   Cache.ScenariosSplitByOSAndSKU[key].Add(testGroup);
Add comment 93 Plus   _logger.LogInformation($"Added {testGroup} to group {key}");
Add comment 94 Plus  
Add comment 95 Plus  
Add comment 96 Plus   Cache.Scenarios.Add(testGroup);
Add comment 97 Plus   Cache.FunctionappDomainToDetails.Add(domain, testGroup);
Add comment 98 Plus   }
Add comment 99 Plus   catch (Exception ex)
Add comment 100 Plus   {
Add comment 101 Plus   _logger.LogError(ex, $"Exception while populating cache for line {line}");
Add comment 102 Plus   }
Add comment 103 Plus   }
Add comment 104 Plus  
Add comment 105 Plus   // For testing/debugging
Add comment 106 Plus   foreach(var key in Cache.ScenariosSplitByOSAndSKU.Keys)
Add comment 107 Plus   {
Add comment 108 Plus   _logger.LogInformation($"{key} has a value count of {Cache.ScenariosSplitByOSAndSKU[key].Count}");
Add comment 109 Plus   }
Add comment 110 Plus   }
Add comment 111 Plus   }
Add comment 112 Plus   catch (Exception ex)
Add comment 113 Plus   {
Add comment 114 Plus   _logger.LogError(ex, $"Exception while clearing/populating cache");
Add comment 115 Plus   }
Add comment 116 Plus   }
Add comment 117 Plus   }
Add comment 118 Plus  }
Add comment 119 Plus  
GetLoaderioTestGroupActivity.cs
/GetLoaderioTestGroupActivity.cs+107
/GetLoaderioTestGroupActivity.cs
Add comment 1 Plus  using System;
Add comment 2 Plus  using System.Threading.Tasks;
Add comment 3 Plus  using Microsoft.Azure.WebJobs;
Add comment 4 Plus  using Microsoft.Azure.WebJobs.Extensions.DurableTask;
Add comment 5 Plus  using Microsoft.Extensions.Logging;
Add comment 6 Plus  using Newtonsoft.Json.Linq;
Add comment 7 Plus  
Add comment 8 Plus  namespace TestScheduler
Add comment 9 Plus  {
Add comment 10 Plus   public class GetLoaderioTestGroupActivity
Add comment 11 Plus   {
Add comment 12 Plus  
Add comment 13 Plus   private readonly ILogger _logger;
Add comment 14 Plus  
Add comment 15 Plus   public GetLoaderioTestGroupActivity(ILoggerFactory loggerFactory)
Add comment 16 Plus   {
Add comment 17 Plus   _logger = loggerFactory.CreateLogger("Microsoft.Azure.WebJobs.GetLoaderioTestGroupActivity");
Add comment 18 Plus   }
Add comment 19 Plus  
Add comment 20 Plus   [FunctionName("GetLoaderioTestGroupActivity")]
Add comment 21 Plus   public async Task<LoaderioTestGroup> Run(
Add comment 22 Plus   [ActivityTrigger] IDurableActivityContext context)
Add comment 23 Plus   {
Add comment 24 Plus   //JObject testGroup = context.GetInput<JObject>();
Add comment 25 Plus   GetLoaderioTestGroupInput testGroupInput = context.GetInput<GetLoaderioTestGroupInput>();
Add comment 26 Plus   JObject testGroup = testGroupInput.TestGroup;
Add comment 27 Plus  
Add comment 28 Plus   LoaderioTestGroup group = new LoaderioTestGroup();
Add comment 29 Plus   string appName = testGroup.Value<string>("AppName");
Add comment 30 Plus   bool shouldWarmUp = !appName.Contains("ep", StringComparison.OrdinalIgnoreCase) && !appName.Contains("cns", StringComparison.OrdinalIgnoreCase);
Add comment 31 Plus   _logger.LogInformation($"Warmup value is {shouldWarmUp} for {appName}");
Add comment 32 Plus  
Add comment 33 Plus   group.SubscriptionId = testGroup.Value<string>("SubscriptionId");
Add comment 34 Plus   group.ResourceGroup = testGroup.Value<string>("ResourceGroup");
Add comment 35 Plus   group.AppName = appName;
Add comment 36 Plus   group.ClientId = testGroupInput.ClientId;
Add comment 37 Plus   group.ServicePrincipalPassword = testGroupInput.ServicePrincipalPassword;
Add comment 38 Plus   group.TenantId = testGroupInput.TenantId;
Add comment 39 Plus  
Add comment 40 Plus   string[] testIds = (testGroup.Value<JArray>("LoaderioTestIDs")).ToObject<string[]>();
Add comment 41 Plus  
Add comment 42 Plus   foreach (string testId in testIds)
Add comment 43 Plus   {
Add comment 44 Plus   group.LoaderioTestsWithinGroup.Add(GetTestInvocationDetails(testId, testGroupInput.LoaderioKey, shouldWarmUp));
Add comment 45 Plus   }
Add comment 46 Plus  
Add comment 47 Plus   // Wait time between tests
Add comment 48 Plus   group.WaitTimeBetweenTestsInMinutes = 30;
Add comment 49 Plus  
Add comment 50 Plus   // Populate current SKU
Add comment 51 Plus   string token = await Helpers.GetToken(group.ClientId, group.ServicePrincipalPassword, group.TenantId);
Add comment 52 Plus   group.CurrentSKU = GetCurrentSKUAsync(token, group.SubscriptionId, group.ResourceGroup, appName);
Add comment 53 Plus  
Add comment 54 Plus   return group;
Add comment 55 Plus   }
Add comment 56 Plus  
Add comment 57 Plus   private LoaderioTest GetTestInvocationDetails(string testId, string loaderioKey, bool shouldWarmUp = false)
Add comment 58 Plus   {
Add comment 59 Plus   JToken testDetails = Helpers.GetTestDetails(testId, loaderioKey);
Add comment 60 Plus   JToken testDetail = testDetails.Value<JArray>("urls")[0];
Add comment 61 Plus   LoaderioTest testParams = new LoaderioTest()
Add comment 62 Plus   {
Add comment 63 Plus   Content = testDetail.Value<string>("raw_post_body"),
Add comment 64 Plus   RequestType = (RequestType)Enum.Parse(typeof(RequestType), testDetail.Value<string>("request_type"), true),
Add comment 65 Plus   FunctionAppUrlForColdstart = testDetail.Value<string>("url"),
Add comment 66 Plus   LoaderioTestUrl = $"https://api.loader.io/v2/tests/{testId}/run",
Add comment 67 Plus   LoaderioStopUrl = $"https://api.loader.io/v2/tests/{testId}/stop",
Add comment 68 Plus   ContentType = testDetail.Value<JObject>("headers").Value<string>("Content-Type"), // ContentType would be null if not present
Add comment 69 Plus   LoaderioKey = loaderioKey,
Add comment 70 Plus   ShouldWarmUp = shouldWarmUp,
Add comment 71 Plus   };
Add comment 72 Plus  
Add comment 73 Plus   return testParams;
Add comment 74 Plus   }
Add comment 75 Plus  
Add comment 76 Plus   private JObject GetCurrentSKUAsync(string token, string subscriptionId, string resourceGroup, string appName)
Add comment 77 Plus   {
Add comment 78 Plus   try
Add comment 79 Plus   {
Add comment 80 Plus   string serverFarmId = Helpers.GetServerFarmId(token, subscriptionId, resourceGroup, appName, _logger);
Add comment 81 Plus  
Add comment 82 Plus   if (string.IsNullOrEmpty(serverFarmId))
Add comment 83 Plus   {
Add comment 84 Plus   _logger.LogError($"Server farm id for {appName} is empty");
Add comment 85 Plus   return null;
Add comment 86 Plus   }
Add comment 87 Plus  
Add comment 88 Plus   JObject serverFarmDetails = Helpers.GetServerFarmDetails(token, serverFarmId, _logger);
Add comment 89 Plus  
Add comment 90 Plus   if (serverFarmDetails == null)
Add comment 91 Plus   {
Add comment 92 Plus   _logger.LogError($"Server farm details for {serverFarmId} is null");
Add comment 93 Plus   return null;
Add comment 94 Plus   }
Add comment 95 Plus  
Add comment 96 Plus   return serverFarmDetails.Value<JObject>("sku");
Add comment 97 Plus   }
Add comment 98 Plus   catch (Exception ex)
Add comment 99 Plus   {
Add comment 100 Plus   _logger.LogError(ex, $"Exception while trying to Get SKU {appName}");
Add comment 101 Plus   }
Add comment 102 Plus  
Add comment 103 Plus   return null;
Add comment 104 Plus   }
Add comment 105 Plus   }
Add comment 106 Plus  }
Add comment 107 Plus  
GetLoaderioTestGroupInput.cs
/GetLoaderioTestGroupInput.cs
/GetLoaderioTestGroupInput.cs
Helpers.cs
/Helpers.cs
/Helpers.cs
HitProxyUrlActivity.cs
/HitProxyUrlActivity.cs
/HitProxyUrlActivity.cs
host.json
/host.json
/host.json
LoaderioActivity.cs
/LoaderioActivity.cs
/LoaderioActivity.cs
LoaderioOrchestration.cs
/LoaderioOrchestration.cs
/LoaderioOrchestration.cs
LoaderioTest.cs
/LoaderioTest.cs
/LoaderioTest.cs
LoaderioTestGroup.cs
/LoaderioTestGroup.cs
/LoaderioTestGroup.cs
MasterOrchestration.cs
/MasterOrchestration.cs
/MasterOrchestration.cs
MasterOrchestrationInput.cs
/MasterOrchestrationInput.cs
/MasterOrchestrationInput.cs
RequestType.cs
/RequestType.cs
/RequestType.cs
RestartFunctionAppActivity.cs
/RestartFunctionAppActivity.cs
/RestartFunctionAppActivity.cs
ScaleChangeActivity.cs
/ScaleChangeActivity.cs
/ScaleChangeActivity.cs
SKUMatchActivity.cs
/SKUMatchActivity.cs
/SKUMatchActivity.cs
TableCommands.txt
/TableCommands.txt
/TableCommands.txt
TestScheduler.csproj
/TestScheduler.csproj
/TestScheduler.csproj
TestScheduler.sln
/TestScheduler.sln
/TestScheduler.sln
Webhook.cs
/Webhook.cs
/Webhook.cs