public void TimeToRestoreServiceDALiveIntegrationTest() { //Arrange bool getSampleData = false; TableStorageAuth tableStorageAuth = Common.GenerateTableAuthorization(Configuration); string resourceGroup = "SamLearnsAzureProd"; DevOpsPlatform targetDevOpsPlatform = DevOpsPlatform.AzureDevOps; int numberOfDays = 30; int maxNumberOfItems = 20; //Act MeanTimeToRestoreDA da = new MeanTimeToRestoreDA(); MeanTimeToRestoreModel model = da.GetAzureMeanTimeToRestore(getSampleData, tableStorageAuth, targetDevOpsPlatform, resourceGroup, numberOfDays, maxNumberOfItems); //Assert Assert.IsTrue(model != null); Assert.IsTrue(model.TargetDevOpsPlatform == targetDevOpsPlatform); Assert.AreEqual(resourceGroup, model.ResourceGroup); Assert.IsTrue(model.MeanTimeToRestoreEvents.Count > 0); Assert.IsTrue(model.MTTRAverageDurationInHours > 0); Assert.IsTrue(model.MTTRAverageDurationDescription != ""); Assert.AreEqual(numberOfDays, model.NumberOfDays); Assert.IsTrue(model.MaxNumberOfItems > 0); Assert.IsTrue(model.TotalItems > 0); }
public void AzureMTTRsAPIControllerIntegrationTest() { //Arrange bool getSampleData = false; string resourceGroupName = "SamLearnsAzureProd"; DevOpsPlatform targetDevOpsPlatform = DevOpsPlatform.AzureDevOps; int numberOfDays = 60; int maxNumberOfItems = 20; MeanTimeToRestoreController controller = new(base.Configuration); //Act MeanTimeToRestoreModel model = controller.GetAzureMeanTimeToRestore(getSampleData, targetDevOpsPlatform, resourceGroupName, numberOfDays, maxNumberOfItems); //Assert Assert.IsTrue(model != null); Assert.AreEqual(targetDevOpsPlatform, model.TargetDevOpsPlatform); Assert.AreEqual(resourceGroupName, model.ResourceGroup); Assert.IsTrue(model.MeanTimeToRestoreEvents.Count >= 0); if (model.MeanTimeToRestoreEvents.Count > 0) { Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Name != ""); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Resource != ""); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Status != ""); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Url != ""); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].StartTime >= DateTime.MinValue); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].EndTime >= DateTime.MinValue); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].ResourceGroup != ""); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].MTTRDurationInHours > 0f); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].MTTRDurationPercent > 0f); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].ItemOrder >= 1); } Assert.AreEqual(numberOfDays, model.NumberOfDays); Assert.IsTrue(model.MaxNumberOfItems >= 0); Assert.IsTrue(model.TotalItems >= 0); }
public void MTTREliteTest() { //Arrange MeanTimeToRestore metrics = new MeanTimeToRestore(); int numberOfDays = 7; List <KeyValuePair <DateTime, TimeSpan> > meanTimeToRestoreList = new List <KeyValuePair <DateTime, TimeSpan> > { new KeyValuePair <DateTime, TimeSpan>(DateTime.Now.AddDays(-3), new TimeSpan(0, 40, 0)), new KeyValuePair <DateTime, TimeSpan>(DateTime.Now.AddDays(-4), new TimeSpan(0, 50, 0)), }; //Act float result = metrics.ProcessMeanTimeToRestore(meanTimeToRestoreList, numberOfDays); MeanTimeToRestoreModel model = new MeanTimeToRestoreModel { MTTRAverageDurationInHours = result, MTTRAverageDurationDescription = metrics.GetMeanTimeToRestoreRating(result), IsProjectView = false, ItemOrder = 1 }; //Assert Assert.IsTrue(model != null); Assert.AreEqual(0.75f, model.MTTRAverageDurationInHours); Assert.AreEqual("Elite", model.MTTRAverageDurationDescription); Assert.AreEqual(false, model.IsProjectView); Assert.AreEqual(1, model.ItemOrder); }
public void AzureMTTRSampleControllerIntegrationTest() { //Arrange bool getSampleData = true; string resourceGroupName = "SamLearnsAzureProd"; DevOpsPlatform targetDevOpsPlatform = DevOpsPlatform.AzureDevOps; int numberOfDays = 7; int maxNumberOfItems = 20; MeanTimeToRestoreController controller = new(base.Configuration); //Act MeanTimeToRestoreModel model = controller.GetAzureMeanTimeToRestore(getSampleData, targetDevOpsPlatform, resourceGroupName, numberOfDays, maxNumberOfItems); //Assert Assert.IsTrue(model != null); Assert.AreEqual(targetDevOpsPlatform, model.TargetDevOpsPlatform); Assert.AreEqual(resourceGroupName, model.ResourceGroup); Assert.IsTrue(model.MeanTimeToRestoreEvents.Count > 0); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Name == "Name1"); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Resource == "Resource1"); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Status == "Completed"); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].Url == "https://mttr.com"); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].StartTime > DateTime.MinValue); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].EndTime > DateTime.MinValue); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].ResourceGroup == resourceGroupName); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].MTTRDurationInHours > 0f); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].MTTRDurationPercent > 0f); Assert.IsTrue(model.MeanTimeToRestoreEvents[0].ItemOrder == 1); Assert.AreEqual(numberOfDays, model.NumberOfDays); Assert.IsTrue(model.MaxNumberOfItems > 0); Assert.IsTrue(model.TotalItems > 0); }
public MeanTimeToRestoreModel GetAzureMeanTimeToRestore(bool getSampleData, DevOpsPlatform targetDevOpsPlatform, string resourceGroup, int numberOfDays, int maxNumberOfItems) { TableStorageConfiguration tableStorageConfig = Common.GenerateTableStorageConfiguration(Configuration); MeanTimeToRestoreDA da = new(); MeanTimeToRestoreModel model = da.GetAzureMeanTimeToRestore(getSampleData, tableStorageConfig, targetDevOpsPlatform, resourceGroup, numberOfDays, maxNumberOfItems); return(model); }
public async Task <IActionResult> MeanTimeToRestore() { int maxNumberOfItems = 20; //20 is the optimium max that looks good with the current UI int numberOfDays = 30; //TODO: Move number of days variable to a drop down list on the current UI bool getSampleData = false; ServiceApiClient serviceApiClient = new ServiceApiClient(Configuration); List <MeanTimeToRestoreModel> items = new List <MeanTimeToRestoreModel>(); //Get a list of settings List <AzureDevOpsSettings> azureDevOpsSettings = await serviceApiClient.GetAzureDevOpsSettings(); List <GitHubSettings> githubSettings = await serviceApiClient.GetGitHubSettings(); //Create MTTR models from each Azure DevOps settings object foreach (AzureDevOpsSettings item in azureDevOpsSettings) { MeanTimeToRestoreModel newMeanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.AzureDevOps, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); newMeanTimeToRestoreModel.ItemOrder = item.ItemOrder; if (newMeanTimeToRestoreModel != null) { items.Add(newMeanTimeToRestoreModel); } } //Create MTTR models from each GitHub settings object foreach (GitHubSettings item in githubSettings) { MeanTimeToRestoreModel newMeanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.GitHub, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); newMeanTimeToRestoreModel.ItemOrder = item.ItemOrder; if (newMeanTimeToRestoreModel != null) { items.Add(newMeanTimeToRestoreModel); } } //sort the final list items = items.OrderBy(o => o.ItemOrder).ToList(); return(View(items)); }
public async Task <IActionResult> MeanTimeToRestore() { int maxNumberOfItems = 20; int numberOfDays = 60; bool getSampleData = false; ServiceApiClient serviceApiClient = new ServiceApiClient(Configuration); List <MeanTimeToRestoreModel> items = new List <MeanTimeToRestoreModel>(); //Get a list of settings List <AzureDevOpsSettings> azureDevOpsSettings = await serviceApiClient.GetAzureDevOpsSettings(); List <GitHubSettings> githubSettings = await serviceApiClient.GetGitHubSettings(); //Create MTTR models from each setting object foreach (AzureDevOpsSettings item in azureDevOpsSettings) { MeanTimeToRestoreModel newMeanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.AzureDevOps, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); newMeanTimeToRestoreModel.ItemOrder = item.ItemOrder; if (newMeanTimeToRestoreModel != null) { items.Add(newMeanTimeToRestoreModel); } } foreach (GitHubSettings item in githubSettings) { MeanTimeToRestoreModel newMeanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.GitHub, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); newMeanTimeToRestoreModel.ItemOrder = item.ItemOrder; if (newMeanTimeToRestoreModel != null) { items.Add(newMeanTimeToRestoreModel); } } //sort the list items = items.OrderBy(o => o.ItemOrder).ToList(); return(View(items)); }
public void MeanTimeToRestoreDAIntegrationTest() { //Arrange bool getSampleData = true; TableStorageConfiguration tableStorageConfig = Common.GenerateTableAuthorization(base.Configuration); string resourceGroup = "DevOpsMetricsTestRG"; DevOpsPlatform targetDevOpsPlatform = DevOpsPlatform.AzureDevOps; int numberOfDays = 30; int maxNumberOfItems = 20; //Act MeanTimeToRestoreDA da = new(); MeanTimeToRestoreModel model = da.GetAzureMeanTimeToRestore(getSampleData, tableStorageConfig, targetDevOpsPlatform, resourceGroup, numberOfDays, maxNumberOfItems); //Assert Assert.IsTrue(model != null); Assert.IsTrue(model.TargetDevOpsPlatform == targetDevOpsPlatform); Assert.AreEqual(resourceGroup, model.ResourceGroup); Assert.IsTrue(model.MeanTimeToRestoreEvents.Count > 0); Assert.IsTrue(model.MTTRAverageDurationInHours > 0); Assert.AreEqual(numberOfDays, model.NumberOfDays); Assert.IsTrue(model.MaxNumberOfItems > 0); Assert.IsTrue(model.TotalItems > 0); }
public async Task <IActionResult> Project(string rowKey, int numberOfDays = 30) { int maxNumberOfItems = 20; bool getSampleData = false; bool useCache = true; string patToken = Configuration["AppSettings:AzureDevOpsPatToken"]; string clientId = Configuration["AppSettings:GitHubClientId"]; string clientSecret = Configuration["AppSettings:GitHubClientSecret"]; ProjectViewModel model = new ProjectViewModel(); //Find the right project to load ServiceApiClient serviceApiClient = new ServiceApiClient(Configuration); List <AzureDevOpsSettings> azureDevOpsSettings = await serviceApiClient.GetAzureDevOpsSettings(); List <GitHubSettings> githubSettings = await serviceApiClient.GetGitHubSettings(); //Create the days to view dropdown List <NumberOfDaysItem> numberOfDaysList = new List <NumberOfDaysItem> { new NumberOfDaysItem { NumberOfDays = 7 }, new NumberOfDaysItem { NumberOfDays = 14 }, new NumberOfDaysItem { NumberOfDays = 21 }, new NumberOfDaysItem { NumberOfDays = 30 }, new NumberOfDaysItem { NumberOfDays = 60 }, new NumberOfDaysItem { NumberOfDays = 90 } }; //Get Azure DevOps project details AzureDevOpsSettings azureDevOpsSetting; foreach (AzureDevOpsSettings item in azureDevOpsSettings) { if (item.RowKey == rowKey) { azureDevOpsSetting = item; DeploymentFrequencyModel deploymentFrequencyModel = await serviceApiClient.GetAzureDevOpsDeploymentFrequency(getSampleData, patToken, item.Organization, item.Project, item.Branch, item.BuildName, item.BuildId, numberOfDays, maxNumberOfItems, useCache); LeadTimeForChangesModel leadTimeForChangesModel = await serviceApiClient.GetAzureDevOpsLeadTimeForChanges(getSampleData, patToken, item.Organization, item.Project, item.Repository, item.Branch, item.BuildName, item.BuildId, numberOfDays, maxNumberOfItems, useCache); MeanTimeToRestoreModel meanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.AzureDevOps, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); ChangeFailureRateModel changeFailureRateModel = await serviceApiClient.GetChangeFailureRate(getSampleData, DevOpsPlatform.AzureDevOps, item.Organization, item.Project, item.Branch, item.BuildName, numberOfDays, maxNumberOfItems); deploymentFrequencyModel.IsProjectView = true; leadTimeForChangesModel.IsProjectView = true; meanTimeToRestoreModel.IsProjectView = true; changeFailureRateModel.IsProjectView = true; model = new ProjectViewModel { RowKey = item.RowKey, ProjectName = item.Project, TargetDevOpsPlatform = DevOpsPlatform.AzureDevOps, DeploymentFrequency = deploymentFrequencyModel, LeadTimeForChanges = leadTimeForChangesModel, MeanTimeToRestore = meanTimeToRestoreModel, ChangeFailureRate = changeFailureRateModel, NumberOfDays = new SelectList(numberOfDaysList, "NumberOfDays", "NumberOfDays"), NumberOfDaysSelected = numberOfDays }; } } //Get GitHub project details GitHubSettings githubSetting; foreach (GitHubSettings item in githubSettings) { if (item.RowKey == rowKey) { githubSetting = item; DeploymentFrequencyModel deploymentFrequencyModel = await serviceApiClient.GetGitHubDeploymentFrequency(getSampleData, clientId, clientSecret, item.Owner, item.Repo, item.Branch, item.WorkflowName, item.WorkflowId, numberOfDays, maxNumberOfItems, useCache); LeadTimeForChangesModel leadTimeForChangesModel = await serviceApiClient.GetGitHubLeadTimeForChanges(getSampleData, clientId, clientSecret, item.Owner, item.Repo, item.Branch, item.WorkflowName, item.WorkflowId, numberOfDays, maxNumberOfItems, useCache); MeanTimeToRestoreModel meanTimeToRestoreModel = await serviceApiClient.GetAzureMeanTimeToRestore(getSampleData, DevOpsPlatform.GitHub, item.ProductionResourceGroup, numberOfDays, maxNumberOfItems); ChangeFailureRateModel changeFailureRateModel = await serviceApiClient.GetChangeFailureRate(getSampleData, DevOpsPlatform.GitHub, item.Owner, item.Repo, item.Branch, item.WorkflowName, numberOfDays, maxNumberOfItems); deploymentFrequencyModel.IsProjectView = true; leadTimeForChangesModel.IsProjectView = true; meanTimeToRestoreModel.IsProjectView = true; changeFailureRateModel.IsProjectView = true; model = new ProjectViewModel { RowKey = item.RowKey, ProjectName = item.Repo, TargetDevOpsPlatform = DevOpsPlatform.GitHub, DeploymentFrequency = deploymentFrequencyModel, LeadTimeForChanges = leadTimeForChangesModel, MeanTimeToRestore = meanTimeToRestoreModel, ChangeFailureRate = changeFailureRateModel, NumberOfDays = new SelectList(numberOfDaysList, "NumberOfDays", "NumberOfDays"), NumberOfDaysSelected = numberOfDays }; } } return(View(model)); }
public MeanTimeToRestoreModel GetAzureMeanTimeToRestore(bool getSampleData, TableStorageConfiguration tableStorageConfig, DevOpsPlatform targetDevOpsPlatform, string resourceGroup, int numberOfDays, int maxNumberOfItems) { ListUtility <MeanTimeToRestoreEvent> utility = new ListUtility <MeanTimeToRestoreEvent>(); if (getSampleData == false) { //If the user didn't specify a resource group, it comes in as null and causes havoc. Setting it as "" helps, it if (resourceGroup == null) { resourceGroup = ""; } //Pull the events from the table storage AzureTableStorageDA daTableStorage = new AzureTableStorageDA(); Newtonsoft.Json.Linq.JArray list = daTableStorage.GetTableStorageItemsFromStorage(tableStorageConfig, tableStorageConfig.TableMTTR, resourceGroup); List <AzureAlert> alerts = new List <AzureAlert>(); foreach (JToken item in list) { alerts.Add( new AzureAlert { name = item["data"]["context"]["name"].ToString(), resourceGroupName = item["data"]["context"]["resourceGroupName"].ToString(), resourceName = item["data"]["context"]["resourceName"].ToString(), status = item["data"]["status"].ToString(), timestamp = DateTime.Parse(item["data"]["context"]["timestamp"].ToString()) }); } //sort the events by timestamp alerts = alerts.OrderBy(o => o.timestamp).ToList(); //Compile the events, looking for pairs, using the ordered data, and name, resource group name and resource name List <MeanTimeToRestoreEvent> events = new List <MeanTimeToRestoreEvent>(); //Loop through first finding the activated alerts int i = 0; List <AzureAlert> startingAlerts = alerts.Where(o => o.status == "Activated").ToList(); foreach (AzureAlert item in startingAlerts) { if (item.timestamp > DateTime.Now.AddDays(-numberOfDays)) { i++; MeanTimeToRestoreEvent newEvent = new MeanTimeToRestoreEvent { Name = item.name, Resource = item.resourceName, ResourceGroup = item.resourceGroupName, StartTime = item.timestamp, Status = "inProgress", ItemOrder = i }; events.Add(newEvent); } } //Now loop through again, looking for the deactivated matching pair float maxEventDuration = 0; List <AzureAlert> endingAlerts = alerts.Where(o => o.status == "Deactivated").ToList(); foreach (MeanTimeToRestoreEvent item in events) { //Search for the next matching deactivated alert int foundItemIndex = -1; for (int j = 0; j <= endingAlerts.Count - 1; j++) { if (endingAlerts[j].name == item.Name && endingAlerts[j].resourceName == item.Resource && endingAlerts[j].resourceGroupName == item.ResourceGroup && endingAlerts[j].timestamp > item.StartTime) { item.EndTime = endingAlerts[j].timestamp; item.Status = "completed"; foundItemIndex = j; break; } } if (foundItemIndex >= 0) { //Remove the found item from the list, so we don't use it again. endingAlerts.RemoveAt(foundItemIndex); if (item.MTTRDurationInHours > maxEventDuration) { maxEventDuration = item.MTTRDurationInHours; } } } //Calculate the MTTR metric MeanTimeToRestore mttr = new MeanTimeToRestore(); List <KeyValuePair <DateTime, TimeSpan> > dateList = ConvertEventsToDateList(events); float averageMTTR = mttr.ProcessMeanTimeToRestore(dateList, numberOfDays); //Calculate the SLA metric SLA slaMetric = new SLA(); float sla = slaMetric.ProcessSLA(dateList, numberOfDays); //Filter the list for the UI, and sort the final list (May not be needed due to the initial sort on the starting alerts) List <MeanTimeToRestoreEvent> uiEvents = utility.GetLastNItems(events, maxNumberOfItems); uiEvents = uiEvents.OrderBy(o => o.StartTime).ToList(); //Finally, process the percent calculation foreach (MeanTimeToRestoreEvent item in uiEvents) { float interiumResult = ((item.MTTRDurationInHours / maxEventDuration) * 100f); item.MTTRDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100); } //Pull together the results into a single model MeanTimeToRestoreModel model = new MeanTimeToRestoreModel { TargetDevOpsPlatform = targetDevOpsPlatform, ResourceGroup = resourceGroup, MeanTimeToRestoreEvents = uiEvents, MTTRAverageDurationInHours = averageMTTR, MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR), NumberOfDays = numberOfDays, MaxNumberOfItems = uiEvents.Count, TotalItems = events.Count, SLA = sla, SLADescription = slaMetric.GetSLARating(sla) }; return(model); } else { //Get sample data MeanTimeToRestore mttr = new MeanTimeToRestore(); List <MeanTimeToRestoreEvent> sampleEvents = GetSampleMTTREvents(resourceGroup); List <KeyValuePair <DateTime, TimeSpan> > dateList = ConvertEventsToDateList(sampleEvents); float averageMTTR = mttr.ProcessMeanTimeToRestore(dateList, numberOfDays); SLA slaMetric = new SLA(); float sla = slaMetric.ProcessSLA(dateList, numberOfDays); MeanTimeToRestoreModel model = new MeanTimeToRestoreModel { TargetDevOpsPlatform = targetDevOpsPlatform, ResourceGroup = resourceGroup, MeanTimeToRestoreEvents = sampleEvents, MTTRAverageDurationInHours = averageMTTR, MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR), NumberOfDays = numberOfDays, MaxNumberOfItems = sampleEvents.Count, TotalItems = sampleEvents.Count, SLA = sla, SLADescription = slaMetric.GetSLARating(sla) }; return(model); } }