263 lines
6.1 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|