Files
el/engram/bindings/go/engram_test.go
T
Will Anderson 2454c83e82 feat: HNSW index, consolidation engine, Kotlin/TS/Go bindings, SQLite migration connector
- vector.rs: replace flat O(n) scan with instant-distance HNSW for stores
  >= 100 nodes; flat scan retained as fallback for small graphs; dirty-flag
  persistence in sled triggers index rebuild only when nodes are added

- consolidation.rs: Episodic → Semantic promotion based on activation_count
  and salience_floor thresholds; global decay pass after each cycle;
  ConsolidationConfig + ConsolidationReport types; 8 tests

- migration.rs: reads Neuron SQLite (memory_nodes, knowledge_entries,
  graph_edges) and writes to Engram sled; placeholder unit-vector embeddings
  with TODO for ONNX; 5 tests including full in-memory DB roundtrip

- crates/engram-migrate: CLI binary (engram-migrate --sqlite / --output)

- crates/engram-jni: JNI cdylib exposing open/close/put_node/get_node/
  activate/search_embedding/touch/decay/node_count/edge_count via
  Java_ai_neuron_engram_EngramDb_* entry points; 6 tests

- bindings/kotlin: EngramDb.kt (AutoCloseable JNI wrapper), EngramNode,
  EngramEdge, ActivatedNode, EngramTypes; build.gradle.kts; settings.gradle.kts

- bindings/typescript: engram-wasm crate (wasm-bindgen, serde-wasm-bindgen);
  WasmEngramDb with in-memory backend (sled not available in WASM);
  TypeScript wrapper (index.ts, types.ts, package.json, tsconfig.json)

- bindings/go: engram.go (CGo wrapper), engram.h (C header), engram_test.go
  (4 tests covering open/close/put_node/get_node/node_count/decay); go.mod

- engram-core: wasm feature gate for in-memory backend; mem_storage.rs;
  activation.activate_mem for WASM path; Node::with_id helper;
  salience.rs doctest fixed (text block)

- examples/basic.rs: consolidation section added
- examples/migrate.rs: migration API demonstration

Build: cargo build --workspace -- zero warnings, zero errors
Tests: 38 pass (25 engram-core + 7 engram-ffi + 6 engram-jni)
2026-04-27 16:00:47 -05:00

131 lines
2.7 KiB
Go

// Package engram basic test.
//
// NOTE: This test requires the FFI shared library to be compiled first:
//
// cargo build --package engram-ffi --release
//
// Then run:
//
// DYLD_LIBRARY_PATH=../../target/release go test ./...
// # or on Linux:
// LD_LIBRARY_PATH=../../target/release go test ./...
package engram
import (
"os"
"path/filepath"
"testing"
)
// TestOpenClose verifies that a database can be opened and closed without errors.
func TestOpenClose(t *testing.T) {
dir := t.TempDir()
db, err := Open(filepath.Join(dir, "test-engram"))
if err != nil {
t.Fatalf("Open: %v", err)
}
defer db.Close()
n, err := db.NodeCount()
if err != nil {
t.Fatalf("NodeCount: %v", err)
}
if n != 0 {
t.Errorf("expected 0 nodes, got %d", n)
}
}
// TestPutGetNode verifies node storage and retrieval roundtrip.
func TestPutGetNode(t *testing.T) {
dir := t.TempDir()
db, err := Open(filepath.Join(dir, "test-engram"))
if err != nil {
t.Fatalf("Open: %v", err)
}
defer db.Close()
input := &NodeInput{
Content: "Spreading activation is the core retrieval mechanism",
NodeType: "Concept",
Tier: "Semantic",
Importance: 0.9,
Embedding: []float32{0.1, 0.2, 0.3, 0.4},
}
id, err := db.PutNode(input)
if err != nil {
t.Fatalf("PutNode: %v", err)
}
if id == "" {
t.Fatal("expected non-empty UUID")
}
node, err := db.GetNode(id)
if err != nil {
t.Fatalf("GetNode: %v", err)
}
if node == nil {
t.Fatal("expected node, got nil")
}
if node.Content != input.Content {
t.Errorf("content mismatch: got %q, want %q", node.Content, input.Content)
}
}
// TestNodeCount verifies node count increments.
func TestNodeCount(t *testing.T) {
dir := t.TempDir()
db, err := Open(filepath.Join(dir, "test-engram"))
if err != nil {
t.Fatalf("Open: %v", err)
}
defer db.Close()
for i := 0; i < 3; i++ {
_, err := db.PutNode(&NodeInput{
Content: "node content",
Embedding: []float32{float32(i), 0.0, 0.0},
})
if err != nil {
t.Fatalf("PutNode[%d]: %v", i, err)
}
}
n, err := db.NodeCount()
if err != nil {
t.Fatalf("NodeCount: %v", err)
}
if n != 3 {
t.Errorf("expected 3 nodes, got %d", n)
}
}
// TestDecay verifies salience decay runs without error.
func TestDecay(t *testing.T) {
dir := t.TempDir()
db, err := Open(filepath.Join(dir, "test-engram"))
if err != nil {
t.Fatalf("Open: %v", err)
}
defer db.Close()
_, err = db.PutNode(&NodeInput{
Content: "test node",
Embedding: []float32{1.0, 0.0},
})
if err != nil {
t.Fatalf("PutNode: %v", err)
}
updated, err := db.Decay(0.95)
if err != nil {
t.Fatalf("Decay: %v", err)
}
if updated == 0 {
t.Error("expected at least one node to be decayed")
}
}
// ensure test file exists (compile guard)
var _ = os.DevNull