Add RPC infrastructure and updated database

- RPC Phase 1: Protocol, server, client implementation
- Updated renumber.go with proper text reference updates (3-phase approach)
- Clean database exported: 344 issues (bd-1 to bd-344)
- Added DAEMON_DESIGN.md documentation
- Updated go.mod/go.sum for RPC dependencies

Amp-Thread-ID: https://ampcode.com/threads/T-456af77c-8b7f-4004-9027-c37b95e10ea5
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-16 20:36:23 -07:00
parent 44550df33e
commit 872f203c57
11 changed files with 1606 additions and 720 deletions

115
internal/rpc/client_test.go Normal file
View File

@@ -0,0 +1,115 @@
package rpc
import (
"path/filepath"
"testing"
"time"
)
func TestTryConnectNoSocket(t *testing.T) {
tmpDir := t.TempDir()
sockPath := filepath.Join(tmpDir, "nonexistent.sock")
client := TryConnect(sockPath)
if client != nil {
t.Error("Expected nil client when socket doesn't exist")
}
}
func TestTryConnectSuccess(t *testing.T) {
tmpDir := t.TempDir()
sockPath := filepath.Join(tmpDir, "test.sock")
store := &mockStorage{}
server := NewServer(store, sockPath)
if err := server.Start(); err != nil {
t.Fatalf("Failed to start server: %v", err)
}
defer server.Stop()
time.Sleep(100 * time.Millisecond)
client := TryConnect(sockPath)
if client == nil {
t.Fatal("Expected client to connect successfully")
}
defer client.Close()
if client.sockPath != sockPath {
t.Errorf("Expected sockPath %s, got %s", sockPath, client.sockPath)
}
}
func TestClientExecute(t *testing.T) {
tmpDir := t.TempDir()
sockPath := filepath.Join(tmpDir, "test.sock")
store := &mockStorage{}
server := NewServer(store, sockPath)
if err := server.Start(); err != nil {
t.Fatalf("Failed to start server: %v", err)
}
defer server.Stop()
time.Sleep(100 * time.Millisecond)
client := TryConnect(sockPath)
if client == nil {
t.Fatal("Failed to connect to server")
}
defer client.Close()
req, _ := NewRequest(OpList, map[string]string{"status": "open"})
resp, err := client.Execute(req)
if err != nil {
t.Fatalf("Execute failed: %v", err)
}
if resp.Success {
t.Error("Expected error response for unimplemented operation")
}
}
func TestClientMultipleRequests(t *testing.T) {
tmpDir := t.TempDir()
sockPath := filepath.Join(tmpDir, "test.sock")
store := &mockStorage{}
server := NewServer(store, sockPath)
if err := server.Start(); err != nil {
t.Fatalf("Failed to start server: %v", err)
}
defer server.Stop()
time.Sleep(100 * time.Millisecond)
client := TryConnect(sockPath)
if client == nil {
t.Fatal("Failed to connect to server")
}
defer client.Close()
for i := 0; i < 5; i++ {
req, _ := NewRequest(OpStats, nil)
resp, err := client.Execute(req)
if err != nil {
t.Fatalf("Execute %d failed: %v", i, err)
}
if resp == nil {
t.Fatalf("Execute %d returned nil response", i)
}
}
}
func TestSocketPath(t *testing.T) {
beadsDir := "/home/user/project/.beads"
expected := "/home/user/project/.beads/bd.sock"
result := SocketPath(beadsDir)
if result != expected {
t.Errorf("Expected %s, got %s", expected, result)
}
}