Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/e2e-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ jobs:
- distribution: oracle
os: ubuntu-latest
version: 21
- distribution: oracle-openjdk
os: macos-15-intel
version: 21
- distribution: oracle-openjdk
os: windows-latest
version: 21
- distribution: oracle-openjdk
os: ubuntu-latest
version: 21
- distribution: graalvm
os: macos-latest
version: 17.0.12
Expand Down
25 changes: 25 additions & 0 deletions __tests__/distributors/base-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,31 @@ describe('setupJava', () => {
expect(spyCoreSetOutput).not.toHaveBeenCalled();
});

it('should not repeat version resolution when downloadTool fails', async () => {
mockJavaBase = new EmptyJavaBase({
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false,
forceDownload: true
});
const findPackageForDownload = jest.fn(async () => ({
version: '11.0.9',
url: 'https://example.com/jdk.tar.gz'
}));
const downloadError = new Error('download failed');
const downloadTool = jest.fn(async () => {
throw downloadError;
});
mockJavaBase['findPackageForDownload'] = findPackageForDownload;
mockJavaBase['downloadTool'] = downloadTool;

await expect(mockJavaBase.setupJava()).rejects.toBe(downloadError);

expect(findPackageForDownload).toHaveBeenCalledTimes(1);
expect(downloadTool).toHaveBeenCalledTimes(1);
});

it.each([
[
{
Expand Down
32 changes: 32 additions & 0 deletions __tests__/distributors/distribution-factory.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
import {getJavaDistribution} from '../../src/distributions/distribution-factory.js';
import {RetryingHttpClient} from '../../src/retrying-http-client.js';

describe('getJavaDistribution', () => {
it.each([
'adopt',
'adopt-hotspot',
'adopt-openj9',
'temurin',
'zulu',
'liberica',
'liberica-nik',
'microsoft',
'semeru',
'corretto',
'oracle',
'dragonwell',
'sapmachine',
'graalvm',
'graalvm-community',
'jetbrains',
'kona',
'oracle-openjdk'
])('uses the shared retrying HTTP client for %s', distributionName => {
const distribution = getJavaDistribution(distributionName, {
version: '21',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});

expect(distribution).not.toBeNull();
expect(distribution!['http']).toBeInstanceOf(RetryingHttpClient);
});

it("rejects java-package 'jdk+jmods' for non-Temurin distributions", () => {
expect(() =>
getJavaDistribution('zulu', {
Expand Down
52 changes: 51 additions & 1 deletion __tests__/distributors/jetbrains-installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
afterAll
} from '@jest/globals';
import https from 'https';
import {HttpClient} from '@actions/http-client';
import {HttpClient, HttpClientResponse} from '@actions/http-client';
import type {IncomingMessage} from 'http';
import {Readable} from 'stream';

import manifestData from '../data/jetbrains.json' with {type: 'json'};
import os from 'os';
Expand Down Expand Up @@ -44,6 +46,18 @@ jest.unstable_mockModule('@actions/core', () => ({
const core = await import('@actions/core');
const {JetBrainsDistribution} =
await import('../../src/distributions/jetbrains/installer.js');
const {RetryingHttpClient} = await import('../../src/retrying-http-client.js');

function response(
statusCode: number,
body = '',
headers: IncomingMessage['headers'] = {}
): HttpClientResponse {
const message = Readable.from([Buffer.from(body)]) as IncomingMessage;
message.statusCode = statusCode;
message.headers = headers;
return new HttpClientResponse(message);
}

describe('getAvailableVersions', () => {
let spyHttpClient: any;
Expand Down Expand Up @@ -95,6 +109,42 @@ describe('getAvailableVersions', () => {
os.platform() === 'win32' ? manifestData.length : manifestData.length + 2;
expect(availableVersions.length).toBe(length);
}, 10_000);

it('retries a GitHub rate limit using Retry-After', async () => {
spyHttpClient.mockRestore();
const sleep = jest.fn(async () => undefined);
const requestRaw = jest
.spyOn(HttpClient.prototype, 'requestRaw')
.mockResolvedValueOnce(response(429, '', {'retry-after': '2'}))
.mockResolvedValueOnce(response(200, '[]'))
.mockResolvedValueOnce(response(200))
.mockResolvedValueOnce(response(200));
const distribution = new JetBrainsDistribution({
version: '17',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
distribution['http'] = new RetryingHttpClient('test', {
sleep,
random: () => 0
});

const availableVersions = await distribution['getAvailableVersions']();

expect(availableVersions).toHaveLength(2);
expect(requestRaw).toHaveBeenCalledTimes(4);
expect(requestRaw.mock.calls[0][0].options.path).toBe(
requestRaw.mock.calls[1][0].options.path
);
expect(requestRaw.mock.calls[0][0].options.path).toContain(
'/repos/JetBrains/JetBrainsRuntime/releases'
);
expect(sleep).toHaveBeenCalledWith(2000);
expect(core.info).toHaveBeenCalledWith(
'Request attempt 1 of 4 failed (HTTP 429); retrying in 2000 ms'
);
});
});

describe('findPackageForDownload', () => {
Expand Down
Loading
Loading