refactor: move worker choice instance helper into the context class
[poolifier.git] / tests / pools / selection-strategies / worker-choice-strategy-context.test.js
1 const { expect } = require('expect')
2 const sinon = require('sinon')
3 const {
4 FixedThreadPool,
5 DynamicThreadPool,
6 WorkerChoiceStrategies
7 } = require('../../../lib/index')
8 const {
9 WorkerChoiceStrategyContext
10 } = require('../../../lib/pools/selection-strategies/worker-choice-strategy-context')
11 const {
12 RoundRobinWorkerChoiceStrategy
13 } = require('../../../lib/pools/selection-strategies/round-robin-worker-choice-strategy')
14 const {
15 LessUsedWorkerChoiceStrategy
16 } = require('../../../lib/pools/selection-strategies/less-used-worker-choice-strategy')
17 const {
18 LessBusyWorkerChoiceStrategy
19 } = require('../../../lib/pools/selection-strategies/less-busy-worker-choice-strategy')
20 const {
21 FairShareWorkerChoiceStrategy
22 } = require('../../../lib/pools/selection-strategies/fair-share-worker-choice-strategy')
23 const {
24 WeightedRoundRobinWorkerChoiceStrategy
25 } = require('../../../lib/pools/selection-strategies/weighted-round-robin-worker-choice-strategy')
26
27 describe('Worker choice strategy context test suite', () => {
28 const min = 1
29 const max = 3
30 let fixedPool, dynamicPool
31
32 before(() => {
33 fixedPool = new FixedThreadPool(
34 max,
35 './tests/worker-files/thread/testWorker.js'
36 )
37 dynamicPool = new DynamicThreadPool(
38 min,
39 max,
40 './tests/worker-files/thread/testWorker.js'
41 )
42 })
43
44 afterEach(() => {
45 sinon.restore()
46 })
47
48 after(async () => {
49 await fixedPool.destroy()
50 await dynamicPool.destroy()
51 })
52
53 it('Verify that execute() return the worker chosen by the strategy with fixed pool', () => {
54 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
55 fixedPool
56 )
57 const WorkerChoiceStrategyStub = sinon.createStubInstance(
58 RoundRobinWorkerChoiceStrategy,
59 {
60 choose: sinon.stub().returns(0)
61 }
62 )
63 workerChoiceStrategyContext.workerChoiceStrategy = WorkerChoiceStrategyStub
64 const chosenWorkerKey = workerChoiceStrategyContext.execute()
65 expect(
66 workerChoiceStrategyContext.workerChoiceStrategy.choose.calledOnce
67 ).toBe(true)
68 expect(chosenWorkerKey).toBe(0)
69 })
70
71 it('Verify that execute() return the worker chosen by the strategy with dynamic pool', () => {
72 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
73 dynamicPool
74 )
75 const WorkerChoiceStrategyStub = sinon.createStubInstance(
76 RoundRobinWorkerChoiceStrategy,
77 {
78 choose: sinon.stub().returns(0)
79 }
80 )
81 workerChoiceStrategyContext.workerChoiceStrategy = WorkerChoiceStrategyStub
82 const chosenWorkerKey = workerChoiceStrategyContext.execute()
83 expect(
84 workerChoiceStrategyContext.workerChoiceStrategy.choose.calledOnce
85 ).toBe(true)
86 expect(chosenWorkerKey).toBe(0)
87 })
88
89 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and fixed pool', () => {
90 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
91 fixedPool
92 )
93 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
94 RoundRobinWorkerChoiceStrategy
95 )
96 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
97 WorkerChoiceStrategies.ROUND_ROBIN
98 )
99 workerChoiceStrategyContext.setWorkerChoiceStrategy(
100 fixedPool,
101 WorkerChoiceStrategies.ROUND_ROBIN
102 )
103 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
104 RoundRobinWorkerChoiceStrategy
105 )
106 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
107 WorkerChoiceStrategies.ROUND_ROBIN
108 )
109 })
110
111 it('Verify that setWorkerChoiceStrategy() works with ROUND_ROBIN and dynamic pool', () => {
112 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
113 dynamicPool
114 )
115 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
116 RoundRobinWorkerChoiceStrategy
117 )
118 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
119 WorkerChoiceStrategies.ROUND_ROBIN
120 )
121 workerChoiceStrategyContext.setWorkerChoiceStrategy(
122 dynamicPool,
123 WorkerChoiceStrategies.ROUND_ROBIN
124 )
125 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
126 RoundRobinWorkerChoiceStrategy
127 )
128 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
129 WorkerChoiceStrategies.ROUND_ROBIN
130 )
131 })
132
133 it('Verify that setWorkerChoiceStrategy() works with LESS_USED and fixed pool', () => {
134 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
135 fixedPool
136 )
137 workerChoiceStrategyContext.setWorkerChoiceStrategy(
138 fixedPool,
139 WorkerChoiceStrategies.LESS_USED
140 )
141 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
142 LessUsedWorkerChoiceStrategy
143 )
144 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
145 WorkerChoiceStrategies.LESS_USED
146 )
147 })
148
149 it('Verify that setWorkerChoiceStrategy() works with LESS_USED and dynamic pool', () => {
150 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
151 dynamicPool
152 )
153 workerChoiceStrategyContext.setWorkerChoiceStrategy(
154 dynamicPool,
155 WorkerChoiceStrategies.LESS_USED
156 )
157 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
158 LessUsedWorkerChoiceStrategy
159 )
160 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
161 WorkerChoiceStrategies.LESS_USED
162 )
163 })
164
165 it('Verify that setWorkerChoiceStrategy() works with LESS_BUSY and fixed pool', () => {
166 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
167 fixedPool
168 )
169 workerChoiceStrategyContext.setWorkerChoiceStrategy(
170 fixedPool,
171 WorkerChoiceStrategies.LESS_BUSY
172 )
173 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
174 LessBusyWorkerChoiceStrategy
175 )
176 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
177 WorkerChoiceStrategies.LESS_BUSY
178 )
179 })
180
181 it('Verify that setWorkerChoiceStrategy() works with LESS_BUSY and dynamic pool', () => {
182 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
183 dynamicPool
184 )
185 workerChoiceStrategyContext.setWorkerChoiceStrategy(
186 dynamicPool,
187 WorkerChoiceStrategies.LESS_BUSY
188 )
189 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
190 LessBusyWorkerChoiceStrategy
191 )
192 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
193 WorkerChoiceStrategies.LESS_BUSY
194 )
195 })
196
197 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and fixed pool', () => {
198 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
199 fixedPool
200 )
201 workerChoiceStrategyContext.setWorkerChoiceStrategy(
202 fixedPool,
203 WorkerChoiceStrategies.FAIR_SHARE
204 )
205 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
206 FairShareWorkerChoiceStrategy
207 )
208 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
209 WorkerChoiceStrategies.FAIR_SHARE
210 )
211 })
212
213 it('Verify that setWorkerChoiceStrategy() works with FAIR_SHARE and dynamic pool', () => {
214 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
215 dynamicPool
216 )
217 workerChoiceStrategyContext.setWorkerChoiceStrategy(
218 dynamicPool,
219 WorkerChoiceStrategies.FAIR_SHARE
220 )
221 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
222 FairShareWorkerChoiceStrategy
223 )
224 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
225 WorkerChoiceStrategies.FAIR_SHARE
226 )
227 })
228
229 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and fixed pool', () => {
230 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
231 fixedPool
232 )
233 workerChoiceStrategyContext.setWorkerChoiceStrategy(
234 fixedPool,
235 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
236 )
237 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
238 WeightedRoundRobinWorkerChoiceStrategy
239 )
240 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
241 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
242 )
243 })
244
245 it('Verify that setWorkerChoiceStrategy() works with WEIGHTED_ROUND_ROBIN and dynamic pool', () => {
246 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
247 dynamicPool
248 )
249 workerChoiceStrategyContext.setWorkerChoiceStrategy(
250 dynamicPool,
251 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
252 )
253 expect(workerChoiceStrategyContext.workerChoiceStrategy).toBeInstanceOf(
254 WeightedRoundRobinWorkerChoiceStrategy
255 )
256 expect(workerChoiceStrategyContext.workerChoiceStrategyType).toBe(
257 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
258 )
259 })
260
261 it('Verify that getWorkerChoiceStrategy() default return ROUND_ROBIN strategy', () => {
262 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
263 fixedPool
264 )
265 const strategy =
266 workerChoiceStrategyContext.getWorkerChoiceStrategy(fixedPool)
267 expect(strategy).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
268 })
269
270 it('Verify that getWorkerChoiceStrategy() can return ROUND_ROBIN strategy', () => {
271 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
272 fixedPool
273 )
274 const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy(
275 fixedPool,
276 WorkerChoiceStrategies.ROUND_ROBIN
277 )
278 expect(strategy).toBeInstanceOf(RoundRobinWorkerChoiceStrategy)
279 })
280
281 it('Verify that getWorkerChoiceStrategy() can return LESS_USED strategy', () => {
282 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
283 fixedPool
284 )
285 const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy(
286 fixedPool,
287 WorkerChoiceStrategies.LESS_USED
288 )
289 expect(strategy).toBeInstanceOf(LessUsedWorkerChoiceStrategy)
290 })
291
292 it('Verify that getWorkerChoiceStrategy() can return LESS_BUSY strategy', () => {
293 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
294 fixedPool
295 )
296 const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy(
297 fixedPool,
298 WorkerChoiceStrategies.LESS_BUSY
299 )
300 expect(strategy).toBeInstanceOf(LessBusyWorkerChoiceStrategy)
301 })
302
303 it('Verify that getWorkerChoiceStrategy() can return FAIR_SHARE strategy', () => {
304 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
305 fixedPool
306 )
307 const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy(
308 fixedPool,
309 WorkerChoiceStrategies.FAIR_SHARE
310 )
311 expect(strategy).toBeInstanceOf(FairShareWorkerChoiceStrategy)
312 })
313
314 it('Verify that getWorkerChoiceStrategy() can return WEIGHTED_ROUND_ROBIN strategy', () => {
315 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
316 fixedPool
317 )
318 const strategy = workerChoiceStrategyContext.getWorkerChoiceStrategy(
319 fixedPool,
320 WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN
321 )
322 expect(strategy).toBeInstanceOf(WeightedRoundRobinWorkerChoiceStrategy)
323 })
324
325 it('Verify that getWorkerChoiceStrategy() throw error on unknown strategy', () => {
326 const workerChoiceStrategyContext = new WorkerChoiceStrategyContext(
327 fixedPool
328 )
329 expect(() => {
330 workerChoiceStrategyContext.getWorkerChoiceStrategy(
331 fixedPool,
332 'UNKNOWN_STRATEGY'
333 )
334 }).toThrowError(
335 new Error("Worker choice strategy 'UNKNOWN_STRATEGY' not found")
336 )
337 })
338 })