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)); }
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); } } }
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); }
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); } }
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); } }
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); }
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); } }
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); } }
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); }
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)); }
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); } } }
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>()); }
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); }
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))); }
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))); }