This repository has been archived on 2026-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
ollie-core/pkg/tools/execute/registry_test.go

222 lines
4.7 KiB
Go

package execute
import (
"os"
"testing"
)
func init() {
os.Setenv("OLLIE_TOOLS_PATH", "testdata/tools")
}
func TestOrderArgsBySchema(t *testing.T) {
script := `#!/usr/bin/env bash
# args_json: {"type":"object","properties":{"pattern":{"type":"string"},"path":{"type":"string"}},"required":["pattern"]}
# ollie:prompt
# ## test_tool
# ollie:end
`
// Run 100 times to ensure deterministic ordering
for i := 0; i < 100; i++ {
argMap := map[string]interface{}{
"pattern": "*.go",
"path": "/some/dir",
}
result := orderArgsBySchema(script, argMap)
if len(result) != 2 {
t.Fatalf("iteration %d: expected 2 args, got %d: %v", i, len(result), result)
}
if result[0] != "*.go" {
t.Fatalf("iteration %d: expected result[0]='*.go', got %q", i, result[0])
}
if result[1] != "/some/dir" {
t.Fatalf("iteration %d: expected result[1]='/some/dir', got %q", i, result[1])
}
}
}
func TestOrderArgsBySchemaReversed(t *testing.T) {
script := `#!/usr/bin/env bash
# args_json: {"type":"object","properties":{"path":{"type":"string"},"pattern":{"type":"string"}},"required":["path"]}
# ollie:prompt
# ## test_tool
# ollie:end
`
for i := 0; i < 100; i++ {
argMap := map[string]interface{}{
"pattern": "*.go",
"path": "/some/dir",
}
result := orderArgsBySchema(script, argMap)
if len(result) != 2 {
t.Fatalf("iteration %d: expected 2 args, got %d: %v", i, len(result), result)
}
if result[0] != "/some/dir" {
t.Fatalf("iteration %d: expected result[0]='/some/dir', got %q", i, result[0])
}
if result[1] != "*.go" {
t.Fatalf("iteration %d: expected result[1]='*.go', got %q", i, result[1])
}
}
}
func TestRegistryLoadUnload(t *testing.T) {
r, err := NewRegistry()
if err != nil {
t.Fatalf("NewRegistry: %v", err)
}
// Check global discovery
names := r.GlobalToolNames()
if len(names) == 0 {
t.Fatal("expected at least one tool")
}
// Load a tool
sid := "test-session-1"
err = r.Load(sid, names[0])
if err != nil {
t.Fatalf("Load: %v", err)
}
// Loaded should have 1 tool
loaded := r.Loaded(sid)
if len(loaded) != 1 {
t.Fatalf("expected 1 loaded tool, got %d", len(loaded))
}
if loaded[0].Name != names[0] {
t.Fatalf("expected %s, got %s", names[0], loaded[0].Name)
}
// Revision should be 1
rev := r.Revision(sid)
if rev != 1 {
t.Fatalf("expected revision 1, got %d", rev)
}
// Lookup should work
_, ok := r.Lookup(sid, names[0])
if !ok {
t.Fatal("Lookup should find promoted tool")
}
// Unload
err = r.Unload(sid, names[0])
if err != nil {
t.Fatalf("Unload: %v", err)
}
// Revision should be 2
rev = r.Revision(sid)
if rev != 2 {
t.Fatalf("expected revision 2, got %d", rev)
}
// Loaded should be empty
loaded = r.Loaded(sid)
if len(loaded) != 0 {
t.Fatalf("expected 0 loaded tools, got %d", len(loaded))
}
}
func TestRegistrySummaries(t *testing.T) {
r, err := NewRegistry()
if err != nil {
t.Fatalf("NewRegistry: %v", err)
}
summaries := r.Summaries()
if len(summaries) == 0 {
t.Fatal("expected at least one summary")
}
for _, s := range summaries {
if s.Name == "" {
t.Fatal("summary missing name")
}
}
}
func TestRegistryIdempotentLoad(t *testing.T) {
r, err := NewRegistry()
if err != nil {
t.Fatalf("NewRegistry: %v", err)
}
names := r.GlobalToolNames()
if len(names) == 0 {
t.Fatal("expected at least one tool")
}
sid := "test-session-2"
// Load twice
err = r.Load(sid, names[0])
if err != nil {
t.Fatalf("first Load: %v", err)
}
rev1 := r.Revision(sid)
err = r.Load(sid, names[0])
if err != nil {
t.Fatalf("second Load: %v", err)
}
rev2 := r.Revision(sid)
if rev1 != rev2 {
t.Fatal("idempotent load should not bump revision")
}
}
func TestRegistryToolNotFound(t *testing.T) {
r, err := NewRegistry()
if err != nil {
t.Fatalf("NewRegistry: %v", err)
}
err = r.Load("test", "nonexistent-tool")
if err == nil {
t.Fatal("expected error for nonexistent tool")
}
}
func TestRegistryServerListTools(t *testing.T) {
r, err := NewRegistry()
if err != nil {
t.Fatalf("NewRegistry: %v", err)
}
names := r.GlobalToolNames()
if len(names) == 0 {
t.Fatal("expected at least one tool")
}
sid := "test-session-3"
r.Load(sid, names[0])
srv := &Server{}
srv.SetToolRegistry(r, sid)
tools, err := srv.ListTools()
if err != nil {
t.Fatalf("ListTools: %v", err)
}
if len(tools) < 1 {
t.Fatalf("expected at least 1 tool, got %d", len(tools))
}
// First tool is execute_code, promoted tools come after
found := false
for _, ti := range tools {
if ti.Name == names[0] {
found = true
break
}
}
if !found {
t.Fatalf("expected promoted tool %s in list", names[0])
}
if tools[0].InputSchema == nil {
t.Fatal("expected InputSchema to be non-nil")
}
}