simpleserver replies with error instead of crashing, adding tests on

storage
This commit is contained in:
Nicolas Dextraze 2016-02-16 21:30:50 -08:00
parent 0a45ebd8cb
commit 6ff83ff680
2 changed files with 109 additions and 50 deletions

View File

@ -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
*/

View File

@ -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)
} }