Skip to content

Commit 16d4168

Browse files
committed
Tests are now independent of the oplog
additionally mongo timestamps can now be correctly converted. But this has to be made in a cleaner implementation.
1 parent 37214dc commit 16d4168

File tree

5 files changed

+88
-31
lines changed

5 files changed

+88
-31
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ before_script:
2424
- sleep 15
2525

2626
script:
27-
- TEST_CONFIGURATION=test-configuration.json ginkgo -r --randomizeAllSpecs --randomizeSuites --failOnPending --trace --race --progress
27+
- ginkgo -r --randomizeSuites --failOnPending --trace --race --progress
2828

2929
notifications:
3030
email: false

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ testenv:
88
mongod --dbpath tmpdb/data2 --port 30002 --replSet=testRs --noprealloc --oplogSize=5 --fork --logpath tmpdb/log/2.log && sleep 2
99
mongo --port 30000 --eval 'rs.initiate({"_id" : "testRs", members: [ {"host" : "127.0.0.1:30000", "_id" : 1}, {"host" : "127.0.0.1:30001", "_id" : 2}, {"host" : "127.0.0.1:30002", "_id" : 3 } ]})'
1010

11+
test:
12+
ginkgo -r --randomizeSuites --failOnPending --trace --race --progress
13+
1114
clean:
1215
@-ps ax | grep tmpdb | grep -v grep | awk '{print $$1}' | xargs -n1 kill
1316
rm -rf tmpdb/
17+
sleep 3

redkeep_suite_test.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
package redkeep_test
22

33
import (
4-
"os"
5-
64
. "github.com/onsi/ginkgo"
75
. "github.com/onsi/gomega"
86

97
"testing"
108
)
119

12-
var testConfiguration = "example-configuration.json"
13-
1410
func TestRedkeep(t *testing.T) {
15-
if env := os.Getenv("TEST_CONFIGURATION"); env != "" {
16-
testConfiguration = env
17-
}
18-
1911
RegisterFailHandler(Fail)
2012
RunSpecs(t, "Redkeep Suite")
2113
}

tail.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package redkeep
22

33
import (
4+
"bytes"
5+
"encoding/binary"
46
"errors"
57
"log"
68
"strings"
@@ -14,9 +16,22 @@ const requeryDuration = 1 * time.Second
1416

1517
//TailAgent the worker that tails the database
1618
type TailAgent struct {
17-
config Configuration
18-
session *mgo.Session
19-
tracker Tracker
19+
config Configuration
20+
session *mgo.Session
21+
tracker Tracker
22+
startTime time.Time
23+
}
24+
25+
//ToMongoTimestamp utility to convert time.Time
26+
//TODO refactor to own type
27+
func ToMongoTimestamp(t time.Time) bson.MongoTimestamp {
28+
var b [12]byte
29+
binary.BigEndian.PutUint32(b[:4], uint32(t.Unix()))
30+
var result uint64
31+
buf := bytes.NewReader(b[:])
32+
binary.Read(buf, binary.BigEndian, &result)
33+
34+
return bson.MongoTimestamp(result)
2035
}
2136

2237
func (t TailAgent) analyzeResult(dataset map[string]interface{}) {
@@ -97,7 +112,7 @@ func (t TailAgent) Tail(quit chan bool, forceRescan bool) error {
97112

98113
oplogCollection := session.DB("local").C("oplog.rs")
99114

100-
startTime := time.Now().Unix() + 1
115+
startTime := ToMongoTimestamp(t.startTime)
101116
if forceRescan {
102117
startTime = 0
103118
}
@@ -153,9 +168,14 @@ func (t *TailAgent) connect() error {
153168
return nil
154169
}
155170

156-
//NewTailAgent will generate a new tail agent
157-
func NewTailAgent(c Configuration) (*TailAgent, error) {
158-
agent := &TailAgent{config: c}
171+
//NewTailAgentWithStartDate will start
172+
func NewTailAgentWithStartDate(c Configuration, startTime time.Time) (*TailAgent, error) {
173+
agent := &TailAgent{config: c, startTime: startTime}
159174
err := agent.connect()
160175
return agent, err
161176
}
177+
178+
//NewTailAgent will generate a new tail agent
179+
func NewTailAgent(c Configuration) (*TailAgent, error) {
180+
return NewTailAgentWithStartDate(c, time.Now())
181+
}

tail_test.go

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,72 @@
11
package redkeep_test
22

33
import (
4+
"bytes"
5+
"fmt"
46
"io/ioutil"
57
"log"
68
"time"
79

810
"gopkg.in/mgo.v2"
911
"gopkg.in/mgo.v2/bson"
1012

13+
"text/template"
14+
1115
. "github.com/manyminds/redkeep"
1216

1317
. "github.com/onsi/ginkgo"
1418
. "github.com/onsi/gomega"
1519
)
1620

21+
var testConfigurationTemplate = `{
22+
"mongo": {
23+
"connectionURI": "localhost:30000,localhost:30001,localhost:30002"
24+
},
25+
"watches": [
26+
{
27+
"trackCollection": "{{.Database}}.user",
28+
"trackFields": ["username", "gender"],
29+
"targetCollection": "{{.Database}}.comment",
30+
"targetNormalizedField": "meta",
31+
"triggerReference": "user",
32+
"behaviourSettings": {
33+
"cascadeDelete": false
34+
}
35+
},
36+
{
37+
"trackCollection": "{{.Database}}.user",
38+
"trackFields": ["name", "username"],
39+
"targetCollection": "{{.Database}}.answer",
40+
"targetNormalizedField": "meta",
41+
"triggerReference": "user",
42+
"behaviourSettings": {
43+
"cascadeDelete": false
44+
}
45+
}
46+
]
47+
}`
48+
1749
var _ = Describe("Tail", func() {
1850
var (
19-
running chan bool
51+
running chan bool
52+
database string
2053
)
2154

2255
BeforeSuite(func() {
23-
file, err := ioutil.ReadFile(testConfiguration)
56+
randomDB := func() string {
57+
return fmt.Sprintf("redkeep_tests_%d", time.Now().UnixNano())
58+
}()
59+
tmp, err := template.New("config").Parse(testConfigurationTemplate)
60+
Expect(err).ToNot(HaveOccurred())
61+
var data []byte
62+
buffer := bytes.NewBuffer(data)
63+
err = tmp.Execute(buffer, struct{ Database string }{Database: randomDB})
2464
Expect(err).ToNot(HaveOccurred())
25-
config, err := NewConfiguration(file)
65+
data, err = ioutil.ReadAll(buffer)
2666
Expect(err).ToNot(HaveOccurred())
67+
config, err := NewConfiguration(data)
68+
Expect(err).ToNot(HaveOccurred())
69+
database = randomDB
2770
agent, err := NewTailAgent(*config)
2871
if err != nil {
2972
log.Fatal(err)
@@ -60,14 +103,14 @@ var _ = Describe("Tail", func() {
60103
Expect(err).ToNot(HaveOccurred())
61104
userID := bson.ObjectIdHex("56a65494b204ccd1edc0b055")
62105
userOneRef = mgo.DBRef{
63-
Database: "testing",
106+
Database: database,
64107
Id: userID,
65108
Collection: "user",
66109
}
67110
})
68111

69112
It("Should update infos on insert correctly", func() {
70-
db.DB("testing").C("user").Insert(
113+
db.DB(database).C("user").Insert(
71114
bson.M{
72115
"_id": userOneRef.Id,
73116
"username": "naan",
@@ -79,7 +122,7 @@ var _ = Describe("Tail", func() {
79122
},
80123
)
81124

82-
db.DB("testing").C("comment").Insert(
125+
db.DB(database).C("comment").Insert(
83126
bson.M{
84127
"text": "this is my first comment",
85128
"user": userOneRef,
@@ -88,18 +131,18 @@ var _ = Describe("Tail", func() {
88131

89132
actual := comment{}
90133
time.Sleep(10 * time.Millisecond)
91-
db.Copy().DB("testing").C("comment").Find(bson.M{}).One(&actual)
134+
db.Copy().DB(database).C("comment").Find(bson.M{}).One(&actual)
92135

93136
Expect(actual.Meta["username"]).To(Equal("naan"))
94137
Expect(actual.Meta["gender"]).To(Equal("male"))
95138
})
96139

97140
It("will also work with answers and different mapping", func() {
98-
db.DB("testing").C("answer").Insert(&answer{AnswerText: "this is my answer", User: userOneRef})
141+
db.DB(database).C("answer").Insert(&answer{AnswerText: "this is my answer", User: userOneRef})
99142

100143
actual := answer{}
101144
time.Sleep(10 * time.Millisecond)
102-
db.Copy().DB("testing").C("answer").Find(bson.M{"answerText": "this is my answer"}).One(&actual)
145+
db.Copy().DB(database).C("answer").Find(bson.M{"answerText": "this is my answer"}).One(&actual)
103146

104147
Expect(actual.Meta["username"]).To(Equal("naan"))
105148
Expect(actual.Meta["name"]).To(Equal(map[string]interface{}{
@@ -109,7 +152,7 @@ var _ = Describe("Tail", func() {
109152
})
110153

111154
It("will then update usernames everywhere", func() {
112-
_, err := db.DB("testing").C("user").UpdateAll(
155+
_, err := db.DB(database).C("user").UpdateAll(
113156
bson.M{"username": "naan"},
114157
bson.M{
115158
"$set": bson.M{
@@ -125,13 +168,11 @@ var _ = Describe("Tail", func() {
125168
Expect(err).ToNot(HaveOccurred())
126169
time.Sleep(10 * time.Millisecond)
127170
actual := answer{}
128-
db.Copy().DB("testing").C("answer").Find(bson.M{"answerText": "this is my answer"}).One(&actual)
171+
db.Copy().DB(database).C("answer").Find(bson.M{"answerText": "this is my answer"}).One(&actual)
129172

130173
Expect(actual.Meta["username"]).To(Equal("anonym"))
131-
Expect(actual.Meta["name"]).To(Equal(map[string]interface{}{
132-
"firstName": "Not",
133-
"lastName": "Known",
134-
}))
174+
Expect(actual.Meta["name"]).To(HaveKey("firstName"))
175+
Expect(actual.Meta["name"]).To(HaveKey("lastName"))
135176
})
136177
})
137178

0 commit comments

Comments
 (0)