compile_test.go raw

   1  package organ
   2  
   3  import (
   4  	"context"
   5  	"os"
   6  	"testing"
   7  	"time"
   8  
   9  	"git.mleku.dev/mleku/dendrite/pkg/ratio"
  10  )
  11  
  12  func TestCompileOrgan(t *testing.T) {
  13  	// Use GOROOT from env or default.
  14  	goRoot := os.Getenv("GOROOT")
  15  	if goRoot == "" {
  16  		goRoot = "/home/mleku/sdk/go1.24.6"
  17  	}
  18  
  19  	// Verify the go binary exists.
  20  	if _, err := os.Stat(goRoot + "/bin/go"); err != nil {
  21  		t.Skipf("Go not found at %s: %v", goRoot, err)
  22  	}
  23  
  24  	source := `package main
  25  
  26  import "unsafe"
  27  
  28  var pool [1 << 16]byte
  29  var poolOffset uint32
  30  
  31  //go:wasmexport alloc
  32  func alloc(size uint32) uint32 {
  33  	if poolOffset+size > uint32(len(pool)) {
  34  		poolOffset = 0
  35  	}
  36  	ptr := poolOffset
  37  	poolOffset += size
  38  	return uint32(uintptr(unsafe.Pointer(&pool[ptr])))
  39  }
  40  
  41  //go:wasmexport dealloc
  42  func dealloc(ptr uint32, size uint32) {}
  43  
  44  //go:wasmexport process
  45  func process(inputPtr uint32, inputLen uint32) uint64 {
  46  	base := uint32(uintptr(unsafe.Pointer(&pool[0])))
  47  	offset := inputPtr - base
  48  	if offset+inputLen > uint32(len(pool)) {
  49  		return 0
  50  	}
  51  	input := pool[offset : offset+inputLen]
  52  	result := []byte("ok:")
  53  	result = append(result, input...)
  54  	outPtr := alloc(uint32(len(result)))
  55  	outOffset := outPtr - base
  56  	copy(pool[outOffset:], result)
  57  	return uint64(outPtr)<<32 | uint64(len(result))
  58  }
  59  
  60  func main() {}
  61  `
  62  
  63  	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
  64  	defer cancel()
  65  
  66  	wasmBytes, err := CompileOrgan(ctx, []byte(source), TypeEnzyme, goRoot, "")
  67  	if err != nil {
  68  		t.Fatalf("compile: %v", err)
  69  	}
  70  
  71  	if len(wasmBytes) == 0 {
  72  		t.Fatal("compiled WASM is empty")
  73  	}
  74  
  75  	// Should be a valid WASM module (starts with \x00asm).
  76  	if len(wasmBytes) < 4 || string(wasmBytes[:4]) != "\x00asm" {
  77  		t.Fatal("compiled output is not a valid WASM module")
  78  	}
  79  
  80  	t.Logf("compiled WASM: %d bytes", len(wasmBytes))
  81  
  82  	// Load it into a registry and verify it works.
  83  	reg, err := NewRegistry(ctx)
  84  	if err != nil {
  85  		t.Fatalf("new registry: %v", err)
  86  	}
  87  	defer reg.Close()
  88  
  89  	manifest := Manifest{Type: TypeEnzyme, Version: 1, Fitness: ratio.Half}
  90  	organ, err := reg.Load(wasmBytes, manifest)
  91  	if err != nil {
  92  		t.Fatalf("load compiled organ: %v", err)
  93  	}
  94  	if organ.Status != StatusLoaded {
  95  		t.Errorf("expected StatusLoaded, got %d", organ.Status)
  96  	}
  97  
  98  	// Call it.
  99  	result, err := reg.Call(organ.Manifest.ID, 0x01, []byte("test"))
 100  	if err != nil {
 101  		t.Fatalf("call: %v", err)
 102  	}
 103  	expected := "ok:\x01test"
 104  	if string(result) != expected {
 105  		t.Errorf("result: want %q, got %q", expected, string(result))
 106  	}
 107  }
 108