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