131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
|
|
package shell_test
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"apigo.cc/go/shell"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestRunTimeout(t *testing.T) {
|
||
|
|
// 测试超时功能
|
||
|
|
_, err := shell.Run("sleep", []string{"2"}, &shell.Options{
|
||
|
|
Timeout: 100 * time.Millisecond,
|
||
|
|
})
|
||
|
|
if err == nil || !strings.Contains(err.Error(), "timed out") {
|
||
|
|
t.Errorf("Expected timeout error, got: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunEnv(t *testing.T) {
|
||
|
|
// 测试环境变量传递
|
||
|
|
// 使用 printenv 检查是否设置了自定义变量
|
||
|
|
res, err := shell.Run("printenv", []string{"TEST_VAR"}, &shell.Options{
|
||
|
|
Env: []string{"TEST_VAR=hello_env"},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("Run with env failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stdout)) != "hello_env" {
|
||
|
|
t.Errorf("Expected 'hello_env', got: %s", res.Stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunCallbacks(t *testing.T) {
|
||
|
|
// 测试 OnStdout 回调
|
||
|
|
var stdoutCaptured bytes.Buffer
|
||
|
|
_, err := shell.Run("echo", []string{"test_callback"}, &shell.Options{
|
||
|
|
OnStdout: func(data []byte) {
|
||
|
|
stdoutCaptured.Write(data)
|
||
|
|
},
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("Run with callback failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(stdoutCaptured.String()) != "test_callback" {
|
||
|
|
t.Errorf("Callback didn't capture expected output, got: %s", stdoutCaptured.String())
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunStderr(t *testing.T) {
|
||
|
|
// 测试标准错误捕获
|
||
|
|
// 使用 sh -c 显式输出到 stderr
|
||
|
|
res, _ := shell.Run("sh", []string{"-c", "echo error_msg >&2; exit 1"}, nil)
|
||
|
|
// 因为返回错误,所以检查 res
|
||
|
|
if res.ProcessErr == nil {
|
||
|
|
t.Error("Expected error, but got nil")
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stderr)) != "error_msg" {
|
||
|
|
t.Errorf("Expected 'error_msg', got: %s", res.Stderr)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestPipeline(t *testing.T) {
|
||
|
|
res, err := shell.Pipeline([][]string{{"echo", "hello", "world"}, {"grep", "hello"}}, nil)
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("Pipeline failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stdout)) != "hello world" {
|
||
|
|
t.Errorf("Expected 'hello world', got %s", res.Stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRun(t *testing.T) {
|
||
|
|
// 测试直接 Run
|
||
|
|
res, err := shell.Run("echo", []string{"hello"}, nil)
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("Run failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stdout)) != "hello" {
|
||
|
|
t.Errorf("Expected 'hello', got %s", res.Stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunAdvanced(t *testing.T) {
|
||
|
|
// 测试 Timeout, Dir, Verbose
|
||
|
|
_, err := shell.Run("sleep", []string{"0.1"}, &shell.Options{
|
||
|
|
Timeout: 1 * time.Second,
|
||
|
|
Verbose: true,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("Run failed: %v", err)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunCommand(t *testing.T) {
|
||
|
|
// 测试完整命令字符串 RunCommand
|
||
|
|
res, err := shell.RunCommand("echo hello world", nil)
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("RunCommand failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stdout)) != "hello world" {
|
||
|
|
t.Errorf("Expected 'hello world', got %s", res.Stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunCommandWithPipe(t *testing.T) {
|
||
|
|
// 测试包含管道的 RunCommand
|
||
|
|
res, err := shell.RunCommand("echo hello world | grep hello", nil)
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("RunCommand with pipe failed: %v", err)
|
||
|
|
}
|
||
|
|
if strings.TrimSpace(string(res.Stdout)) != "hello world" {
|
||
|
|
t.Errorf("Expected 'hello world', got %s", res.Stdout)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestRunCommandMixedPipeAndChain(t *testing.T) {
|
||
|
|
// 测试 | 和 && 混合使用
|
||
|
|
// 期望:(echo hello | grep h) && (echo world | grep w)
|
||
|
|
res, err := shell.RunCommand("echo hello | grep h && echo world | grep w", nil)
|
||
|
|
if err != nil {
|
||
|
|
t.Errorf("RunCommand with mixed operators failed: %v", err)
|
||
|
|
}
|
||
|
|
output := strings.TrimSpace(string(res.Stdout))
|
||
|
|
if !strings.Contains(output, "hello") || !strings.Contains(output, "world") {
|
||
|
|
t.Errorf("Expected 'hello' and 'world' in output, got: %s", output)
|
||
|
|
}
|
||
|
|
}
|