Skip to content

Commit d74afab

Browse files
committed
test: rename misnamed integration_test, add watch streaming integration test
1 parent 2ed869f commit d74afab

3 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/test/integration/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import patchNamespace from './patchNamespace.js';
22
import cpFromPod from './cpFromPod.js';
33
import portForwardIntegration from './portForward.js';
4+
import watchPods from './watchPods.js';
45

56
console.log('Integration testing');
67

78
await patchNamespace();
89
await cpFromPod();
910
await portForwardIntegration();
11+
await watchPods();

src/test/integration/watchPods.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import assert from 'node:assert';
2+
import { CoreV1Api, KubeConfig, V1Pod } from '../../index.js';
3+
import { Watch } from '../../watch.js';
4+
import { generateName } from './name.js';
5+
6+
export default async function watchPods() {
7+
const kc = new KubeConfig();
8+
kc.loadFromDefault();
9+
10+
const coreV1Client = kc.makeApiClient(CoreV1Api);
11+
const watch = new Watch(kc);
12+
13+
const namespace = 'default';
14+
const labelKey = 'watch-test';
15+
const labelValue = generateName('run');
16+
17+
console.log(`\n=== Watch Integration Test (label=${labelValue}) ===`);
18+
19+
const receivedEvents: { type: string; name: string }[] = [];
20+
21+
let addResolve: () => void;
22+
const addPromise = new Promise<void>((resolve) => {
23+
addResolve = resolve;
24+
});
25+
26+
let deleteResolve: () => void;
27+
const deletePromise = new Promise<void>((resolve) => {
28+
deleteResolve = resolve;
29+
});
30+
31+
const controller = await watch.watch(
32+
`/api/v1/namespaces/${namespace}/pods`,
33+
{ labelSelector: `${labelKey}=${labelValue}` },
34+
(phase: string, obj: V1Pod) => {
35+
const name = obj.metadata?.name ?? 'unknown';
36+
console.log(`Watch event: ${phase} ${name}`);
37+
receivedEvents.push({ type: phase, name });
38+
39+
if (phase === 'ADDED') addResolve();
40+
if (phase === 'DELETED') deleteResolve();
41+
},
42+
(err: any) => {
43+
if (err && err.name !== 'AbortError') console.log('Watch done with error:', err);
44+
},
45+
);
46+
47+
const podName = generateName('watch-test-pod');
48+
try {
49+
console.log(`Creating pod ${podName}`);
50+
const pod = new V1Pod();
51+
pod.metadata = { name: podName, labels: { [labelKey]: labelValue } };
52+
pod.spec = {
53+
containers: [{ name: 'test', image: 'busybox', command: ['sleep', '3600'] }],
54+
restartPolicy: 'Never',
55+
};
56+
await coreV1Client.createNamespacedPod({ namespace, body: pod });
57+
58+
await Promise.race([
59+
addPromise,
60+
new Promise((_, reject) =>
61+
setTimeout(() => reject(new Error('Timed out waiting for ADDED event')), 15000),
62+
),
63+
]);
64+
65+
const addEvent = receivedEvents.find((e) => e.type === 'ADDED' && e.name === podName);
66+
assert.ok(addEvent, 'Should have received ADDED event for pod');
67+
console.log('✓ Received ADDED event');
68+
69+
console.log(`Deleting pod ${podName}`);
70+
await coreV1Client.deleteNamespacedPod({ name: podName, namespace });
71+
72+
await Promise.race([
73+
deletePromise,
74+
new Promise((_, reject) =>
75+
setTimeout(() => reject(new Error('Timed out waiting for DELETED event')), 15000),
76+
),
77+
]);
78+
79+
const deleteEvent = receivedEvents.find((e) => e.type === 'DELETED' && e.name === podName);
80+
assert.ok(deleteEvent, 'Should have received DELETED event for pod');
81+
console.log('✓ Received DELETED event');
82+
} finally {
83+
controller.abort();
84+
try {
85+
await coreV1Client.deleteNamespacedPod({ name: podName, namespace });
86+
} catch {
87+
// already deleted or never created
88+
}
89+
}
90+
91+
console.log('Watch integration test passed!');
92+
}

0 commit comments

Comments
 (0)