Files
replicator/replicator/driver_test.go
2023-11-05 21:21:30 -07:00

263 lines
6.1 KiB
Go

package replicator
import (
"bytes"
"context"
"testing"
"time"
)
func TestDriverInterface(t *testing.T) {
var _ Driver = FileTree("")
var _ Driver = Map{}
var _ Driver = Must{}
}
func testDriver(t *testing.T, d Driver) {
ctx, can := context.WithTimeout(context.Background(), time.Second*2)
defer can()
key := Key{Namespace: "x/y", Key: "z"}
version := TimeAsVersion(time.Now())
value := Value([]byte(t.Name()))
t.Run("get does not exist", func(t *testing.T) {
v, err := d.Get(ctx, key)
if err != nil {
t.Errorf("getting 404 returned an err: %v", err)
}
if v.Value != nil || v.Version != nil {
t.Errorf("expected nil for 404 but got %q/%s", v.Value, v.Version)
}
})
t.Run("404 set get", func(t *testing.T) {
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
v, err := d.Get(ctx, key)
if err != nil {
t.Errorf("getting key returned an err: %v", err)
}
if !bytes.Equal(v.Value, value) {
t.Errorf("value didnt match set-get: want %q, got %q", value, v.Value)
}
if !bytes.Equal(v.Version, version) {
t.Errorf("version didnt match set-get: want %q, got %q", version, v.Version)
}
if err := d.Del(ctx, key, nil); err != nil {
t.Errorf("failed to clean up: %v", err)
}
})
t.Run("keys of nothing", func(t *testing.T) {
ch, err := d.KeysSince(ctx, time.Time{})
for got := range ch {
t.Error("expected nothing but got", got)
}
if *err != nil {
t.Error(*err)
}
})
t.Run("keys of one key", func(t *testing.T) {
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
ch, err := d.KeysSince(ctx, time.Time{})
n := 0
for got := range ch {
n += 1
if got.Key != key {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
}
if n == 0 {
t.Error("expected to find at least 1 key")
}
if *err != nil {
t.Error(*err)
}
})
t.Run("conditional set vs nothing", func(t *testing.T) {
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
})
t.Run("conditional set vs older", func(t *testing.T) {
oldValue := []byte("teehee")
oldVersion := TimeAsVersion(time.Now().Add(-1 * time.Minute))
if err := d.Set(ctx, key, oldValue, oldVersion); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, oldValue) {
t.Error(got)
} else if !bytes.Equal(got.Version, oldVersion) {
t.Error(got)
}
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
})
t.Run("conditional set vs equal", func(t *testing.T) {
oldValue := []byte("teehee")
oldVersion := TimeAsVersion(time.Now().Add(-1 * time.Minute))
if err := d.Set(ctx, key, oldValue, oldVersion); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, oldValue) {
t.Error(got)
} else if !bytes.Equal(got.Version, oldVersion) {
t.Error(got)
}
if err := d.Set(ctx, key, value, oldVersion); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, oldVersion) {
t.Error(got)
}
})
t.Run("conditional set vs newer", func(t *testing.T) {
oldValue := []byte("teehee")
oldVersion := TimeAsVersion(time.Now().Add(-1 * time.Minute))
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
if err := d.Set(ctx, key, oldValue, oldVersion); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
})
t.Run("conditional del vs nothing", func(t *testing.T) {
if err := d.Del(ctx, key, version); err != nil {
t.Fatal(err)
}
})
t.Run("conditional del vs older", func(t *testing.T) {
oldValue := []byte("teehee")
oldVersion := TimeAsVersion(time.Now().Add(-1 * time.Minute))
if err := d.Set(ctx, key, oldValue, oldVersion); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if err := d.Del(ctx, key, version); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if got.Value != nil {
t.Error(got)
} else if got.Version != nil {
t.Error(got)
}
})
t.Run("conditional del vs equal", func(t *testing.T) {
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if err := d.Del(ctx, key, version); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if got.Value != nil {
t.Error(got)
} else if got.Version != nil {
t.Error(got)
}
})
t.Run("conditional del vs newer", func(t *testing.T) {
oldVersion := TimeAsVersion(time.Now().Add(-1 * time.Minute))
if err := d.Set(ctx, key, value, version); err != nil {
t.Fatal(err)
}
defer d.Del(ctx, key, nil)
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
if err := d.Del(ctx, key, oldVersion); err != nil {
t.Fatal(err)
}
if got, err := d.Get(ctx, key); err != nil {
t.Fatal(err)
} else if !bytes.Equal(got.Value, value) {
t.Error(got)
} else if !bytes.Equal(got.Version, version) {
t.Error(got)
}
})
}