150 lines
4.7 KiB
Go
150 lines
4.7 KiB
Go
package workspaceops
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/aritmolab/thothii/tools/tht/internal/compose"
|
|
"github.com/aritmolab/thothii/tools/tht/internal/config"
|
|
)
|
|
|
|
type fakeRunner struct {
|
|
run func(args []string, stdin string) (compose.Result, error)
|
|
all [][]string
|
|
stdins []string
|
|
}
|
|
|
|
func (r *fakeRunner) Run(_ context.Context, args []string, stdin io.Reader) (compose.Result, error) {
|
|
payload := ""
|
|
if stdin != nil {
|
|
contents, err := io.ReadAll(stdin)
|
|
if err != nil {
|
|
return compose.Result{}, err
|
|
}
|
|
payload = string(contents)
|
|
}
|
|
r.all = append(r.all, append([]string(nil), args...))
|
|
r.stdins = append(r.stdins, payload)
|
|
return r.run(args, payload)
|
|
}
|
|
|
|
func TestExecuteRunSendsOnlyTheOneShotEnvelope(t *testing.T) {
|
|
installation := testInstallation(t)
|
|
runner := &fakeRunner{run: func(args []string, stdin string) (compose.Result, error) {
|
|
switch {
|
|
case contains(args, "config", "--format", "json"):
|
|
return compose.Result{Stdout: `{"services":{"core":{"image":"thothii-core:local"}}}`}, nil
|
|
case reflect.DeepEqual(args, []string{"image", "inspect", "--format", "{{.Id}}", "thothii-core:local"}):
|
|
return compose.Result{Stdout: "sha256:" + strings.Repeat("a", 64)}, nil
|
|
case contains(args, "workspace-maintenance", "preprocess-run"):
|
|
var envelope map[string]any
|
|
if err := json.Unmarshal([]byte(stdin), &envelope); err != nil {
|
|
t.Fatalf("stdin JSON = %q, err=%v", stdin, err)
|
|
}
|
|
if !reflect.DeepEqual(envelope, map[string]any{
|
|
"schemaVersion": float64(1),
|
|
"workspaceId": "abc",
|
|
}) {
|
|
t.Fatalf("unexpected envelope: %#v", envelope)
|
|
}
|
|
return compose.Result{Stdout: successResult("preprocess run")}, nil
|
|
default:
|
|
t.Fatalf("unexpected Docker invocation: %#v", args)
|
|
return compose.Result{}, nil
|
|
}
|
|
}}
|
|
|
|
result, err := Execute(
|
|
context.Background(),
|
|
installation,
|
|
runner,
|
|
RunRequest{baseRequest: baseRequest{Workspace: "abc", JSON: true}},
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("Execute() error = %v", err)
|
|
}
|
|
if result.Status != "succeeded" || result.Operation != "preprocess run" {
|
|
t.Fatalf("unexpected result: %#v", result)
|
|
}
|
|
}
|
|
|
|
func TestParseAcceptsOnlyInspectAndCompletePreprocessing(t *testing.T) {
|
|
for _, args := range [][]string{
|
|
{"inspect", "--workspace", "abc", "--json"},
|
|
{"preprocess", "run", "--workspace", "abc", "--json"},
|
|
{"preprocess", "clear", "--workspace", "abc", "--json"},
|
|
} {
|
|
if _, err := Parse(args); err != nil {
|
|
t.Fatalf("Parse(%v) error = %v", args, err)
|
|
}
|
|
}
|
|
|
|
retired := [][]string{
|
|
{"preprocess", "dwh", "--workspace", "abc"},
|
|
{"preprocess", "evidence", "--workspace", "abc"},
|
|
{"preprocess", "run", "--workspace", "abc", "--resume", strings.Repeat("a", 32)},
|
|
{"preprocess", "run", "--workspace", "abc", "--dry-run"},
|
|
{"schema", "suggest-fks", "--workspace", "abc"},
|
|
{"schema", "check", "--workspace", "abc"},
|
|
{"schema", "accept", "--workspace", "abc"},
|
|
{"index-schema", "--workspace", "abc"},
|
|
{"vector", "inspect", "--workspace", "abc"},
|
|
{"vector", "rebuild", "--workspace", "abc"},
|
|
}
|
|
for _, args := range retired {
|
|
if _, err := Parse(args); err == nil {
|
|
t.Fatalf("retired command accepted: %v", args)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testInstallation(t *testing.T) config.Installation {
|
|
t.Helper()
|
|
temporaryRoot, err := filepath.EvalSymlinks(os.TempDir())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
root, err := os.MkdirTemp(temporaryRoot, "tht-workspaceops-")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Cleanup(func() { _ = os.RemoveAll(root) })
|
|
project := filepath.Join(root, "project")
|
|
if err := os.MkdirAll(filepath.Join(project, "deploy"), 0o700); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(project, "compose.yaml"), []byte("services: {}\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(project, "deploy", "compose.local.yaml"), []byte("services: {}\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
envFile := filepath.Join(root, "installation.env")
|
|
if err := os.WriteFile(envFile, []byte("SAFE_VALUE=1\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return config.Installation{
|
|
Path: filepath.Join(root, "thothii-installation.yaml"), Profile: "local",
|
|
ProjectDirectory: project, EnvFile: envFile,
|
|
}
|
|
}
|
|
|
|
func contains(values []string, sequence ...string) bool {
|
|
for start := range values {
|
|
if start+len(sequence) <= len(values) && reflect.DeepEqual(values[start:start+len(sequence)], sequence) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func successResult(operation string) string {
|
|
return `{"schemaVersion":1,"status":"succeeded","code":"ok","workspaceId":"abc","workspaceRevision":"1234567890abcdef1234567890abcdef12345678","descriptorBlob":"sha256:` + strings.Repeat("f", 64) + `","operation":"` + operation + `","completedStages":[]}`
|
|
}
|