115 lines
4.0 KiB
Go
115 lines
4.0 KiB
Go
//go:build !windows
|
|
|
|
package windows
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
|
"github.com/rvbox/rvbox/internal/client/supervisor"
|
|
"github.com/rvbox/rvbox/internal/domain"
|
|
)
|
|
|
|
func TestExecProcessReleaseIsIdempotent_BH_LAUNCH_05(t *testing.T) {
|
|
var calls atomic.Int32
|
|
process := &execProcess{releaseFn: func() error {
|
|
calls.Add(1)
|
|
return errors.New("release failed")
|
|
}}
|
|
if err := process.Release(context.Background()); err == nil || err.Error() != "release failed" {
|
|
t.Fatalf("first release error = %v", err)
|
|
}
|
|
if err := process.Release(context.Background()); err == nil || err.Error() != "release failed" {
|
|
t.Fatalf("repeated release error = %v", err)
|
|
}
|
|
if got := calls.Load(); got != 1 {
|
|
t.Fatalf("release calls = %d, want one", got)
|
|
}
|
|
}
|
|
|
|
func TestPortableSupervisorCapturesOutputAndSupportsStdin_HP_SUPERVISOR_03(t *testing.T) {
|
|
t.Parallel()
|
|
manager, err := NewSupervisor(NativeOptions{MaxOutputChunk: 8, WindowsTermGrace: 10 * time.Millisecond})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
issue, err := domain.ParseUUIDv7("019c46f1-1d02-7000-8000-0000000000c1")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
process, err := manager.Start(context.Background(), supervisor.StartSpec{IssueUUID: issue, CommandRevision: 1, WorkingDirectory: t.TempDir(), Execution: &rvboxv1.ExecutionSpec{ShellType: rvboxv1.ShellType_SHELL_SH, Source: &rvboxv1.ExecutionSpec_CommandText{CommandText: "read line; printf 'out:%s\\n' \"$line\"; printf 'err\\n' >&2"}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if process.PID() == 0 {
|
|
t.Fatal("portable supervisor did not expose process identity PID")
|
|
}
|
|
if err := process.WriteStdin(context.Background(), []byte("hello"), true); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := process.CloseStdin(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
status, err := process.Wait(context.Background())
|
|
if err != nil || status.Code != 0 {
|
|
t.Fatalf("wait = %+v, %v", status, err)
|
|
}
|
|
var output strings.Builder
|
|
streams := map[rvboxv1.StreamKind]bool{}
|
|
for {
|
|
chunk, err := process.ReadOutput(context.Background())
|
|
if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
output.Write(chunk.Data)
|
|
streams[chunk.Stream] = true
|
|
}
|
|
if !strings.Contains(output.String(), "out:hello\n") || !strings.Contains(output.String(), "err\n") || !streams[rvboxv1.StreamKind_STREAM_STDOUT] || !streams[rvboxv1.StreamKind_STREAM_STDERR] {
|
|
t.Fatalf("captured output = %q streams=%v", output.String(), streams)
|
|
}
|
|
second, err := manager.Start(context.Background(), supervisor.StartSpec{IssueUUID: issue, CommandRevision: 1, WorkingDirectory: t.TempDir(), Execution: &rvboxv1.ExecutionSpec{ShellType: rvboxv1.ShellType_SHELL_SH, Source: &rvboxv1.ExecutionSpec_CommandText{CommandText: "true"}}})
|
|
if err != nil {
|
|
t.Fatalf("restart after terminal = %v", err)
|
|
}
|
|
_, _ = second.Wait(context.Background())
|
|
}
|
|
|
|
func TestPortableSupervisorScriptMaterializationAndCleanup_HP_SUPERVISOR_04(t *testing.T) {
|
|
t.Parallel()
|
|
manager, err := NewSupervisor(NativeOptions{MaxWrapperBytes: 1024})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
issue, _ := domain.ParseUUIDv7("019c46f1-1d02-7000-8000-0000000000c2")
|
|
body := []byte("printf script-ok")
|
|
process, err := manager.Start(context.Background(), supervisor.StartSpec{IssueUUID: issue, CommandRevision: 1, WorkingDirectory: t.TempDir(), ScriptBody: body, Execution: &rvboxv1.ExecutionSpec{ShellType: rvboxv1.ShellType_SHELL_SH, Source: &rvboxv1.ExecutionSpec_Script{Script: &rvboxv1.ScriptDescriptor{SizeBytes: uint64(len(body)), Sha256: digest(body)}}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := process.Wait(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
chunk, err := process.ReadOutput(context.Background())
|
|
if err != nil || string(chunk.Data) != "script-ok" {
|
|
t.Fatalf("script output = %+v, %v", chunk, err)
|
|
}
|
|
if _, err := process.ReadOutput(context.Background()); !errors.Is(err, io.EOF) {
|
|
t.Fatalf("script output close = %v", err)
|
|
}
|
|
}
|
|
|
|
func digest(value []byte) []byte {
|
|
result := sha256.Sum256(value)
|
|
return result[:]
|
|
}
|