All checks were successful
release-tag / release-image (push) Successful in 2m43s
124 lines
4.3 KiB
Go
124 lines
4.3 KiB
Go
package sourceagent
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/local/glpi-neural-brain/internal/vectorgraph"
|
|
)
|
|
|
|
func TestVectorGraphComputeWireRoundTrip(t *testing.T) {
|
|
request := VectorGraphComputeRequest{
|
|
Header: VectorGraphComputeHeader{
|
|
SchemaVersion: SchemaVersion,
|
|
JobID: "compute-test",
|
|
Kind: ComputeKindVectorGraph,
|
|
GraphVersion: 42,
|
|
Primary: vectorgraph.Config{Neighbors: 2, CandidateLimit: 8, HashBits: 8, HashTables: 2, BandBits: 4, MinSimilarity: .8, MinAffinity: .2},
|
|
OrphanPass: true,
|
|
OrphanFocusIDs: []string{"c"},
|
|
},
|
|
Entries: []vectorgraph.Entry{
|
|
{ID: "a", Vector: []float32{1, 0, 0}},
|
|
{ID: "b", Vector: []float32{.99, .01, 0}},
|
|
{ID: "c", Vector: []float32{.98, .02, 0}},
|
|
},
|
|
}
|
|
var buffer bytes.Buffer
|
|
if err := WriteVectorGraphJob(&buffer, request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
decoded, err := ReadVectorGraphJob(bytes.NewReader(buffer.Bytes()), 1<<20)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if decoded.Header.JobID != request.Header.JobID || decoded.Header.GraphVersion != 42 || len(decoded.Entries) != 3 {
|
|
t.Fatalf("unexpected decoded job: %+v", decoded.Header)
|
|
}
|
|
for i := range request.Entries {
|
|
if decoded.Entries[i].ID != request.Entries[i].ID || len(decoded.Entries[i].Vector) != len(request.Entries[i].Vector) {
|
|
t.Fatalf("entry %d mismatch: got=%+v want=%+v", i, decoded.Entries[i], request.Entries[i])
|
|
}
|
|
for j := range request.Entries[i].Vector {
|
|
if decoded.Entries[i].Vector[j] != request.Entries[i].Vector[j] {
|
|
t.Fatalf("entry %d vector %d mismatch", i, j)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestExecuteVectorGraphJobRunsOrphanSecondPassWithoutModel(t *testing.T) {
|
|
entries := []vectorgraph.Entry{
|
|
{ID: "a", Vector: []float32{1, 0, 0}},
|
|
{ID: "b", Vector: []float32{.99, .01, 0}},
|
|
{ID: "orphan", Vector: []float32{.97, .03, 0}},
|
|
{ID: "far", Vector: []float32{0, 1, 0}},
|
|
}
|
|
request := VectorGraphComputeRequest{Header: VectorGraphComputeHeader{
|
|
SchemaVersion: SchemaVersion, JobID: "compute-orphan", Kind: ComputeKindVectorGraph, GraphVersion: 7,
|
|
Primary: vectorgraph.Config{Neighbors: 1, CandidateLimit: 4, HashBits: 8, HashTables: 2, BandBits: 4, MinSimilarity: .995, MinAffinity: .2},
|
|
OrphanPass: true,
|
|
Orphan: vectorgraph.Config{Neighbors: 1, CandidateLimit: 8, HashBits: 8, HashTables: 2, BandBits: 4, MinSimilarity: .90, MinAffinity: .1},
|
|
OrphanFocusIDs: []string{"orphan"},
|
|
}, Entries: entries}
|
|
result := ExecuteVectorGraphJob(request)
|
|
if result.Kind != ComputeKindVectorGraph || result.GraphVersion != 7 || result.Error != "" {
|
|
t.Fatalf("unexpected result: %+v", result)
|
|
}
|
|
if result.Orphan.Stats.Focused == 0 {
|
|
t.Fatalf("orphan pass did not inspect requested focus: %+v", result.Orphan.Stats)
|
|
}
|
|
for _, link := range result.Orphan.Links {
|
|
if link.Source != "orphan" && link.Target != "orphan" {
|
|
t.Fatalf("orphan pass emitted unrelated link: %+v", link)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVectorGraphComputeBrokerClaimComplete(t *testing.T) {
|
|
store := &Store{computeJobs: map[string]*computeJobState{}}
|
|
request := VectorGraphComputeRequest{Header: VectorGraphComputeHeader{JobID: "broker-job", Kind: ComputeKindVectorGraph, GraphVersion: 9}, Entries: []vectorgraph.Entry{{ID: "a", Vector: []float32{1, 0}}, {ID: "b", Vector: []float32{.99, .01}}}}
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
resultCh := make(chan VectorGraphComputeResult, 1)
|
|
errCh := make(chan error, 1)
|
|
go func() {
|
|
result, err := store.SubmitVectorGraphJob(ctx, request)
|
|
if err != nil {
|
|
errCh <- err
|
|
return
|
|
}
|
|
resultCh <- result
|
|
}()
|
|
|
|
deadline := time.Now().Add(time.Second)
|
|
var claimed VectorGraphComputeRequest
|
|
var ok bool
|
|
for time.Now().Before(deadline) {
|
|
claimed, ok = store.ClaimVectorGraphJob("agent-cpu", time.Minute)
|
|
if ok {
|
|
break
|
|
}
|
|
time.Sleep(time.Millisecond)
|
|
}
|
|
if !ok || claimed.Header.JobID != "broker-job" {
|
|
t.Fatalf("compute job was not claimable: ok=%v job=%+v", ok, claimed.Header)
|
|
}
|
|
result := ExecuteVectorGraphJob(claimed)
|
|
if err := store.CompleteVectorGraphJob("agent-cpu", result); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
select {
|
|
case err := <-errCh:
|
|
t.Fatal(err)
|
|
case got := <-resultCh:
|
|
if got.AgentID != "agent-cpu" || got.GraphVersion != 9 || got.Kind != ComputeKindVectorGraph {
|
|
t.Fatalf("unexpected completed result: %+v", got)
|
|
}
|
|
case <-ctx.Done():
|
|
t.Fatal(ctx.Err())
|
|
}
|
|
}
|