-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathtest-grpc-metrics-interval-reconfigure.mjs
More file actions
128 lines (111 loc) · 3.72 KB
/
Copy pathtest-grpc-metrics-interval-reconfigure.mjs
File metadata and controls
128 lines (111 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Flags: --expose-internals
import { mustSucceed } from '../common/index.mjs';
import assert from 'node:assert';
import { setTimeout as delay } from 'node:timers/promises';
import {
GRPCServer,
TestClient,
} from '../common/nsolid-grpc-agent/index.js';
const INITIAL_INTERVAL = 600;
const UPDATED_INTERVAL = 100;
const FAST_INTERVAL_UPPER_BOUND = 300;
const METRICS_TIMEOUT_MS = 1500;
function waitForMetricsEvent(grpcServer, timeoutMs = METRICS_TIMEOUT_MS) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
grpcServer.off('metrics', onMetrics);
reject(new Error(`Timed out waiting for metrics event after ${timeoutMs}ms`));
}, timeoutMs);
function onMetrics() {
clearTimeout(timer);
grpcServer.off('metrics', onMetrics);
resolve(Date.now());
}
grpcServer.on('metrics', onMetrics);
});
}
async function collectMetricsEventTimestamps(grpcServer,
count,
timeoutMs = METRICS_TIMEOUT_MS) {
const timestamps = [];
const deadline = Date.now() + timeoutMs;
while (timestamps.length < count) {
const remaining = deadline - Date.now();
if (remaining <= 0) {
break;
}
timestamps.push(await waitForMetricsEvent(grpcServer, remaining));
}
return timestamps;
}
async function runTest({ getEnv }) {
return new Promise((resolve) => {
const grpcServer = new GRPCServer();
grpcServer.start(mustSucceed(async (port) => {
const env = getEnv(port);
const opts = {
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
env,
};
const child = new TestClient([], opts);
const agentId = await child.id();
const initialConfig = await child.config({ interval: INITIAL_INTERVAL });
assert.strictEqual(initialConfig.interval, INITIAL_INTERVAL);
// Wait for one periodic metrics push so the next interval boundary is
// well-defined before reconfiguring.
await waitForMetricsEvent(grpcServer, INITIAL_INTERVAL * 3);
const { data, requestId } = await grpcServer.reconfigure(agentId, {
interval: UPDATED_INTERVAL,
});
assert.strictEqual(data.msg.common.requestId, requestId);
assert.strictEqual(Number(data.msg.body.interval), UPDATED_INTERVAL);
const updatedConfig = await child.config();
assert.strictEqual(updatedConfig.interval, UPDATED_INTERVAL);
const timestamps = await collectMetricsEventTimestamps(grpcServer,
3,
METRICS_TIMEOUT_MS);
assert.strictEqual(
timestamps.length,
3,
`Expected 3 metrics events after reconfigure, got ${timestamps.length}`,
);
const deltas = [
timestamps[1] - timestamps[0],
timestamps[2] - timestamps[1],
];
for (const delta of deltas) {
assert.ok(
delta < FAST_INTERVAL_UPPER_BOUND,
`Expected fast metrics cadence after reconfigure, got ${delta}ms`,
);
}
await child.shutdown(0);
grpcServer.close();
resolve();
}));
});
}
const testConfigs = [
{
getEnv: (port) => {
return {
NODE_DEBUG_NATIVE: 'nsolid_grpc_agent',
NSOLID_GRPC_INSECURE: 1,
NSOLID_GRPC: `localhost:${port}`,
};
},
},
{
getEnv: (port) => {
return {
NODE_DEBUG_NATIVE: 'nsolid_grpc_agent',
NSOLID_GRPC_INSECURE: 1,
NSOLID_SAAS: `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbtesting.localhost:${port}`,
};
},
},
];
for (const testConfig of testConfigs) {
await runTest(testConfig);
await delay(100);
}