chore: add an e2e test covering first time setup user journeys

This commit is contained in:
Gareth
2025-09-07 01:16:33 -07:00
parent edf992e701
commit 5772c79a16
5 changed files with 140 additions and 4 deletions

View File

@@ -42,8 +42,6 @@ jobs:
- name: Test
run: PATH=$(pwd):$PATH gotestsum ./... -- --race
test-webui: runs-on
test-win:
runs-on: windows-latest
steps:

3
.gitignore vendored
View File

@@ -1,4 +1,3 @@
test*
backrest-*
dist
__debug_bin
@@ -6,4 +5,4 @@ cmd/backrest/backrest
*.exe
.DS_Store
.idea/
.pnpm-store/
.pnpm-store/

1
go.mod
View File

@@ -46,6 +46,7 @@ require (
require (
github.com/akavel/rsrc v0.10.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bufbuild/connect-go v1.10.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dchest/jsmin v1.0.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect

2
go.sum
View File

@@ -11,6 +11,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bool64/dev v0.2.39 h1:kP8DnMGlWXhGYJEZE/J0l/gVBdbuhoPGL+MJG4QbofE=
github.com/bool64/dev v0.2.39/go.mod h1:iJbh1y/HkunEPhgebWRNcs8wfGq7sjvJ6W5iabL8ACg=
github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg=
github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=

136
test/e2e/first_run_test.go Normal file
View File

@@ -0,0 +1,136 @@
package e2e
import (
"context"
"fmt"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
"time"
"connectrpc.com/connect"
"github.com/garethgeorge/backrest/gen/go/types"
v1 "github.com/garethgeorge/backrest/gen/go/v1"
"github.com/garethgeorge/backrest/gen/go/v1/v1connect"
"github.com/garethgeorge/backrest/internal/testutil"
"google.golang.org/protobuf/types/known/emptypb"
)
func TestFirstRun(t *testing.T) {
tmpDir, err := os.MkdirTemp("", "backrest-e2e-test")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)
binPath := filepath.Join(tmpDir, "backrest")
if runtime.GOOS == "windows" {
binPath += ".exe"
}
// Build backrest binary
buildCmd := exec.Command("go", "build", "-o", binPath, "../../cmd/backrest")
buildCmd.Stderr = os.Stderr
buildCmd.Stdout = os.Stdout
if err := buildCmd.Run(); err != nil {
t.Fatalf("failed to build backrest binary: %v", err)
}
addr := testutil.AllocOpenBindAddr(t)
// Run backrest
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
cmd := exec.CommandContext(ctx, binPath,
"-data-dir", tmpDir, "-config-file",
filepath.Join(tmpDir, "config.json"),
"-bind-address", addr)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Start(); err != nil {
t.Fatalf("failed to start backrest: %v", err)
}
testutil.TryNonfatal(t, ctx, func() error {
resp, err := http.Get(fmt.Sprintf("http://%s", addr))
if err != nil {
return err
}
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("expected status code %d, got %d", http.StatusOK, resp.StatusCode)
}
return nil
})
t.Run("set instance ID", func(t *testing.T) {
client := v1connect.NewBackrestClient(
http.DefaultClient,
fmt.Sprintf("http://%s", addr),
)
req := connect.NewRequest(&v1.Config{
Instance: "TestInstance",
})
resp, err := client.SetConfig(context.Background(), req)
if err != nil {
t.Fatalf("SetConfig failed: %v", err)
}
if resp.Msg.Instance != "TestInstance" {
t.Errorf("expected instance ID to be 'TestInstance', got %q", resp.Msg.Instance)
}
})
t.Run("get config", func(t *testing.T) {
client := v1connect.NewBackrestClient(
http.DefaultClient,
fmt.Sprintf("http://%s", addr),
)
req := connect.NewRequest(&emptypb.Empty{})
resp, err := client.GetConfig(context.Background(), req)
if err != nil {
t.Fatalf("GetConfig failed: %v", err)
}
if resp.Msg.Instance != "TestInstance" {
t.Errorf("expected instance ID to be 'TestInstance', got %q", resp.Msg.Instance)
}
})
t.Run("add repo", func(t *testing.T) {
client := v1connect.NewBackrestClient(
http.DefaultClient,
fmt.Sprintf("http://%s", addr),
)
req := connect.NewRequest(&v1.Repo{
Id: "test-repo",
Uri: filepath.Join(tmpDir, "test-repo"),
})
_, err := client.AddRepo(context.Background(), req)
if err != nil {
t.Fatalf("AddRepo failed: %v", err)
}
})
t.Run("trigger backup", func(t *testing.T) {
client := v1connect.NewBackrestClient(
http.DefaultClient,
fmt.Sprintf("http://%s", addr),
)
req := connect.NewRequest(&types.StringValue{
Value: "test-repo",
})
_, err := client.Backup(context.Background(), req)
if err != nil {
t.Fatalf("Backup failed: %v", err)
}
})
}