@serverkgg/bridge 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/rules/package.md +60 -0
- package/src/blog/articleFrontmatter.test.ts +10 -10
- package/src/blog/compile.test.ts +9 -9
- package/src/bot/botDeploy.test.ts +16 -16
- package/src/bot/botEnvironment.test.ts +8 -8
- package/src/bot/botIdentity.test.ts +12 -12
- package/src/bot/botPanel.test.ts +41 -11
- package/src/bot/botPanel.ts +13 -5
- package/src/bot/botState.test.ts +3 -3
- package/src/bot/botTerminal.test.ts +5 -5
- package/src/bot/botVariables.test.ts +8 -8
- package/src/bot/detect/botToken.test.ts +6 -6
- package/src/bot/detect/detect.test.ts +21 -21
- package/src/bot/detect/detectTable.test.ts +5 -5
- package/src/bot/detect/envExample.test.ts +2 -2
- package/src/bot/detect/envScan.test.ts +4 -4
- package/src/bot/detect/inferBotPlatform.test.ts +4 -4
- package/src/bot/detect/keys.test.ts +3 -3
- package/src/bot/detect/sensitiveKey.test.ts +5 -5
- package/src/bot/detect/serverkJson.test.ts +5 -5
- package/src/catalogs/curseforge.test.ts +35 -35
- package/src/catalogs/thunderstore.test.ts +9 -9
- package/src/cli/detectTable.test.ts +3 -3
- package/src/cli/link.test.ts +11 -11
- package/src/cli/main.ts +8 -0
- package/src/cli/rules.test.ts +198 -0
- package/src/cli/rules.ts +188 -0
- package/src/cli/validate.test.ts +123 -29
- package/src/cli/validate.ts +37 -1
- package/src/codecs/ini.test.ts +13 -13
- package/src/codecs/javaProperties.test.ts +11 -11
- package/src/codecs/sourceCfg.test.ts +14 -14
- package/src/codecs/xmlProperties.test.ts +10 -10
- package/src/context/bridgeContext.ts +6 -1
- package/src/core/bridgeAction.ts +2 -0
- package/src/core/bridgeActivity.ts +9 -0
- package/src/core/bridgeAvailability.ts +10 -0
- package/src/core/bridgePort.test.ts +6 -6
- package/src/core/bridgeUserError.test.ts +13 -3
- package/src/core/bridgeUserError.ts +6 -2
- package/src/core/bridgeValue.test.ts +5 -5
- package/src/core/describeDownloadFailure.test.ts +58 -0
- package/src/core/describeDownloadFailure.ts +69 -0
- package/src/core/index.ts +3 -0
- package/src/guides/markdown.test.ts +31 -31
- package/src/install/installStamp.test.ts +9 -9
- package/src/manifest/extension.ts +36 -0
- package/src/manifest/index.ts +1 -0
- package/src/manifest/manifest.test.ts +208 -90
- package/src/manifest/manifest.ts +34 -0
- package/src/modules/bridge.ts +8 -1
- package/src/modules/bridgeModule.ts +13 -1
- package/src/net/loopback.test.ts +10 -10
- package/src/panel/bridgeDetail.ts +2 -1
- package/src/presence/rosterSync.test.ts +7 -7
- package/src/probes/a2s.test.ts +5 -5
- package/src/probes/minecraftPing.test.ts +17 -17
- package/src/probes/raknetPing.test.ts +13 -13
- package/src/protocol/bridgeActivity.ts +54 -0
- package/src/protocol/bridgeEvents.ts +30 -0
- package/src/protocol/bridgeFrame.ts +10 -1
- package/src/protocol/index.ts +1 -0
- package/src/rcon/rconAccess.test.ts +20 -20
- package/src/rcon/rconAccess.ts +13 -13
- package/src/rcon/rconClient.test.ts +49 -49
- package/src/rcon/rconFrame.test.ts +14 -14
- package/src/rcon/rconIds.test.ts +4 -4
- package/src/rcon/rconWriter.test.ts +6 -6
- package/src/runtime/bridgeActions.ts +19 -2
- package/src/runtime/bridgeActivity.test.ts +318 -0
- package/src/runtime/bridgeActivity.ts +268 -0
- package/src/runtime/bridgeBackupLease.test.ts +9 -9
- package/src/runtime/bridgeConfigReader.test.ts +5 -5
- package/src/runtime/bridgeConsoleHandler.test.ts +8 -8
- package/src/runtime/bridgeContext.test.ts +11 -5
- package/src/runtime/bridgeContext.ts +8 -1
- package/src/runtime/bridgeDriver.test.ts +114 -93
- package/src/runtime/bridgeDriver.ts +10 -7
- package/src/runtime/bridgeEvents.test.ts +15 -15
- package/src/runtime/bridgeFiles.test.ts +54 -54
- package/src/runtime/bridgeInstall.test.ts +10 -10
- package/src/runtime/bridgeLiveConfig.test.ts +6 -6
- package/src/runtime/bridgeLog.ts +10 -0
- package/src/runtime/bridgePending.test.ts +6 -6
- package/src/runtime/bridgeRedaction.test.ts +16 -16
- package/src/runtime/bridgeRefusalError.ts +13 -0
- package/src/runtime/bridgeRegistry.test.ts +1077 -34
- package/src/runtime/bridgeRegistry.ts +464 -65
- package/src/runtime/bridgeScopedContext.ts +55 -0
- package/src/runtime/bridgeServer.test.ts +424 -24
- package/src/runtime/bridgeServer.ts +125 -35
- package/src/runtime/bridgeSetup.test.ts +27 -27
- package/src/runtime/bridgeSetup.ts +1 -1
- package/src/runtime/bridgeSetupHandlers.test.ts +80 -17
- package/src/runtime/bridgeSetupHandlers.ts +45 -10
- package/src/runtime/bridgeSignal.test.ts +7 -7
- package/src/runtime/bridgeSupervisor.test.ts +42 -42
- package/src/runtime/serve.ts +45 -3
- package/src/steam/avatars.test.ts +13 -13
- package/src/steam/steamApp.test.ts +8 -8
- package/src/steam/steamcmd.test.ts +44 -13
- package/src/steam/steamcmd.ts +27 -4
- package/src/steam/steamcmdNarrator.test.ts +4 -4
- package/src/steam/workshop.test.ts +5 -5
- package/src/utils/changedSettingKeys.test.ts +65 -0
- package/src/utils/changedSettingKeys.ts +6 -0
- package/src/utils/describeExecFailure.test.ts +34 -0
- package/src/utils/describeExecFailure.ts +9 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/sameSettingValue.test.ts +35 -0
- package/src/utils/sameSettingValue.ts +40 -0
- package/src/utils/token.test.ts +7 -7
- package/src/wine/protonCommand.test.ts +5 -5
- package/src/wine/wineCommand.test.ts +6 -6
- package/src/wine/winePrefix.test.ts +6 -6
- package/src/wire/activity.test.ts +95 -0
- package/src/wire/activity.ts +41 -0
- package/src/wire/index.ts +1 -0
- package/src/wire/panel.test.ts +91 -25
- package/src/wire/panel.ts +11 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { describe, expect,
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import type { BridgeContext } from "../context";
|
|
4
4
|
import { BridgeKind, BridgeSetupPromptKind, BridgeSetupStepKind, BridgeSetupStepState, BridgeUserError } from "../core";
|
|
5
5
|
import type { BridgeDriver, BridgeSetupModule } from "../modules";
|
|
6
|
-
import type
|
|
6
|
+
import { type BridgeConfig, BridgeEventName, type BridgeSetupRuntime } from "../protocol";
|
|
7
7
|
import { createContext } from "./bridgeContext";
|
|
8
8
|
import type { BridgeLeveledLogger } from "./bridgeLog";
|
|
9
9
|
import { log } from "./bridgeLog";
|
|
@@ -51,6 +51,9 @@ const contextOf = (): BridgeContext => {
|
|
|
51
51
|
onSetup() {
|
|
52
52
|
return;
|
|
53
53
|
},
|
|
54
|
+
onActivity() {
|
|
55
|
+
return;
|
|
56
|
+
},
|
|
54
57
|
async onRestart() {
|
|
55
58
|
return;
|
|
56
59
|
},
|
|
@@ -137,7 +140,7 @@ const setupWith = (submit?: BridgeSetupModule["submit"]): BridgeSetupModule => (
|
|
|
137
140
|
});
|
|
138
141
|
|
|
139
142
|
describe("the setup handlers", () => {
|
|
140
|
-
|
|
143
|
+
it("answer unsupported for a driver that declares no setup", async () => {
|
|
141
144
|
const { logger } = recorder();
|
|
142
145
|
const handlers = createSetupHandlers(driverWith(), logger);
|
|
143
146
|
|
|
@@ -146,13 +149,13 @@ describe("the setup handlers", () => {
|
|
|
146
149
|
runtime: null,
|
|
147
150
|
});
|
|
148
151
|
|
|
149
|
-
expect(await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).toEqual({
|
|
152
|
+
expect((await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).result).toEqual({
|
|
150
153
|
supported: false,
|
|
151
154
|
runtime: null,
|
|
152
155
|
});
|
|
153
156
|
});
|
|
154
157
|
|
|
155
|
-
|
|
158
|
+
it("keep nothing for a driver that declares no setup, whatever it reports", () => {
|
|
156
159
|
const { logger, warnings } = recorder();
|
|
157
160
|
const handlers = createSetupHandlers(driverWith(), logger);
|
|
158
161
|
|
|
@@ -162,7 +165,7 @@ describe("the setup handlers", () => {
|
|
|
162
165
|
expect(warnings).toEqual([]);
|
|
163
166
|
});
|
|
164
167
|
|
|
165
|
-
|
|
168
|
+
it("answer the normalized runtime the driver reported", () => {
|
|
166
169
|
const { logger, warnings } = recorder();
|
|
167
170
|
const handlers = createSetupHandlers(driverWith(setupWith()), logger);
|
|
168
171
|
|
|
@@ -203,17 +206,17 @@ describe("the setup handlers", () => {
|
|
|
203
206
|
]);
|
|
204
207
|
});
|
|
205
208
|
|
|
206
|
-
|
|
209
|
+
it("answer unsupported for a setup that exports no submit", async () => {
|
|
207
210
|
const { logger } = recorder();
|
|
208
211
|
const handlers = createSetupHandlers(driverWith(setupWith()), logger);
|
|
209
212
|
|
|
210
|
-
expect(await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).toEqual({
|
|
213
|
+
expect((await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).result).toEqual({
|
|
211
214
|
supported: false,
|
|
212
215
|
runtime: null,
|
|
213
216
|
});
|
|
214
217
|
});
|
|
215
218
|
|
|
216
|
-
|
|
219
|
+
it("turn a user error into a failed prompt that keeps the previous actions", async () => {
|
|
217
220
|
const { logger, warnings } = recorder();
|
|
218
221
|
|
|
219
222
|
const handlers = createSetupHandlers(
|
|
@@ -227,7 +230,7 @@ describe("the setup handlers", () => {
|
|
|
227
230
|
|
|
228
231
|
handlers.onSetup(signIn());
|
|
229
232
|
|
|
230
|
-
expect(await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).toEqual({
|
|
233
|
+
expect((await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).result).toEqual({
|
|
231
234
|
supported: true,
|
|
232
235
|
runtime: {
|
|
233
236
|
steps: [
|
|
@@ -251,7 +254,66 @@ describe("the setup handlers", () => {
|
|
|
251
254
|
expect(warnings.at(-1)?.message).toBe("setup submit rejected");
|
|
252
255
|
});
|
|
253
256
|
|
|
254
|
-
|
|
257
|
+
it("add one rejected entry built from the user error", async () => {
|
|
258
|
+
const { logger } = recorder();
|
|
259
|
+
|
|
260
|
+
const handlers = createSetupHandlers(
|
|
261
|
+
driverWith(
|
|
262
|
+
setupWith(async () => {
|
|
263
|
+
throw new BridgeUserError({
|
|
264
|
+
ar: "الكود ما عاد ينفع",
|
|
265
|
+
en: "this code cannot be renewed any more",
|
|
266
|
+
});
|
|
267
|
+
}),
|
|
268
|
+
),
|
|
269
|
+
logger,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
handlers.onSetup(signIn());
|
|
273
|
+
|
|
274
|
+
const { activity } = await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {});
|
|
275
|
+
|
|
276
|
+
expect(activity).toEqual([
|
|
277
|
+
{
|
|
278
|
+
name: BridgeEventName.SetupRejected,
|
|
279
|
+
text: {
|
|
280
|
+
ar: "الكود ما عاد ينفع",
|
|
281
|
+
en: "this code cannot be renewed any more",
|
|
282
|
+
},
|
|
283
|
+
details: {
|
|
284
|
+
step: "sign-in",
|
|
285
|
+
action: "renew",
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
]);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("answer what the driver reported while submitting", async () => {
|
|
292
|
+
const { logger } = recorder();
|
|
293
|
+
|
|
294
|
+
const handlers = createSetupHandlers(
|
|
295
|
+
driverWith(
|
|
296
|
+
setupWith(async (context) => {
|
|
297
|
+
context.activity.report({
|
|
298
|
+
name: BridgeEventName.SetupCompleted,
|
|
299
|
+
text: text("signed in"),
|
|
300
|
+
});
|
|
301
|
+
}),
|
|
302
|
+
),
|
|
303
|
+
logger,
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
const { activity } = await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {});
|
|
307
|
+
|
|
308
|
+
expect(activity).toEqual([
|
|
309
|
+
{
|
|
310
|
+
name: BridgeEventName.SetupCompleted,
|
|
311
|
+
text: text("signed in"),
|
|
312
|
+
},
|
|
313
|
+
]);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it("answer the runtime the driver reported while submitting", async () => {
|
|
255
317
|
const { logger } = recorder();
|
|
256
318
|
|
|
257
319
|
const handlers = createSetupHandlers(
|
|
@@ -273,7 +335,7 @@ describe("the setup handlers", () => {
|
|
|
273
335
|
|
|
274
336
|
handlers.onSetup(signIn());
|
|
275
337
|
|
|
276
|
-
expect(await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).toEqual({
|
|
338
|
+
expect((await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {})).result).toEqual({
|
|
277
339
|
supported: true,
|
|
278
340
|
runtime: {
|
|
279
341
|
steps: [
|
|
@@ -287,7 +349,7 @@ describe("the setup handlers", () => {
|
|
|
287
349
|
});
|
|
288
350
|
});
|
|
289
351
|
|
|
290
|
-
|
|
352
|
+
it("let an error the driver cannot explain out", async () => {
|
|
291
353
|
const { logger } = recorder();
|
|
292
354
|
|
|
293
355
|
const handlers = createSetupHandlers(
|
|
@@ -310,7 +372,7 @@ describe("the setup handlers redaction", () => {
|
|
|
310
372
|
|
|
311
373
|
const redact = (value: string) => value.split(SECRET).join("••••");
|
|
312
374
|
|
|
313
|
-
|
|
375
|
+
it("blanks a secret value in the prompt a driver reports", () => {
|
|
314
376
|
const { logger } = recorder();
|
|
315
377
|
const handlers = createSetupHandlers(driverWith(setupWith()), logger, redact);
|
|
316
378
|
|
|
@@ -337,7 +399,7 @@ describe("the setup handlers redaction", () => {
|
|
|
337
399
|
});
|
|
338
400
|
});
|
|
339
401
|
|
|
340
|
-
|
|
402
|
+
it("blanks a secret value in every text of a link prompt", () => {
|
|
341
403
|
const { logger } = recorder();
|
|
342
404
|
const handlers = createSetupHandlers(driverWith(setupWith()), logger, redact);
|
|
343
405
|
const reported = signIn();
|
|
@@ -367,7 +429,7 @@ describe("the setup handlers redaction", () => {
|
|
|
367
429
|
});
|
|
368
430
|
});
|
|
369
431
|
|
|
370
|
-
|
|
432
|
+
it("blanks a secret value in the text of a rejected submit", async () => {
|
|
371
433
|
const { logger } = recorder();
|
|
372
434
|
const handlers = createSetupHandlers(
|
|
373
435
|
driverWith(
|
|
@@ -381,11 +443,12 @@ describe("the setup handlers redaction", () => {
|
|
|
381
443
|
|
|
382
444
|
handlers.onSetup(signIn());
|
|
383
445
|
|
|
384
|
-
const result = await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {});
|
|
446
|
+
const { result, activity } = await handlers.onSetupSubmit(contextOf(), "sign-in", "renew", {});
|
|
385
447
|
|
|
386
448
|
expect(result.runtime?.prompt).toMatchObject({
|
|
387
449
|
kind: BridgeSetupPromptKind.Failed,
|
|
388
450
|
message: text("telegram refused ••••"),
|
|
389
451
|
});
|
|
452
|
+
expect(JSON.stringify(activity)).not.toContain(SECRET);
|
|
390
453
|
});
|
|
391
454
|
});
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import type { BridgeContext } from "../context";
|
|
2
2
|
import { BridgeUserError, type BridgeValues } from "../core";
|
|
3
3
|
import type { BridgeDriver } from "../modules";
|
|
4
|
-
import type
|
|
5
|
-
import type
|
|
6
|
-
import { type
|
|
4
|
+
import { BridgeEventName, type BridgeSetupResult, type BridgeSetupRuntime } from "../protocol";
|
|
5
|
+
import { type ActivityNormalizeOptions, type BridgeActivityAnswer, createActivityScope } from "./bridgeActivity";
|
|
6
|
+
import { type BridgeLeveledLogger, errorDetail } from "./bridgeLog";
|
|
7
|
+
import { type BridgeRedact, redactLocalized, redactSetupRuntime, secretFieldKeys } from "./bridgeRedaction";
|
|
8
|
+
import { scopedContext } from "./bridgeScopedContext";
|
|
7
9
|
import { failedSetup, normalizeSetupRuntime, unsupportedSetup } from "./bridgeSetup";
|
|
8
10
|
|
|
9
11
|
export interface BridgeSetupHandlers {
|
|
10
12
|
onSetup(runtime: BridgeSetupRuntime | null): void;
|
|
11
13
|
onSetupStatus(): BridgeSetupResult;
|
|
12
|
-
onSetupSubmit(
|
|
14
|
+
onSetupSubmit(
|
|
15
|
+
context: BridgeContext,
|
|
16
|
+
step: string,
|
|
17
|
+
action: string,
|
|
18
|
+
args: BridgeValues,
|
|
19
|
+
): Promise<BridgeActivityAnswer<BridgeSetupResult>>;
|
|
13
20
|
current(): BridgeSetupRuntime | null;
|
|
14
21
|
}
|
|
15
22
|
|
|
@@ -22,6 +29,12 @@ export const createSetupHandlers = (
|
|
|
22
29
|
): BridgeSetupHandlers => {
|
|
23
30
|
const declared: ReadonlySet<string> = new Set((driver.setup?.steps ?? []).map((step) => step.id));
|
|
24
31
|
|
|
32
|
+
const activity: ActivityNormalizeOptions = {
|
|
33
|
+
secretKeys: new Set(secretFieldKeys(driver)),
|
|
34
|
+
redact,
|
|
35
|
+
warn: log.warn,
|
|
36
|
+
};
|
|
37
|
+
|
|
25
38
|
let current: BridgeSetupRuntime | null = null;
|
|
26
39
|
|
|
27
40
|
return {
|
|
@@ -53,28 +66,50 @@ export const createSetupHandlers = (
|
|
|
53
66
|
const module = driver.setup;
|
|
54
67
|
|
|
55
68
|
if (!module?.submit) {
|
|
56
|
-
return
|
|
69
|
+
return {
|
|
70
|
+
result: unsupportedSetup(),
|
|
71
|
+
activity: [],
|
|
72
|
+
};
|
|
57
73
|
}
|
|
58
74
|
|
|
75
|
+
const scope = createActivityScope(context.activity, activity);
|
|
76
|
+
|
|
59
77
|
try {
|
|
60
|
-
await module.submit(context, step, action, args);
|
|
78
|
+
await module.submit(scopedContext(context, scope.reporter), step, action, args);
|
|
61
79
|
} catch (error) {
|
|
62
80
|
if (!(error instanceof BridgeUserError)) {
|
|
81
|
+
scope.drain();
|
|
82
|
+
|
|
63
83
|
throw error;
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
log.warn("setup submit rejected", {
|
|
67
87
|
step,
|
|
68
88
|
action,
|
|
69
|
-
error: error
|
|
89
|
+
error: errorDetail(error),
|
|
70
90
|
});
|
|
71
91
|
|
|
72
|
-
|
|
92
|
+
scope.reporter.report({
|
|
93
|
+
name: BridgeEventName.SetupRejected,
|
|
94
|
+
text: error.text,
|
|
95
|
+
details: {
|
|
96
|
+
step,
|
|
97
|
+
action,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
result: failedSetup(current, redactLocalized(error.text, redact)),
|
|
103
|
+
activity: scope.close(),
|
|
104
|
+
};
|
|
73
105
|
}
|
|
74
106
|
|
|
75
107
|
return {
|
|
76
|
-
|
|
77
|
-
|
|
108
|
+
result: {
|
|
109
|
+
supported: true,
|
|
110
|
+
runtime: current,
|
|
111
|
+
},
|
|
112
|
+
activity: scope.close(),
|
|
78
113
|
};
|
|
79
114
|
},
|
|
80
115
|
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { describe, expect,
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
2
|
import { leadsGroup, readProcessGroup, signalGroup } from "./bridgeSignal";
|
|
3
3
|
|
|
4
4
|
const MISSING_PID = 2 ** 22 - 1;
|
|
5
5
|
|
|
6
6
|
describe("readProcessGroup", () => {
|
|
7
|
-
|
|
7
|
+
it("reads the process group of this process", async () => {
|
|
8
8
|
const group = await readProcessGroup(process.pid);
|
|
9
9
|
|
|
10
10
|
expect(group).not.toBeNull();
|
|
11
11
|
expect(group).toBeGreaterThan(0);
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
it("puts a detached child in a group of its own and an attached one in ours", async () => {
|
|
15
15
|
const detached = Bun.spawn(
|
|
16
16
|
[
|
|
17
17
|
"sleep",
|
|
@@ -49,13 +49,13 @@ describe("readProcessGroup", () => {
|
|
|
49
49
|
}
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
it("answers null for a pid that does not exist", async () => {
|
|
53
53
|
expect(await readProcessGroup(MISSING_PID)).toBeNull();
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
describe("leadsGroup", () => {
|
|
58
|
-
|
|
58
|
+
it("only a pid equal to its own group leads it", () => {
|
|
59
59
|
expect(leadsGroup(1234, 1234)).toBe(true);
|
|
60
60
|
expect(leadsGroup(1234, 1200)).toBe(false);
|
|
61
61
|
expect(leadsGroup(1234, null)).toBe(false);
|
|
@@ -63,7 +63,7 @@ describe("leadsGroup", () => {
|
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
describe("signalGroup", () => {
|
|
66
|
-
|
|
66
|
+
it("signals every process sharing the leader's group", async () => {
|
|
67
67
|
const leader = Bun.spawn(
|
|
68
68
|
[
|
|
69
69
|
"bash",
|
|
@@ -90,7 +90,7 @@ describe("signalGroup", () => {
|
|
|
90
90
|
expect(() => process.kill(child, 0)).toThrow();
|
|
91
91
|
}, 20_000);
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
it("refuses to signal a group the pid does not lead", async () => {
|
|
94
94
|
const attached = Bun.spawn(
|
|
95
95
|
[
|
|
96
96
|
"sleep",
|