public void AzGetPRCommitsDAIntegrationTest()
        {
            //Arrange
            TableStorageAuth tableStorageAuth = Common.GenerateTableAuthorization(Configuration);
            string           organization     = "samsmithnz";
            string           project          = "SamLearnsAzure";

            //Act
            AzureTableStorageDA da = new AzureTableStorageDA();
            JArray prList          = da.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsPRs, da.CreateAzureDevOpsPRPartitionKey(organization, project));
            int    itemsAdded      = 0;

            foreach (JToken item in prList)
            {
                AzureDevOpsPR pullRequest   = JsonConvert.DeserializeObject <AzureDevOpsPR>(item.ToString());
                string        pullRequestId = pullRequest.PullRequestId;
                JArray        list          = da.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsPRCommits, da.CreateAzureDevOpsPRCommitPartitionKey(organization, project, pullRequestId));
                if (list.Count > 0)
                {
                    itemsAdded = list.Count;
                    break;
                }
            }

            //Assert
            Assert.IsTrue(itemsAdded >= 0);
        }
Пример #2
0
        public async Task <GitHubPR> GetGitHubPullRequest(string clientId, string clientSecret, TableStorageAuth tableStorageAuth, string owner, string repo, string branch, bool useCache)
        {
            List <GitHubPR> prs = new List <GitHubPR>();

            Newtonsoft.Json.Linq.JArray list;
            if (useCache == true)
            {
                //Get the pull requests from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableGitHubPRs, daTableStorage.CreateGitHubPRPartitionKey(owner, repo));
            }
            else
            {
                //Get the pull requests from the GitHub API
                GitHubAPIAccess api = new GitHubAPIAccess();
                list = await api.GetGitHubPullRequestsJArray(clientId, clientSecret, owner, repo, branch);
            }
            if (list != null)
            {
                prs = JsonConvert.DeserializeObject <List <GitHubPR> >(list.ToString());
            }

            //Find the PR id
            GitHubPR pr = null;

            foreach (GitHubPR item in prs)
            {
                if (item.head.@ref == branch)
                {
                    pr = item;
                    break;
                }
            }
            return(pr);
        }
Пример #3
0
        public async Task <AzureDevOpsPR> GetAzureDevOpsPullRequest(string patToken, TableStorageAuth tableStorageAuth, string organization, string project, string repositoryId, string branch, bool useCache)
        {
            List <AzureDevOpsPR> prs = new List <AzureDevOpsPR>();

            Newtonsoft.Json.Linq.JArray list;
            if (useCache == true)
            {
                //Get the pull requests from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsPRs, daTableStorage.CreateGitHubPRPartitionKey(organization, project));
            }
            else
            {
                //Get the pull requests from the Azure DevOps API
                AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess();
                list = await api.GetAzureDevOpsPullRequestsJArray(patToken, organization, project, repositoryId);
            }
            if (list != null)
            {
                prs = JsonConvert.DeserializeObject <List <AzureDevOpsPR> >(list.ToString());
            }

            //Find the PR id
            AzureDevOpsPR pr = null;

            foreach (AzureDevOpsPR item in prs)
            {
                if (item.sourceRefName == branch)
                {
                    pr = item;
                    break;
                }
            }
            return(pr);
        }
Пример #4
0
        public async Task <List <GitHubActionsRun> > GetGitHubActionRuns(string clientId, string clientSecret, TableStorageAuth tableStorageAuth,
                                                                         string owner, string repo, string workflowName, string workflowId, bool useCache)
        {
            List <GitHubActionsRun> runs = new List <GitHubActionsRun>();

            Newtonsoft.Json.Linq.JArray list = null;
            if (useCache == true)
            {
                //Get the builds from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableGitHubRuns, daTableStorage.CreateBuildWorkflowPartitionKey(owner, repo, workflowName));
            }
            else
            {
                //Get the builds from the GitHub API
                GitHubAPIAccess api = new GitHubAPIAccess();
                list = await api.GetGitHubActionRunsJArray(clientId, clientSecret, owner, repo, workflowId);
            }
            if (list != null)
            {
                runs = JsonConvert.DeserializeObject <List <GitHubActionsRun> >(list.ToString());

                //sort the final list
                runs = runs.OrderBy(o => o.created_at).ToList();
            }

            return(runs);
        }
Пример #5
0
        public async Task <List <AzureDevOpsBuild> > GetAzureDevOpsBuilds(string patToken, TableStorageAuth tableStorageAuth,
                                                                          string organization, string project, string buildName, bool useCache)
        {
            List <AzureDevOpsBuild> builds = new List <AzureDevOpsBuild>();

            Newtonsoft.Json.Linq.JArray list = null;
            if (useCache == true)
            {
                //Get the builds from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsBuilds, daTableStorage.CreateBuildWorkflowPartitionKey(organization, project, buildName));
            }
            else
            {
                //Get the builds from the Azure DevOps API
                AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess();
                list = await api.GetAzureDevOpsBuildsJArray(patToken, organization, project);
            }
            if (list != null)
            {
                builds = JsonConvert.DeserializeObject <List <AzureDevOpsBuild> >(list.ToString());
                //We need to do some post processing and loop over the list to construct a usable url
                foreach (AzureDevOpsBuild item in builds)
                {
                    item.url = $"https://dev.azure.com/{organization}/{project}/_build/results?buildId={item.id}&view=results";
                }

                //sort the final list
                builds = builds.OrderBy(o => o.queueTime).ToList();
            }

            return(builds);
        }
Пример #6
0
        public async Task <bool> UpdateChangeFailureRate(TableStorageAuth tableStorageAuth,
                                                         string organization_owner, string project_repo, string buildName_workflowName,
                                                         int percentComplete, int numberOfDays)
        {
            //Gets a list of change failure rate builds
            AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
            string partitionKey = daTableStorage.CreateBuildWorkflowPartitionKey(organization_owner, project_repo, buildName_workflowName);

            Newtonsoft.Json.Linq.JArray   list          = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableChangeFailureRate, partitionKey);
            List <ChangeFailureRateBuild> initialBuilds = JsonConvert.DeserializeObject <List <ChangeFailureRateBuild> >(list.ToString());

            //Get the list of items we are going to process, within the date/day range
            List <ChangeFailureRateBuild> builds = new List <ChangeFailureRateBuild>();

            foreach (ChangeFailureRateBuild item in initialBuilds)
            {
                if (item.StartTime > DateTime.Now.AddDays(-numberOfDays))
                {
                    builds.Add(item);
                }
            }

            //Using the percent, convert it to a fraction
            FractionConverter converter      = new FractionConverter();
            FractionModel     fracationModel = converter.ConvertToFraction(percentComplete);
            int numerator   = fracationModel.Numerator;
            int denominator = fracationModel.Denominator;

            //Get builds for positive (builds we will set DeploymentWasSuccessful=true) and negative (builds we will set to DeploymentWasSuccessful=false)
            Console.WriteLine($"numerator {numerator} / denominator {denominator}");
            //TODO: remember how this (x, numerator) syntax works so it can be documented. oooof.
            List <ChangeFailureRateBuild> postiveBuilds  = builds.Where((x, numerator) => numerator % denominator != 0).ToList();
            List <ChangeFailureRateBuild> negativeBuilds = builds.Where((x, numerator) => numerator % denominator == 0).ToList();

            //Make the updates
            TableStorageCommonDA tableChangeFailureRateDA = new TableStorageCommonDA(tableStorageAuth, tableStorageAuth.TableChangeFailureRate);

            foreach (ChangeFailureRateBuild item in postiveBuilds)
            {
                item.DeploymentWasSuccessful = true;
                await daTableStorage.UpdateChangeFailureRate(tableChangeFailureRateDA, item, partitionKey, true);
            }
            foreach (ChangeFailureRateBuild item in negativeBuilds)
            {
                item.DeploymentWasSuccessful = false;
                await daTableStorage.UpdateChangeFailureRate(tableChangeFailureRateDA, item, partitionKey, true);
            }

            return(true);
        }
        public void AzGetPRsDAIntegrationTest()
        {
            //Arrange
            TableStorageAuth tableStorageAuth = Common.GenerateTableAuthorization(Configuration);
            string           organization     = "samsmithnz";
            string           project          = "SamLearnsAzure";

            //Act
            AzureTableStorageDA da = new AzureTableStorageDA();
            JArray list            = da.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsBuilds, da.CreateAzureDevOpsPRPartitionKey(organization, project));

            //Assert
            Assert.IsTrue(list.Count >= 0);
        }
        public void GHGetPRsDAIntegrationTest()
        {
            //Arrange
            TableStorageAuth tableStorageAuth = Common.GenerateTableAuthorization(Configuration);
            string           owner            = "samsmithnz";
            string           repo             = "DevOpsMetrics";

            //Act
            AzureTableStorageDA da = new AzureTableStorageDA();
            JArray list            = da.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableGitHubPRs, da.CreateGitHubPRPartitionKey(owner, repo));

            //Assert
            Assert.IsTrue(list.Count >= 0);
        }
Пример #9
0
        public async Task <List <GitHubPRCommit> > GetGitHubPullRequestCommits(string clientId, string clientSecret, TableStorageAuth tableStorageAuth, string owner, string repo, string pull_number, bool useCache)
        {
            Newtonsoft.Json.Linq.JArray list;
            if (useCache == true)
            {
                //Get the commits from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableGitHubPRCommits, daTableStorage.CreateGitHubPRCommitPartitionKey(owner, repo, pull_number));
            }
            else
            {
                //Get the commits from the GitHub API
                GitHubAPIAccess api = new GitHubAPIAccess();
                list = await api.GetGitHubPullRequestCommitsJArray(clientId, clientSecret, owner, repo, pull_number);
            }
            List <GitHubPRCommit> commits = JsonConvert.DeserializeObject <List <GitHubPRCommit> >(list.ToString());

            return(commits);
        }
Пример #10
0
        public async Task <List <AzureDevOpsPRCommit> > GetAzureDevOpsPullRequestCommits(string patToken, TableStorageAuth tableStorageAuth, string organization, string project, string repositoryId, string pullRequestId, bool useCache)
        {
            Newtonsoft.Json.Linq.JArray list;
            if (useCache == true)
            {
                //Get the commits from Azure storage
                AzureTableStorageDA daTableStorage = new AzureTableStorageDA();
                list = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableAzureDevOpsPRCommits, daTableStorage.CreateAzureDevOpsPRCommitPartitionKey(organization, project, pullRequestId));
            }
            else
            {
                //Get the commits from the Azure DevOps API
                AzureDevOpsAPIAccess api = new AzureDevOpsAPIAccess();
                list = await api.GetAzureDevOpsPullRequestCommitsJArray(patToken, organization, project, repositoryId, pullRequestId);
            }

            List <AzureDevOpsPRCommit> commits = JsonConvert.DeserializeObject <List <AzureDevOpsPRCommit> >(list.ToString());

            return(commits);
        }
Пример #11
0
        public ChangeFailureRateModel GetChangeFailureRate(bool getSampleData, TableStorageAuth tableStorageAuth,
                                                           DevOpsPlatform targetDevOpsPlatform, string organization_owner, string project_repo, string branch, string buildName_workflowName,
                                                           int numberOfDays, int maxNumberOfItems)
        {
            ListUtility <ChangeFailureRateBuild> utility = new ListUtility <ChangeFailureRateBuild>();
            ChangeFailureRate changeFailureRate          = new ChangeFailureRate();

            if (getSampleData == false)
            {
                //Gets a list of change failure rate builds from Azure storage
                AzureTableStorageDA           daTableStorage = new AzureTableStorageDA();
                Newtonsoft.Json.Linq.JArray   list           = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.TableChangeFailureRate, daTableStorage.CreateBuildWorkflowPartitionKey(organization_owner, project_repo, buildName_workflowName));
                List <ChangeFailureRateBuild> initialBuilds  = JsonConvert.DeserializeObject <List <ChangeFailureRateBuild> >(list.ToString());

                //Build the date list and then generate the change failure rate metric
                List <ChangeFailureRateBuild>         builds   = new List <ChangeFailureRateBuild>();
                List <KeyValuePair <DateTime, bool> > dateList = new List <KeyValuePair <DateTime, bool> >();
                float maxBuildDuration = 0f;
                foreach (ChangeFailureRateBuild item in initialBuilds)
                {
                    if (item.Branch == branch && item.StartTime > DateTime.Now.AddDays(-numberOfDays))
                    {
                        //Special branch for Azure DevOps to construct the Url to each build
                        if (targetDevOpsPlatform == DevOpsPlatform.AzureDevOps)
                        {
                            item.Url = $"https://dev.azure.com/{organization_owner}/{project_repo}/_build/results?buildId={item.Id}&view=results";
                        }
                        builds.Add(item);
                    }
                }

                //then build the calcuation
                foreach (ChangeFailureRateBuild item in builds)
                {
                    KeyValuePair <DateTime, bool> newItem = new KeyValuePair <DateTime, bool>(item.StartTime, item.DeploymentWasSuccessful);
                    dateList.Add(newItem);
                }
                //calculate the metric on all of the results
                float changeFailureRateMetric = changeFailureRate.ProcessChangeFailureRate(dateList, numberOfDays);

                //Filter the results to return the last n (maxNumberOfItems)
                List <ChangeFailureRateBuild> uiBuilds = utility.GetLastNItems(builds, maxNumberOfItems);
                foreach (ChangeFailureRateBuild item in uiBuilds)
                {
                    if (item.BuildDuration > maxBuildDuration)
                    {
                        maxBuildDuration = item.BuildDuration;
                    }
                }
                //We need to do some post processing and loop over the list a couple times to find the max build duration, construct a usable url, and calculate a build duration percentage
                foreach (ChangeFailureRateBuild item in uiBuilds)
                {
                    float interiumResult = ((item.BuildDuration / maxBuildDuration) * 100f);
                    item.BuildDurationPercent = Scaling.ScaleNumberToRange(interiumResult, 0, 100, 20, 100);
                }

                ChangeFailureRateModel model = new ChangeFailureRateModel
                {
                    TargetDevOpsPlatform               = targetDevOpsPlatform,
                    DeploymentName                     = buildName_workflowName,
                    ChangeFailureRateBuildList         = uiBuilds,
                    ChangeFailureRateMetric            = changeFailureRateMetric,
                    ChangeFailureRateMetricDescription = changeFailureRate.GetChangeFailureRateRating(changeFailureRateMetric),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = uiBuilds.Count,
                    TotalItems       = builds.Count
                };
                return(model);
            }
            else
            {
                //Get sample data
                List <ChangeFailureRateBuild> sampleBuilds = utility.GetLastNItems(GetSampleBuilds(), maxNumberOfItems);
                ChangeFailureRateModel        model        = new ChangeFailureRateModel
                {
                    TargetDevOpsPlatform               = targetDevOpsPlatform,
                    DeploymentName                     = buildName_workflowName,
                    ChangeFailureRateBuildList         = sampleBuilds,
                    ChangeFailureRateMetric            = 2f / 10f,
                    ChangeFailureRateMetricDescription = changeFailureRate.GetChangeFailureRateRating(2f / 10f),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = sampleBuilds.Count,
                    TotalItems       = sampleBuilds.Count
                };
                return(model);
            }
        }
Пример #12
0
        public MeanTimeToRestoreModel GetAzureMeanTimeToRestore(bool getSampleData,
                                                                TableStorageAuth tableStorageAuth,
                                                                DevOpsPlatform targetDevOpsPlatform, string resourceGroup,
                                                                int numberOfDays, int maxNumberOfItems)
        {
            ListUtility <MeanTimeToRestoreEvent> utility = new ListUtility <MeanTimeToRestoreEvent>();

            if (getSampleData == false)
            {
                //Pull the events from the table storage
                AzureTableStorageDA         daTableStorage = new AzureTableStorageDA();
                Newtonsoft.Json.Linq.JArray list           = daTableStorage.GetTableStorageItems(tableStorageAuth, tableStorageAuth.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();
                float             averageMTTR = CalculateMTTRDuration(events);

                //Filter 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
                };
                return(model);
            }
            else
            {
                //Get sample data
                MeanTimeToRestore             mttr         = new MeanTimeToRestore();
                float                         averageMTTR  = CalculateMTTRDuration(GetSampleMTTREvents(resourceGroup));
                List <MeanTimeToRestoreEvent> sampleEvents = GetSampleMTTREvents(resourceGroup);
                MeanTimeToRestoreModel        model        = new MeanTimeToRestoreModel
                {
                    TargetDevOpsPlatform           = targetDevOpsPlatform,
                    ResourceGroup                  = resourceGroup,
                    MeanTimeToRestoreEvents        = sampleEvents,
                    MTTRAverageDurationInHours     = averageMTTR,
                    MTTRAverageDurationDescription = mttr.GetMeanTimeToRestoreRating(averageMTTR),
                    NumberOfDays     = numberOfDays,
                    MaxNumberOfItems = sampleEvents.Count,
                    TotalItems       = sampleEvents.Count
                };
                return(model);
            }
        }