Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
[#1545] Protect sub-second deterministic ordering with a unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
placer14 committed Apr 18, 2019
1 parent 5cf7cb0 commit b34537b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
6 changes: 6 additions & 0 deletions repo/db/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ func (c *ChatDB) Put(messageId string, peerId string, subject string, message st
c.lock.Lock()
defer c.lock.Unlock()

// timestamp.UnixNano() is undefined when time has a zero value
if timestamp.IsZero() {
log.Errorf("putting chat message (%s): recieved zero timestamp, using current time", messageId)
timestamp = time.Now()
}

tx, err := c.db.Begin()
if err != nil {
return err
Expand Down
44 changes: 44 additions & 0 deletions repo/db/chat_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package db_test

import (
"fmt"
"math/rand"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -457,3 +459,45 @@ func TestChatDB_DeleteConversation(t *testing.T) {
}
stmt.Close()
}

// https://github.com/OpenBazaar/openbazaar-go/issues/1545
func TestChatDB_DeterministicNanosecondOrdering_Issue1545(t *testing.T) {
var (
numMessages = 10
startTime = time.Now()
chdb, teardown, err = buildNewChatStore()
)
if err != nil {
t.Fatal(err)
}
defer teardown()

// send numMessages in a random order where
// msg index 0 has the earliest timetstamp and index numMessages has the latest
for _, msgID := range rand.Perm(numMessages) {
var (
n = fmt.Sprintf("%d", msgID)
u = startTime.Add(time.Millisecond * time.Duration(msgID))
)
err = chdb.Put(n, "peerid", "subject", n, u, false, true)
if err != nil {
t.Fatal(err)
}
}

messages := chdb.GetMessages("peerid", "subject", "", -1)
if len(messages) != numMessages {
t.Fatalf("expected %d messages, but got %d", numMessages, len(messages))
return
}
// msgs should be in chronological order from most recent to oldest, thus never
// having an older time than the previous message
var latestTime = time.Now()
for _, m := range messages {
if m.Timestamp.After(latestTime) {
t.Fatalf("expected the messages to return in decending timestamp order, but were not")
t.Logf("\tmessages recieved: %+v", messages)
}
latestTime = m.Timestamp
}
}

0 comments on commit b34537b

Please sign in to comment.