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

plm_test.go

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

package spine

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

func TestPLMGuest(t *testing.T) {
	wasm, err := os.ReadFile("dist/spine.wasm")
	if err != nil {
		t.Fatal(err)
	}
	var mu sync.Mutex
	counts := map[string]int{}
	var secondStarted, waitStarted, waitStopped chan struct{}
	var secondFails bool
	read := func(ctx context.Context, args json.RawMessage) (any, error) {
		var a struct {
			Key string `json:"key"`
		}
		if err := json.Unmarshal(args, &a); err != nil {
			return nil, err
		}
		mu.Lock()
		counts[a.Key]++
		mu.Unlock()
		switch a.Key {
		case "first":
			select {
			case <-secondStarted:
				return 21, nil
			case <-ctx.Done():
				return nil, ctx.Err()
			}
		case "second":
			close(secondStarted)
			if secondFails {
				return nil, errors.New("early failure")
			}
			return 5, nil
		case "fail":
			select {
			case <-waitStarted:
				return nil, errors.New("first failed")
			case <-ctx.Done():
				return nil, ctx.Err()
			}
		case "wait":
			close(waitStarted)
			<-ctx.Done()
			close(waitStopped)
			return nil, ctx.Err()
		case "book":
			return 21, nil
		case "shipping":
			return 5, nil
		case "choose":
			return "book", nil
		default:
			return nil, errors.New("missing key: " + a.Key)
		}
	}
	// This is the whole-suite budget, including wazero compilation under -race.
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancel()
	r, err := New(ctx, wasm, map[string]Tool{"lookup": read}, "lookup")
	if err != nil {
		t.Fatal(err)
	}
	defer r.Close(context.Background())
	run := func(t *testing.T, source, want string, transformed bool) {
		t.Helper()
		out, err := r.RunPLM(ctx, source, map[string]any{"item": "book", "yes": false})
		if err != nil || string(out.Value) != want {
			t.Fatalf("got %+v, %v; want %s", out, err, want)
		}
		if (out.Transformed != "") != transformed {
			t.Fatalf("unexpected transformed source: %q", out.Transformed)
		}
	}
	t.Run("actual transformed Guest", func(t *testing.T) {
		run(t, `a=tool("lookup",key="book")
b=tool("lookup",key="shipping")
result=a+b`, "26", true)
	})
	t.Run("both started before first resolves", func(t *testing.T) {
		secondStarted = make(chan struct{})
		secondFails = false
		run(t, `a=tool("lookup",key="first")
b=tool("lookup",key="second")
result=a+b`, "26", true)
	})
	t.Run("error delivered after first assignment", func(t *testing.T) {
		secondStarted = make(chan struct{})
		secondFails = true
		run(t, `try:
 a=tool("lookup",key="first")
 b=tool("lookup",key="second")
except RuntimeError:
 result=a`, "21", true)
	})
	t.Run("dependency and branch", func(t *testing.T) {
		run(t, `key=tool("lookup",key="choose")
a=tool("lookup",key=key)
if inputs["yes"]:
 b=tool("lookup",key="unselected")
else:
 b=tool("lookup",key="shipping")
result=a+b`, "26", true)
		mu.Lock()
		defer mu.Unlock()
		if counts["unselected"] != 0 {
			t.Fatal("unselected branch executed")
		}
	})
	t.Run("argument error stays at original call", func(t *testing.T) {
		run(t, `try:
 a=tool("lookup",key="book")
 b=tool("lookup",key=inputs["absent"])
except KeyError:
 result=a`, "21", true)
	})
	t.Run("unused future cancelled and joined", func(t *testing.T) {
		waitStarted, waitStopped = make(chan struct{}), make(chan struct{})
		run(t, `try:
 a=tool("lookup",key="fail")
 b=tool("lookup",key="wait")
except RuntimeError:
 result=7`, "7", true)
		select {
		case <-waitStopped:
		default:
			t.Fatal("Run returned with live worker")
		}
	})
	t.Run("unsupported loop executes normally", func(t *testing.T) {
		run(t, `result=0
for i in range(2):
 result += tool("lookup",key="book")`, "42", false)
	})
	t.Run("mismatch never reuses old value", func(t *testing.T) {
		run(t, `import _spine, json
h=_spine.prepare(json.dumps({"tool":"lookup","args":{"key":"book"}}))
response=json.loads(_spine.resolve(h,json.dumps({"tool":"lookup","args":{"key":"shipping"}})))
result=response["value"]`, "5", false)
	})
	t.Run("future does not cross run", func(t *testing.T) {
		run(t, `import _spine, json
response=json.loads(_spine.resolve(1,json.dumps({"tool":"lookup","args":{"key":"book"}})))
result="error" in response`, "true", false)
	})
	t.Run("handle is consumed only once", func(t *testing.T) {
		run(t, `import _spine,json
request=json.dumps({"tool":"lookup","args":{"key":"book"}})
h=_spine.prepare(request)
a=json.loads(_spine.resolve(h,request))
b=json.loads(_spine.resolve(h,request))
result=a["value"] == 21 and "error" in b`, "true", false)
	})
	t.Run("ordinary run does not prepare", func(t *testing.T) {
		out, err := r.Run(ctx, `import _spine
result=_spine.prepare('{"tool":"lookup","args":{"key":"book"}}')`, nil)
		if err != nil || string(out.Value) != "0" {
			t.Fatalf("%+v %v", out, err)
		}
	})
	t.Run("pending limit falls back explicitly", func(t *testing.T) {
		run(t, `import _spine
handles=[_spine.prepare('{"tool":"lookup","args":{"key":"book"}}') for _ in range(65)]
result=handles[-1] == 0 and len(set(handles[:-1])) == 64`, "true", false)
	})
	t.Run("not opted in executes normally", func(t *testing.T) {
		s, err := New(ctx, wasm, map[string]Tool{"lookup": read})
		if err != nil {
			t.Fatal(err)
		}
		defer s.Close(context.Background())
		out, err := s.RunPLM(ctx, `result=tool("lookup",key="book")`, nil)
		if err != nil || string(out.Value) != "21" || !strings.Contains(out.Transformed, "_spine_prepare") {
			t.Fatalf("%+v %v", out, err)
		}
	})
}