UNPKG

judoscale-node-core

Version:

Core dependencies for NodeJS adapters for the JudoScale autoscaling add-on for Heroku

135 lines (107 loc) 5.21 kB
/* global test, expect, describe, jest */ // Mock to return our controlled monotonic time const mockMonotonicTime = jest.fn() jest.mock('process', () => { return { ...jest.requireActual('process'), hrtime: { bigint: mockMonotonicTime } } }) const UtilizationTracker = require('../src/utilization-tracker') describe('UtilizationTracker', () => { // after { reset_tracker_state } test('tracks utilization percentage based on time spent with no active requests', () => { // T=0: Start tracker // T=1: Request 1 starts -> total_idle_time=1 // T=2: Request 1 ends -> total_idle_time=1 // T=4: Request 2 starts -> total_idle_time=3 (1 + 2) // T=5: Request 3 starts -> total_idle_time=3 // T=6: Request 2 ends -> total_idle_time=3 // T=8: Request 3 ends -> total_idle_time=3 // T=10: Report cycle -> total_idle_time=5 (3 + 2), utilization_pct=50 const tracker = new UtilizationTracker() // T=0: Tracker starts mockMonotonicTime.mockReturnValue(0n) tracker.start() expect(tracker.utilizationPct(false)).toBe(100) // No time has passed yet // T=1: Request 1 starts mockMonotonicTime.mockReturnValue(1n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(0) // 1 second idle out of 1 total second = 100% idle // T=2: Request 1 ends mockMonotonicTime.mockReturnValue(2n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(50) // 1 second idle out of 2 total seconds = 50% idle // T=4: Request 2 starts mockMonotonicTime.mockReturnValue(4n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(25) // 3 seconds idle out of 4 total seconds = 75% idle // T=5: Request 3 starts mockMonotonicTime.mockReturnValue(5n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(40) // 3 seconds idle out of 5 total seconds = 60% idle // T=6: Request 2 ends mockMonotonicTime.mockReturnValue(6n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(50) // 3 seconds idle out of 6 total seconds = 50% idle // T=8: Request 3 ends mockMonotonicTime.mockReturnValue(8n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(62) // 3 seconds idle out of 8 total seconds = 37.5% idle // T=10: Report cycle - should calculate final utilization percentage mockMonotonicTime.mockReturnValue(10n) expect(tracker.utilizationPct()).toBe(50) // 5 seconds idle out of 10 total seconds = 50% idle }) test('resets the tracking cycle when utilization_pct is requested with no args', () => { // T=0: Start tracker // T=1: Request 1 starts -> total_idle_time=1 // T=2: Request 1 ends -> total_idle_time=1 // T=4: Report cycle -> total_idle_time=3 (1 + 2), utilization_pct=25 // T=5: Request 2 starts -> total_idle_time=1 // T=8: Report cycle -> total_idle_time=1 (request still running), utilization_pct=75 // T=9: Request 3 starts -> total_idle_time=0 // T=10: Request 2 ends -> total_idle_time=0 // T=11: Request 3 ends -> total_idle_time=0 // T=12: Report cycle -> total_idle_time=1, utilization_pct=75 const tracker = new UtilizationTracker() // T=0: Tracker starts mockMonotonicTime.mockReturnValue(0n) tracker.start() expect(tracker.utilizationPct(false)).toBe(100) // No time has passed yet // T=1: Request 1 starts mockMonotonicTime.mockReturnValue(1n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(0) // 1 second idle out of 1 total second = 100% idle // T=2: Request 1 ends mockMonotonicTime.mockReturnValue(2n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(50) // 1 second idle out of 2 total seconds = 50% idle mockMonotonicTime.mockReturnValue(3n) expect(tracker.utilizationPct(false)).toBe(33) // 2 seconds idle out of 3 total seconds = 66.66% idle // T=4: Report cycle mockMonotonicTime.mockReturnValue(4n) expect(tracker.utilizationPct()).toBe(25) // 3 seconds idle out of 4 total seconds = 75% idle // T=5: Request 2 starts mockMonotonicTime.mockReturnValue(5n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(0) // 1 second idle out of 1 total second = 100% idle // T=8: Report cycle mockMonotonicTime.mockReturnValue(8n) expect(tracker.utilizationPct()).toBe(75) // 1 second idle out of 4 total seconds = 25% idle // T=9: Request 3 starts mockMonotonicTime.mockReturnValue(9n) tracker.incr() expect(tracker.utilizationPct(false)).toBe(100) // 0 seconds idle out of 1 total second = 0% idle // T=10: Request 2 ends mockMonotonicTime.mockReturnValue(10n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(100) // 0 seconds idle out of 2 total second = 0% idle // T=11: Request 3 ends mockMonotonicTime.mockReturnValue(11n) tracker.decr() expect(tracker.utilizationPct(false)).toBe(100) // 0 seconds idle out of 3 total second = 0% idle // T=12: Report cycle mockMonotonicTime.mockReturnValue(12n) expect(tracker.utilizationPct()).toBe(75) // 1 second idle out of 4 total seconds = 25% idle }) })