test: test for wait node readiness in dynamic pool
[poolifier.git] / tests / utils.test.mjs
CommitLineData
a074ffee
JB
1import { Worker } from 'node:worker_threads'
2import cluster from 'node:cluster'
3import os from 'node:os'
4import { randomInt } from 'node:crypto'
5import { expect } from 'expect'
6import {
9274aa14
JB
7 DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
8 DEFAULT_TASK_NAME,
9 DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS,
10 EMPTY_FUNCTION,
afe0d5bf 11 availableParallelism,
dc021bcc 12 average,
98446b39 13 exponentialDelay,
9fe8fd69 14 getWorkerId,
a074ffee 15 getWorkerType,
78ac1a90 16 isAsyncFunction,
59317253 17 isKillBehavior,
afe0d5bf 18 isPlainObject,
90d6701c 19 max,
afe0d5bf 20 median,
90d6701c 21 min,
55082af9 22 // once,
a91f7b35 23 round,
970b38d6 24 secureRandom,
bfc75cca 25 sleep
a074ffee
JB
26} from '../lib/utils.js'
27import { KillBehaviors, WorkerTypes } from '../lib/index.js'
aba955e1
JB
28
29describe('Utils test suite', () => {
9274aa14
JB
30 it('Verify DEFAULT_TASK_NAME value', () => {
31 expect(DEFAULT_TASK_NAME).toBe('default')
32 })
33
34 it('Verify EMPTY_FUNCTION value', () => {
35 expect(EMPTY_FUNCTION).toStrictEqual(expect.any(Function))
36 })
37
38 it('Verify DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS values', () => {
39 expect(DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS).toStrictEqual({
40 retries: 6,
41 runTime: { median: false },
42 waitTime: { median: false },
43 elu: { median: false }
44 })
45 })
46
47 it('Verify DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS values', () => {
48 expect(DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS).toStrictEqual({
49 aggregate: false,
50 average: false,
51 median: false
52 })
53 })
54
afe0d5bf 55 it('Verify availableParallelism() behavior', () => {
9fe8fd69
JB
56 const parallelism = availableParallelism()
57 expect(typeof parallelism === 'number').toBe(true)
37e31fac 58 expect(Number.isSafeInteger(parallelism)).toBe(true)
562a4037
JB
59 let expectedParallelism = 1
60 try {
61 expectedParallelism = os.availableParallelism()
62 } catch {
63 expectedParallelism = os.cpus().length
64 }
65 expect(parallelism).toBe(expectedParallelism)
9fe8fd69
JB
66 })
67
68 it('Verify getWorkerType() behavior', () => {
69 expect(
b2fd3f4a 70 getWorkerType(new Worker('./tests/worker-files/thread/testWorker.mjs'))
9fe8fd69
JB
71 ).toBe(WorkerTypes.thread)
72 expect(getWorkerType(cluster.fork())).toBe(WorkerTypes.cluster)
73 })
74
75 it('Verify getWorkerId() behavior', () => {
b2fd3f4a
JB
76 const threadWorker = new Worker(
77 './tests/worker-files/thread/testWorker.mjs'
78 )
9fe8fd69
JB
79 const clusterWorker = cluster.fork()
80 expect(getWorkerId(threadWorker)).toBe(threadWorker.threadId)
81 expect(getWorkerId(clusterWorker)).toBe(clusterWorker.id)
afe0d5bf
JB
82 })
83
bb9423b7 84 it('Verify sleep() behavior', async () => {
65deb7f0 85 const start = performance.now()
b91134ce
JB
86 const sleepMs = 1000
87 await sleep(sleepMs)
6543999f 88 const elapsed = performance.now() - start
b91134ce 89 expect(elapsed).toBeGreaterThanOrEqual(sleepMs - 1)
98446b39
JB
90 })
91
92 it('Verify exponentialDelay() behavior', () => {
1f0766e7
JB
93 const delay = exponentialDelay(randomInt(1000))
94 expect(typeof delay === 'number').toBe(true)
95 expect(delay).toBeGreaterThanOrEqual(Number.MIN_VALUE)
96 expect(delay).toBeLessThanOrEqual(Number.MAX_VALUE)
98446b39
JB
97 })
98
dc021bcc
JB
99 it('Verify average() computation', () => {
100 expect(average([])).toBe(0)
101 expect(average([0.08])).toBe(0.08)
102 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(
103 3.1642857142857146
104 )
105 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(
106 2.8533333333333335
107 )
108 })
109
bb615bd0 110 it('Verify median() computation', () => {
4a45e8d2 111 expect(median([])).toBe(0)
76845835
JB
112 expect(median([0.08])).toBe(0.08)
113 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05)
114 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535)
aba955e1
JB
115 })
116
afe0d5bf
JB
117 it('Verify round() behavior', () => {
118 expect(round(0)).toBe(0)
119 expect(round(0.5, 0)).toBe(1)
120 expect(round(0.5)).toBe(0.5)
121 expect(round(-0.5, 0)).toBe(-1)
122 expect(round(-0.5)).toBe(-0.5)
123 expect(round(1.005)).toBe(1.01)
124 expect(round(2.175)).toBe(2.18)
125 expect(round(5.015)).toBe(5.02)
126 expect(round(-1.005)).toBe(-1.01)
127 expect(round(-2.175)).toBe(-2.18)
128 expect(round(-5.015)).toBe(-5.02)
129 })
130
aba955e1
JB
131 it('Verify isPlainObject() behavior', () => {
132 expect(isPlainObject(null)).toBe(false)
133 expect(isPlainObject(undefined)).toBe(false)
134 expect(isPlainObject(true)).toBe(false)
135 expect(isPlainObject(false)).toBe(false)
136 expect(isPlainObject(0)).toBe(false)
137 expect(isPlainObject('')).toBe(false)
138 expect(isPlainObject([])).toBe(false)
139 expect(isPlainObject(() => {})).toBe(false)
140 expect(isPlainObject(new Date())).toBe(false)
141 expect(isPlainObject(new RegExp())).toBe(false)
142 expect(isPlainObject(new Error())).toBe(false)
143 expect(isPlainObject(new Map())).toBe(false)
144 expect(isPlainObject(new Set())).toBe(false)
145 expect(isPlainObject(new WeakMap())).toBe(false)
146 expect(isPlainObject(new WeakSet())).toBe(false)
147 expect(isPlainObject(new Int8Array())).toBe(false)
148 expect(isPlainObject(new Uint8Array())).toBe(false)
149 expect(isPlainObject(new Uint8ClampedArray())).toBe(false)
150 expect(isPlainObject(new Int16Array())).toBe(false)
151 expect(isPlainObject(new Uint16Array())).toBe(false)
152 expect(isPlainObject(new Int32Array())).toBe(false)
153 expect(isPlainObject(new Uint32Array())).toBe(false)
154 expect(isPlainObject(new Float32Array())).toBe(false)
155 expect(isPlainObject(new Float64Array())).toBe(false)
156 expect(isPlainObject(new BigInt64Array())).toBe(false)
157 expect(isPlainObject(new BigUint64Array())).toBe(false)
158 expect(isPlainObject(new Promise(() => {}))).toBe(false)
159 expect(isPlainObject(new WeakRef({}))).toBe(false)
160 expect(isPlainObject(new FinalizationRegistry(() => {}))).toBe(false)
161 expect(isPlainObject(new ArrayBuffer())).toBe(false)
162 expect(isPlainObject(new SharedArrayBuffer())).toBe(false)
163 expect(isPlainObject(new DataView(new ArrayBuffer()))).toBe(false)
164 expect(isPlainObject({})).toBe(true)
165 expect(isPlainObject({ a: 1 })).toBe(true)
166 })
47aacbaa
JB
167
168 it('Verify isKillBehavior() behavior', () => {
169 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.SOFT)).toBe(true)
170 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.HARD)).toBe(false)
171 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.HARD)).toBe(true)
172 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.SOFT)).toBe(false)
173 expect(isKillBehavior(KillBehaviors.SOFT)).toBe(false)
174 expect(isKillBehavior(KillBehaviors.HARD)).toBe(false)
175 expect(isKillBehavior(KillBehaviors.HARD, null)).toBe(false)
78ac1a90 176 expect(isKillBehavior(KillBehaviors.HARD, undefined)).toBe(false)
47aacbaa
JB
177 expect(isKillBehavior(KillBehaviors.SOFT, 'unknown')).toBe(false)
178 })
78ac1a90
JB
179
180 it('Verify isAsyncFunction() behavior', () => {
181 expect(isAsyncFunction(null)).toBe(false)
182 expect(isAsyncFunction(undefined)).toBe(false)
183 expect(isAsyncFunction(true)).toBe(false)
184 expect(isAsyncFunction(false)).toBe(false)
185 expect(isAsyncFunction(0)).toBe(false)
186 expect(isAsyncFunction('')).toBe(false)
187 expect(isAsyncFunction([])).toBe(false)
188 expect(isAsyncFunction(new Date())).toBe(false)
189 expect(isAsyncFunction(new RegExp())).toBe(false)
190 expect(isAsyncFunction(new Error())).toBe(false)
191 expect(isAsyncFunction(new Map())).toBe(false)
192 expect(isAsyncFunction(new Set())).toBe(false)
193 expect(isAsyncFunction(new WeakMap())).toBe(false)
194 expect(isAsyncFunction(new WeakSet())).toBe(false)
195 expect(isAsyncFunction(new Int8Array())).toBe(false)
196 expect(isAsyncFunction(new Uint8Array())).toBe(false)
197 expect(isAsyncFunction(new Uint8ClampedArray())).toBe(false)
198 expect(isAsyncFunction(new Int16Array())).toBe(false)
199 expect(isAsyncFunction(new Uint16Array())).toBe(false)
200 expect(isAsyncFunction(new Int32Array())).toBe(false)
201 expect(isAsyncFunction(new Uint32Array())).toBe(false)
202 expect(isAsyncFunction(new Float32Array())).toBe(false)
203 expect(isAsyncFunction(new Float64Array())).toBe(false)
204 expect(isAsyncFunction(new BigInt64Array())).toBe(false)
205 expect(isAsyncFunction(new BigUint64Array())).toBe(false)
206 expect(isAsyncFunction(new Promise(() => {}))).toBe(false)
207 expect(isAsyncFunction(new WeakRef({}))).toBe(false)
208 expect(isAsyncFunction(new FinalizationRegistry(() => {}))).toBe(false)
209 expect(isAsyncFunction(new ArrayBuffer())).toBe(false)
210 expect(isAsyncFunction(new SharedArrayBuffer())).toBe(false)
211 expect(isAsyncFunction(new DataView(new ArrayBuffer()))).toBe(false)
212 expect(isAsyncFunction({})).toBe(false)
213 expect(isAsyncFunction({ a: 1 })).toBe(false)
214 expect(isAsyncFunction(() => {})).toBe(false)
215 expect(isAsyncFunction(function () {})).toBe(false)
216 expect(isAsyncFunction(function named () {})).toBe(false)
217 expect(isAsyncFunction(async () => {})).toBe(true)
218 expect(isAsyncFunction(async function () {})).toBe(true)
219 expect(isAsyncFunction(async function named () {})).toBe(true)
220 })
a91f7b35 221
970b38d6
JB
222 it('Verify secureRandom() behavior', () => {
223 const randomNumber = secureRandom()
224 expect(typeof randomNumber === 'number').toBe(true)
225 expect(randomNumber).toBeGreaterThanOrEqual(0)
226 expect(randomNumber).toBeLessThan(1)
227 })
90d6701c
JB
228
229 it('Verify min() behavior', () => {
625449e0 230 expect(min()).toBe(Infinity)
90d6701c
JB
231 expect(min(1, 2)).toBe(1)
232 expect(min(2, 1)).toBe(1)
233 expect(min(1, 1)).toBe(1)
234 })
235
236 it('Verify max() behavior', () => {
625449e0 237 expect(max()).toBe(-Infinity)
90d6701c
JB
238 expect(max(1, 2)).toBe(2)
239 expect(max(2, 1)).toBe(2)
240 expect(max(1, 1)).toBe(1)
241 })
d91689fd 242
55082af9
JB
243 // it('Verify once()', () => {
244 // let called = 0
245 // const fn = () => ++called
246 // const onceFn = once(fn, this)
247 // const result1 = onceFn()
248 // expect(called).toBe(1)
249 // expect(result1).toBe(1)
250 // const result2 = onceFn()
251 // expect(called).toBe(1)
252 // expect(result2).toBe(1)
253 // const result3 = onceFn()
254 // expect(called).toBe(1)
255 // expect(result3).toBe(1)
256 // })
aba955e1 257})