simpleserver replies with error instead of crashing, adding tests on
storage
This commit is contained in:
parent
0a45ebd8cb
commit
6ff83ff680
145
goes_test.go
145
goes_test.go
|
@ -4,17 +4,16 @@ import
|
||||||
(
|
(
|
||||||
"testing"
|
"testing"
|
||||||
"github.com/satori/go.uuid"
|
"github.com/satori/go.uuid"
|
||||||
"crypto/rand"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"fmt"
|
"io/ioutil"
|
||||||
"math/big"
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tempDir string
|
var tempDir string
|
||||||
|
|
||||||
type MyEvent struct {
|
type AnEvent struct {
|
||||||
A int64
|
A int64
|
||||||
B string
|
B string
|
||||||
}
|
}
|
||||||
|
@ -29,7 +28,7 @@ func setUp() {
|
||||||
tempDir := path.Join(os.TempDir(), uuid.NewV4().String())
|
tempDir := path.Join(os.TempDir(), uuid.NewV4().String())
|
||||||
storage := NewDiskStorage(tempDir)
|
storage := NewDiskStorage(tempDir)
|
||||||
SetStorage(storage)
|
SetStorage(storage)
|
||||||
serializer := NewJsonSerializer((*MyEvent)(nil), (*AnotherEvent)(nil))
|
serializer := NewJsonSerializer((*AnEvent)(nil), (*AnotherEvent)(nil))
|
||||||
SetSerializer(serializer)
|
SetSerializer(serializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,44 +39,78 @@ func tearDown() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRandomEvent() *Event {
|
func wrapEvent(aggregateId uuid.UUID, event interface{}) Event {
|
||||||
id := uuid.NewV4()
|
return Event{aggregateId, event}
|
||||||
return createRandomEventFor(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRandomEventFor(id uuid.UUID) *Event {
|
func TestSerializeEventToJson(t *testing.T) {
|
||||||
a, _ := rand.Int(rand.Reader, big.NewInt(100000))
|
|
||||||
b, _ := rand.Int(rand.Reader, big.NewInt(1000000))
|
|
||||||
payload := MyEvent{a.Int64(), fmt.Sprintf("abc-%v", b.Int64())}
|
|
||||||
return &Event{id, payload}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddEvent(t *testing.T) {
|
|
||||||
setUp()
|
setUp()
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
||||||
ev := createRandomEvent()
|
ev := wrapEvent(uuid.NewV4(), AnEvent{int64(1024), "Tests"})
|
||||||
err := AddEvent(*ev)
|
err := AddEvent(ev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AddEvent failed with %q", err)
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := (storage.(*DiskStorage)).getFilenameForEvents(ev.AggregateId.String());
|
||||||
|
if fi, _ := os.Stat(filename); fi == nil {
|
||||||
|
t.Errorf("AddEvent failed to create file %q", filename)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content, _ := ioutil.ReadFile(filename)
|
||||||
|
if !bytes.Contains(content, []byte("{\"A\":1024,\"B\":\"Tests\"}")) {
|
||||||
|
t.Errorf("AddEvent failed. File doesn't contain event json.")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddEventsToSameAggregate(t *testing.T) {
|
func TestSerializeEventsForSameAggregateInSameFile(t *testing.T) {
|
||||||
setUp()
|
setUp()
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
||||||
id := uuid.NewV4()
|
aggregateId := uuid.NewV4()
|
||||||
ev1 := createRandomEventFor(id)
|
ev1 := wrapEvent(aggregateId, AnEvent{int64(12345), "Hello"})
|
||||||
err := AddEvent(*ev1)
|
err := AddEvent(ev1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AddEvent() failed with %q", err)
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ev2 := createRandomEventFor(id)
|
ev2 := wrapEvent(aggregateId, AnotherEvent{int64(23456), "Bob", 123.45})
|
||||||
err = AddEvent(*ev2)
|
err = AddEvent(ev2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("AddEvent() failed with %q", err)
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := (storage.(*DiskStorage)).getFilenameForEvents(aggregateId.String())
|
||||||
|
content, _ := ioutil.ReadFile(filename)
|
||||||
|
if !bytes.Contains(content, []byte("Hello")) || !bytes.Contains(content, []byte("Bob")) {
|
||||||
|
t.Error("AddEvent failed. Both events are not serialized in same file.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTypeInformationIsProvided(t *testing.T) {
|
||||||
|
setUp()
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
ev := wrapEvent(uuid.NewV4(), AnEvent{int64(1024), "Tests"})
|
||||||
|
err := AddEvent(ev)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := (storage.(*DiskStorage)).getFilenameForEvents(ev.AggregateId.String());
|
||||||
|
if fi, _ := os.Stat(filename); fi == nil {
|
||||||
|
t.Errorf("AddEvent failed to create file %q", filename)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content, _ := ioutil.ReadFile(filename)
|
||||||
|
if !bytes.Contains(content, []byte("AnEvent")) {
|
||||||
|
t.Errorf("AddEvent failed. File doesn't contain event type.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,43 +119,63 @@ func (me *Event) Equals(other *Event) bool {
|
||||||
return me.AggregateId == other.AggregateId && reflect.DeepEqual(me.Payload, other.Payload)
|
return me.AggregateId == other.AggregateId && reflect.DeepEqual(me.Payload, other.Payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRetrieveFor(t *testing.T) {
|
func TestEventsCanBeRetrieved(t *testing.T) {
|
||||||
setUp()
|
setUp()
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
||||||
id := uuid.NewV4()
|
aggregateId := uuid.NewV4()
|
||||||
ev1 := createRandomEventFor(id)
|
ev1 := wrapEvent(aggregateId, AnEvent{int64(12345), "Hello"})
|
||||||
ev2 := createRandomEventFor(id)
|
err := AddEvent(ev1)
|
||||||
AddEvent(*ev1)
|
if err != nil {
|
||||||
AddEvent(*ev2)
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
AddEvent(*createRandomEvent())
|
return
|
||||||
|
}
|
||||||
|
ev2 := wrapEvent(aggregateId, AnotherEvent{int64(23456), "Bob", 123.45})
|
||||||
|
err = AddEvent(ev2)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("AddEvent failed with %q", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
events, err := RetrieveFor(id)
|
events, err := RetrieveFor(aggregateId)
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
t.Errorf("RetrieveFor(%q) failed with %q", id.String(), err)
|
t.Errorf("RetrieveFor(%q) failed with %q", aggregateId.String(), err)
|
||||||
case len(events) != 2:
|
case len(events) != 2:
|
||||||
t.Errorf("RetrieveFor(%q) returned %v events, expected %v", id.String(), len(events), 2)
|
t.Errorf("RetrieveFor(%q) returned %v events, expected %v", aggregateId.String(), len(events), 2)
|
||||||
case !events[0].Equals(ev1):
|
case !ev1.Equals(events[0]):
|
||||||
t.Errorf("RetrieveFor(%q) first event doesn't match %+v != %+v", id.String(), events[0], ev1)
|
t.Errorf("RetrieveFor(%q) first event doesn't match %+v != %+v", aggregateId.String(), events[0], ev1)
|
||||||
case !events[1].Equals(ev2):
|
case !ev2.Equals(events[1]):
|
||||||
t.Errorf("RetrieveFor(%q) second event doesn't match %+v != %+v", id.String(), events[1], ev2)
|
t.Errorf("RetrieveFor(%q) second event doesn't match %+v != %+v", aggregateId.String(), events[1], ev2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRetrieveAll(t *testing.T) {
|
func TestEventsCanBeReplayedInOrder(t *testing.T) {
|
||||||
setUp()
|
setUp()
|
||||||
defer tearDown()
|
defer tearDown()
|
||||||
|
|
||||||
AddEvent(*createRandomEvent())
|
aggregateId1 := uuid.NewV4()
|
||||||
AddEvent(*createRandomEvent())
|
aggregateId2 := uuid.NewV4()
|
||||||
AddEvent(*createRandomEvent())
|
testEvent1 := wrapEvent(aggregateId1, AnEvent{int64(123), "Hello 1"})
|
||||||
|
testEvent2 := wrapEvent(aggregateId2, AnEvent{int64(456), "Hello 2"})
|
||||||
|
testEvent3 := wrapEvent(aggregateId1, AnEvent{int64(789), "Hello 3"})
|
||||||
|
AddEvent(testEvent1)
|
||||||
|
AddEvent(testEvent2)
|
||||||
|
AddEvent(testEvent3)
|
||||||
|
|
||||||
events, err := RetrieveAll()
|
events, err := RetrieveAll()
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
t.Errorf("RetrieveAll() failed with %q", err)
|
t.Errorf("RetrieveAll failed with %q", err)
|
||||||
case len(events) != 3:
|
case len(events) != 3:
|
||||||
t.Errorf("RetrieveAll() returned %v events, expected %v", len(events), 3)
|
t.Errorf("RetrieveAll returned %v events, expected %v", len(events), 3)
|
||||||
|
case !testEvent1.Equals(events[0]) || !testEvent2.Equals(events[1]) || !testEvent3.Equals(events[2]):
|
||||||
|
t.Error("RetrieveAll returned events in wrong order.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Missing tests from https://gist.github.com/adymitruk/b4627b74617a37b6d949
|
||||||
|
- GUID reversal for distribution
|
||||||
|
- Created date stored with event
|
||||||
|
*/
|
|
@ -57,7 +57,9 @@ func main() {
|
||||||
data := message[2]
|
data := message[2]
|
||||||
err = goes.AddEvent(goes.Event{aggregateId, data})
|
err = goes.AddEvent(goes.Event{aggregateId, data})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
replySocket.Send(fmt.Sprintf("Error: %v", err), 0)
|
||||||
|
fmt.Println(err)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
replySocket.Send("Ok", 0)
|
replySocket.Send("Ok", 0)
|
||||||
case "ReadStream":
|
case "ReadStream":
|
||||||
|
@ -69,14 +71,18 @@ func main() {
|
||||||
fmt.Println("->", command, aggregateId.String())
|
fmt.Println("->", command, aggregateId.String())
|
||||||
events, err := goes.RetrieveFor(aggregateId)
|
events, err := goes.RetrieveFor(aggregateId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
replySocket.Send(fmt.Sprintf("Error: %v", err), 0)
|
||||||
|
fmt.Println(err)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
sendEvents(replySocket, events)
|
sendEvents(replySocket, events)
|
||||||
case "ReadAll":
|
case "ReadAll":
|
||||||
fmt.Println("->", command)
|
fmt.Println("->", command)
|
||||||
events, err := goes.RetrieveAll()
|
events, err := goes.RetrieveAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
replySocket.Send(fmt.Sprintf("Error: %v", err), 0)
|
||||||
|
fmt.Println(err)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
sendEvents(replySocket, events)
|
sendEvents(replySocket, events)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user