build(deps-dev): apply updates
[poolifier.git] / tests / pools / utils.test.mjs
1 import cluster, { Worker as ClusterWorker } from 'node:cluster'
2 import { Worker as ThreadWorker } from 'node:worker_threads'
3
4 import { expect } from 'expect'
5
6 import {
7 CircularArray,
8 DEFAULT_CIRCULAR_ARRAY_SIZE
9 } from '../../lib/circular-array.cjs'
10 import {
11 FixedClusterPool,
12 FixedThreadPool,
13 WorkerTypes
14 } from '../../lib/index.cjs'
15 import {
16 buildWorkerChoiceStrategyOptions,
17 createWorker,
18 DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
19 getDefaultTasksQueueOptions,
20 getWorkerChoiceStrategyRetries,
21 getWorkerId,
22 getWorkerType,
23 updateMeasurementStatistics
24 } from '../../lib/pools/utils.cjs'
25
26 describe('Pool utils test suite', () => {
27 it('Verify DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS values', () => {
28 expect(DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS).toStrictEqual({
29 aggregate: false,
30 average: false,
31 median: false
32 })
33 })
34
35 it('Verify getDefaultTasksQueueOptions() behavior', () => {
36 const poolMaxSize = 4
37 expect(getDefaultTasksQueueOptions(poolMaxSize)).toStrictEqual({
38 concurrency: 1,
39 size: Math.pow(poolMaxSize, 2),
40 taskStealing: true,
41 tasksStealingOnBackPressure: true,
42 tasksFinishedTimeout: 2000
43 })
44 })
45
46 it('Verify getWorkerChoiceStrategyRetries() behavior', async () => {
47 const numberOfThreads = 4
48 const pool = new FixedThreadPool(
49 numberOfThreads,
50 './tests/worker-files/thread/testWorker.mjs'
51 )
52 expect(getWorkerChoiceStrategyRetries(pool)).toBe(pool.info.maxSize * 2)
53 const workerChoiceStrategyOptions = {
54 runTime: { median: true },
55 waitTime: { median: true },
56 elu: { median: true },
57 weights: {
58 0: 100,
59 1: 100
60 }
61 }
62 expect(
63 getWorkerChoiceStrategyRetries(pool, workerChoiceStrategyOptions)
64 ).toBe(
65 pool.info.maxSize +
66 Object.keys(workerChoiceStrategyOptions.weights).length
67 )
68 await pool.destroy()
69 })
70
71 it('Verify buildWorkerChoiceStrategyOptions() behavior', async () => {
72 const numberOfWorkers = 4
73 const pool = new FixedClusterPool(
74 numberOfWorkers,
75 './tests/worker-files/cluster/testWorker.cjs'
76 )
77 expect(buildWorkerChoiceStrategyOptions(pool)).toStrictEqual({
78 runTime: { median: false },
79 waitTime: { median: false },
80 elu: { median: false },
81 weights: expect.objectContaining({
82 0: expect.any(Number),
83 [pool.info.maxSize - 1]: expect.any(Number)
84 })
85 })
86 const workerChoiceStrategyOptions = {
87 runTime: { median: true },
88 waitTime: { median: true },
89 elu: { median: true },
90 weights: {
91 0: 100,
92 1: 100
93 }
94 }
95 expect(
96 buildWorkerChoiceStrategyOptions(pool, workerChoiceStrategyOptions)
97 ).toStrictEqual(workerChoiceStrategyOptions)
98 await pool.destroy()
99 })
100
101 it('Verify updateMeasurementStatistics() behavior', () => {
102 const measurementStatistics = {
103 history: new CircularArray()
104 }
105 updateMeasurementStatistics(
106 measurementStatistics,
107 { aggregate: true, average: false, median: false },
108 0.01
109 )
110 expect(measurementStatistics).toStrictEqual({
111 aggregate: 0.01,
112 maximum: 0.01,
113 minimum: 0.01,
114 history: new CircularArray()
115 })
116 updateMeasurementStatistics(
117 measurementStatistics,
118 { aggregate: true, average: false, median: false },
119 0.02
120 )
121 expect(measurementStatistics).toStrictEqual({
122 aggregate: 0.03,
123 maximum: 0.02,
124 minimum: 0.01,
125 history: new CircularArray()
126 })
127 updateMeasurementStatistics(
128 measurementStatistics,
129 { aggregate: true, average: true, median: false },
130 0.001
131 )
132 expect(measurementStatistics).toStrictEqual({
133 aggregate: 0.031,
134 maximum: 0.02,
135 minimum: 0.001,
136 average: 0.001,
137 history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001)
138 })
139 updateMeasurementStatistics(
140 measurementStatistics,
141 { aggregate: true, average: true, median: false },
142 0.003
143 )
144 expect(measurementStatistics).toStrictEqual({
145 aggregate: 0.034,
146 maximum: 0.02,
147 minimum: 0.001,
148 average: 0.002,
149 history: new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, 0.001, 0.003)
150 })
151 updateMeasurementStatistics(
152 measurementStatistics,
153 { aggregate: true, average: false, median: true },
154 0.006
155 )
156 expect(measurementStatistics).toStrictEqual({
157 aggregate: 0.04,
158 maximum: 0.02,
159 minimum: 0.001,
160 median: 0.003,
161 history: new CircularArray(
162 DEFAULT_CIRCULAR_ARRAY_SIZE,
163 0.001,
164 0.003,
165 0.006
166 )
167 })
168 updateMeasurementStatistics(
169 measurementStatistics,
170 { aggregate: true, average: true, median: false },
171 0.01
172 )
173 expect(measurementStatistics).toStrictEqual({
174 aggregate: 0.05,
175 maximum: 0.02,
176 minimum: 0.001,
177 average: 0.005,
178 history: new CircularArray(
179 DEFAULT_CIRCULAR_ARRAY_SIZE,
180 0.001,
181 0.003,
182 0.006,
183 0.01
184 )
185 })
186 })
187
188 it('Verify createWorker() behavior', () => {
189 expect(
190 createWorker(
191 WorkerTypes.thread,
192 './tests/worker-files/thread/testWorker.mjs',
193 {}
194 )
195 ).toBeInstanceOf(ThreadWorker)
196 expect(
197 createWorker(
198 WorkerTypes.cluster,
199 './tests/worker-files/cluster/testWorker.mjs',
200 {}
201 )
202 ).toBeInstanceOf(ClusterWorker)
203 })
204
205 it('Verify getWorkerType() behavior', () => {
206 expect(
207 getWorkerType(
208 new ThreadWorker('./tests/worker-files/thread/testWorker.mjs')
209 )
210 ).toBe(WorkerTypes.thread)
211 expect(getWorkerType(cluster.fork())).toBe(WorkerTypes.cluster)
212 })
213
214 it('Verify getWorkerId() behavior', () => {
215 const threadWorker = new ThreadWorker(
216 './tests/worker-files/thread/testWorker.mjs'
217 )
218 const clusterWorker = cluster.fork()
219 expect(getWorkerId(threadWorker)).toBe(threadWorker.threadId)
220 expect(getWorkerId(clusterWorker)).toBe(clusterWorker.id)
221 })
222 })