1
0
Fork 0
forked from lthn/LEM
LEM/influx_test.go
Claude e0d352c803
feat: add Go lem CLI and scoring-agent scripts
Go lem CLI (stdlib + DuckDB) replaces scattered Python scripts:
- score: heuristic regex + LLM-as-judge scoring
- probe: generate responses then score
- compare: diff two score files
- status: InfluxDB training/generation progress
- export: golden set to training JSONL splits
- expand: distributed expansion via API + InfluxDB coordination

New scripts from Feb 14 creative session:
- scoring_agent.py: ROCm daemon that auto-scores checkpoints
- probes.py: 23 binary pass/fail capability probes
- convert_adapter.py: MLX to PEFT adapter conversion
- score_r1_capability.py: DeepSeek R1 checkpoint scoring
- lek_content_scorer.py: 6-dimension ethics content scorer
- lem_train_15k.py: InfluxDB-coordinated training script
- pipeline.py: DuckDB pipeline (seeds, golden set, expansion)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:22:13 +00:00

265 lines
7 KiB
Go

package main
import (
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
)
func TestEscapeLp(t *testing.T) {
tests := []struct {
name string
in string
want string
}{
{name: "no special chars", in: "hello", want: "hello"},
{name: "spaces", in: "hello world", want: `hello\ world`},
{name: "commas", in: "a,b,c", want: `a\,b\,c`},
{name: "equals", in: "key=val", want: `key\=val`},
{name: "all specials", in: "a b,c=d", want: `a\ b\,c\=d`},
{name: "empty string", in: "", want: ""},
{name: "multiple spaces", in: "a b", want: `a\ \ b`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := escapeLp(tt.in)
if got != tt.want {
t.Errorf("escapeLp(%q) = %q, want %q", tt.in, got, tt.want)
}
})
}
}
func TestNewInfluxClientTokenFromEnv(t *testing.T) {
t.Setenv("INFLUX_TOKEN", "env-token-123")
client := NewInfluxClient("http://localhost:8181", "testdb")
if client.token != "env-token-123" {
t.Errorf("expected token 'env-token-123', got %q", client.token)
}
if client.url != "http://localhost:8181" {
t.Errorf("expected url 'http://localhost:8181', got %q", client.url)
}
if client.db != "testdb" {
t.Errorf("expected db 'testdb', got %q", client.db)
}
}
func TestNewInfluxClientTokenFromFile(t *testing.T) {
// Clear env var so file is used.
t.Setenv("INFLUX_TOKEN", "")
// Write a temp token file.
tmpDir := t.TempDir()
tokenFile := filepath.Join(tmpDir, ".influx_token")
if err := os.WriteFile(tokenFile, []byte("file-token-456\n"), 0600); err != nil {
t.Fatalf("write token file: %v", err)
}
// Override home dir so NewInfluxClient reads our temp file.
t.Setenv("HOME", tmpDir)
client := NewInfluxClient("", "")
if client.token != "file-token-456" {
t.Errorf("expected token 'file-token-456', got %q", client.token)
}
}
func TestNewInfluxClientDefaults(t *testing.T) {
t.Setenv("INFLUX_TOKEN", "tok")
client := NewInfluxClient("", "")
if client.url != "http://10.69.69.165:8181" {
t.Errorf("expected default url, got %q", client.url)
}
if client.db != "training" {
t.Errorf("expected default db 'training', got %q", client.db)
}
}
func TestWriteLp(t *testing.T) {
var gotBody string
var gotAuth string
var gotContentType string
var gotPath string
var gotQuery string
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath = r.URL.Path
gotQuery = r.URL.Query().Get("db")
gotAuth = r.Header.Get("Authorization")
gotContentType = r.Header.Get("Content-Type")
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("read body: %v", err)
}
gotBody = string(body)
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
lines := []string{
"cpu,host=server01 value=0.64",
"cpu,host=server02 value=0.72",
}
err := client.WriteLp(lines)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gotPath != "/api/v3/write_lp" {
t.Errorf("expected path /api/v3/write_lp, got %q", gotPath)
}
if gotQuery != "testdb" {
t.Errorf("expected db=testdb, got %q", gotQuery)
}
if gotAuth != "Bearer test-token" {
t.Errorf("expected 'Bearer test-token', got %q", gotAuth)
}
if gotContentType != "text/plain" {
t.Errorf("expected 'text/plain', got %q", gotContentType)
}
want := "cpu,host=server01 value=0.64\ncpu,host=server02 value=0.72"
if gotBody != want {
t.Errorf("expected body %q, got %q", want, gotBody)
}
}
func TestWriteLpError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("invalid line protocol"))
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
err := client.WriteLp([]string{"bad data"})
if err == nil {
t.Fatal("expected error for 400 response, got nil")
}
}
func TestQuerySQL(t *testing.T) {
var gotBody map[string]string
var gotAuth string
var gotContentType string
var gotPath string
responseData := []map[string]interface{}{
{"id": "row1", "score": float64(7.5)},
{"id": "row2", "score": float64(8.2)},
}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotPath = r.URL.Path
gotAuth = r.Header.Get("Authorization")
gotContentType = r.Header.Get("Content-Type")
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatalf("read body: %v", err)
}
if err := json.Unmarshal(body, &gotBody); err != nil {
t.Fatalf("unmarshal request body: %v", err)
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(responseData)
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
rows, err := client.QuerySQL("SELECT * FROM scores LIMIT 2")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if gotPath != "/api/v3/query_sql" {
t.Errorf("expected path /api/v3/query_sql, got %q", gotPath)
}
if gotAuth != "Bearer test-token" {
t.Errorf("expected 'Bearer test-token', got %q", gotAuth)
}
if gotContentType != "application/json" {
t.Errorf("expected 'application/json', got %q", gotContentType)
}
if gotBody["db"] != "testdb" {
t.Errorf("expected db 'testdb' in body, got %q", gotBody["db"])
}
if gotBody["q"] != "SELECT * FROM scores LIMIT 2" {
t.Errorf("expected query in body, got %q", gotBody["q"])
}
if len(rows) != 2 {
t.Fatalf("expected 2 rows, got %d", len(rows))
}
if rows[0]["id"] != "row1" {
t.Errorf("expected row 0 id 'row1', got %v", rows[0]["id"])
}
if rows[1]["score"] != 8.2 {
t.Errorf("expected row 1 score 8.2, got %v", rows[1]["score"])
}
}
func TestQuerySQLError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("internal error"))
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
_, err := client.QuerySQL("SELECT bad")
if err == nil {
t.Fatal("expected error for 500 response, got nil")
}
}
func TestQuerySQLBadJSON(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte("not valid json"))
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
_, err := client.QuerySQL("SELECT 1")
if err == nil {
t.Fatal("expected error for invalid JSON response, got nil")
}
}
func TestWriteLpEmptyLines(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
t.Setenv("INFLUX_TOKEN", "test-token")
client := NewInfluxClient(server.URL, "testdb")
// Empty slice should still work -- sends empty body.
err := client.WriteLp([]string{})
if err != nil {
t.Fatalf("unexpected error for empty lines: %v", err)
}
}