-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathbash-enhanced.test.ts
More file actions
170 lines (139 loc) · 4.33 KB
/
bash-enhanced.test.ts
File metadata and controls
170 lines (139 loc) · 4.33 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* Tests for enhanced bash background process tracking
*/
import { describe, test, expect, beforeEach } from 'bun:test';
import {
BashTool,
getBackgroundProcess,
backgroundProcesses,
cleanupBackgroundProcesses,
} from '../../src/tools/bash';
import type { ToolContext } from '../../src/types/tools';
describe('BashTool - Enhanced Background Process Tracking', () => {
let tool: BashTool;
let context: ToolContext;
beforeEach(() => {
backgroundProcesses.clear();
tool = new BashTool();
context = {
cwd: process.cwd(),
env: {},
abortController: new AbortController(),
};
});
test('should return shellId when running in background', async () => {
const result = await tool.handler(
{
command: 'echo "hello"',
run_in_background: true,
},
context
);
expect(result.shellId).toBeDefined();
expect(result.shellId).toMatch(/^shell_\d+$/);
expect(result.exitCode).toBe(0);
expect(result.output).toContain('running in background');
});
test('should store process in backgroundProcesses map', async () => {
const result = await tool.handler(
{
command: 'sleep 0.1',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
const process = getBackgroundProcess(shellId);
expect(process).toBeDefined();
expect(process?.pid).toBeGreaterThan(0);
expect(process?.startTime).toBeGreaterThan(0);
expect(process?.stdout).toBeDefined();
expect(process?.stderr).toBeDefined();
});
test('should capture stdout in background process', async () => {
const result = await tool.handler(
{
command: 'echo "test output"',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
// Wait for process to complete
await new Promise((resolve) => setTimeout(resolve, 200));
const process = getBackgroundProcess(shellId);
expect(process?.stdout).toContain('test output');
});
test('should capture stderr in background process', async () => {
const result = await tool.handler(
{
command: 'echo "error message" >&2',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
// Wait for process to complete
await new Promise((resolve) => setTimeout(resolve, 200));
const process = getBackgroundProcess(shellId);
expect(process?.stderr).toContain('error message');
});
test('should set exitCode when process exits', async () => {
const result = await tool.handler(
{
command: 'exit 42',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
// Wait for process to complete
await new Promise((resolve) => setTimeout(resolve, 200));
const process = getBackgroundProcess(shellId);
expect(process?.exitCode).toBe(42);
});
test('should keep process in map after exit', async () => {
const result = await tool.handler(
{
command: 'echo "done"',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
// Wait for process to complete
await new Promise((resolve) => setTimeout(resolve, 200));
// Process should still be in the map
const process = getBackgroundProcess(shellId);
expect(process).toBeDefined();
expect(process?.stdout).toContain('done');
});
test('should store process reference in backgroundProcesses', async () => {
const result = await tool.handler(
{
command: 'sleep 0.5',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
const process = getBackgroundProcess(shellId);
expect(process?.process).toBeDefined();
expect(process?.process.pid).toBe(process?.pid);
});
test('should cleanup running background processes', async () => {
const result = await tool.handler(
{
command: 'sleep 10',
run_in_background: true,
},
context
);
const shellId = result.shellId!;
const processBeforeCleanup = getBackgroundProcess(shellId);
expect(processBeforeCleanup?.exitCode).toBeNull();
await cleanupBackgroundProcesses(200);
const processAfterCleanup = getBackgroundProcess(shellId);
expect(processAfterCleanup?.exitCode).not.toBeNull();
});
});