197 lines
4.3 KiB
Go
197 lines
4.3 KiB
Go
package memory
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestClientIngest(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.URL.Path != "/memory/ingest" {
|
||
|
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||
|
|
}
|
||
|
|
|
||
|
|
if r.Header.Get("Authorization") == "" {
|
||
|
|
t.Error("missing Authorization header")
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusCreated)
|
||
|
|
json.NewEncoder(w).Encode(IngestResponse{
|
||
|
|
ID: "chunk-123",
|
||
|
|
SHA256: "abc123",
|
||
|
|
QueueStatus: "pending",
|
||
|
|
})
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL, "test-token")
|
||
|
|
resp, err := client.Ingest(context.Background(), &IngestRequest{
|
||
|
|
Project: "poimen",
|
||
|
|
Source: "test",
|
||
|
|
Kind: "L1",
|
||
|
|
Text: "test content",
|
||
|
|
})
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("ingest failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if resp.ID != "chunk-123" {
|
||
|
|
t.Errorf("expected ID chunk-123, got %s", resp.ID)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClientQuery(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.URL.Path != "/memory/query" {
|
||
|
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(QueryResponse{
|
||
|
|
Query: "test query",
|
||
|
|
TotalHits: 1,
|
||
|
|
SearchTimeMS: 100,
|
||
|
|
Results: []QueryResult{
|
||
|
|
{
|
||
|
|
ID: "chunk-123",
|
||
|
|
Level: "L1",
|
||
|
|
Score: 0.95,
|
||
|
|
Text: "matching result",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL, "test-token")
|
||
|
|
resp, err := client.Query(context.Background(), &QueryRequest{
|
||
|
|
Project: "poimen",
|
||
|
|
Query: "test query",
|
||
|
|
Limit: 10,
|
||
|
|
})
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("query failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(resp.Results) != 1 {
|
||
|
|
t.Errorf("expected 1 result, got %d", len(resp.Results))
|
||
|
|
}
|
||
|
|
|
||
|
|
if resp.Results[0].Text != "matching result" {
|
||
|
|
t.Errorf("unexpected result text")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClientContext(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.URL.Path != "/memory/context" {
|
||
|
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(ContextResponse{
|
||
|
|
Tier: 1,
|
||
|
|
Lessons: []ContextLesson{
|
||
|
|
{
|
||
|
|
Tier: 1,
|
||
|
|
Level: "L1",
|
||
|
|
Score: 1.0,
|
||
|
|
Text: "tier-1 lesson",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
Budget: ContextBudget{
|
||
|
|
Requested: 8192,
|
||
|
|
Used: 100,
|
||
|
|
Dropped: 0,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL, "test-token")
|
||
|
|
resp, err := client.Context(context.Background(), &ContextRequest{
|
||
|
|
Project: "poimen",
|
||
|
|
Tool: "kubectl",
|
||
|
|
Task: "debug",
|
||
|
|
SignatureSource: "log",
|
||
|
|
})
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("context failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if resp.Tier != 1 {
|
||
|
|
t.Errorf("expected tier 1, got %d", resp.Tier)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(resp.Lessons) != 1 {
|
||
|
|
t.Errorf("expected 1 lesson, got %d", len(resp.Lessons))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClientVault(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.URL.Path != "/memory/vault" {
|
||
|
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(VaultResponse{
|
||
|
|
Project: "poimen",
|
||
|
|
TotalRecords: 42,
|
||
|
|
Files: []VaultFile{
|
||
|
|
{
|
||
|
|
Path: "test.md",
|
||
|
|
Title: "Test",
|
||
|
|
Level: "L1",
|
||
|
|
RecordCount: 5,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL, "test-token")
|
||
|
|
resp, err := client.Vault(context.Background(), "poimen")
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("vault failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(resp.Files) != 1 {
|
||
|
|
t.Errorf("expected 1 file, got %d", len(resp.Files))
|
||
|
|
}
|
||
|
|
|
||
|
|
if resp.TotalRecords != 42 {
|
||
|
|
t.Errorf("expected 42 records, got %d", resp.TotalRecords)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestClientHealth(t *testing.T) {
|
||
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
if r.URL.Path != "/health" {
|
||
|
|
t.Errorf("unexpected path: %s", r.URL.Path)
|
||
|
|
}
|
||
|
|
|
||
|
|
w.WriteHeader(http.StatusOK)
|
||
|
|
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
|
||
|
|
}))
|
||
|
|
defer server.Close()
|
||
|
|
|
||
|
|
client := NewClient(server.URL, "test-token")
|
||
|
|
ok, err := client.Health(context.Background())
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("health check failed: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
if !ok {
|
||
|
|
t.Error("expected health check to pass")
|
||
|
|
}
|
||
|
|
}
|