Files
beads/internal/storage/dolt/server_integration_test.go
beads/crew/darcy da4584ae57 feat(federation): add dolt sql-server mode for daemon (bd-wkumz.2)
Add --federation flag to bd daemon start that runs dolt sql-server
instead of the embedded driver. Enables multi-writer support and
exposes remotesapi on port 8080 for peer-to-peer push/pull.

Changes:
- Add --federation flag to daemon start command
- Create dolt server manager (internal/storage/dolt/server.go)
- Update DoltStore to support server mode via MySQL protocol
- Integrate server lifecycle into daemon (auto-start/stop)
- Add tests for server management and server mode connections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:48:24 -08:00

123 lines
3.1 KiB
Go

package dolt
import (
"context"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/steveyegge/beads/internal/types"
)
// TestServerModeConnection tests connecting to DoltStore via server mode
func TestServerModeConnection(t *testing.T) {
// Skip if dolt is not available
if _, err := exec.LookPath("dolt"); err != nil {
t.Skip("dolt not installed, skipping server mode test")
}
// Create temp directory for test
tmpDir, err := os.MkdirTemp("", "dolt-server-mode-test-*")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)
// Initialize dolt repo
cmd := exec.Command("dolt", "init")
cmd.Dir = tmpDir
if err := cmd.Run(); err != nil {
t.Fatalf("failed to init dolt repo: %v", err)
}
// Start server on non-standard ports
server := NewServer(ServerConfig{
DataDir: tmpDir,
SQLPort: 13307,
RemotesAPIPort: 18081,
Host: "127.0.0.1",
LogFile: filepath.Join(tmpDir, "server.log"),
})
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
defer cancel()
if err := server.Start(ctx); err != nil {
t.Fatalf("failed to start server: %v", err)
}
defer func() {
if err := server.Stop(); err != nil {
t.Logf("warning: failed to stop server: %v", err)
}
}()
// Connect using server mode
store, err := New(ctx, &Config{
Path: tmpDir,
Database: "beads",
ServerMode: true,
ServerHost: "127.0.0.1",
ServerPort: 13307,
})
if err != nil {
t.Fatalf("failed to create server mode store: %v", err)
}
defer store.Close()
// Set issue prefix (required for creating issues)
if err := store.SetConfig(ctx, "issue_prefix", "test"); err != nil {
t.Fatalf("failed to set issue_prefix: %v", err)
}
// Verify we can perform basic operations
// Create an issue
issue := &types.Issue{
Title: "Test issue in server mode",
Description: "Original description",
Status: types.StatusOpen,
Priority: 2,
IssueType: types.TypeTask,
}
if err := store.CreateIssue(ctx, issue, "test"); err != nil {
t.Fatalf("failed to create issue: %v", err)
}
if issue.ID == "" {
t.Fatal("expected issue ID to be generated")
}
t.Logf("Created issue: %s", issue.ID)
// Read it back
readIssue, err := store.GetIssue(ctx, issue.ID)
if err != nil {
t.Fatalf("failed to get issue: %v", err)
}
if readIssue.Title != issue.Title {
t.Errorf("title mismatch: expected %q, got %q", issue.Title, readIssue.Title)
}
// Update it
updates := map[string]interface{}{
"description": "Updated description",
"priority": 1,
}
if err := store.UpdateIssue(ctx, issue.ID, updates, "test"); err != nil {
t.Fatalf("failed to update issue: %v", err)
}
// Verify update
updatedIssue, err := store.GetIssue(ctx, issue.ID)
if err != nil {
t.Fatalf("failed to get updated issue: %v", err)
}
if updatedIssue.Description != "Updated description" {
t.Errorf("expected description 'Updated description', got %q", updatedIssue.Description)
}
if updatedIssue.Priority != 1 {
t.Errorf("expected priority 1, got %d", updatedIssue.Priority)
}
t.Logf("Server mode connection test passed: created and updated issue %s", issue.ID)
}