fix: fix worker usage statistics handling
[poolifier.git] / tests / utils.test.js
CommitLineData
98446b39 1const { randomInt } = require('crypto')
9fe8fd69
JB
2const { Worker } = require('worker_threads')
3const cluster = require('cluster')
aba955e1 4const { expect } = require('expect')
dc021bcc
JB
5const {
6 CircularArray,
7 DEFAULT_CIRCULAR_ARRAY_SIZE
8} = require('../lib/circular-array')
afe0d5bf
JB
9const {
10 availableParallelism,
dc021bcc 11 average,
98446b39 12 exponentialDelay,
9fe8fd69
JB
13 getWorkerType,
14 getWorkerId,
78ac1a90 15 isAsyncFunction,
59317253 16 isKillBehavior,
afe0d5bf
JB
17 isPlainObject,
18 median,
a91f7b35 19 round,
970b38d6 20 secureRandom,
98446b39 21 sleep,
a91f7b35 22 updateMeasurementStatistics
afe0d5bf 23} = require('../lib/utils')
9fe8fd69 24const { KillBehaviors, WorkerTypes } = require('../lib')
aba955e1
JB
25
26describe('Utils test suite', () => {
afe0d5bf 27 it('Verify availableParallelism() behavior', () => {
9fe8fd69
JB
28 const parallelism = availableParallelism()
29 expect(typeof parallelism === 'number').toBe(true)
30 expect(parallelism).toBeGreaterThan(0)
31 expect(Number.isSafeInteger(parallelism)).toBe(true)
32 })
33
34 it('Verify getWorkerType() behavior', () => {
35 expect(
36 getWorkerType(new Worker('./tests/worker-files/thread/testWorker.js'))
37 ).toBe(WorkerTypes.thread)
38 expect(getWorkerType(cluster.fork())).toBe(WorkerTypes.cluster)
39 })
40
41 it('Verify getWorkerId() behavior', () => {
42 const threadWorker = new Worker('./tests/worker-files/thread/testWorker.js')
43 const clusterWorker = cluster.fork()
44 expect(getWorkerId(threadWorker)).toBe(threadWorker.threadId)
45 expect(getWorkerId(clusterWorker)).toBe(clusterWorker.id)
afe0d5bf
JB
46 })
47
6543999f 48 it.skip('Verify sleep() behavior', async () => {
65deb7f0 49 const start = performance.now()
98446b39 50 await sleep(1000)
6543999f
JB
51 const elapsed = performance.now() - start
52 expect(elapsed).toBeGreaterThanOrEqual(1000)
98446b39
JB
53 })
54
55 it('Verify exponentialDelay() behavior', () => {
1f0766e7
JB
56 const delay = exponentialDelay(randomInt(1000))
57 expect(typeof delay === 'number').toBe(true)
58 expect(delay).toBeGreaterThanOrEqual(Number.MIN_VALUE)
59 expect(delay).toBeLessThanOrEqual(Number.MAX_VALUE)
98446b39
JB
60 })
61
dc021bcc
JB
62 it('Verify average() computation', () => {
63 expect(average([])).toBe(0)
64 expect(average([0.08])).toBe(0.08)
65 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(
66 3.1642857142857146
67 )
68 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(
69 2.8533333333333335
70 )
71 })
72
bb615bd0 73 it('Verify median() computation', () => {
4a45e8d2 74 expect(median([])).toBe(0)
76845835
JB
75 expect(median([0.08])).toBe(0.08)
76 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05)
77 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535)
aba955e1
JB
78 })
79
afe0d5bf
JB
80 it('Verify round() behavior', () => {
81 expect(round(0)).toBe(0)
82 expect(round(0.5, 0)).toBe(1)
83 expect(round(0.5)).toBe(0.5)
84 expect(round(-0.5, 0)).toBe(-1)
85 expect(round(-0.5)).toBe(-0.5)
86 expect(round(1.005)).toBe(1.01)
87 expect(round(2.175)).toBe(2.18)
88 expect(round(5.015)).toBe(5.02)
89 expect(round(-1.005)).toBe(-1.01)
90 expect(round(-2.175)).toBe(-2.18)
91 expect(round(-5.015)).toBe(-5.02)
92 })
93
aba955e1
JB
94 it('Verify isPlainObject() behavior', () => {
95 expect(isPlainObject(null)).toBe(false)
96 expect(isPlainObject(undefined)).toBe(false)
97 expect(isPlainObject(true)).toBe(false)
98 expect(isPlainObject(false)).toBe(false)
99 expect(isPlainObject(0)).toBe(false)
100 expect(isPlainObject('')).toBe(false)
101 expect(isPlainObject([])).toBe(false)
102 expect(isPlainObject(() => {})).toBe(false)
103 expect(isPlainObject(new Date())).toBe(false)
104 expect(isPlainObject(new RegExp())).toBe(false)
105 expect(isPlainObject(new Error())).toBe(false)
106 expect(isPlainObject(new Map())).toBe(false)
107 expect(isPlainObject(new Set())).toBe(false)
108 expect(isPlainObject(new WeakMap())).toBe(false)
109 expect(isPlainObject(new WeakSet())).toBe(false)
110 expect(isPlainObject(new Int8Array())).toBe(false)
111 expect(isPlainObject(new Uint8Array())).toBe(false)
112 expect(isPlainObject(new Uint8ClampedArray())).toBe(false)
113 expect(isPlainObject(new Int16Array())).toBe(false)
114 expect(isPlainObject(new Uint16Array())).toBe(false)
115 expect(isPlainObject(new Int32Array())).toBe(false)
116 expect(isPlainObject(new Uint32Array())).toBe(false)
117 expect(isPlainObject(new Float32Array())).toBe(false)
118 expect(isPlainObject(new Float64Array())).toBe(false)
119 expect(isPlainObject(new BigInt64Array())).toBe(false)
120 expect(isPlainObject(new BigUint64Array())).toBe(false)
121 expect(isPlainObject(new Promise(() => {}))).toBe(false)
122 expect(isPlainObject(new WeakRef({}))).toBe(false)
123 expect(isPlainObject(new FinalizationRegistry(() => {}))).toBe(false)
124 expect(isPlainObject(new ArrayBuffer())).toBe(false)
125 expect(isPlainObject(new SharedArrayBuffer())).toBe(false)
126 expect(isPlainObject(new DataView(new ArrayBuffer()))).toBe(false)
127 expect(isPlainObject({})).toBe(true)
128 expect(isPlainObject({ a: 1 })).toBe(true)
129 })
47aacbaa
JB
130
131 it('Verify isKillBehavior() behavior', () => {
132 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.SOFT)).toBe(true)
133 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.HARD)).toBe(false)
134 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.HARD)).toBe(true)
135 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.SOFT)).toBe(false)
136 expect(isKillBehavior(KillBehaviors.SOFT)).toBe(false)
137 expect(isKillBehavior(KillBehaviors.HARD)).toBe(false)
138 expect(isKillBehavior(KillBehaviors.HARD, null)).toBe(false)
78ac1a90 139 expect(isKillBehavior(KillBehaviors.HARD, undefined)).toBe(false)
47aacbaa
JB
140 expect(isKillBehavior(KillBehaviors.SOFT, 'unknown')).toBe(false)
141 })
78ac1a90
JB
142
143 it('Verify isAsyncFunction() behavior', () => {
144 expect(isAsyncFunction(null)).toBe(false)
145 expect(isAsyncFunction(undefined)).toBe(false)
146 expect(isAsyncFunction(true)).toBe(false)
147 expect(isAsyncFunction(false)).toBe(false)
148 expect(isAsyncFunction(0)).toBe(false)
149 expect(isAsyncFunction('')).toBe(false)
150 expect(isAsyncFunction([])).toBe(false)
151 expect(isAsyncFunction(new Date())).toBe(false)
152 expect(isAsyncFunction(new RegExp())).toBe(false)
153 expect(isAsyncFunction(new Error())).toBe(false)
154 expect(isAsyncFunction(new Map())).toBe(false)
155 expect(isAsyncFunction(new Set())).toBe(false)
156 expect(isAsyncFunction(new WeakMap())).toBe(false)
157 expect(isAsyncFunction(new WeakSet())).toBe(false)
158 expect(isAsyncFunction(new Int8Array())).toBe(false)
159 expect(isAsyncFunction(new Uint8Array())).toBe(false)
160 expect(isAsyncFunction(new Uint8ClampedArray())).toBe(false)
161 expect(isAsyncFunction(new Int16Array())).toBe(false)
162 expect(isAsyncFunction(new Uint16Array())).toBe(false)
163 expect(isAsyncFunction(new Int32Array())).toBe(false)
164 expect(isAsyncFunction(new Uint32Array())).toBe(false)
165 expect(isAsyncFunction(new Float32Array())).toBe(false)
166 expect(isAsyncFunction(new Float64Array())).toBe(false)
167 expect(isAsyncFunction(new BigInt64Array())).toBe(false)
168 expect(isAsyncFunction(new BigUint64Array())).toBe(false)
169 expect(isAsyncFunction(new Promise(() => {}))).toBe(false)
170 expect(isAsyncFunction(new WeakRef({}))).toBe(false)
171 expect(isAsyncFunction(new FinalizationRegistry(() => {}))).toBe(false)
172 expect(isAsyncFunction(new ArrayBuffer())).toBe(false)
173 expect(isAsyncFunction(new SharedArrayBuffer())).toBe(false)
174 expect(isAsyncFunction(new DataView(new ArrayBuffer()))).toBe(false)
175 expect(isAsyncFunction({})).toBe(false)
176 expect(isAsyncFunction({ a: 1 })).toBe(false)
177 expect(isAsyncFunction(() => {})).toBe(false)
178 expect(isAsyncFunction(function () {})).toBe(false)
179 expect(isAsyncFunction(function named () {})).toBe(false)
180 expect(isAsyncFunction(async () => {})).toBe(true)
181 expect(isAsyncFunction(async function () {})).toBe(true)
182 expect(isAsyncFunction(async function named () {})).toBe(true)
183 })
a91f7b35
JB
184
185 it('Verify updateMeasurementStatistics() behavior', () => {
997bbcba
JB
186 const measurementStatistics = {
187 history: new CircularArray()
188 }
a91f7b35
JB
189 updateMeasurementStatistics(
190 measurementStatistics,
191 { aggregate: true, average: false, median: false },
dc021bcc 192 0.01
a91f7b35 193 )
997bbcba 194 expect(measurementStatistics).toStrictEqual({
a91f7b35
JB
195 aggregate: 0.01,
196 maximum: 0.01,
997bbcba 197 minimum: 0.01,
dc021bcc 198 history: new CircularArray()
a91f7b35
JB
199 })
200 updateMeasurementStatistics(
201 measurementStatistics,
202 { aggregate: true, average: false, median: false },
dc021bcc 203 0.02
a91f7b35 204 )
997bbcba 205 expect(measurementStatistics).toStrictEqual({
a91f7b35
JB
206 aggregate: 0.03,
207 maximum: 0.02,
997bbcba 208 minimum: 0.01,
dc021bcc 209 history: new CircularArray()
a91f7b35
JB
210 })
211 updateMeasurementStatistics(
212 measurementStatistics,
213 { aggregate: true, average: true, median: false },
dc021bcc 214 0.001
a91f7b35 215 )
997bbcba 216 expect(measurementStatistics).toStrictEqual({
a91f7b35
JB
217 aggregate: 0.031,
218 maximum: 0.02,
219 minimum: 0.001,
dc021bcc
JB
220 average: 0.001,
221 history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001)
222 })
223 updateMeasurementStatistics(
224 measurementStatistics,
225 { aggregate: true, average: true, median: false },
226 0.003
227 )
228 expect(measurementStatistics).toStrictEqual({
229 aggregate: 0.034,
230 maximum: 0.02,
231 minimum: 0.001,
232 average: 0.002,
233 history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001, 0.003)
a91f7b35 234 })
bdb9d712
JB
235 updateMeasurementStatistics(
236 measurementStatistics,
237 { aggregate: true, average: false, median: true },
238 0.006
239 )
240 expect(measurementStatistics).toStrictEqual({
241 aggregate: 0.04,
242 maximum: 0.02,
243 minimum: 0.001,
244 median: 0.003,
245 history: new CircularArray(
246 DEFAULT_CIRCULAR_ARRAY_SIZE,
247 0.001,
248 0.003,
249 0.006
250 )
251 })
252 updateMeasurementStatistics(
253 measurementStatistics,
254 { aggregate: true, average: true, median: false },
255 0.01
256 )
257 expect(measurementStatistics).toStrictEqual({
258 aggregate: 0.05,
259 maximum: 0.02,
260 minimum: 0.001,
261 average: 0.005,
262 history: new CircularArray(
263 DEFAULT_CIRCULAR_ARRAY_SIZE,
264 0.001,
265 0.003,
266 0.006,
267 0.01
268 )
269 })
a91f7b35 270 })
970b38d6
JB
271
272 it('Verify secureRandom() behavior', () => {
273 const randomNumber = secureRandom()
274 expect(typeof randomNumber === 'number').toBe(true)
275 expect(randomNumber).toBeGreaterThanOrEqual(0)
276 expect(randomNumber).toBeLessThan(1)
277 })
aba955e1 278})