fix(KAN-58): retry transient public downloads for macOS 0.1.1
CI/CD / preconditions (pull_request) Successful in 2s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m4s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m28s
CI/CD / Publish immutable image (pull_request) Canceled after 0s
CI/CD / test_and_check_app (pull_request) Canceled after 2m15s
CI/CD / preconditions (pull_request) Successful in 2s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m4s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m28s
CI/CD / Publish immutable image (pull_request) Canceled after 0s
CI/CD / test_and_check_app (pull_request) Canceled after 2m15s
This commit is contained in:
@@ -70,7 +70,16 @@ function fixture(t) {
|
||||
arrayBuffer: async () => objects.get(key),
|
||||
};
|
||||
};
|
||||
return { directory, metadata, env, objects, events, run, fetchPublic };
|
||||
return {
|
||||
directory,
|
||||
metadata,
|
||||
env,
|
||||
objects,
|
||||
events,
|
||||
run,
|
||||
fetchPublic,
|
||||
wait: async () => {},
|
||||
};
|
||||
}
|
||||
|
||||
test('uploads immutable files and writes completion record after public verification', async (t) => {
|
||||
@@ -194,6 +203,7 @@ for (const failure of ['private', 'wrong-content', 'network']) {
|
||||
}
|
||||
return {
|
||||
ok: failure !== 'private',
|
||||
status: failure === 'private' ? 403 : 200,
|
||||
arrayBuffer: async () => Buffer.from('wrong'),
|
||||
};
|
||||
};
|
||||
@@ -223,6 +233,77 @@ test('a partial upload can resume with the same files', async (t) => {
|
||||
assert.equal(f.objects.size, 3);
|
||||
});
|
||||
|
||||
for (const status of [403, 404, 408, 429, 500, 502, 503, 504, 'network']) {
|
||||
test(`temporary public download failure ${status} recovers before completion`, async (t) => {
|
||||
const f = fixture(t);
|
||||
const fetchPublic = f.fetchPublic;
|
||||
let attempts = 0;
|
||||
let cancelled = 0;
|
||||
const waits = [];
|
||||
f.wait = async (ms) => waits.push(ms);
|
||||
f.fetchPublic = async (...args) => {
|
||||
if (++attempts <= 2) {
|
||||
if (status === 'network') {
|
||||
throw new Error('temporary network failure');
|
||||
}
|
||||
return {
|
||||
ok: false,
|
||||
status,
|
||||
body: { cancel: async () => cancelled++ },
|
||||
};
|
||||
}
|
||||
return fetchPublic(...args);
|
||||
};
|
||||
await publishMacos(f);
|
||||
assert.deepEqual(waits, [2000, 2000]);
|
||||
assert.equal(cancelled, status === 'network' ? 0 : 2);
|
||||
assert.equal(f.objects.size, 3);
|
||||
assert(f.events.at(-1).key.endsWith('/release.json'));
|
||||
});
|
||||
}
|
||||
|
||||
test('persistent public access denial stops after five attempts with HTTP status', async (t) => {
|
||||
const f = fixture(t);
|
||||
let attempts = 0;
|
||||
const waits = [];
|
||||
f.wait = async (ms) => waits.push(ms);
|
||||
f.fetchPublic = async () => {
|
||||
attempts++;
|
||||
return { ok: false, status: 403 };
|
||||
};
|
||||
await assert.rejects(publishMacos(f), /HTTP 403/);
|
||||
assert.equal(attempts, 5);
|
||||
assert.equal(waits.length, 4);
|
||||
assert.equal(f.objects.size, 1);
|
||||
});
|
||||
|
||||
test('incorrect public bytes fail immediately without retry or completion record', async (t) => {
|
||||
const f = fixture(t);
|
||||
f.wait = async () => assert.fail('Do not retry mismatched content');
|
||||
f.fetchPublic = async () => ({
|
||||
ok: true,
|
||||
arrayBuffer: async () => Buffer.from('incorrect'),
|
||||
});
|
||||
await assert.rejects(publishMacos(f), /SHA-256 mismatch/);
|
||||
assert.equal(f.objects.size, 1);
|
||||
});
|
||||
|
||||
test('checksum access retries finish before publishing the completion record', async (t) => {
|
||||
const f = fixture(t);
|
||||
const fetchPublic = f.fetchPublic;
|
||||
let failures = 0;
|
||||
f.fetchPublic = async (url, options) => {
|
||||
if (url.endsWith('.sha256') && ++failures <= 2) {
|
||||
assert.equal(f.objects.size, 2);
|
||||
return { ok: false, status: 403 };
|
||||
}
|
||||
return fetchPublic(url, options);
|
||||
};
|
||||
await publishMacos(f);
|
||||
assert.equal(failures, 3);
|
||||
assert.equal(f.objects.size, 3);
|
||||
});
|
||||
|
||||
for (const overrides of [
|
||||
{ S3_REGION: '' },
|
||||
{ S3_REGION: 'eu-central-1' },
|
||||
|
||||
Reference in New Issue
Block a user