tests: add testing around set and es aggregate
This commit is contained in:
parent
700d6370f2
commit
a42270c6ac
4
Makefile
4
Makefile
|
@ -33,8 +33,10 @@ ifeq (, $(shell which gqlgen))
|
||||||
endif
|
endif
|
||||||
gqlgen
|
gqlgen
|
||||||
|
|
||||||
|
|
||||||
|
EV_HOST?=localhost:8080
|
||||||
load:
|
load:
|
||||||
watch -n .1 "http POST localhost:8080/inbox/asdf/test a=b one=1 two:='{\"v\":2}' | jq"
|
watch -n .1 "http POST $(EV_HOST)/inbox/asdf/test a=b one=1 two:='{\"v\":2}' | jq"
|
||||||
|
|
||||||
bi:
|
bi:
|
||||||
go build .
|
go build .
|
||||||
|
|
BIN
local.mk.secret
BIN
local.mk.secret
Binary file not shown.
|
@ -89,9 +89,21 @@ func (m *eventLog) Append(ctx context.Context, events event.Events, version uint
|
||||||
for i := range events {
|
for i := range events {
|
||||||
span.AddEvent(fmt.Sprintf("read event %d of %d", i, len(events)))
|
span.AddEvent(fmt.Sprintf("read event %d of %d", i, len(events)))
|
||||||
|
|
||||||
|
// --- clone event
|
||||||
|
e := events[i]
|
||||||
|
b, err := event.MarshalBinary(e)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e, err = event.UnmarshalBinary(ctx, b, e.EventMeta().Position)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
|
||||||
pos := last + uint64(i) + 1
|
pos := last + uint64(i) + 1
|
||||||
event.SetPosition(events[i], pos)
|
event.SetPosition(e, pos)
|
||||||
*stream = append(*stream, events[i])
|
*stream = append(*stream, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -126,8 +138,17 @@ func (m *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Even
|
||||||
events = make([]event.Event, math.Abs(count))
|
events = make([]event.Event, math.Abs(count))
|
||||||
for i := range events {
|
for i := range events {
|
||||||
span.AddEvent(fmt.Sprintf("read event %d of %d", i, math.Abs(count)))
|
span.AddEvent(fmt.Sprintf("read event %d of %d", i, math.Abs(count)))
|
||||||
// ---
|
|
||||||
events[i] = (*stream)[start-1]
|
// --- clone event
|
||||||
|
e := (*stream)[start-1]
|
||||||
|
b, err := event.MarshalBinary(e)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
events[i], err = event.UnmarshalBinary(ctx, b, e.EventMeta().Position)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
|
@ -140,6 +161,7 @@ func (m *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Even
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
event.SetStreamID(m.streamID, events...)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -147,8 +169,6 @@ func (m *eventLog) Read(ctx context.Context, pos int64, count int64) (event.Even
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
event.SetStreamID(m.streamID, events...)
|
|
||||||
|
|
||||||
return events, nil
|
return events, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,9 @@ func (w *wrapper) Append(ctx context.Context, events event.Events, version uint6
|
||||||
for i := range events {
|
for i := range events {
|
||||||
e := events[i]
|
e := events[i]
|
||||||
eventType := event.TypeOf(e)
|
eventType := event.TypeOf(e)
|
||||||
streamID := e.EventMeta().StreamID
|
m := e.EventMeta()
|
||||||
streamPos := e.EventMeta().Position
|
streamID := m.StreamID
|
||||||
|
streamPos := m.Position
|
||||||
|
|
||||||
e1 := event.NewPtr(streamID, streamPos)
|
e1 := event.NewPtr(streamID, streamPos)
|
||||||
event.SetStreamID("$all", e1)
|
event.SetStreamID("$all", e1)
|
||||||
|
|
|
@ -76,8 +76,6 @@ func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, erro
|
||||||
ctx, span := lg.Span(ctx)
|
ctx, span := lg.Span(ctx)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
Mes_open.Add(ctx, 1)
|
|
||||||
|
|
||||||
name, _, ok := strings.Cut(dsn, ":")
|
name, _, ok := strings.Cut(dsn, ":")
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("%w: no scheme", ErrNoDriver)
|
return nil, fmt.Errorf("%w: no scheme", ErrNoDriver)
|
||||||
|
@ -101,6 +99,8 @@ func Open(ctx context.Context, dsn string, options ...Option) (*EventStore, erro
|
||||||
o.Apply(es)
|
o.Apply(es)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mes_open.Add(ctx, 1)
|
||||||
|
|
||||||
return es, err
|
return es, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +197,9 @@ func (es *EventStore) LastIndex(ctx context.Context, streamID string) (uint64, e
|
||||||
return l.LastIndex(ctx)
|
return l.LastIndex(ctx)
|
||||||
}
|
}
|
||||||
func (es *EventStore) EventStream() driver.EventStream {
|
func (es *EventStore) EventStream() driver.EventStream {
|
||||||
|
if es == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
d := es.Driver
|
d := es.Driver
|
||||||
for d != nil {
|
for d != nil {
|
||||||
if d, ok := d.(driver.EventStream); ok {
|
if d, ok := d.(driver.EventStream); ok {
|
||||||
|
|
|
@ -12,63 +12,15 @@ import (
|
||||||
|
|
||||||
"github.com/sour-is/ev/pkg/es"
|
"github.com/sour-is/ev/pkg/es"
|
||||||
memstore "github.com/sour-is/ev/pkg/es/driver/mem-store"
|
memstore "github.com/sour-is/ev/pkg/es/driver/mem-store"
|
||||||
|
"github.com/sour-is/ev/pkg/es/driver/projecter"
|
||||||
|
"github.com/sour-is/ev/pkg/es/driver/streamer"
|
||||||
"github.com/sour-is/ev/pkg/es/event"
|
"github.com/sour-is/ev/pkg/es/event"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestES(t *testing.T) {
|
var (
|
||||||
is := is.New(t)
|
_ event.Event = (*ValueSet)(nil)
|
||||||
|
_ event.Aggregate = (*Thing)(nil)
|
||||||
ctx := context.Background()
|
)
|
||||||
|
|
||||||
err := event.Register(ctx, &ValueSet{})
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
memstore.Init(ctx)
|
|
||||||
|
|
||||||
_, err = es.Open(ctx, "mem")
|
|
||||||
is.True(errors.Is(err, es.ErrNoDriver))
|
|
||||||
|
|
||||||
_, err = es.Open(ctx, "bogo:")
|
|
||||||
is.True(errors.Is(err, es.ErrNoDriver))
|
|
||||||
|
|
||||||
es, err := es.Open(ctx, "mem:")
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
thing := &Thing{Name: "time"}
|
|
||||||
err = es.Load(ctx, thing)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
t.Log(thing.StreamVersion(), thing.Name, thing.Value)
|
|
||||||
|
|
||||||
err = thing.OnSetValue(time.Now().String())
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
i, err := es.Save(ctx, thing)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
t.Log(thing.StreamVersion(), thing.Name, thing.Value)
|
|
||||||
t.Log("Wrote: ", i)
|
|
||||||
|
|
||||||
i, err = es.Append(ctx, "thing-time", event.NewEvents(&ValueSet{Value: "xxx"}))
|
|
||||||
is.NoErr(err)
|
|
||||||
is.Equal(i, uint64(1))
|
|
||||||
|
|
||||||
events, err := es.Read(ctx, "thing-time", -1, -11)
|
|
||||||
is.NoErr(err)
|
|
||||||
|
|
||||||
for i, e := range events {
|
|
||||||
t.Logf("event %d %d - %v\n", i, e.EventMeta().Position, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
first, err := es.FirstIndex(ctx, "thing-time")
|
|
||||||
is.NoErr(err)
|
|
||||||
is.Equal(first, uint64(1))
|
|
||||||
|
|
||||||
last, err := es.LastIndex(ctx, "thing-time")
|
|
||||||
is.NoErr(err)
|
|
||||||
is.Equal(last, uint64(2))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type Thing struct {
|
type Thing struct {
|
||||||
Name string
|
Name string
|
||||||
|
@ -77,9 +29,9 @@ type Thing struct {
|
||||||
event.AggregateRoot
|
event.AggregateRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Thing) StreamID() string {
|
// func (a *Thing) StreamID() string {
|
||||||
return fmt.Sprintf("thing-%s", a.Name)
|
// return fmt.Sprintf("thing-%s", a.Name)
|
||||||
}
|
// }
|
||||||
func (a *Thing) ApplyEvent(lis ...event.Event) {
|
func (a *Thing) ApplyEvent(lis ...event.Event) {
|
||||||
for _, e := range lis {
|
for _, e := range lis {
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
|
@ -118,7 +70,120 @@ func (e *ValueSet) UnmarshalBinary(b []byte) error {
|
||||||
return json.Unmarshal(b, e)
|
return json.Unmarshal(b, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
func TestES(t *testing.T) {
|
||||||
_ event.Event = (*ValueSet)(nil)
|
is := is.New(t)
|
||||||
_ event.Aggregate = (*Thing)(nil)
|
|
||||||
)
|
ctx := context.Background()
|
||||||
|
|
||||||
|
err := event.Register(ctx, &ValueSet{})
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
es.Init(ctx)
|
||||||
|
memstore.Init(ctx)
|
||||||
|
|
||||||
|
{
|
||||||
|
store, err := es.Open(ctx, "mem")
|
||||||
|
is.True(errors.Is(err, es.ErrNoDriver))
|
||||||
|
is.True(store.EventStream() == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
_, err := es.Open(ctx, "bogo:")
|
||||||
|
is.True(errors.Is(err, es.ErrNoDriver))
|
||||||
|
}
|
||||||
|
|
||||||
|
store, err := es.Open(ctx, "mem:", streamer.New(ctx), projecter.New(ctx))
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
thing := &Thing{Name: "time"}
|
||||||
|
err = store.Load(ctx, thing)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
t.Log(thing.StreamVersion(), thing.Name, thing.Value)
|
||||||
|
|
||||||
|
err = thing.OnSetValue(time.Now().String())
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
thing.SetStreamID("thing-time")
|
||||||
|
i, err := store.Save(ctx, thing)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
t.Log(thing.StreamVersion(), thing.Name, thing.Value)
|
||||||
|
t.Log("Wrote: ", i)
|
||||||
|
|
||||||
|
i, err = store.Append(ctx, "thing-time", event.NewEvents(&ValueSet{Value: "xxx"}))
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(i, uint64(1))
|
||||||
|
|
||||||
|
events, err := store.Read(ctx, "thing-time", -1, -11)
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
for i, e := range events {
|
||||||
|
t.Logf("event %d %d - %v\n", i, e.EventMeta().Position, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
first, err := store.FirstIndex(ctx, "thing-time")
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(first, uint64(1))
|
||||||
|
|
||||||
|
last, err := store.LastIndex(ctx, "thing-time")
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(last, uint64(2))
|
||||||
|
|
||||||
|
stream := store.EventStream()
|
||||||
|
is.True(stream != nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestESOperations(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
es.Init(ctx)
|
||||||
|
memstore.Init(ctx)
|
||||||
|
|
||||||
|
store, err := es.Open(ctx, "mem:", streamer.New(ctx), projecter.New(ctx))
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
|
thing, err := es.Create(ctx, store, "thing-1", func(ctx context.Context, agg *Thing) error {
|
||||||
|
return agg.OnSetValue("foo")
|
||||||
|
})
|
||||||
|
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(thing.Version(), uint64(1))
|
||||||
|
is.Equal(thing.Value, "foo")
|
||||||
|
|
||||||
|
thing, err = es.Update(ctx, store, "thing-1", func(ctx context.Context, agg *Thing) error {
|
||||||
|
return agg.OnSetValue("bar")
|
||||||
|
})
|
||||||
|
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(thing.Version(), uint64(2))
|
||||||
|
is.Equal(thing.Value, "bar")
|
||||||
|
|
||||||
|
thing, err = es.Upsert(ctx, store, "thing-2", func(ctx context.Context, agg *Thing) error {
|
||||||
|
return agg.OnSetValue("bin")
|
||||||
|
})
|
||||||
|
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(thing.Version(), uint64(1))
|
||||||
|
is.Equal(thing.Value, "bin")
|
||||||
|
|
||||||
|
thing, err = es.Upsert(ctx, store, "thing-2", func(ctx context.Context, agg *Thing) error {
|
||||||
|
return agg.OnSetValue("baz")
|
||||||
|
})
|
||||||
|
|
||||||
|
is.NoErr(err)
|
||||||
|
is.Equal(thing.Version(), uint64(2))
|
||||||
|
is.Equal(thing.Value, "baz")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnwrap(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
|
||||||
|
err := errors.New("foo")
|
||||||
|
werr := fmt.Errorf("wrap: %w", err)
|
||||||
|
|
||||||
|
is.Equal(es.Unwrap(werr), err)
|
||||||
|
is.Equal(es.Unwrap("test"), "")
|
||||||
|
}
|
||||||
|
|
25
pkg/set/set_test.go
Normal file
25
pkg/set/set_test.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package set_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matryer/is"
|
||||||
|
"github.com/sour-is/ev/pkg/set"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStringSet(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
|
|
||||||
|
s := set.New(strings.Fields("one two three")...)
|
||||||
|
|
||||||
|
is.True(s.Has("one"))
|
||||||
|
is.True(s.Has("two"))
|
||||||
|
is.True(s.Has("three"))
|
||||||
|
is.True(!s.Has("four"))
|
||||||
|
|
||||||
|
is.Equal(set.New("one").String(), "set(one)")
|
||||||
|
|
||||||
|
var n set.Set[string]
|
||||||
|
is.Equal(n.String(), "set(<nil>)")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user