PPysolate SpineREAD THE CODE · UNDERSTAND THE SYSTEM
章节目录
源码索引 / CURRENT IMPLEMENTATION

runner_test.go

112 行 · 构建时读取的实际文件,不是讲解用伪代码。

package spine

import (
	"context"
	"encoding/json"
	"errors"
	"os"
	"strings"
	"testing"
	"time"
)

// Deliberately fail if the real artifact is missing: no native substitute or skip.
func TestRealGuest(t *testing.T) {
	wasm, err := os.ReadFile("dist/spine.wasm")
	if err != nil {
		t.Fatal(err)
	}
	calls := 0
	tools := map[string]Tool{"lookup": func(ctx context.Context, args json.RawMessage) (any, error) {
		calls++
		var a struct {
			Key string `json:"key"`
		}
		if err := json.Unmarshal(args, &a); err != nil {
			return nil, err
		}
		if a.Key == "empty-error" {
			return nil, errors.New("")
		}
		if a.Key == "null" {
			return nil, nil
		}
		if a.Key == "price" {
			return 21, nil
		}
		return nil, errors.New("missing key: " + a.Key)
	}}
	ctx := context.Background()
	r, err := New(ctx, wasm, tools)
	if err != nil {
		t.Fatal(err)
	}
	defer r.Close(ctx)
	cases := []struct {
		name, source, value, failure string
		calls                        int
	}{
		{"python", `import sys; result = {"answer": 6 * 7, "version": sys.version_info[:2]}`, `{"answer":42,"version":[3,14]}`, "", 0},
		{"host", `result = tool("lookup", key="price") * inputs["quantity"]`, `42`, "", 1},
		{"null tool result", `result = tool("lookup", key="null")`, `null`, "", 1},
		{"caught tool error", "try:\n    tool('lookup', key='absent')\nexcept RuntimeError as e:\n    result = str(e)", `"missing key: absent"`, "", 1},
		{"uncaught tool error", `result = tool("lookup", key="absent")`, "", "RuntimeError: missing key: absent", 1},
		{"empty tool error", `result = tool("lookup", key="empty-error")`, "", "RuntimeError", 1},
		{"malformed tool request", `from _spine import call; import json; result = "error" in json.loads(call("{"))`, `true`, "", 0},
		{"unknown tool", `result = tool("delete", key="price")`, "", "unknown tool: delete", 0},
		{"python error", `result = 1 / 0`, "", "ZeroDivisionError", 0},
		{"syntax error", `result = (`, "", "SyntaxError", 0},
		{"non JSON result", `result = {1, 2}`, "", "TypeError", 0},
		{"private state write", `import builtins; builtins.secret = 123; result = 1`, `1`, "", 0},
		{"private state read", `import builtins; result = hasattr(builtins, "secret")`, `false`, "", 0},
		{"no host filesystem", "try:\n    open('/etc/passwd').read()\nexcept OSError:\n    result = 'denied'", `"denied"`, "", 0},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			before := calls
			out, err := r.Run(ctx, tc.source, map[string]any{"quantity": 2})
			if calls-before != tc.calls {
				t.Fatalf("tool calls = %d, want %d", calls-before, tc.calls)
			}
			if tc.failure != "" {
				if err == nil || !strings.Contains(err.Error(), tc.failure) {
					t.Fatalf("got %v; want %q", err, tc.failure)
				}
			} else {
				if err != nil {
					t.Fatal(err)
				}
				var got, want any
				if err := json.Unmarshal(out.Value, &got); err != nil {
					t.Fatal(err)
				}
				if err := json.Unmarshal([]byte(tc.value), &want); err != nil {
					t.Fatal(err)
				}
				g, _ := json.Marshal(got)
				w, _ := json.Marshal(want)
				if string(g) != string(w) {
					t.Fatalf("got %s; want %s", g, w)
				}
			}
		})
	}
	t.Run("stdout", func(t *testing.T) {
		out, err := r.Run(ctx, "print('hello'); result = 42", nil)
		if err != nil || out.Stdout != "hello\n" {
			t.Fatalf("out=%+v err=%v", out, err)
		}
	})
	t.Run("deadline", func(t *testing.T) {
		deadline, cancel := context.WithTimeout(ctx, 2*time.Second)
		defer cancel()
		_, err := r.Run(deadline, "while True: pass", nil)
		if err == nil || deadline.Err() == nil {
			t.Fatalf("expected deadline, got %v", err)
		}
		out, err := r.Run(ctx, "result = 7", nil)
		if err != nil || string(out.Value) != "7" {
			t.Fatalf("run after cancellation: %+v, %v", out, err)
		}
	})
}