[7.3] [failedTestsReporter] load github issues on demand (#479… (#48004)

This commit is contained in:
Spencer 2019-10-11 11:08:33 -07:00 committed by GitHub
parent 321736b19e
commit 5c6ce86415
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 23 deletions

View file

@ -10,7 +10,7 @@ To fetch some JUnit reports from a recent build on CI, visit its `Google Cloud S
copy(`wget "${Array.from($$('a[href$=".xml"]')).filter(a => a.innerText === 'Download').map(a => a.href.replace('https://storage.cloud.google.com/', 'https://storage.googleapis.com/')).join('" "')}"`)
```
This copies a script to download the reporets, which can be executed in the `test/junit` directory.
This copies a script to download the reports, which you should execute in the `test/junit` directory.
Next, run the CLI in `--dry-run` mode so that it doesn't actually communicate with Github.

View file

@ -61,10 +61,12 @@ export class GithubApi {
}
}
async getAllFailedTestIssues() {
this.log.info('Fetching failed-test issues');
const issues: GithubIssue[] = [];
let nextRequest: RequestOptions = {
private failedTestIssuesPageCache: {
pages: GithubIssue[][];
nextRequest: RequestOptions | undefined;
} = {
pages: [],
nextRequest: {
safeForDryRun: true,
method: 'GET',
url: Url.resolve(BASE_URL, 'issues'),
@ -72,30 +74,55 @@ export class GithubApi {
state: 'all',
per_page: '100',
labels: 'failed-test',
sort: 'updated',
direction: 'desc',
},
};
},
};
while (true) {
const resp = await this.request<GithubIssue[]>(nextRequest, []);
/**
* Iterate the `failed-test` issues from elastic/kibana, each response
* from Github is cached and subsequent calls to this method will first
* iterate the previous responses from Github, then start requesting
* more pages of issues from github until all pages have been cached.
*
* Aborting the iterator part way through will prevent unnecessary request
* to Github from being issued.
*/
async *iterateCachedFailedTestIssues() {
const cache = this.failedTestIssuesPageCache;
for (const issue of resp.data) {
issues.push(issue);
// start from page 0, and progress forward if we have cache or a request that will load that cache page
for (let page = 0; page < cache.pages.length || cache.nextRequest; page++) {
if (page >= cache.pages.length && cache.nextRequest) {
const resp = await this.request<GithubIssue[]>(cache.nextRequest, []);
cache.pages.push(resp.data);
const link =
typeof resp.headers.link === 'string' ? parseLinkHeader(resp.headers.link) : undefined;
cache.nextRequest =
link && link.next && link.next.url
? {
safeForDryRun: true,
method: 'GET',
url: link.next.url,
}
: undefined;
}
const parsed =
typeof resp.headers.link === 'string' ? parseLinkHeader(resp.headers.link) : undefined;
if (parsed && parsed.next && parsed.next.url) {
nextRequest = {
safeForDryRun: true,
method: 'GET',
url: parsed.next.url,
};
} else {
break;
for (const issue of cache.pages[page]) {
yield issue;
}
}
}
return issues;
async findFailedTestIssue(test: (issue: GithubIssue) => boolean) {
for await (const issue of this.iterateCachedFailedTestIssues()) {
if (test(issue)) {
return issue;
}
}
}
async editIssueBodyAndEnsureOpen(issueNumber: number, newBody: string) {

View file

@ -61,7 +61,6 @@ export function runFailedTestsReporterCli() {
}
const githubApi = new GithubApi(log, process.env.GITHUB_TOKEN, dryRun);
const issues = await githubApi.getAllFailedTestIssues();
const reportPaths = await globby(['target/junit/**/*.xml'], {
cwd: REPO_ROOT,
absolute: true,
@ -69,7 +68,7 @@ export function runFailedTestsReporterCli() {
for (const reportPath of reportPaths) {
for (const failure of await getFailures(log, reportPath)) {
const existingIssue = issues.find(
const existingIssue = await githubApi.findFailedTestIssue(
i =>
getIssueMetadata(i.body, 'test.class') === failure.classname &&
getIssueMetadata(i.body, 'test.name') === failure.name