Artifact f1591b01a2fb97da5de6e34fddbd1ea470834c808429caec51931291b8461d15:
- File
bridge/bridge/integration_test.go
— part of check-in
[eda7960b81]
at
2026-04-23 19:23:42
on branch trunk
— rename module to github.com/danmestas/EdgeSync
Fix the case-sensitive module path to match the actual GitHub repo URL (danmestas/EdgeSync). Remove tracked leaf/leaf binary and ignore .claude/skills/ scratchpad dirs. (user: [email protected], size: 4307) [annotate] [blame] [check-ins using] [more...]
package bridge import ( "fmt" "net" "os" "os/exec" "path/filepath" "testing" "time" leafagent "github.com/danmestas/EdgeSync/leaf/agent" libfossil "github.com/danmestas/libfossil" _ "github.com/danmestas/libfossil/db/driver/modernc" "github.com/danmestas/libfossil/testutil" ) // startFossilServer starts a fossil server on a free port and returns the URL // and a cleanup function. The server is shut down when the test ends. func startFossilServer(t *testing.T, repoPath string) string { t.Helper() bin := testutil.FossilBinary() if bin == "" { t.Skip("fossil not in PATH") } // Find a free port. ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatalf("listen: %v", err) } port := ln.Addr().(*net.TCPAddr).Port ln.Close() cmd := exec.Command(bin, "server", fmt.Sprintf("--port=%d", port), repoPath) cmd.Stdout = os.Stderr cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { t.Fatalf("fossil server start: %v", err) } // Wait for the server to accept connections (poll up to 5s). deadline := time.Now().Add(5 * time.Second) for time.Now().Before(deadline) { conn, err := net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%d", port), 200*time.Millisecond) if err == nil { conn.Close() goto ready } time.Sleep(100 * time.Millisecond) } cmd.Process.Kill() cmd.Wait() t.Fatalf("fossil server did not become ready on port %d within 5s", port) ready: serverURL := fmt.Sprintf("http://127.0.0.1:%d", port) t.Cleanup(func() { cmd.Process.Kill() cmd.Wait() os.Remove(repoPath + "-wal") os.Remove(repoPath + "-shm") }) return serverURL } func TestIntegrationLeafBridgeFossil(t *testing.T) { if !testutil.HasFossil() { t.Skip("fossil not in PATH") } bin := testutil.FossilBinary() dir := t.TempDir() // 1. Create a Go-managed local repo with a checkin. localPath := filepath.Join(dir, "local.fossil") r, err := libfossil.Create(localPath, libfossil.CreateOpts{User: "testuser"}) if err != nil { t.Fatalf("Create: %v", err) } _, _, err = r.Commit(libfossil.CommitOpts{ Files: []libfossil.FileToCommit{ {Name: "hello.txt", Content: []byte("hello from leaf+bridge integration test")}, }, Comment: "initial checkin from leaf+bridge integration test", User: "testuser", Time: time.Date(2026, 3, 15, 12, 0, 0, 0, time.UTC), }) if err != nil { r.Close() t.Fatalf("Commit: %v", err) } r.Close() // 2. Clone to create a matching remote (ensures project-code/server-code match). remotePath := filepath.Join(dir, "remote.fossil") cloneCmd := exec.Command(bin, "clone", localPath, remotePath) cloneOut, err := cloneCmd.CombinedOutput() if err != nil { t.Fatalf("fossil clone: %v\n%s", err, cloneOut) } // 3. Start fossil server on the remote. fossilURL := startFossilServer(t, remotePath) // 4. Start embedded NATS. natsURL := startEmbeddedNATS(t) // Read project-code from the local repo for the bridge config. localRepo, err := libfossil.Open(localPath) if err != nil { t.Fatalf("Open local: %v", err) } projectCode, err := localRepo.Config("project-code") if err != nil { localRepo.Close() t.Fatalf("read project-code: %v", err) } localRepo.Close() // 5. Start Bridge (NATS -> fossil server). b, err := New(Config{ NATSUrl: natsURL, FossilURL: fossilURL, ProjectCode: projectCode, }) if err != nil { t.Fatalf("bridge.New: %v", err) } if err := b.Start(); err != nil { t.Fatalf("bridge.Start: %v", err) } defer b.Stop() // 6. Start leaf Agent (repo -> NATS). a, err := leafagent.New(leafagent.Config{ RepoPath: localPath, NATSUpstream: natsURL, PollInterval: 10 * time.Second, // long interval; we use SyncNow Push: true, Pull: true, User: "anonymous", }) if err != nil { t.Fatalf("leafagent.New: %v", err) } if err := a.Start(); err != nil { t.Fatalf("leafagent.Start: %v", err) } // 7. Trigger SyncNow on leaf. a.SyncNow() // 8. Wait for sync to complete, then log results. time.Sleep(3 * time.Second) // 9. Stop both. if err := a.Stop(); err != nil { t.Fatalf("leafagent.Stop: %v", err) } t.Logf("Integration test completed successfully.") t.Logf(" Fossil server URL: %s", fossilURL) t.Logf(" NATS URL: %s", natsURL) t.Logf(" Project code: %s", projectCode) }