mirror of https://github.com/buster-so/buster.git
fix: update bash-execute-tool tests to match working file tool patterns
- Use proper RuntimeContext<SandboxContext> type - Add comprehensive mocking for @buster/sandbox and functions - Test both sandbox and local execution paths - Handle JSON parse errors and execution failures - Follow patterns from create-files-tool tests Co-Authored-By: Dallin Bentley <dallinbentley98@gmail.com>
This commit is contained in:
parent
535af8d902
commit
e27a5ce0c5
|
@ -1,27 +1,102 @@
|
||||||
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
import { RuntimeContext } from '@mastra/core/runtime-context';
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { type SandboxContext, SandboxContextKey } from '../../../context/sandbox-context';
|
||||||
|
import { bashExecute } from './bash-execute-tool';
|
||||||
|
|
||||||
|
vi.mock('@buster/sandbox', () => ({
|
||||||
|
runTypescript: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
vi.mock('./bash-execute-functions', () => ({
|
vi.mock('./bash-execute-functions', () => ({
|
||||||
|
generateBashExecuteCode: vi.fn(),
|
||||||
executeBashCommandsSafely: vi.fn(),
|
executeBashCommandsSafely: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { executeBashCommandsSafely } from './bash-execute-functions';
|
import { runTypescript } from '@buster/sandbox';
|
||||||
import { bashExecute } from './bash-execute-tool';
|
import { executeBashCommandsSafely, generateBashExecuteCode } from './bash-execute-functions';
|
||||||
|
|
||||||
|
const mockRunTypescript = vi.mocked(runTypescript);
|
||||||
|
const mockGenerateBashExecuteCode = vi.mocked(generateBashExecuteCode);
|
||||||
const mockExecuteBashCommandsSafely = vi.mocked(executeBashCommandsSafely);
|
const mockExecuteBashCommandsSafely = vi.mocked(executeBashCommandsSafely);
|
||||||
|
|
||||||
describe('bash-execute-tool', () => {
|
describe('bash-execute-tool', () => {
|
||||||
let mockRuntimeContext: RuntimeContext;
|
let runtimeContext: RuntimeContext<SandboxContext>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
|
runtimeContext = new RuntimeContext<SandboxContext>();
|
||||||
mockRuntimeContext = {
|
|
||||||
get: vi.fn(),
|
|
||||||
} as any;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should execute commands locally', async () => {
|
afterEach(() => {
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('bashExecute tool', () => {
|
||||||
|
it('should have correct tool configuration', () => {
|
||||||
|
expect(bashExecute.id).toBe('bash_execute');
|
||||||
|
expect(bashExecute.description).toContain('Executes bash commands');
|
||||||
|
expect(bashExecute.inputSchema).toBeDefined();
|
||||||
|
expect(bashExecute.outputSchema).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate input schema correctly', () => {
|
||||||
|
const validInput = {
|
||||||
|
commands: [
|
||||||
|
{ command: 'echo "hello"', description: 'test command' },
|
||||||
|
{ command: 'ls -la', timeout: 5000 },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(() => bashExecute.inputSchema.parse(validInput)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should execute with sandbox when available', async () => {
|
||||||
|
const mockSandbox = { process: { codeRun: vi.fn() } };
|
||||||
|
runtimeContext.set(SandboxContextKey.Sandbox, mockSandbox as any);
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
commands: [{ command: 'echo "hello"' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCode = 'generated typescript code';
|
||||||
|
const mockSandboxResult = {
|
||||||
|
result: JSON.stringify([
|
||||||
|
{
|
||||||
|
command: 'echo "hello"',
|
||||||
|
stdout: 'hello',
|
||||||
|
stderr: undefined,
|
||||||
|
exitCode: 0,
|
||||||
|
success: true,
|
||||||
|
error: undefined,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
exitCode: 0,
|
||||||
|
stderr: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
mockGenerateBashExecuteCode.mockReturnValue(mockCode);
|
||||||
|
mockRunTypescript.mockResolvedValue(mockSandboxResult);
|
||||||
|
|
||||||
|
const result = await bashExecute.execute({
|
||||||
|
context: input,
|
||||||
|
runtimeContext,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockGenerateBashExecuteCode).toHaveBeenCalledWith(input.commands);
|
||||||
|
expect(mockRunTypescript).toHaveBeenCalledWith(mockSandbox, mockCode);
|
||||||
|
expect(result.results).toHaveLength(1);
|
||||||
|
expect(result.results[0]).toEqual({
|
||||||
|
command: 'echo "hello"',
|
||||||
|
stdout: 'hello',
|
||||||
|
stderr: undefined,
|
||||||
|
exitCode: 0,
|
||||||
|
success: true,
|
||||||
|
error: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to local execution when sandbox not available', async () => {
|
||||||
const input = {
|
const input = {
|
||||||
commands: [{ command: 'echo "hello"' }],
|
commands: [{ command: 'echo "hello"' }],
|
||||||
};
|
};
|
||||||
|
@ -41,13 +116,47 @@ describe('bash-execute-tool', () => {
|
||||||
|
|
||||||
const result = await bashExecute.execute({
|
const result = await bashExecute.execute({
|
||||||
context: input,
|
context: input,
|
||||||
runtimeContext: mockRuntimeContext,
|
runtimeContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mockExecuteBashCommandsSafely).toHaveBeenCalledWith(input.commands);
|
expect(mockExecuteBashCommandsSafely).toHaveBeenCalledWith(input.commands);
|
||||||
expect(result.results).toEqual(mockLocalResults);
|
expect(result.results).toEqual(mockLocalResults);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle sandbox execution errors', async () => {
|
||||||
|
const mockSandbox = { process: { codeRun: vi.fn() } };
|
||||||
|
runtimeContext.set(SandboxContextKey.Sandbox, mockSandbox as any);
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
commands: [{ command: 'echo "hello"' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCode = 'generated typescript code';
|
||||||
|
const mockSandboxResult = {
|
||||||
|
result: 'error output',
|
||||||
|
exitCode: 1,
|
||||||
|
stderr: 'Execution failed',
|
||||||
|
};
|
||||||
|
|
||||||
|
mockGenerateBashExecuteCode.mockReturnValue(mockCode);
|
||||||
|
mockRunTypescript.mockResolvedValue(mockSandboxResult);
|
||||||
|
|
||||||
|
const result = await bashExecute.execute({
|
||||||
|
context: input,
|
||||||
|
runtimeContext,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.results).toHaveLength(1);
|
||||||
|
expect(result.results[0]).toEqual({
|
||||||
|
command: 'echo "hello"',
|
||||||
|
stdout: '',
|
||||||
|
stderr: undefined,
|
||||||
|
exitCode: 1,
|
||||||
|
success: false,
|
||||||
|
error: 'Execution error: Sandbox execution failed: Execution failed',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle execution errors', async () => {
|
it('should handle execution errors', async () => {
|
||||||
const input = {
|
const input = {
|
||||||
commands: [{ command: 'echo "hello"' }],
|
commands: [{ command: 'echo "hello"' }],
|
||||||
|
@ -57,7 +166,7 @@ describe('bash-execute-tool', () => {
|
||||||
|
|
||||||
const result = await bashExecute.execute({
|
const result = await bashExecute.execute({
|
||||||
context: input,
|
context: input,
|
||||||
runtimeContext: mockRuntimeContext,
|
runtimeContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.results).toHaveLength(1);
|
expect(result.results).toHaveLength(1);
|
||||||
|
@ -70,9 +179,44 @@ describe('bash-execute-tool', () => {
|
||||||
|
|
||||||
const result = await bashExecute.execute({
|
const result = await bashExecute.execute({
|
||||||
context: input,
|
context: input,
|
||||||
runtimeContext: mockRuntimeContext,
|
runtimeContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result.results).toHaveLength(0);
|
expect(result.results).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle JSON parse errors from sandbox', async () => {
|
||||||
|
const mockSandbox = { process: { codeRun: vi.fn() } };
|
||||||
|
runtimeContext.set(SandboxContextKey.Sandbox, mockSandbox as any);
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
commands: [{ command: 'echo "hello"' }],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCode = 'generated typescript code';
|
||||||
|
const mockSandboxResult = {
|
||||||
|
result: 'invalid json output',
|
||||||
|
exitCode: 0,
|
||||||
|
stderr: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
mockGenerateBashExecuteCode.mockReturnValue(mockCode);
|
||||||
|
mockRunTypescript.mockResolvedValue(mockSandboxResult);
|
||||||
|
|
||||||
|
const result = await bashExecute.execute({
|
||||||
|
context: input,
|
||||||
|
runtimeContext,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.results).toHaveLength(1);
|
||||||
|
expect(result.results[0]).toEqual({
|
||||||
|
command: 'echo "hello"',
|
||||||
|
stdout: '',
|
||||||
|
stderr: undefined,
|
||||||
|
exitCode: 1,
|
||||||
|
success: false,
|
||||||
|
error: expect.stringContaining('Failed to parse sandbox output'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue