Skip to content
Open
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
16 changes: 4 additions & 12 deletions src/cache_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ListPromise } from './informer.js';

import { MockAgent, setGlobalDispatcher, getGlobalDispatcher } from 'undici';
import { Watch } from './watch.js';
import { deferred } from './test/deferred.js';

const server = 'https://foo.company.com';

Expand Down Expand Up @@ -1442,14 +1443,11 @@ describe('ListWatchCache', () => {

await informer.start();

let doneResolve: any;
const donePromise = new Promise((resolve) => {
doneResolve = resolve;
});
const done = deferred<V1Namespace>();

informer.on('add', doneResolve);
informer.on('add', done.resolve);

const value = await donePromise;
const value = await done.promise;

deepStrictEqual(value, {
metadata: {
Expand Down Expand Up @@ -1716,12 +1714,6 @@ describe('ListWatchCache', () => {
deepStrictEqual(errors, [error]);
});

function deferred<T = void>() {
let resolve!: (value: T | PromiseLike<T>) => void;
const promise = new Promise<T>((done) => (resolve = done));
return { promise, resolve };
}

function lifecycleCache(
t: TestContext,
options: {
Expand Down
3 changes: 3 additions & 0 deletions src/test/deferred.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function deferred<T = void>() {
return Promise.withResolvers<T>();
}
29 changes: 10 additions & 19 deletions src/test/integration/informerReconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Watch } from '../../watch.js';
import { ListWatch } from '../../cache.js';
import { generateName } from './name.js';
import { withTimeout } from './helpers.js';
import { deferred } from '../deferred.js';

export default async function informerReconnect() {
const kc = new KubeConfig();
Expand Down Expand Up @@ -37,35 +38,25 @@ export default async function informerReconnect() {
let connectCount = 0;
let errorCount = 0;

let cm1AddResolve: () => void;
const cm1AddPromise = new Promise<void>((resolve) => {
cm1AddResolve = resolve;
});

let cm2AddResolve: () => void;
const cm2AddPromise = new Promise<void>((resolve) => {
cm2AddResolve = resolve;
});
const cm1Add = deferred();
const cm2Add = deferred();

const initialConnects = 0;
let reconnectResolve: () => void;
const reconnectPromise = new Promise<void>((resolve) => {
reconnectResolve = resolve;
});
const reconnect = deferred();

informer.on('add', (obj: V1ConfigMap) => {
const name = obj.metadata?.name ?? 'unknown';
console.log(`Informer event: add ${name}`);
addedNames.push(name);

if (name === cm1Name) cm1AddResolve();
if (name === cm2Name) cm2AddResolve();
if (name === cm1Name) cm1Add.resolve();
if (name === cm2Name) cm2Add.resolve();
});

informer.on('connect', () => {
connectCount++;
console.log(`Informer event: connect (#${connectCount})`);
if (connectCount > initialConnects + 1) reconnectResolve();
if (connectCount > initialConnects + 1) reconnect.resolve();
});

informer.on('error', (err: any) => {
Expand All @@ -89,12 +80,12 @@ export default async function informerReconnect() {
},
});

await withTimeout(cm1AddPromise, 15000, 'Timed out waiting for cm1 add event');
await withTimeout(cm1Add.promise, 15000, 'Timed out waiting for cm1 add event');
assert.ok(addedNames.includes(cm1Name), 'Should have received add event for cm1');
console.log('✓ Received add event for cm1');

console.log(`Waiting for watch reconnection (up to 45s)...`);
await withTimeout(reconnectPromise, 45000, 'Timed out waiting for informer reconnect');
await withTimeout(reconnect.promise, 45000, 'Timed out waiting for informer reconnect');
assert.ok(connectCount > initialConnects + 1, 'Informer should have reconnected');
console.log(`✓ Informer reconnected (connect count: ${connectCount})`);

Expand All @@ -107,7 +98,7 @@ export default async function informerReconnect() {
},
});

await withTimeout(cm2AddPromise, 15000, 'Timed out waiting for cm2 add event');
await withTimeout(cm2Add.promise, 15000, 'Timed out waiting for cm2 add event');
assert.ok(addedNames.includes(cm2Name), 'Should have received add event for cm2 after reconnect');
console.log('✓ Received add event for cm2 after reconnection');

Expand Down
20 changes: 7 additions & 13 deletions src/test/integration/watchPods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CoreV1Api, KubeConfig, V1Pod } from '../../index.js';
import { Watch } from '../../watch.js';
import { generateName } from './name.js';
import { withTimeout } from './helpers.js';
import { deferred } from '../deferred.js';

export default async function watchPods() {
const kc = new KubeConfig();
Expand All @@ -19,15 +20,8 @@ export default async function watchPods() {

const receivedEvents: { type: string; name: string }[] = [];

let addResolve: () => void;
const addPromise = new Promise<void>((resolve) => {
addResolve = resolve;
});

let deleteResolve: () => void;
const deletePromise = new Promise<void>((resolve) => {
deleteResolve = resolve;
});
const added = deferred();
const deleted = deferred();

const controller = await watch.watch(
`/api/v1/namespaces/${namespace}/pods`,
Expand All @@ -37,8 +31,8 @@ export default async function watchPods() {
console.log(`Watch event: ${phase} ${name}`);
receivedEvents.push({ type: phase, name });

if (phase === 'ADDED') addResolve();
if (phase === 'DELETED') deleteResolve();
if (phase === 'ADDED') added.resolve();
if (phase === 'DELETED') deleted.resolve();
},
(err: any) => {
if (err && err.name !== 'AbortError') console.log('Watch done with error:', err);
Expand All @@ -56,7 +50,7 @@ export default async function watchPods() {
};
await coreV1Client.createNamespacedPod({ namespace, body: pod });

await withTimeout(addPromise, 15000, 'Timed out waiting for ADDED event');
await withTimeout(added.promise, 15000, 'Timed out waiting for ADDED event');

const addEvent = receivedEvents.find((e) => e.type === 'ADDED' && e.name === podName);
assert.ok(addEvent, 'Should have received ADDED event for pod');
Expand All @@ -65,7 +59,7 @@ export default async function watchPods() {
console.log(`Deleting pod ${podName}`);
await coreV1Client.deleteNamespacedPod({ name: podName, namespace });

await withTimeout(deletePromise, 15000, 'Timed out waiting for DELETED event');
await withTimeout(deleted.promise, 15000, 'Timed out waiting for DELETED event');

const deleteEvent = receivedEvents.find((e) => e.type === 'DELETED' && e.name === podName);
assert.ok(deleteEvent, 'Should have received DELETED event for pod');
Expand Down
Loading