From e9baef64aec5d89c35c25f605bcaf059da0dd82e Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Thu, 25 May 2023 11:25:55 -0400 Subject: [PATCH 1/9] Updated Test --- .../Service/DORASummaryControllerTests.cs | 110 +++++++++--------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs index 5dfb5e8d..e2398dd0 100644 --- a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs +++ b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs @@ -1,5 +1,10 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using DevOpsMetrics.Core.DataAccess.TableStorage; +using DevOpsMetrics.Core.Models.AzureDevOps; using DevOpsMetrics.Core.Models.Common; +using DevOpsMetrics.Core.Models.GitHub; using DevOpsMetrics.Service.Controllers; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -107,59 +112,56 @@ public async Task DORASummaryControllerAzureDevOpsUpdateIntegrationTest() Assert.IsNotNull(model); } - //[TestMethod] - //public async Task DORASummaryControllerUpdateALLIntegrationTest() - //{ - // //Arrange - // int numberOfDays = 30; - // int maxNumberOfItems = 20; - // int totalResults = 0; - // DORASummaryController controller = new(base.Configuration); - // SettingsController settingsController = new(base.Configuration, new AzureTableStorageDA()); - - // //Act - // List azSettings = settingsController.GetAzureDevOpsSettings(); - // List ghSettings = settingsController.GetGitHubSettings(); - - // foreach (AzureDevOpsSettings item in azSettings) - // { - // // (int, string) buildsUpdated = (0, null); - // // (int, string) prsUpdated = (0, null); - // // try - // // { - // //log.LogInformation($"Processing Azure DevOps organization {item.Organization}, project {item.Project}"); - // // buildsUpdated = await api.UpdateAzureDevOpsBuilds(item.Organization, item.Project, item.Repository, item.Branch, item.BuildName, item.BuildId, numberOfDays, maxNumberOfItems); - // // prsUpdated = await api.UpdateAzureDevOpsPullRequests(item.Organization, item.Project, item.Repository, numberOfDays, maxNumberOfItems); - // // log.LogInformation($"Processed Azure DevOps organization {item.Organization}, project {item.Project}. {buildsUpdated.Item1} builds and {prsUpdated.Item1} prs/commits updated"); - // // totalResults += buildsUpdated.Item1 + prsUpdated.Item1; - // // await api.UpdateAzureDevOpsProjectLog(item.Organization, item.Project, item.Repository, buildsUpdated.Item1, prsUpdated.Item1, buildsUpdated.Item2, prsUpdated.Item2, null, null); - // // } - // // catch (Exception ex) - // // { - // // string error = $"Exception while processing Azure DevOps organization {item.Organization}, project {item.Project}. {buildsUpdated.Item1} builds and {prsUpdated.Item1} prs/commits updated"; - // // log.LogInformation(error); - // // await api.UpdateAzureDevOpsProjectLog(item.Organization, item.Project, item.Repository, buildsUpdated.Item1, prsUpdated.Item1, buildsUpdated.Item2, prsUpdated.Item2, ex.Message, error); - // // } - // } - - // foreach (GitHubSettings ghSetting in ghSettings) - // { - // Debug.WriteLine($"Owner {ghSetting.Owner}, Repo {ghSetting.Repo}"); - // ProcessingResult ghResult = await controller.UpdateDORASummaryItem( - // ghSetting.Owner, ghSetting.Repo, ghSetting.Branch, - // ghSetting.WorkflowName, ghSetting.WorkflowId, - // ghSetting.ProductionResourceGroup, - // numberOfDays, maxNumberOfItems); - // totalResults += ghResult.TotalResults; - // Assert.IsNotNull(ghResult); - // } - - // //ProcessingResult model = await controller.UpdateDORASummaryItem(organization, repository, - // // branch, workflowName, workflowId, resourceGroup, numberOfDays, maxNumberOfItems); - - // //Assert - // Assert.IsTrue(totalResults > 0); - //} + [TestMethod] + public async Task DORASummaryControllerUpdateALLIntegrationTest() + { + //Arrange + int numberOfDays = 30; + int maxNumberOfItems = 20; + int totalResults = 0; + DORASummaryController controller = new(base.Configuration); + SettingsController settingsController = new(base.Configuration, new AzureTableStorageDA()); + bool runExpensiveTest = true; + + //Act + if (runExpensiveTest) + { + List azSettings = settingsController.GetAzureDevOpsSettings(); + List ghSettings = settingsController.GetGitHubSettings(); + + foreach (AzureDevOpsSettings azSetting in azSettings) + { + Debug.WriteLine($"Processing Azure DevOps organization {azSetting.Organization}, project {azSetting.Project}"); + ProcessingResult ghResult = await controller.UpdateDORASummaryItem( + azSetting.Organization, azSetting.Project, azSetting.Repository, + azSetting.Branch, azSetting.BuildName, azSetting.BuildId, + azSetting.ProductionResourceGroup, + numberOfDays, maxNumberOfItems, null, true, false); + totalResults = ghResult.TotalResults; + } + + foreach (GitHubSettings ghSetting in ghSettings) + { + Debug.WriteLine($"Processing GitHub owner {ghSetting.Owner}, repo {ghSetting.Repo}"); + ProcessingResult ghResult = await controller.UpdateDORASummaryItem( + ghSetting.Owner, "", ghSetting.Repo, ghSetting.Branch, + ghSetting.WorkflowName, ghSetting.WorkflowId, + ghSetting.ProductionResourceGroup, + numberOfDays, maxNumberOfItems, null, true, true); + totalResults = ghResult.TotalResults; + } + } + + //Assert + if (runExpensiveTest) + { + Assert.IsTrue(totalResults > 0); + } + else + { + Assert.IsTrue(totalResults == 0); + } + } } } From 45adf417dddc0c3567dc1e498933d76dca453200 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Thu, 25 May 2023 13:29:44 -0400 Subject: [PATCH 2/9] improved test --- src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs index e2398dd0..47da6713 100644 --- a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs +++ b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs @@ -137,7 +137,7 @@ public async Task DORASummaryControllerUpdateALLIntegrationTest() azSetting.Branch, azSetting.BuildName, azSetting.BuildId, azSetting.ProductionResourceGroup, numberOfDays, maxNumberOfItems, null, true, false); - totalResults = ghResult.TotalResults; + totalResults += ghResult.TotalResults; } foreach (GitHubSettings ghSetting in ghSettings) @@ -148,7 +148,7 @@ public async Task DORASummaryControllerUpdateALLIntegrationTest() ghSetting.WorkflowName, ghSetting.WorkflowId, ghSetting.ProductionResourceGroup, numberOfDays, maxNumberOfItems, null, true, true); - totalResults = ghResult.TotalResults; + totalResults += ghResult.TotalResults; } } From a9dca773477e303683040d9d868b01a88da840fe Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Thu, 25 May 2023 13:29:56 -0400 Subject: [PATCH 3/9] improved test --- src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs index 47da6713..11c431b0 100644 --- a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs +++ b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs @@ -121,7 +121,7 @@ public async Task DORASummaryControllerUpdateALLIntegrationTest() int totalResults = 0; DORASummaryController controller = new(base.Configuration); SettingsController settingsController = new(base.Configuration, new AzureTableStorageDA()); - bool runExpensiveTest = true; + bool runExpensiveTest = false; //Act if (runExpensiveTest) From ceb738db9d06e0d5ac082399cd29aebfeadd999a Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 06:31:11 -0400 Subject: [PATCH 4/9] Optimizations to project processing --- .../Controllers/DORASummaryController.cs | 6 ++--- .../Service/DORASummaryControllerTests.cs | 22 +++++++++--------- .../Controllers/HomeController.cs | 23 +++++++++++-------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs index c5b27c4a..cc225c2a 100644 --- a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs +++ b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs @@ -167,9 +167,9 @@ public async Task UpdateDORASummaryItem( } ChangeFailureRateModel changeFailureRateModel = ChangeFailureRateDA.GetChangeFailureRate(false, tableStorageConfig, - DevOpsPlatform.GitHub, - owner, repo, branch, workflowName, - numberOfDays, maxNumberOfItems); + DevOpsPlatform.GitHub, + owner, repo, branch, workflowName, + numberOfDays, maxNumberOfItems); //Summarize the results into a new object DORASummaryItem DORASummary = new() diff --git a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs index 11c431b0..8b496c2d 100644 --- a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs +++ b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs @@ -50,18 +50,18 @@ public void DORASummaryControllerGetIntegrationTest2() public async Task DORASummaryControllerGitHubUpdateIntegrationTest() { //Arrange - string organization = "DeveloperMetrics"; - string repository = "DevOpsMetrics"; - string branch = "main"; - string workflowName = "CI/CD"; - string workflowId = "1162561"; - string resourceGroup = "DevOpsMetrics"; - //string organization = "samsmithnz"; - //string repository = "AzurePipelinesToGitHubActionsConverter"; + //string organization = "DeveloperMetrics"; + //string repository = "DevOpsMetrics"; //string branch = "main"; - //string workflowName = "CI/ CD"; - //string workflowId = "38158"; - //string resourceGroup = null; + //string workflowName = "CI/CD"; + //string workflowId = "1162561"; + //string resourceGroup = "DevOpsMetrics"; + string organization = "samsmithnz"; + string repository = "AzurePipelinesToGitHubActionsConverter"; + string branch = "main"; + string workflowName = "CI/ CD"; + string workflowId = "38158"; + string resourceGroup = null; //string organization = "samsmithnz"; //string repository = "AzurePipelinesToGitHubActionsConverterWeb"; //string branch = "main"; diff --git a/src/DevOpsMetrics.Web/Controllers/HomeController.cs b/src/DevOpsMetrics.Web/Controllers/HomeController.cs index 56836f12..c7e80d53 100644 --- a/src/DevOpsMetrics.Web/Controllers/HomeController.cs +++ b/src/DevOpsMetrics.Web/Controllers/HomeController.cs @@ -427,18 +427,23 @@ public async Task UpdateChangeFailureRate(string ProjectIdSelecte project_repo = item.Project; repository = item.Repository; buildName_workflowName = item.BuildName; + break; } } //Update each GitHub setting - foreach (GitHubSettings item in githubSettings) + if (targetDevOpsPlatform == DevOpsPlatform.UnknownDevOpsPlatform) { - if (item.RowKey == ProjectIdSelected) + foreach (GitHubSettings item in githubSettings) { - targetDevOpsPlatform = DevOpsPlatform.GitHub; - organization_owner = item.Owner; - project_repo = item.Repo; - repository = ""; - buildName_workflowName = item.WorkflowName; + if (item.RowKey == ProjectIdSelected) + { + targetDevOpsPlatform = DevOpsPlatform.GitHub; + organization_owner = item.Owner; + project_repo = item.Repo; + repository = ""; + buildName_workflowName = item.WorkflowName; + break; + } } } @@ -451,11 +456,11 @@ public async Task UpdateChangeFailureRate(string ProjectIdSelecte //Redirect to the correct project page to see the changes if (targetDevOpsPlatform == DevOpsPlatform.AzureDevOps) { - return RedirectToAction("Project", "Home", new { rowKey = organization_owner + "_" + project_repo + "_" + repository + "_" + buildName_workflowName }); + return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo + "_" + repository + "_" + buildName_workflowName }); } else if (targetDevOpsPlatform == DevOpsPlatform.GitHub) { - return RedirectToAction("Project", "Home", new { rowKey = organization_owner + "_" + project_repo + "_" + buildName_workflowName }); + return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo + "_" + buildName_workflowName }); } else { From 00828176a8e5fe35b16f8b0dfe5cbdad0f4ce1da Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 06:35:46 -0400 Subject: [PATCH 5/9] Updated dependencies --- .../DevOpsMetrics.FunctionalTests.csproj | 4 ++-- src/DevOpsMetrics.Tests/DevOpsMetrics.Tests.csproj | 4 ++-- src/DevOpsMetrics.sln | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DevOpsMetrics.FunctionalTests/DevOpsMetrics.FunctionalTests.csproj b/src/DevOpsMetrics.FunctionalTests/DevOpsMetrics.FunctionalTests.csproj index 4966af45..9ebafa02 100644 --- a/src/DevOpsMetrics.FunctionalTests/DevOpsMetrics.FunctionalTests.csproj +++ b/src/DevOpsMetrics.FunctionalTests/DevOpsMetrics.FunctionalTests.csproj @@ -8,8 +8,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DevOpsMetrics.Tests/DevOpsMetrics.Tests.csproj b/src/DevOpsMetrics.Tests/DevOpsMetrics.Tests.csproj index ea9576cb..01b85c89 100644 --- a/src/DevOpsMetrics.Tests/DevOpsMetrics.Tests.csproj +++ b/src/DevOpsMetrics.Tests/DevOpsMetrics.Tests.csproj @@ -29,8 +29,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DevOpsMetrics.sln b/src/DevOpsMetrics.sln index 3c9dcbd6..d45e0301 100644 --- a/src/DevOpsMetrics.sln +++ b/src/DevOpsMetrics.sln @@ -41,7 +41,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Probot", "Probot", "{912990 EndProject Project("{151D2E53-A2C4-4D7D-83FE-D05416EBD58E}") = "DevOpsMetrics.Infrastructure", "DevOpsMetrics.Infrastructure\DevOpsMetrics.Infrastructure.deployproj", "{0465BF7A-C791-49CA-A7DE-27B4EECD2020}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevOpsMetrics.Cmd", "DevOpsMetrics.Cmd\DevOpsMetrics.Cmd.csproj", "{D15713F2-D089-45A7-A0FA-1F16D664130D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DevOpsMetrics.Cmd", "DevOpsMetrics.Cmd\DevOpsMetrics.Cmd.csproj", "{D15713F2-D089-45A7-A0FA-1F16D664130D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 461ffe37612ee70a6e446f405d665eb2177ebfe7 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 06:50:30 -0400 Subject: [PATCH 6/9] Fix to project error handling --- .../Controllers/HomeController.cs | 72 ++++++++++--------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/src/DevOpsMetrics.Web/Controllers/HomeController.cs b/src/DevOpsMetrics.Web/Controllers/HomeController.cs index c7e80d53..0c602cf3 100644 --- a/src/DevOpsMetrics.Web/Controllers/HomeController.cs +++ b/src/DevOpsMetrics.Web/Controllers/HomeController.cs @@ -49,7 +49,7 @@ public async Task Project(string projectId, int numberOfDays = 30 bool useCache = true; string clientId = Configuration["AppSettings:GitHubClientId"]; string clientSecret = Configuration["AppSettings:GitHubClientSecret"]; - ProjectViewModel model = new(); + ProjectViewModel model = null; //Find the right project to load ServiceApiClient serviceApiClient = new(Configuration); @@ -102,43 +102,49 @@ public async Task Project(string projectId, int numberOfDays = 30 NumberOfDays = new SelectList(numberOfDaysList, "NumberOfDays", "NumberOfDays"), NumberOfDaysSelected = numberOfDays }; + break; } } + //Get GitHub project details GitHubSettings githubSetting; - foreach (GitHubSettings item in githubSettings) + if (model == null) { - if (item.RowKey == projectId) + foreach (GitHubSettings item in githubSettings) { - 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 + if (item.RowKey == projectId) { - 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 - }; + 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 + }; + break; + } } } @@ -456,11 +462,11 @@ public async Task UpdateChangeFailureRate(string ProjectIdSelecte //Redirect to the correct project page to see the changes if (targetDevOpsPlatform == DevOpsPlatform.AzureDevOps) { - return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo + "_" + repository + "_" + buildName_workflowName }); + return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo + "_" + repository });// + "_" + buildName_workflowName }); } else if (targetDevOpsPlatform == DevOpsPlatform.GitHub) { - return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo + "_" + buildName_workflowName }); + return RedirectToAction("Project", "Home", new { projectId = organization_owner + "_" + project_repo });//+ "_" + buildName_workflowName }); } else { From ae41c0a0da76f118915528f7807174e3dc27ea11 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 07:00:58 -0400 Subject: [PATCH 7/9] Added refresh button --- src/DevOpsMetrics.Web/Views/Home/Index.cshtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DevOpsMetrics.Web/Views/Home/Index.cshtml b/src/DevOpsMetrics.Web/Views/Home/Index.cshtml index e2fb022f..7d61c35a 100644 --- a/src/DevOpsMetrics.Web/Views/Home/Index.cshtml +++ b/src/DevOpsMetrics.Web/Views/Home/Index.cshtml @@ -26,14 +26,14 @@ { if (item.ShowSetting) { -
  • Azure DevOps icon  @item.Project
  • +
  • Azure DevOps icon  @item.Project | Refresh metric
  • } } @foreach (GitHubSettings item in Model.Item2) { if (item.ShowSetting) { -
  • GitHub icon  @item.Repo
  • +
  • GitHub icon  @item.Repo | Refresh metric
  • } } From 307b1b3b62f45f43e8bfca88885990e57ca002c3 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 08:15:21 -0400 Subject: [PATCH 8/9] Updated logic to include more info with errors --- .../Models/Common/DORASummaryItem.cs | 4 ++ .../Controllers/DORASummaryController.cs | 57 ++++++++++++++++--- .../Service/DORASummaryControllerTests.cs | 22 +++---- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs b/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs index 83f06542..80e1f8cb 100644 --- a/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs +++ b/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs @@ -58,5 +58,9 @@ public string ChangeFailureRateBadgeWithMetricURL { get; set; } + public string ProcessingLogMessage + { + get; set; + } } } diff --git a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs index cc225c2a..6e32c9cb 100644 --- a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs +++ b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading.Tasks; using DevOpsMetrics.Core; using DevOpsMetrics.Core.DataAccess; @@ -55,6 +56,8 @@ public async Task UpdateDORASummaryItem( bool useCache = true, bool isGitHub = true) { + //Start timer + DateTime startTime = DateTime.Now; AzureTableStorageDA azureTableStorageDA = new(); TableStorageConfiguration tableStorageConfig = Common.GenerateTableStorageConfiguration(Configuration); string clientId = null; @@ -82,6 +85,10 @@ public async Task UpdateDORASummaryItem( } ProcessingResult result = new(); + DeploymentFrequencyModel deploymentFrequencyModel = new(); + LeadTimeForChangesModel leadTimeForChangesModel = new(); + MeanTimeToRestoreModel meanTimeToRestoreModel = new(); + ChangeFailureRateModel changeFailureRateModel = new(); try { string message = ""; @@ -130,8 +137,6 @@ public async Task UpdateDORASummaryItem( //Process summary results for last 90 days, creating badges for the four metrics //Get the DORA metrics for the last 90 days - DeploymentFrequencyModel deploymentFrequencyModel = new(); - LeadTimeForChangesModel leadTimeForChangesModel = new(); if (isGitHub == true) { deploymentFrequencyModel = await DeploymentFrequencyDA.GetGitHubDeploymentFrequency(false, clientId, clientSecret, tableStorageConfig, @@ -152,7 +157,6 @@ public async Task UpdateDORASummaryItem( owner, project, repo, branch, workflowName, numberOfDays, maxNumberOfItems, useCache); } - MeanTimeToRestoreModel meanTimeToRestoreModel = new(); if (resourceGroup != null) { meanTimeToRestoreModel = MeanTimeToRestoreDA.GetAzureMeanTimeToRestore(false, tableStorageConfig, @@ -166,10 +170,13 @@ public async Task UpdateDORASummaryItem( meanTimeToRestoreModel.MTTRAverageDurationDescription = MeanTimeToRestore.GetMeanTimeToRestoreRating(0); } - ChangeFailureRateModel changeFailureRateModel = ChangeFailureRateDA.GetChangeFailureRate(false, tableStorageConfig, - DevOpsPlatform.GitHub, - owner, repo, branch, workflowName, - numberOfDays, maxNumberOfItems); + changeFailureRateModel = ChangeFailureRateDA.GetChangeFailureRate(false, tableStorageConfig, + DevOpsPlatform.GitHub, + owner, repo, branch, workflowName, + numberOfDays, maxNumberOfItems); + + //Get the total time since startTime + string processingLogMessage = $"Processed summary for {owner}, repo {repo} in {(DateTime.Now - startTime).TotalSeconds} seconds"; //Summarize the results into a new object DORASummaryItem DORASummary = new() @@ -187,7 +194,8 @@ public async Task UpdateDORASummaryItem( MeanTimeToRestoreBadgeWithMetricURL = meanTimeToRestoreModel.BadgeWithMetricURL, ChangeFailureRate = changeFailureRateModel.ChangeFailureRateMetric, ChangeFailureRateBadgeURL = changeFailureRateModel.BadgeURL, - ChangeFailureRateBadgeWithMetricURL = changeFailureRateModel.BadgeWithMetricURL + ChangeFailureRateBadgeWithMetricURL = changeFailureRateModel.BadgeWithMetricURL, + ProcessingLogMessage = processingLogMessage }; //Serialize the summary into an Azure storage table @@ -244,6 +252,39 @@ public async Task UpdateDORASummaryItem( owner + "_" + project + "_" + repo + "_" + branch + "_" + numberOfDays + "_" + maxNumberOfItems, ex.ToString(), error); } + //Update the DORA object with the error message + try + { + //Get the total time since startTime + string processingLogMessage = $"Error processing summary for {owner}, repo {repo} in {(DateTime.Now - startTime).TotalSeconds} seconds"; + + //Summarize the results into a new object + DORASummaryItem DORASummary = new() + { + Owner = owner, + Repo = repo, + DeploymentFrequency = deploymentFrequencyModel.DeploymentsPerDayMetric, + DeploymentFrequencyBadgeURL = deploymentFrequencyModel.BadgeURL, + DeploymentFrequencyBadgeWithMetricURL = deploymentFrequencyModel.BadgeWithMetricURL, + LeadTimeForChanges = leadTimeForChangesModel.LeadTimeForChangesMetric, + LeadTimeForChangesBadgeURL = leadTimeForChangesModel.BadgeURL, + LeadTimeForChangesBadgeWithMetricURL = leadTimeForChangesModel.BadgeWithMetricURL, + MeanTimeToRestore = meanTimeToRestoreModel.MTTRAverageDurationInHours, + MeanTimeToRestoreBadgeURL = meanTimeToRestoreModel.BadgeURL, + MeanTimeToRestoreBadgeWithMetricURL = meanTimeToRestoreModel.BadgeWithMetricURL, + ChangeFailureRate = changeFailureRateModel.ChangeFailureRateMetric, + ChangeFailureRateBadgeURL = changeFailureRateModel.BadgeURL, + ChangeFailureRateBadgeWithMetricURL = changeFailureRateModel.BadgeWithMetricURL, + ProcessingLogMessage = processingLogMessage + }; + //Serialize the summary into an Azure storage table + await AzureTableStorageDA.UpdateDORASummaryItem(tableStorageConfig, owner, project, repo, DORASummary); + } + catch + { + //Do nothing, we handled the error above + } + if (projectLog != null) { await azureTableStorageDA.UpdateProjectLogInStorage(tableStorageConfig, projectLog); diff --git a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs index 8b496c2d..11c431b0 100644 --- a/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs +++ b/src/DevOpsMetrics.Tests/Service/DORASummaryControllerTests.cs @@ -50,18 +50,18 @@ public void DORASummaryControllerGetIntegrationTest2() public async Task DORASummaryControllerGitHubUpdateIntegrationTest() { //Arrange - //string organization = "DeveloperMetrics"; - //string repository = "DevOpsMetrics"; - //string branch = "main"; - //string workflowName = "CI/CD"; - //string workflowId = "1162561"; - //string resourceGroup = "DevOpsMetrics"; - string organization = "samsmithnz"; - string repository = "AzurePipelinesToGitHubActionsConverter"; + string organization = "DeveloperMetrics"; + string repository = "DevOpsMetrics"; string branch = "main"; - string workflowName = "CI/ CD"; - string workflowId = "38158"; - string resourceGroup = null; + string workflowName = "CI/CD"; + string workflowId = "1162561"; + string resourceGroup = "DevOpsMetrics"; + //string organization = "samsmithnz"; + //string repository = "AzurePipelinesToGitHubActionsConverter"; + //string branch = "main"; + //string workflowName = "CI/ CD"; + //string workflowId = "38158"; + //string resourceGroup = null; //string organization = "samsmithnz"; //string repository = "AzurePipelinesToGitHubActionsConverterWeb"; //string branch = "main"; From 4ffc3bb11827483f6b1670dbb45ed61ca0efadbb Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Fri, 26 May 2023 09:14:40 -0400 Subject: [PATCH 9/9] Added number of days --- src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs | 4 ++++ .../Controllers/DORASummaryController.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs b/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs index 80e1f8cb..7754e68b 100644 --- a/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs +++ b/src/DevOpsMetrics.Core/Models/Common/DORASummaryItem.cs @@ -10,6 +10,10 @@ public string Repo { get; set; } + public int NumberOfDays + { + get; set; + } public float DeploymentFrequency { get; set; diff --git a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs index 6e32c9cb..0ff04555 100644 --- a/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs +++ b/src/DevOpsMetrics.Service/Controllers/DORASummaryController.cs @@ -183,6 +183,7 @@ public async Task UpdateDORASummaryItem( { Owner = owner, Repo = repo, + NumberOfDays = numberOfDays, DeploymentFrequency = deploymentFrequencyModel.DeploymentsPerDayMetric, DeploymentFrequencyBadgeURL = deploymentFrequencyModel.BadgeURL, DeploymentFrequencyBadgeWithMetricURL = deploymentFrequencyModel.BadgeWithMetricURL, @@ -263,6 +264,7 @@ public async Task UpdateDORASummaryItem( { Owner = owner, Repo = repo, + NumberOfDays = numberOfDays, DeploymentFrequency = deploymentFrequencyModel.DeploymentsPerDayMetric, DeploymentFrequencyBadgeURL = deploymentFrequencyModel.BadgeURL, DeploymentFrequencyBadgeWithMetricURL = deploymentFrequencyModel.BadgeWithMetricURL,