Skip to content
Snippets Groups Projects
Commit 19d2e956 authored by Jonah Husson's avatar Jonah Husson
Browse files

Add testing with cypher tests

parent 3b80a8c5
No related branches found
No related tags found
2 merge requests!60Revert "Fail a test to be sure it works",!45Add testing with cypher tests
......@@ -15,6 +15,7 @@ import (
"github.com/hack-pad/go-indexeddb/idb"
"gitlab.com/elixxir/xxdk-wasm/indexedDb"
"gitlab.com/elixxir/xxdk-wasm/storage"
"gitlab.com/xx_network/crypto/csprng"
"gitlab.com/xx_network/primitives/netTime"
"os"
"strconv"
......@@ -26,6 +27,7 @@ import (
"gitlab.com/elixxir/client/v4/cmix/rounds"
cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
"gitlab.com/elixxir/crypto/channel"
cryptoChannel "gitlab.com/elixxir/crypto/channel"
"gitlab.com/xx_network/primitives/id"
)
......@@ -38,326 +40,385 @@ func dummyCallback(uint64, *id.ID, bool) {}
// Happy path, insert message and look it up
func TestWasmModel_msgIDLookup(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test"
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
storage.GetLocalStorage().Clear()
testString := "test"
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
uuid, err := eventModel.msgIDLookup(testMsgId)
if err != nil {
t.Fatalf("%+v", err)
}
if uuid == 0 {
t.Fatalf("Expected to get a UUID!")
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
uuid, err := eventModel.msgIDLookup(testMsgId)
if err != nil {
t.Fatalf("%+v", err)
}
if uuid == 0 {
t.Fatalf("Expected to get a UUID!")
}
})
}
}
// Test wasmModel.UpdateSentStatus happy path and ensure fields don't change.
func Test_wasmModel_UpdateSentStatus(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test"
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test"
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
// Store a test message
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
uuid, err := eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
// Store a test message
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
uuid, err := eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
// Ensure one message is stored
results, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 message to exist")
}
// Ensure one message is stored
results, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 message to exist")
}
// Update the sentStatus
expectedStatus := channels.Failed
eventModel.UpdateSentStatus(uuid, testMsgId, netTime.Now(),
rounds.Round{ID: 8675309}, expectedStatus)
// Update the sentStatus
expectedStatus := channels.Failed
eventModel.UpdateSentStatus(uuid, testMsgId, netTime.Now(),
rounds.Round{ID: 8675309}, expectedStatus)
// Check the resulting status
results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 message to exist")
}
resultMsg := &Message{}
err = json.Unmarshal([]byte(results[0]), resultMsg)
if err != nil {
t.Fatalf("%+v", err)
}
if resultMsg.Status != uint8(expectedStatus) {
t.Fatalf("Unexpected Status: %v", resultMsg.Status)
}
// Check the resulting status
results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 message to exist")
}
resultMsg := &Message{}
err = json.Unmarshal([]byte(results[0]), resultMsg)
if err != nil {
t.Fatalf("%+v", err)
}
if resultMsg.Status != uint8(expectedStatus) {
t.Fatalf("Unexpected Status: %v", resultMsg.Status)
}
// Make sure other fields didn't change
if resultMsg.Nickname != testString {
t.Fatalf("Unexpected Nickname: %v", resultMsg.Nickname)
// Make sure other fields didn't change
if resultMsg.Nickname != testString {
t.Fatalf("Unexpected Nickname: %v", resultMsg.Nickname)
}
})
}
}
// Smoke test wasmModel.JoinChannel/wasmModel.LeaveChannel happy paths.
func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
storage.GetLocalStorage().Clear()
eventModel, err := newWASMModel("test", nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
eventModel, err := newWASMModel("test", c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
testChannel := &cryptoBroadcast.Channel{
ReceptionID: id.NewIdFromString("test", id.Generic, t),
Name: "test",
Description: "test",
Salt: nil,
}
testChannel2 := &cryptoBroadcast.Channel{
ReceptionID: id.NewIdFromString("test2", id.Generic, t),
Name: "test2",
Description: "test2",
Salt: nil,
}
eventModel.JoinChannel(testChannel)
eventModel.JoinChannel(testChannel2)
results, err := indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 2 {
t.Fatalf("Expected 2 channels to exist")
}
eventModel.LeaveChannel(testChannel.ReceptionID)
results, err = indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 channels to exist")
testChannel := &cryptoBroadcast.Channel{
ReceptionID: id.NewIdFromString("test", id.Generic, t),
Name: "test",
Description: "test",
Salt: nil,
}
testChannel2 := &cryptoBroadcast.Channel{
ReceptionID: id.NewIdFromString("test2", id.Generic, t),
Name: "test2",
Description: "test2",
Salt: nil,
}
eventModel.JoinChannel(testChannel)
eventModel.JoinChannel(testChannel2)
results, err := indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 2 {
t.Fatalf("Expected 2 channels to exist")
}
eventModel.LeaveChannel(testChannel.ReceptionID)
results, err = indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected 1 channels to exist")
}
})
}
}
// Test UUID gets returned when different messages are added.
func Test_wasmModel_UUIDTest(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "testHello"
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "testHello"
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
uuids := make([]uint64, 10)
for i := 0; i < 10; i++ {
// Store a test message
channelID := id.NewIdFromBytes([]byte(testString), t)
msgID := channel.MessageID{}
copy(msgID[:], testString+fmt.Sprintf("%d", i))
rnd := rounds.Round{ID: id.Round(42)}
uuid := eventModel.ReceiveMessage(channelID, msgID, "test",
testString+fmt.Sprintf("%d", i), []byte{8, 6, 7, 5}, 0,
netTime.Now(), time.Hour, rnd, 0, channels.Sent)
uuids[i] = uuid
}
uuids := make([]uint64, 10)
for i := 0; i < 10; i++ {
// Store a test message
channelID := id.NewIdFromBytes([]byte(testString), t)
msgID := channel.MessageID{}
copy(msgID[:], testString+fmt.Sprintf("%d", i))
rnd := rounds.Round{ID: id.Round(42)}
uuid := eventModel.ReceiveMessage(channelID, msgID, "test",
testString+fmt.Sprintf("%d", i), []byte{8, 6, 7, 5}, 0,
netTime.Now(), time.Hour, rnd, 0, channels.Sent)
uuids[i] = uuid
}
for i := 0; i < 10; i++ {
for j := i + 1; j < 10; j++ {
if uuids[i] == uuids[j] {
t.Fatalf("uuid failed: %d[%d] == %d[%d]",
uuids[i], i, uuids[j], j)
for i := 0; i < 10; i++ {
for j := i + 1; j < 10; j++ {
if uuids[i] == uuids[j] {
t.Fatalf("uuid failed: %d[%d] == %d[%d]",
uuids[i], i, uuids[j], j)
}
}
}
}
})
}
}
// Tests if the same message ID being sent always returns the same UUID.
func Test_wasmModel_DuplicateReceives(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "testHello"
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "testHello"
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
uuids := make([]uint64, 10)
msgID := channel.MessageID{}
copy(msgID[:], testString)
for i := 0; i < 10; i++ {
// Store a test message
channelID := id.NewIdFromBytes([]byte(testString), t)
rnd := rounds.Round{ID: id.Round(42)}
uuid := eventModel.ReceiveMessage(channelID, msgID, "test",
testString+fmt.Sprintf("%d", i), []byte{8, 6, 7, 5}, 0,
netTime.Now(), time.Hour, rnd, 0, channels.Sent)
uuids[i] = uuid
}
uuids := make([]uint64, 10)
msgID := channel.MessageID{}
copy(msgID[:], testString)
for i := 0; i < 10; i++ {
// Store a test message
channelID := id.NewIdFromBytes([]byte(testString), t)
rnd := rounds.Round{ID: id.Round(42)}
uuid := eventModel.ReceiveMessage(channelID, msgID, "test",
testString+fmt.Sprintf("%d", i), []byte{8, 6, 7, 5}, 0,
netTime.Now(), time.Hour, rnd, 0, channels.Sent)
uuids[i] = uuid
}
for i := 0; i < 10; i++ {
for j := i + 1; j < 10; j++ {
if uuids[i] != uuids[j] {
t.Fatalf("uuid failed: %d[%d] != %d[%d]",
uuids[i], i, uuids[j], j)
for i := 0; i < 10; i++ {
for j := i + 1; j < 10; j++ {
if uuids[i] != uuids[j] {
t.Fatalf("uuid failed: %d[%d] != %d[%d]",
uuids[i], i, uuids[j], j)
}
}
}
}
})
}
}
// Happy path: Inserts many messages, deletes some, and checks that the final
// result is as expected.
func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test_deleteMsgByChannel"
totalMessages := 10
expectedMessages := 5
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatalf("%+v", err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test_deleteMsgByChannel"
totalMessages := 10
expectedMessages := 5
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
// Create a test channel id
deleteChannel := id.NewIdFromString("deleteMe", id.Generic, t)
keepChannel := id.NewIdFromString("dontDeleteMe", id.Generic, t)
// Create a test channel id
deleteChannel := id.NewIdFromString("deleteMe", id.Generic, t)
keepChannel := id.NewIdFromString("dontDeleteMe", id.Generic, t)
// Store some test messages
for i := 0; i < totalMessages; i++ {
testStr := testString + strconv.Itoa(i)
// Store some test messages
for i := 0; i < totalMessages; i++ {
testStr := testString + strconv.Itoa(i)
// Interleave the channel id to ensure cursor is behaving intelligently
thisChannel := deleteChannel
if i%2 == 0 {
thisChannel = keepChannel
}
// Interleave the channel id to ensure cursor is behaving intelligently
thisChannel := deleteChannel
if i%2 == 0 {
thisChannel = keepChannel
}
testMsgId := channel.MakeMessageID([]byte(testStr), &id.ID{1})
eventModel.ReceiveMessage(thisChannel, testMsgId, testStr, testStr,
[]byte{8, 6, 7, 5}, 0, netTime.Now(), time.Second,
rounds.Round{ID: id.Round(0)}, 0, channels.Sent)
}
testMsgId := channel.MakeMessageID([]byte(testStr), &id.ID{1})
eventModel.ReceiveMessage(thisChannel, testMsgId, testStr, testStr,
[]byte{8, 6, 7, 5}, 0, netTime.Now(), time.Second,
rounds.Round{ID: id.Round(0)}, 0, channels.Sent)
}
// Check pre-results
result, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != totalMessages {
t.Errorf("Expected %d messages, got %d", totalMessages, len(result))
}
// Check pre-results
result, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != totalMessages {
t.Errorf("Expected %d messages, got %d", totalMessages, len(result))
}
// Do delete
err = eventModel.deleteMsgByChannel(deleteChannel)
if err != nil {
t.Error(err)
}
// Do delete
err = eventModel.deleteMsgByChannel(deleteChannel)
if err != nil {
t.Error(err)
}
// Check final results
result, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != expectedMessages {
t.Errorf("Expected %d messages, got %d", expectedMessages, len(result))
// Check final results
result, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != expectedMessages {
t.Errorf("Expected %d messages, got %d", expectedMessages, len(result))
}
})
}
}
// This test is designed to prove the behavior of unique indexes.
// Inserts will not fail, they simply will not happen.
func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := "test_receiveHelper_UniqueIndex"
eventModel, err := newWASMModel(testString, nil, dummyCallback)
cipher, err := cryptoChannel.NewCipher([]byte("testpass"), []byte("testsalt"), 128, csprng.NewSystemRNG())
if err != nil {
t.Fatal(err)
}
t.Fatalf("Failed to create cipher")
}
for i, c := range []cryptoChannel.Cipher{nil, cipher} {
t.Run(fmt.Sprintf("Test-%d", i), func(t *testing.T) {
storage.GetLocalStorage().Clear()
testString := fmt.Sprintf("test_receiveHelper_UniqueIndex_%d", i)
eventModel, err := newWASMModel(testString, c, dummyCallback)
if err != nil {
t.Fatal(err)
}
// Ensure index is unique
txn, err := eventModel.db.Transaction(
idb.TransactionReadOnly, messageStoreName)
if err != nil {
t.Fatal(err)
}
store, err := txn.ObjectStore(messageStoreName)
if err != nil {
t.Fatal(err)
}
idx, err := store.Index(messageStoreMessageIndex)
if err != nil {
t.Fatal(err)
}
if isUnique, err2 := idx.Unique(); !isUnique {
t.Fatalf("Index is not unique!")
} else if err2 != nil {
t.Fatal(err2)
}
// Ensure index is unique
txn, err := eventModel.db.Transaction(
idb.TransactionReadOnly, messageStoreName)
if err != nil {
t.Fatal(err)
}
store, err := txn.ObjectStore(messageStoreName)
if err != nil {
t.Fatal(err)
}
idx, err := store.Index(messageStoreMessageIndex)
if err != nil {
t.Fatal(err)
}
if isUnique, err2 := idx.Unique(); !isUnique {
t.Fatalf("Index is not unique!")
} else if err2 != nil {
t.Fatal(err2)
}
// First message insert should succeed
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatal(err)
}
// First message insert should succeed
testMsgId := channel.MakeMessageID([]byte(testString), &id.ID{1})
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatal(err)
}
// The duplicate entry won't fail, but it just silently shouldn't happen
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
results, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected only a single message, got %d", len(results))
}
// The duplicate entry won't fail, but it just silently shouldn't happen
_, err = eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatalf("%+v", err)
}
results, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(results) != 1 {
t.Fatalf("Expected only a single message, got %d", len(results))
}
// Now insert a message with a different message ID from the first
testMsgId2 := channel.MakeMessageID([]byte(testString), &id.ID{2})
testMsg = buildMessage([]byte(testString), testMsgId2.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
primaryKey, err := eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatal(err)
}
// Now insert a message with a different message ID from the first
testMsgId2 := channel.MakeMessageID([]byte(testString), &id.ID{2})
testMsg = buildMessage([]byte(testString), testMsgId2.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, netTime.Now(),
time.Second, 0, 0, channels.Sent)
primaryKey, err := eventModel.receiveHelper(testMsg, false)
if err != nil {
t.Fatal(err)
}
// Except this time, we update the second entry to have the same
// message ID as the first
testMsg.ID = primaryKey
testMsg.MessageID = testMsgId.Bytes()
_, err = eventModel.receiveHelper(testMsg, true)
if err != nil {
t.Fatal(err)
}
// Except this time, we update the second entry to have the same
// message ID as the first
testMsg.ID = primaryKey
testMsg.MessageID = testMsgId.Bytes()
_, err = eventModel.receiveHelper(testMsg, true)
if err != nil {
t.Fatal(err)
}
// The update to duplicate message ID won't fail,
// but it just silently shouldn't happen
results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
// The update to duplicate message ID won't fail,
// but it just silently shouldn't happen
results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
// TODO: Convert JSON to Message, ensure Message ID fields differ
})
}
// TODO: Convert JSON to Message, ensure Message ID fields differ
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment