53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
package local
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/joint-online-judge/JOJ3/internal/stage"
|
|
)
|
|
|
|
func TestRunRejectsEmptyArgs(t *testing.T) {
|
|
_, err := (&Local{}).Run(context.Background(), []stage.Cmd{{}})
|
|
if err == nil || err.Error() != "command args must not be empty" {
|
|
t.Fatalf("Run() error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRunCancellationKillsProcessGroup(t *testing.T) {
|
|
dir := t.TempDir()
|
|
ready := filepath.Join(dir, "ready")
|
|
marker := filepath.Join(dir, "marker")
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
done := make(chan error, 1)
|
|
go func() {
|
|
_, err := (&Local{}).Run(ctx, []stage.Cmd{{
|
|
Args: []string{"/bin/sh", "-c", "touch \"$1\"; (sleep 0.3; touch \"$2\") & wait", "sh", ready, marker},
|
|
}})
|
|
done <- err
|
|
}()
|
|
|
|
deadline := time.Now().Add(2 * time.Second)
|
|
for {
|
|
if _, err := os.Stat(ready); err == nil {
|
|
break
|
|
}
|
|
if time.Now().After(deadline) {
|
|
t.Fatal("command did not start")
|
|
}
|
|
time.Sleep(10 * time.Millisecond)
|
|
}
|
|
cancel()
|
|
if err := <-done; !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("Run() error = %v, want context canceled", err)
|
|
}
|
|
time.Sleep(500 * time.Millisecond)
|
|
if _, err := os.Stat(marker); !errors.Is(err, os.ErrNotExist) {
|
|
t.Fatalf("child process survived cancellation: %v", err)
|
|
}
|
|
}
|