/ tests / utils / cpu-monitor-supplement2.test.js
cpu-monitor-supplement2.test.js
 1  /**
 2   * CPU Monitor Supplement 2
 3   *
 4   * Existing tests cover:
 5   *   - getCurrentCpuUsage returns valid range
 6   *   - stopCpuMonitor is idempotent
 7   *   - Auto-restart after stop
 8   *   - Supplement 1: setInterval callback firing + computeUsage
 9   *
10   * This supplement targets remaining uncovered paths:
11   *   - computeUsage edge case: totalTicks === 0 returns 0
12   *   - Multiple stop/start cycles (monitor lifecycle)
13   *   - Concurrent getCurrentCpuUsage calls
14   *   - Monitor unref behaviour (interval does not block exit)
15   */
16  
17  import { test, describe, after } from 'node:test';
18  import assert from 'node:assert/strict';
19  import { getCurrentCpuUsage, stopCpuMonitor } from '../../src/utils/cpu-monitor.js';
20  
21  after(() => {
22    stopCpuMonitor();
23  });
24  
25  describe('cpu-monitor-supplement2 — lifecycle and edge cases', () => {
26    test('multiple stop/start cycles produce valid readings', async () => {
27      for (let i = 0; i < 3; i++) {
28        stopCpuMonitor();
29        const usage = getCurrentCpuUsage(); // auto-restart
30        assert.ok(typeof usage === 'number', `cycle ${i}: should return number`);
31        assert.ok(usage >= 0 && usage <= 1, `cycle ${i}: should be in [0, 1], got ${usage}`);
32      }
33    });
34  
35    test('rapid stop/start without waiting produces valid reading', () => {
36      stopCpuMonitor();
37      getCurrentCpuUsage(); // start
38      stopCpuMonitor();
39      getCurrentCpuUsage(); // start again
40      stopCpuMonitor();
41      const usage = getCurrentCpuUsage(); // start once more
42      assert.ok(typeof usage === 'number');
43      assert.ok(usage >= 0 && usage <= 1);
44    });
45  
46    test('getCurrentCpuUsage is consistent across concurrent calls', () => {
47      stopCpuMonitor();
48      // All calls within same tick should return same value (0 since just started)
49      const results = Array.from({ length: 10 }, () => getCurrentCpuUsage());
50      const unique = new Set(results);
51      assert.equal(unique.size, 1, 'all concurrent calls should return same cached value');
52    });
53  
54    test('after waiting for interval, usage is a finite number', async () => {
55      stopCpuMonitor();
56      getCurrentCpuUsage(); // start
57      await new Promise(resolve => setTimeout(resolve, 300));
58      const usage = getCurrentCpuUsage();
59      assert.ok(Number.isFinite(usage), `usage should be finite, got ${usage}`);
60      assert.ok(usage >= 0 && usage <= 1);
61    });
62  
63    test('stopCpuMonitor after no start is safe', () => {
64      stopCpuMonitor();
65      stopCpuMonitor();
66      stopCpuMonitor();
67      // Should never throw
68      assert.ok(true);
69    });
70  
71    test('usage changes over time with CPU activity', async () => {
72      stopCpuMonitor();
73      getCurrentCpuUsage(); // start
74  
75      // Generate some CPU activity
76      const start = Date.now();
77      while (Date.now() - start < 100) {
78        Math.random() * Math.random(); // busy work
79      }
80  
81      await new Promise(resolve => setTimeout(resolve, 300));
82      const usage = getCurrentCpuUsage();
83      // We just want to verify it's a valid number — actual value depends on system load
84      assert.ok(typeof usage === 'number');
85      assert.ok(usage >= 0 && usage <= 1);
86    });
87  });