예제 #1
0
        private void SetupBuildRangeQuery(JenkinsArtifactDetails details, string result)
        {
            string buildIndexUrl = $"{details.Url}/job/{details.JobName}/api/json?tree=allBuilds[number]";

            _httpClient.Setup(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(buildIndexUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()))
            .Returns(Task.FromResult(result));
        }
예제 #2
0
        public async void CommitsShouldBeUploadedAsAttachment()
        {
            using (TestHostContext tc = Setup())
            {
                string commitRootDirectory = Path.Combine(tc.GetDirectory(WellKnownDirectory.Work), Guid.NewGuid().ToString("D"));
                Directory.CreateDirectory(commitRootDirectory);

                try
                {
                    JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                    details.StartCommitArtifactVersion = "10";
                    details.EndCommitArtifactVersion   = "20";

                    var artifact = new JenkinsArtifact();
                    artifact.Initialize(tc);

                    SetupBuildRangeQuery(details, "{ \"allBuilds\": [{ \"number\": 20 }, { \"number\": 10 }, { \"number\": 2 } ] }");
                    string commitResult = " {\"builds\": [{ \"number\":9, \"result\":\"SUCCESS\", \"changeSet\": { \"items\": [{ \"commitId\" : \"2869c7ccd0b1b649ba6765e89ee5ff36ef6d4805\", \"author\": { \"fullName\" : \"testuser\" }, \"msg\":\"test\" }]}}]}";
                    string commitsUrl   = $"{details.Url}/job/{details.JobName}/api/json?tree=builds[number,result,changeSet[items[commitId,date,msg,author[fullName]]]]{{0,1}}";
                    _httpClient.Setup(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(commitsUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()))
                    .Returns(Task.FromResult(commitResult));

                    string commitFilePath = Path.Combine(commitRootDirectory, $"commits_{details.Alias}_1.json");

                    await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, commitRootDirectory);

                    _ec.Verify(x => x.QueueAttachFile(It.Is <string>(y => y.Equals(CoreAttachmentType.FileAttachment)), It.IsAny <string>(), It.IsAny <string>()), Times.Once);
                }
                finally
                {
                    IOUtil.DeleteDirectory(commitRootDirectory, CancellationToken.None);
                }
            }
        }
예제 #3
0
        private bool IsValidBuild(IGenericHttpClient client, JenkinsArtifactDetails jenkinsDetails)
        {
            var buildUrl =
                string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}/job/{1}/{2}/",
                    jenkinsDetails.Url,
                    jenkinsDetails.JobName,
                    jenkinsDetails.BuildId);

            HttpResponseMessage response = client.GetAsync(buildUrl, jenkinsDetails.AccountName, jenkinsDetails.AccountPassword, jenkinsDetails.AcceptUntrustedCertificates).Result;

            return(response.IsSuccessStatusCode);
        }
예제 #4
0
        public async void MissingStartVersionShouldDownloadCommitsFromSingleBuild()
        {
            using (TestHostContext tc = Setup())
            {
                JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                details.EndCommitArtifactVersion = "10";

                var artifact = new JenkinsArtifact();
                artifact.Initialize(tc);
                string expectedUrl = $"{details.Url}/job/{details.JobName}/{details.EndCommitArtifactVersion}/api/json?tree=number,result,changeSet[items[commitId,date,msg,author[fullName]]]";
                await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, tc.GetDirectory(WellKnownDirectory.Root));

                _httpClient.Verify(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(expectedUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()), Times.Once);
            }
        }
예제 #5
0
        public async void ShouldLogAnIssueIfEndVersionIsInvalidInArtifactDetail()
        {
            using (TestHostContext tc = Setup())
            {
                var trace = tc.GetTrace();

                JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                details.EndCommitArtifactVersion = "xx";
                var artifact = new JenkinsArtifact();
                artifact.Initialize(tc);
                await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, "test");

                _ec.Verify(x => x.AddIssue(It.Is <Issue>(y => y.Type == IssueType.Warning)), Times.Once);
            }
        }
예제 #6
0
        private bool IsValidBuild(HttpClient client, JenkinsArtifactDetails jenkinsDetails)
        {
            var buildUrl =
                new Uri(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "{0}/job/{1}/{2}",
                        jenkinsDetails.Url,
                        jenkinsDetails.JobName,
                        jenkinsDetails.BuildId));

            HttpResponseMessage response = client.GetAsync(buildUrl).Result;

            return(response.IsSuccessStatusCode);
        }
예제 #7
0
        public async void JenkinsCommitsShouldLogAnIssueIfBuildIsDeleted()
        {
            using (TestHostContext tc = Setup())
            {
                JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                details.StartCommitArtifactVersion = "10";
                details.EndCommitArtifactVersion   = "20";

                var artifact = new JenkinsArtifact();
                artifact.Initialize(tc);
                SetupBuildRangeQuery(details, "{ \"allBuilds\": [{ \"number\": 30 }, { \"number\": 29 }, { \"number\": 28 } ] }");

                await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, tc.GetDirectory(WellKnownDirectory.Root));

                _ec.Verify(x => x.AddIssue(It.Is <Issue>(y => y.Type == IssueType.Warning)), Times.Once);
            }
        }
예제 #8
0
        public async void JenkinsCommitsShouldBeFetchedBetweenBuildRange()
        {
            using (TestHostContext tc = Setup())
            {
                JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                details.StartCommitArtifactVersion = "10";
                details.EndCommitArtifactVersion   = "20";

                var artifact = new JenkinsArtifact();
                artifact.Initialize(tc);

                SetupBuildRangeQuery(details, "{ \"allBuilds\": [{ \"number\": 20 }, { \"number\": 10 }, { \"number\": 2 } ] }");
                string expectedUrl = $"{details.Url}/job/{details.JobName}/api/json?tree=builds[number,result,changeSet[items[commitId,date,msg,author[fullName]]]]{{0,1}}";

                await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, tc.GetDirectory(WellKnownDirectory.Root));

                _httpClient.Verify(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(expectedUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()), Times.Once);
            }
        }
예제 #9
0
        private bool IsGitRepo(IExecutionContext executionContext, JenkinsArtifactDetails artifactDetails, int jobId, out string rootUrl)
        {
            bool isGitRepo = false;

            rootUrl = string.Empty;

            executionContext.Debug("Checking if Jenkins job uses git scm");
            string repoUrl    = StringUtil.Format("{0}/job/{1}/{2}/api/json?tree=actions[remoteUrls],changeSet[kind]", artifactDetails.Url, artifactDetails.JobName, jobId);
            var    repoResult = DownloadCommitsJsonContent(executionContext, repoUrl, artifactDetails).Result;

            if (repoResult != null)
            {
                executionContext.Debug($"repo query result from Jenkins api {repoResult.ToString()}");

                var repoKindResult = ParseToken(repoResult.ToString(), "$.changeSet.kind");
                if (repoKindResult != null && repoKindResult.Any())
                {
                    string repoKind = repoKindResult.First().ToString();
                    executionContext.Debug($"Parsed repo result {repoKind}");

                    if (!string.IsNullOrEmpty(repoKind) && repoKind.Equals(GitRepoName, StringComparison.OrdinalIgnoreCase))
                    {
                        executionContext.Debug("Its a git repo, checking if it has root url");
                        var rootUrlResult = ParseToken(repoResult.ToString(), "$.actions[?(@.remoteUrls)]");
                        if (rootUrlResult != null && rootUrlResult.Any())
                        {
                            var resultDictionary = JsonConvert.DeserializeObject <Dictionary <string, JToken> >(rootUrlResult.First().ToString());
                            if (resultDictionary.ContainsKey(RemoteUrlsKey) && resultDictionary[RemoteUrlsKey].Any())
                            {
                                rootUrl   = resultDictionary[RemoteUrlsKey].First().ToString();
                                isGitRepo = true;
                                executionContext.Debug($"Found the git repo root url {rootUrl}");
                            }
                        }
                    }
                }
            }

            return(isGitRepo);
        }
예제 #10
0
        private Tuple <int, int> GetCommitJobIdIndex(IExecutionContext context, JenkinsArtifactDetails artifactDetails, int startJobId, int endJobId)
        {
            Trace.Entering();

            string url = StringUtil.Format("{0}/job/{1}/api/json?tree=allBuilds[number]", artifactDetails.Url, artifactDetails.JobName);
            int    startIndex = -1, endIndex = -1, index = 0;
            var    listOfBuildResult = DownloadCommitsJsonContent(context, url, artifactDetails, "$.allBuilds[*].number").Result;

            foreach (JToken token in listOfBuildResult)
            {
                long value = 0;
                if (long.TryParse((string)token, out value))
                {
                    if (value == startJobId)
                    {
                        startIndex = index;
                    }

                    if (value == endJobId)
                    {
                        endIndex = index;
                    }

                    if (startIndex > 0 && endIndex > 0)
                    {
                        break;
                    }

                    index++;
                }
            }

            context.Debug(StringUtil.Format("Found startIndex {0} and endIndex {1}", startIndex, endIndex));
            if (startIndex < 0 || endIndex < 0)
            {
                throw new CommitsDownloadException(StringUtil.Loc("JenkinsBuildDoesNotExistsForCommits", startJobId, endJobId, startIndex, endIndex));
            }

            return(Tuple.Create <int, int>(startIndex, endIndex));
        }
예제 #11
0
        public async void CommitsShoulHaveUrlIfItsGitRepo()
        {
            using (TestHostContext tc = Setup())
            {
                string commitRootDirectory = tc.GetDirectory(WellKnownDirectory.Root);

                try
                {
                    JenkinsArtifactDetails details = _artifactDefinition.Details as JenkinsArtifactDetails;
                    details.StartCommitArtifactVersion = "10";
                    details.EndCommitArtifactVersion   = "20";

                    var artifact = new JenkinsArtifact();
                    artifact.Initialize(tc);

                    SetupBuildRangeQuery(details, "{ \"allBuilds\": [{ \"number\": 20 }, { \"number\": 10 }, { \"number\": 2 } ] }");
                    string commitResult = " {\"builds\": [{ \"number\":9, \"result\":\"SUCCESS\", \"changeSet\": { \"items\": [{ \"commitId\" : \"2869c7ccd0b1b649ba6765e89ee5ff36ef6d4805\", \"author\": { \"fullName\" : \"testuser\" }, \"msg\":\"test\" }]}}]}";
                    string commitsUrl   = $"{details.Url}/job/{details.JobName}/api/json?tree=builds[number,result,changeSet[items[commitId,date,msg,author[fullName]]]]{{0,1}}";
                    _httpClient.Setup(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(commitsUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()))
                    .Returns(Task.FromResult(commitResult));

                    string repoUrl    = $"{details.Url}/job/{details.JobName}/{details.EndCommitArtifactVersion}/api/json?tree=actions[remoteUrls],changeSet[kind]";
                    string repoResult = "{ \"actions\": [ { \"remoteUrls\": [ \"https://github.com/TestUser/TestRepo\" ] }, ], \"changeSet\": { \"kind\": \"git\" } }";
                    _httpClient.Setup(x => x.GetStringAsync(It.Is <string>(y => y.StartsWith(repoUrl)), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>()))
                    .Returns(Task.FromResult(repoResult));

                    string commitFilePath = Path.Combine(commitRootDirectory, $"commits_{details.Alias}_1.json");
                    Directory.CreateDirectory(commitRootDirectory);

                    string expectedCommitUrl = "https://github.com/TestUser/TestRepo/commit/2869c7ccd0b1b649ba6765e89ee5ff36ef6d4805";
                    await artifact.DownloadCommitsAsync(_ec.Object, _artifactDefinition, commitRootDirectory);

                    _ec.Verify(x => x.QueueAttachFile(It.Is <string>(y => y.Equals(CoreAttachmentType.FileAttachment)), It.IsAny <string>(), It.Is <string>(z => string.Join("", File.ReadAllLines(z)).Contains(expectedCommitUrl))), Times.Once);
                }
                finally
                {
                    IOUtil.DeleteDirectory(commitRootDirectory, CancellationToken.None);
                }
            }
        }
예제 #12
0
        private async Task <IEnumerable <JToken> > DownloadCommitsJsonContent(IExecutionContext executionContext, string url, JenkinsArtifactDetails artifactDetails, string jsonPath)
        {
            Trace.Entering();

            string result = await DownloadCommitsJsonContent(executionContext, url, artifactDetails);

            if (!string.IsNullOrEmpty(result))
            {
                executionContext.Debug($"result will be filtered with {jsonPath}");
                return(ParseToken(result, jsonPath));
            }

            return(new List <JToken>());
        }
예제 #13
0
        private async Task <string> DownloadCommitsJsonContent(IExecutionContext executionContext, string url, JenkinsArtifactDetails artifactDetails)
        {
            Trace.Entering();

            executionContext.Debug($"Querying Jenkins server with the api {url}");
            string result = await HostContext.GetService <IGenericHttpClient>()
                            .GetStringAsync(url, artifactDetails.AccountName, artifactDetails.AccountPassword, artifactDetails.AcceptUntrustedCertificates);

            if (!string.IsNullOrEmpty(result))
            {
                executionContext.Debug($"Found result from Jenkins server: {result}");
            }

            return(result);
        }
예제 #14
0
        private async Task <IEnumerable <Change> > DownloadCommits(IExecutionContext context, JenkinsArtifactDetails artifactDetails, int startJobId, int endJobId)
        {
            Trace.Entering();

            if (startJobId == 0)
            {
                context.Debug($"StartJobId does not exist, downloading changeSet from build {endJobId}");
                return(await DownloadCommits(context, artifactDetails, endJobId));
            }

            //#1. Figure out the index of build numbers
            Tuple <int, int> result = GetCommitJobIdIndex(context, artifactDetails, startJobId, endJobId);
            int startIndex          = result.Item1;
            int endIndex            = result.Item2;

            //#2. Download the commits using range
            string buildParameter  = (startIndex >= 100 || endIndex >= 100) ? "allBuilds" : "builds"; // jenkins by default will return only 100 top builds. Have to use "allBuilds" if we are dealing with build which are older than 100 builds
            string commitsUrl      = StringUtil.Format("{0}/job/{1}/api/json?tree={2}[number,result,changeSet[items[commitId,date,msg,author[fullName]]]]{{{3},{4}}}", artifactDetails.Url, artifactDetails.JobName, buildParameter, endIndex, startIndex);
            var    changeSetResult = await DownloadCommitsJsonContent(context, commitsUrl, artifactDetails, StringUtil.Format("$.{0}[*].changeSet.items[*]", buildParameter));

            string rootUrl;
            bool   isGitRepo = IsGitRepo(context, artifactDetails, endJobId, out rootUrl);

            return(changeSetResult.Select(x => ConvertCommitToChange(context, x, isGitRepo, rootUrl)));
        }
예제 #15
0
        private async Task <IEnumerable <Change> > DownloadCommits(IExecutionContext context, JenkinsArtifactDetails artifactDetails, int jobId)
        {
            context.Output(StringUtil.Format("Getting changeSet associated with build {0} ", jobId));
            string commitsUrl    = StringUtil.Format("{0}/job/{1}/{2}/api/json?tree=number,result,changeSet[items[commitId,date,msg,author[fullName]]]", artifactDetails.Url, artifactDetails.JobName, jobId);
            var    commitsResult = await DownloadCommitsJsonContent(context, commitsUrl, artifactDetails, "$.changeSet.items[*]");

            string rootUrl;
            bool   isGitRepo = IsGitRepo(context, artifactDetails, jobId, out rootUrl);

            return(commitsResult.Select(x => ConvertCommitToChange(context, x, isGitRepo, rootUrl)));
        }