Add end-to-end replication/restore testing
This commit is contained in:
@@ -16,7 +16,7 @@ func TestDatabasesCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"databases", "-config", filepath.Join(testDir, "litestream.yml")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -26,7 +26,7 @@ func TestDatabasesCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"databases", "-config", filepath.Join(testDir, "litestream.yml")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -74,7 +74,7 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (ret error)
|
||||
fmt.Fprintln(w, "name\tgeneration\tlag\tstart\tend")
|
||||
|
||||
for _, r := range replicas {
|
||||
generations, err := r.Client.Generations(ctx)
|
||||
generations, err := r.Client().Generations(ctx)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.stderr, "%s: cannot list generations: %s", r.Name(), err)
|
||||
ret = errExit // signal error return without printing message
|
||||
@@ -83,7 +83,7 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (ret error)
|
||||
|
||||
// Iterate over each generation for the replica.
|
||||
for _, generation := range generations {
|
||||
createdAt, updatedAt, err := litestream.GenerationTimeBounds(ctx, r.Client, generation)
|
||||
createdAt, updatedAt, err := litestream.GenerationTimeBounds(ctx, r.Client(), generation)
|
||||
if err != nil {
|
||||
fmt.Fprintf(c.stderr, "%s: cannot determine generation time bounds: %s", r.Name(), err)
|
||||
ret = errExit // signal error return without printing message
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestGenerationsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"generations", "-config", filepath.Join(testDir, "litestream.yml"), filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -30,7 +30,7 @@ func TestGenerationsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"generations", "-config", filepath.Join(testDir, "litestream.yml"), "-replica", "replica1", filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -43,7 +43,7 @@ func TestGenerationsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"generations", replicaURL}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -55,7 +55,7 @@ func TestGenerationsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"generations", "-config", filepath.Join(testDir, "litestream.yml"), filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -38,6 +38,7 @@ var errExit = errors.New("exit")
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
m := NewMain(os.Stdin, os.Stdout, os.Stderr)
|
||||
if err := m.Run(context.Background(), os.Args[1:]); err == flag.ErrHelp || err == errExit {
|
||||
@@ -354,8 +355,35 @@ func NewReplicaFromConfig(c *ReplicaConfig, db *litestream.DB) (_ *litestream.Re
|
||||
return nil, fmt.Errorf("replica path cannot be a url, please use the 'url' field instead: %s", c.Path)
|
||||
}
|
||||
|
||||
// Build and set client on replica.
|
||||
var client litestream.ReplicaClient
|
||||
switch typ := c.ReplicaType(); typ {
|
||||
case "file":
|
||||
if client, err = newFileReplicaClientFromConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "s3":
|
||||
if client, err = newS3ReplicaClientFromConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "gcs":
|
||||
if client, err = newGCSReplicaClientFromConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "abs":
|
||||
if client, err = newABSReplicaClientFromConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "sftp":
|
||||
if client, err = newSFTPReplicaClientFromConfig(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown replica type in config: %q", typ)
|
||||
}
|
||||
|
||||
// Build replica.
|
||||
r := litestream.NewReplica(db, c.Name)
|
||||
r := litestream.NewReplica(db, c.Name, client)
|
||||
if v := c.Retention; v != nil {
|
||||
r.Retention = *v
|
||||
}
|
||||
@@ -372,37 +400,11 @@ func NewReplicaFromConfig(c *ReplicaConfig, db *litestream.DB) (_ *litestream.Re
|
||||
r.ValidationInterval = *v
|
||||
}
|
||||
|
||||
// Build and set client on replica.
|
||||
switch typ := c.ReplicaType(); typ {
|
||||
case "file":
|
||||
if r.Client, err = newFileReplicaClientFromConfig(c, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "s3":
|
||||
if r.Client, err = newS3ReplicaClientFromConfig(c, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "gcs":
|
||||
if r.Client, err = newGCSReplicaClientFromConfig(c, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "abs":
|
||||
if r.Client, err = newABSReplicaClientFromConfig(c, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "sftp":
|
||||
if r.Client, err = newSFTPReplicaClientFromConfig(c, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown replica type in config: %q", typ)
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// newFileReplicaClientFromConfig returns a new instance of FileReplicaClient built from config.
|
||||
func newFileReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *litestream.FileReplicaClient, err error) {
|
||||
func newFileReplicaClientFromConfig(c *ReplicaConfig) (_ *litestream.FileReplicaClient, err error) {
|
||||
// Ensure URL & path are not both specified.
|
||||
if c.URL != "" && c.Path != "" {
|
||||
return nil, fmt.Errorf("cannot specify url & path for file replica")
|
||||
@@ -431,7 +433,7 @@ func newFileReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_
|
||||
}
|
||||
|
||||
// newS3ReplicaClientFromConfig returns a new instance of s3.ReplicaClient built from config.
|
||||
func newS3ReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *s3.ReplicaClient, err error) {
|
||||
func newS3ReplicaClientFromConfig(c *ReplicaConfig) (_ *s3.ReplicaClient, err error) {
|
||||
// Ensure URL & constituent parts are not both specified.
|
||||
if c.URL != "" && c.Path != "" {
|
||||
return nil, fmt.Errorf("cannot specify url & path for s3 replica")
|
||||
@@ -494,7 +496,7 @@ func newS3ReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *s
|
||||
}
|
||||
|
||||
// newGCSReplicaClientFromConfig returns a new instance of gcs.ReplicaClient built from config.
|
||||
func newGCSReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *gcs.ReplicaClient, err error) {
|
||||
func newGCSReplicaClientFromConfig(c *ReplicaConfig) (_ *gcs.ReplicaClient, err error) {
|
||||
// Ensure URL & constituent parts are not both specified.
|
||||
if c.URL != "" && c.Path != "" {
|
||||
return nil, fmt.Errorf("cannot specify url & path for gcs replica")
|
||||
@@ -533,7 +535,7 @@ func newGCSReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *
|
||||
}
|
||||
|
||||
// newABSReplicaClientFromConfig returns a new instance of abs.ReplicaClient built from config.
|
||||
func newABSReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *abs.ReplicaClient, err error) {
|
||||
func newABSReplicaClientFromConfig(c *ReplicaConfig) (_ *abs.ReplicaClient, err error) {
|
||||
// Ensure URL & constituent parts are not both specified.
|
||||
if c.URL != "" && c.Path != "" {
|
||||
return nil, fmt.Errorf("cannot specify url & path for abs replica")
|
||||
@@ -576,7 +578,7 @@ func newABSReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *
|
||||
}
|
||||
|
||||
// newSFTPReplicaClientFromConfig returns a new instance of sftp.ReplicaClient built from config.
|
||||
func newSFTPReplicaClientFromConfig(c *ReplicaConfig, r *litestream.Replica) (_ *sftp.ReplicaClient, err error) {
|
||||
func newSFTPReplicaClientFromConfig(c *ReplicaConfig) (_ *sftp.ReplicaClient, err error) {
|
||||
// Ensure URL & constituent parts are not both specified.
|
||||
if c.URL != "" && c.Path != "" {
|
||||
return nil, fmt.Errorf("cannot specify url & path for sftp replica")
|
||||
|
||||
@@ -104,7 +104,7 @@ func TestNewFileReplicaFromConfig(t *testing.T) {
|
||||
r, err := main.NewReplicaFromConfig(&main.ReplicaConfig{Path: "/foo"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if client, ok := r.Client.(*litestream.FileReplicaClient); !ok {
|
||||
} else if client, ok := r.Client().(*litestream.FileReplicaClient); !ok {
|
||||
t.Fatal("unexpected replica type")
|
||||
} else if got, want := client.Path(), "/foo"; got != want {
|
||||
t.Fatalf("Path=%s, want %s", got, want)
|
||||
@@ -116,7 +116,7 @@ func TestNewS3ReplicaFromConfig(t *testing.T) {
|
||||
r, err := main.NewReplicaFromConfig(&main.ReplicaConfig{URL: "s3://foo/bar"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if client, ok := r.Client.(*s3.ReplicaClient); !ok {
|
||||
} else if client, ok := r.Client().(*s3.ReplicaClient); !ok {
|
||||
t.Fatal("unexpected replica type")
|
||||
} else if got, want := client.Bucket, "foo"; got != want {
|
||||
t.Fatalf("Bucket=%s, want %s", got, want)
|
||||
@@ -135,7 +135,7 @@ func TestNewS3ReplicaFromConfig(t *testing.T) {
|
||||
r, err := main.NewReplicaFromConfig(&main.ReplicaConfig{URL: "s3://foo.localhost:9000/bar"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if client, ok := r.Client.(*s3.ReplicaClient); !ok {
|
||||
} else if client, ok := r.Client().(*s3.ReplicaClient); !ok {
|
||||
t.Fatal("unexpected replica type")
|
||||
} else if got, want := client.Bucket, "foo"; got != want {
|
||||
t.Fatalf("Bucket=%s, want %s", got, want)
|
||||
@@ -154,7 +154,7 @@ func TestNewS3ReplicaFromConfig(t *testing.T) {
|
||||
r, err := main.NewReplicaFromConfig(&main.ReplicaConfig{URL: "s3://foo.s3.us-west-000.backblazeb2.com/bar"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if client, ok := r.Client.(*s3.ReplicaClient); !ok {
|
||||
} else if client, ok := r.Client().(*s3.ReplicaClient); !ok {
|
||||
t.Fatal("unexpected replica type")
|
||||
} else if got, want := client.Bucket, "foo"; got != want {
|
||||
t.Fatalf("Bucket=%s, want %s", got, want)
|
||||
@@ -174,7 +174,7 @@ func TestNewGCSReplicaFromConfig(t *testing.T) {
|
||||
r, err := main.NewReplicaFromConfig(&main.ReplicaConfig{URL: "gcs://foo/bar"}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if client, ok := r.Client.(*gcs.ReplicaClient); !ok {
|
||||
} else if client, ok := r.Client().(*gcs.ReplicaClient); !ok {
|
||||
t.Fatal("unexpected replica type")
|
||||
} else if got, want := client.Bucket, "foo"; got != want {
|
||||
t.Fatalf("Bucket=%s, want %s", got, want)
|
||||
|
||||
@@ -37,7 +37,7 @@ func runWindowsService(ctx context.Context) error {
|
||||
|
||||
// Set eventlog as log writer while running.
|
||||
log.SetOutput((*eventlogWriter)(elog))
|
||||
defer log.SetOutput(os.Stderr)
|
||||
defer log.SetOutput(os.Stdout)
|
||||
|
||||
log.Print("Litestream service starting")
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ func (c *ReplicateCommand) Run(ctx context.Context) (err error) {
|
||||
for _, db := range c.DBs {
|
||||
log.Printf("initialized db: %s", db.Path())
|
||||
for _, r := range db.Replicas {
|
||||
switch client := r.Client.(type) {
|
||||
switch client := r.Client().(type) {
|
||||
case *litestream.FileReplicaClient:
|
||||
log.Printf("replicating to: name=%q type=%q path=%q", r.Name(), client.Type(), client.Path())
|
||||
case *s3.ReplicaClient:
|
||||
@@ -173,6 +173,8 @@ func (c *ReplicateCommand) Run(ctx context.Context) (err error) {
|
||||
go func() { c.execCh <- c.cmd.Wait() }()
|
||||
}
|
||||
|
||||
log.Printf("litestream initialization complete")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
||||
|
||||
// Determine latest generation if one is not specified.
|
||||
if c.generation == "" {
|
||||
if c.generation, err = litestream.FindLatestGeneration(ctx, r.Client); err == litestream.ErrNoGeneration {
|
||||
if c.generation, err = litestream.FindLatestGeneration(ctx, r.Client()); err == litestream.ErrNoGeneration {
|
||||
// Return an error if no matching targets found.
|
||||
// If optional flag set, return success. Useful for automated recovery.
|
||||
if c.ifReplicaExists {
|
||||
@@ -119,14 +119,14 @@ func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
||||
|
||||
// Determine the maximum available index for the generation if one is not specified.
|
||||
if c.targetIndex == -1 {
|
||||
if c.targetIndex, err = litestream.FindMaxIndexByGeneration(ctx, r.Client, c.generation); err != nil {
|
||||
if c.targetIndex, err = litestream.FindMaxIndexByGeneration(ctx, r.Client(), c.generation); err != nil {
|
||||
return fmt.Errorf("cannot determine latest index in generation %q: %w", c.generation, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Find lastest snapshot that occurs before the index.
|
||||
// TODO: Optionally allow -snapshot-index
|
||||
if c.snapshotIndex, err = litestream.FindSnapshotForIndex(ctx, r.Client, c.generation, c.targetIndex); err != nil {
|
||||
if c.snapshotIndex, err = litestream.FindSnapshotForIndex(ctx, r.Client(), c.generation, c.targetIndex); err != nil {
|
||||
return fmt.Errorf("cannot find snapshot index: %w", err)
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
|
||||
|
||||
c.opt.Logger = log.New(c.stdout, "", log.LstdFlags|log.Lmicroseconds)
|
||||
|
||||
return litestream.Restore(ctx, r.Client, c.outputPath, c.generation, c.snapshotIndex, c.targetIndex, c.opt)
|
||||
return litestream.Restore(ctx, r.Client(), c.outputPath, c.generation, c.snapshotIndex, c.targetIndex, c.opt)
|
||||
}
|
||||
|
||||
func (c *RestoreCommand) loadReplica(ctx context.Context, config Config, arg string) (*litestream.Replica, error) {
|
||||
|
||||
@@ -120,7 +120,7 @@ func TestRestoreCommand(t *testing.T) {
|
||||
err := m.Run(context.Background(), []string{"restore", "-config", filepath.Join(testDir, "litestream.yml"), "-if-db-not-exists", filepath.Join(testDir, "db")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -133,7 +133,7 @@ func TestRestoreCommand(t *testing.T) {
|
||||
err := m.Run(context.Background(), []string{"restore", "-config", filepath.Join(testDir, "litestream.yml"), "-if-replica-exists", filepath.Join(testDir, "db")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -147,9 +147,9 @@ func TestRestoreCommand(t *testing.T) {
|
||||
err := m.Run(context.Background(), []string{"restore", "-config", filepath.Join(testDir, "litestream.yml"), "-o", filepath.Join(tempDir, "db"), filepath.Join(testDir, "db")})
|
||||
if err == nil || err.Error() != `no matching backups found` {
|
||||
t.Fatalf("unexpected error: %s", err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
} else if got, want := stderr.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stderr"))); got != want {
|
||||
} else if got, want := stderr.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stderr"))); got != want {
|
||||
t.Fatalf("stderr=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestSnapshotsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"snapshots", "-config", filepath.Join(testDir, "litestream.yml"), filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -30,7 +30,7 @@ func TestSnapshotsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"snapshots", "-config", filepath.Join(testDir, "litestream.yml"), "-replica", "replica1", filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -43,7 +43,7 @@ func TestSnapshotsCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"snapshots", replicaURL}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -69,7 +69,7 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (ret error) {
|
||||
if c.generation != "" {
|
||||
generations = []string{c.generation}
|
||||
} else {
|
||||
if generations, err = r.Client.Generations(ctx); err != nil {
|
||||
if generations, err = r.Client().Generations(ctx); err != nil {
|
||||
log.Printf("%s: cannot determine generations: %s", r.Name(), err)
|
||||
ret = errExit // signal error return without printing message
|
||||
continue
|
||||
@@ -78,7 +78,7 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (ret error) {
|
||||
|
||||
for _, generation := range generations {
|
||||
if err := func() error {
|
||||
itr, err := r.Client.WALSegments(ctx, generation)
|
||||
itr, err := r.Client().WALSegments(ctx, generation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestWALCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"wal", "-config", filepath.Join(testDir, "litestream.yml"), filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -30,7 +30,7 @@ func TestWALCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"wal", "-config", filepath.Join(testDir, "litestream.yml"), "-replica", "replica1", filepath.Join(testDir, "db")}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
@@ -43,7 +43,7 @@ func TestWALCommand(t *testing.T) {
|
||||
m, _, stdout, _ := newMain()
|
||||
if err := m.Run(context.Background(), []string{"wal", replicaURL}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if got, want := stdout.String(), string(testingutil.MustReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
} else if got, want := stdout.String(), string(testingutil.ReadFile(t, filepath.Join(testDir, "stdout"))); got != want {
|
||||
t.Fatalf("stdout=%q, want %q", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user