clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat/ui-updates
tinyrelay / internal / daemon / lifecycle_test.go
lifecycle_test.go 3.0K
1package daemon23import (4 "context"5 "github.com/FelineStateMachine/tinyrelay/internal/event"6 "strings"7 "testing"8 "time"9)1011func TestServingLifecycleRecoversAndReconcilesCatalog(t *testing.T) {12 ctx := context.Background()13 dir := t.TempDir()14 app, err := New(ctx, Config{DataDir: dir, DefaultTenant: "main"})15 if err != nil {16 t.Fatal(err)17 }18 owner, err := event.PublicKey(strings.Repeat("0", 63) + "1")19 if err != nil {20 t.Fatal(err)21 }22 main, err := app.Create(ctx, CreateOptions{Name: "main", Owner: owner, Template: "default"})23 if err != nil {24 t.Fatal(err)25 }26 if len(app.tenants) != 0 {27 t.Fatal("catalog-only create started tenant workers")28 }29 if err := app.Start(ctx, "http://127.0.0.1:7447"); err != nil {30 t.Fatal(err)31 }32 if app.tenants[main.ID].publicURL != "http://127.0.0.1:7447" {33 t.Fatal("default relay URL lost its listener port")34 }35 other, err := app.Create(ctx, CreateOptions{Name: "other", Owner: owner, Template: "default"})36 if err != nil {37 t.Fatal(err)38 }39 if app.tenants[other.ID].publicURL != "http://127.0.0.1:7447/r/other" {40 t.Fatal("new relay was not started with its tenant path")41 }42 second, err := New(ctx, Config{DataDir: dir})43 if err != nil {44 t.Fatal(err)45 }46 t.Cleanup(func() { _ = second.Close(ctx) })47 if err := second.Start(ctx, "http://127.0.0.1:7448"); err == nil {48 t.Fatal("second serving process acquired the directory")49 }50 old := app.tenants[other.ID]51 if err := app.Catalog().Disable(ctx, other.ID); err != nil {52 t.Fatal(err)53 }54 if err := app.reconcileTenants(ctx, "http://127.0.0.1:7447"); err != nil {55 t.Fatal(err)56 }57 if old.workCtx.Err() == nil {58 t.Fatal("disabled tenant workers still run")59 }60 if err := app.Close(ctx); err != nil {61 t.Fatal(err)62 }63 if err := second.Start(ctx, "http://127.0.0.1:7448"); err != nil {64 t.Fatal(err)65 }66 if second.tenants[main.ID] == nil || second.tenants[other.ID] != nil {67 t.Fatal("restart did not eagerly recover exactly the ready tenants")68 }69 if err := second.Catalog().Enable(ctx, other.ID); err != nil {70 t.Fatal(err)71 }72 deadline := time.Now().Add(3 * time.Second)73 for time.Now().Before(deadline) {74 second.mu.Lock()75 loaded := second.tenants[other.ID] != nil76 second.mu.Unlock()77 if loaded {78 return79 }80 time.Sleep(10 * time.Millisecond)81 }82 t.Fatal("enabled tenant did not restart through catalog reconciliation")83}8485func TestProcessLockExcludesSecondServer(t *testing.T) {86 dir := t.TempDir()87 first, err := AcquireProcessLock(dir)88 if err != nil {89 t.Fatal(err)90 }91 defer first.Close()92 second, err := AcquireProcessLock(dir)93 if err == nil {94 _ = second.Close()95 t.Fatal("second serving process acquired the lock")96 }97 if second != nil {98 t.Fatal("failed lock returned a handle")99 }100}101102func TestProcessLockCanBeReacquiredAfterClose(t *testing.T) {103 dir := t.TempDir()104 first, err := AcquireProcessLock(dir)105 if err != nil {106 t.Fatal(err)107 }108 if err := first.Close(); err != nil {109 t.Fatal(err)110 }111 second, err := AcquireProcessLock(dir)112 if err != nil {113 t.Fatal(err)114 }115 if err := second.Close(); err != nil {116 t.Fatal(err)117 }118}