File size: 2,790 Bytes
25d91a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Verifies CPU-derived and configured agent runtime limits.
import os from "node:os";
import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures";
import { afterEach, describe, expect, it, vi } from "vitest";

async function importFreshAgentLimits(scope: string): Promise<typeof import("./agent-limits.js")> {
  return importFreshModule(import.meta.url, `./agent-limits.js?scope=${scope}`);
}

describe("resolveAgentMaxConcurrent", () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it.each([
    { availableParallelism: 1, expected: 8 },
    { availableParallelism: 2, expected: 8 },
    { availableParallelism: 8, expected: 32 },
    { availableParallelism: 12, expected: 48 },
    { availableParallelism: 48, expected: 192 },
  ])(
    "derives the default from $availableParallelism available CPUs",
    async ({ availableParallelism, expected }) => {
      const availableParallelismSpy = vi
        .spyOn(os, "availableParallelism")
        .mockReturnValue(availableParallelism);
      const runtime = await importFreshAgentLimits(`parallelism-${availableParallelism}`);

      expect(runtime.resolveAgentMaxConcurrent()).toBe(expected);
      expect(runtime.resolveAgentMaxConcurrent()).toBe(expected);
      expect(availableParallelismSpy).toHaveBeenCalledOnce();
    },
  );

  it("falls back to the CPU list when availableParallelism is unavailable", async () => {
    const availableParallelismDescriptor = Object.getOwnPropertyDescriptor(
      os,
      "availableParallelism",
    );
    if (!availableParallelismDescriptor) {
      throw new Error("expected node:os.availableParallelism descriptor");
    }
    const cpu = {
      model: "test",
      speed: 0,
      times: { user: 0, nice: 0, sys: 0, idle: 0, irq: 0 },
    };
    const cpusSpy = vi.spyOn(os, "cpus").mockReturnValue(Array.from({ length: 6 }, () => cpu));
    Object.defineProperty(os, "availableParallelism", {
      ...availableParallelismDescriptor,
      value: undefined,
    });

    try {
      const runtime = await importFreshAgentLimits("cpus-fallback");
      expect(runtime.resolveAgentMaxConcurrent()).toBe(24);
      expect(cpusSpy).toHaveBeenCalledOnce();
    } finally {
      Object.defineProperty(os, "availableParallelism", availableParallelismDescriptor);
    }
  });

  it.each([3, 256])(
    "uses an explicit limit of %i without resolving the CPU default",
    async (limit) => {
      const availableParallelismSpy = vi.spyOn(os, "availableParallelism").mockReturnValue(48);
      const runtime = await importFreshAgentLimits("explicit-override");

      expect(
        runtime.resolveAgentMaxConcurrent({ agents: { defaults: { maxConcurrent: limit } } }),
      ).toBe(limit);
      expect(availableParallelismSpy).not.toHaveBeenCalled();
    },
  );
});