diff --git a/groupChat/receiveRequest_test.go b/groupChat/receiveRequest_test.go index 30b1dc975b48972132c5b5a13fe6e6c128dac44e..e39bbebbeac999409ddfe8fc20e6f3e30957f1bc 100644 --- a/groupChat/receiveRequest_test.go +++ b/groupChat/receiveRequest_test.go @@ -191,7 +191,7 @@ func TestManager_readRequest(t *testing.T) { theirSIDHPrivKey.Generate(prng) theirSIDHPrivKey.GeneratePublicKey(theirSIDHPubKey) - _, _ = m.e2e.AddPartner(m.receptionId, + _, _ = m.e2e.AddPartner( g.Members[0].ID, g.Members[0].DhKey, m.grp.NewInt(2), diff --git a/groupChat/receive_test.go b/groupChat/receive_test.go index f353b83a6c35ccc7865115249cfa86c2e086237d..bc35aee1d8280ebfbf261485b58a6a28476d04fc 100644 --- a/groupChat/receive_test.go +++ b/groupChat/receive_test.go @@ -8,361 +8,14 @@ package groupChat import ( - "bytes" - "gitlab.com/elixxir/client/stoppable" - "gitlab.com/elixxir/crypto/e2e" "gitlab.com/elixxir/crypto/group" - "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/netTime" "math/rand" - "reflect" "strings" "testing" "time" ) -// Tests that Manager.receive returns the correct message on the callback. -func TestManager_receive(t *testing.T) { - // Setup callback - msgChan := make(chan MessageReceive) - receiveFunc := func(msg MessageReceive) { msgChan <- msg } - - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t) - - // Create test parameters - contents := []byte("Test group message.") - timestamp := netTime.Now() - sender := m.gs.GetUser() - - expectedMsg := MessageReceive{ - GroupID: g.ID, - ID: group.MessageID{0, 1, 2, 3}, - Payload: contents, - SenderID: sender.ID, - Timestamp: timestamp.Local(), - RoundTimestamp: timestamp, - } - - // Create cMix message and get public message - cMixMsg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - - intlMsg, _ := newInternalMsg(cMixMsg.ContentsSize() - publicMinLen) - intlMsg.SetTimestamp(timestamp) - intlMsg.SetSenderID(m.gs.GetUser().ID) - intlMsg.SetPayload(contents) - expectedMsg.ID = group.NewMessageID(g.ID, intlMsg.Marshal()) - - receiveChan := make(chan message.Receive, 1) - stop := stoppable.NewSingle("singleStoppable") - - m.gs.SetUser(g.Members[4], t) - go m.receive(receiveChan, stop) - - receiveChan <- message.Receive{ - Payload: cMixMsg.Marshal(), - RoundTimestamp: timestamp, - } - - select { - case msg := <-msgChan: - if !reflect.DeepEqual(expectedMsg, msg) { - t.Errorf("Failed to received expected message."+ - "\nexpected: %+v\nreceived: %+v", expectedMsg, msg) - } - case <-time.NewTimer(10 * time.Millisecond).C: - t.Errorf("Timed out waiting to receive group message.") - } -} - -// Tests that the callback is not called when the message cannot be read. -func TestManager_receive_ReadMessageError(t *testing.T) { - // Setup callback - msgChan := make(chan MessageReceive) - receiveFunc := func(msg MessageReceive) { msgChan <- msg } - - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, _ := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t) - - receiveChan := make(chan message.Receive, 1) - stop := stoppable.NewSingle("singleStoppable") - - go m.receive(receiveChan, stop) - - receiveChan <- message.Receive{ - Payload: make([]byte, format.MinimumPrimeSize*2), - } - - select { - case <-msgChan: - t.Error("Callback called when message should have errored.") - case <-time.NewTimer(5 * time.Millisecond).C: - } -} - -// Tests that the quit channel exits the function. -func TestManager_receive_QuitChan(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - - receiveChan := make(chan message.Receive, 1) - stop := stoppable.NewSingle("singleStoppable") - doneChan := make(chan struct{}) - - go func() { - m.receive(receiveChan, stop) - doneChan <- struct{}{} - }() - - if err := stop.Close(); err != nil { - t.Errorf("Failed to signal close to process: %+v", err) - } - - select { - case <-doneChan: - case <-time.NewTimer(10 * time.Millisecond).C: - t.Errorf("Timed out waiting for thread to quit.") - } -} - -// Tests that Manager.readMessage returns the message data for the correct -// group. -func TestManager_readMessage(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, expectedGrp := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - - // Create test parameters - expectedContents := []byte("Test group message.") - expectedTimestamp := netTime.Now() - sender := m.gs.GetUser() - - // Create cMix message and get public message - cMixMsg, err := m.newCmixMsg(expectedGrp, expectedContents, - expectedTimestamp, expectedGrp.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - - internalMsg, _ := newInternalMsg(cMixMsg.ContentsSize() - publicMinLen) - internalMsg.SetTimestamp(expectedTimestamp) - internalMsg.SetSenderID(sender.ID) - internalMsg.SetPayload(expectedContents) - expectedMsgID := group.NewMessageID(expectedGrp.ID, internalMsg.Marshal()) - - // Build message.Receive - receiveMsg := message.Receive{ - ID: e2e.MessageID{}, - Payload: cMixMsg.Marshal(), - RoundTimestamp: expectedTimestamp, - } - - m.gs.SetUser(expectedGrp.Members[4], t) - g, messageID, timestamp, senderID, contents, noFpMatch, err := - m.readMessage(receiveMsg) - if err != nil { - t.Errorf("readMessage() returned an error: %+v", err) - } - - if noFpMatch { - t.Error("Fingerprint did not match when it should have.") - } - - if !reflect.DeepEqual(expectedGrp, g) { - t.Errorf("readMessage() returned incorrect group."+ - "\nexpected: %#v\nreceived: %#v", expectedGrp, g) - } - - if expectedMsgID != messageID { - t.Errorf("readMessage() returned incorrect message ID."+ - "\nexpected: %s\nreceived: %s", expectedMsgID, messageID) - } - - if !expectedTimestamp.Equal(timestamp) { - t.Errorf("readMessage() returned incorrect timestamp."+ - "\nexpected: %s\nreceived: %s", expectedTimestamp, timestamp) - } - - if !sender.ID.Cmp(senderID) { - t.Errorf("readMessage() returned incorrect sender ID."+ - "\nexpected: %s\nreceived: %s", sender.ID, senderID) - } - - if !bytes.Equal(expectedContents, contents) { - t.Errorf("readMessage() returned incorrect message."+ - "\nexpected: %s\nreceived: %s", expectedContents, contents) - } -} - -// Error path: an error is returned when a group with a matching group -// fingerprint cannot be found. -func TestManager_readMessage_FindGroupKpError(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - - // Create test parameters - expectedContents := []byte("Test group message.") - expectedTimestamp := netTime.Now() - - // Create cMix message and get public message - cMixMsg, err := m.newCmixMsg( - g, expectedContents, expectedTimestamp, g.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - - cMixMsg.SetKeyFP(format.NewFingerprint([]byte("invalid Fingerprint"))) - - // Build message.Receive - receiveMsg := message.Receive{ - ID: e2e.MessageID{}, - Payload: cMixMsg.Marshal(), - RoundTimestamp: expectedTimestamp, - } - - expectedErr := strings.SplitN(findGroupKeyFpErr, "%", 2)[0] - - m.gs.SetUser(g.Members[4], t) - _, _, _, _, _, _, err = m.readMessage(receiveMsg) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("readMessage() failed to return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } -} - -// Tests that a cMix message created by Manager.newCmixMsg can be read by -// Manager.readMessage. -func TestManager_decryptMessage(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManager(prng, t) - - // Create test parameters - expectedContents := []byte("Test group message.") - expectedTimestamp := netTime.Now() - - // Create cMix message and get public message - msg, err := m.newCmixMsg( - g, expectedContents, expectedTimestamp, g.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - publicMsg, err := unmarshalPublicMsg(msg.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) - } - - internalMsg, _ := newInternalMsg(publicMsg.GetPayloadSize()) - internalMsg.SetTimestamp(expectedTimestamp) - internalMsg.SetSenderID(m.gs.GetUser().ID) - internalMsg.SetPayload(expectedContents) - expectedMsgID := group.NewMessageID(g.ID, internalMsg.Marshal()) - - // Read message and check if the outputs are correct - messageID, timestamp, senderID, contents, err := m.decryptMessage(g, msg, - publicMsg, expectedTimestamp) - if err != nil { - t.Errorf("decryptMessage() returned an error: %+v", err) - } - - if expectedMsgID != messageID { - t.Errorf("decryptMessage() returned incorrect message ID."+ - "\nexpected: %s\nreceived: %s", expectedMsgID, messageID) - } - - if !expectedTimestamp.Equal(timestamp) { - t.Errorf("decryptMessage() returned incorrect timestamp."+ - "\nexpected: %s\nreceived: %s", expectedTimestamp, timestamp) - } - - if !m.gs.GetUser().ID.Cmp(senderID) { - t.Errorf("decryptMessage() returned incorrect sender ID."+ - "\nexpected: %s\nreceived: %s", m.gs.GetUser().ID, senderID) - } - - if !bytes.Equal(expectedContents, contents) { - t.Errorf("decryptMessage() returned incorrect message."+ - "\nexpected: %s\nreceived: %s", expectedContents, contents) - } -} - -// Error path: an error is returned when the wrong timestamp is passed in and -// the decryption key cannot be generated because of the wrong epoch. -func TestManager_decryptMessage_GetCryptKeyError(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManager(prng, t) - - // Create test parameters - contents := []byte("Test group message.") - timestamp := netTime.Now() - - // Create cMix message and get public message - msg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - publicMsg, err := unmarshalPublicMsg(msg.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) - } - - // Check if error is correct - expectedErr := strings.SplitN(genCryptKeyMacErr, "%", 2)[0] - _, _, _, _, err = m.decryptMessage(g, msg, publicMsg, timestamp.Add(time.Hour)) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("decryptMessage() failed to return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } -} - -// Error path: an error is returned when the decrypted payload cannot be -// unmarshalled. -func TestManager_decryptMessage_UnmarshalInternalMsgError(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManager(prng, t) - - // Create test parameters - contents := []byte("Test group message.") - timestamp := netTime.Now() - - // Create cMix message and get public message - msg, err := m.newCmixMsg(g, contents, timestamp, g.Members[4], prng) - if err != nil { - t.Errorf("Failed to create new cMix message: %+v", err) - } - publicMsg, err := unmarshalPublicMsg(msg.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) - } - - // Modify publicMsg to have invalid payload - publicMsg = mapPublicMsg(publicMsg.Marshal()[:33]) - key, err := group.NewKdfKey( - g.Key, group.ComputeEpoch(timestamp), publicMsg.GetSalt()) - if err != nil { - t.Errorf("failed to create new key: %+v", err) - } - msg.SetMac( - group.NewMAC(key, publicMsg.GetPayload(), g.DhKeys[*g.Members[4].ID])) - - // Check if error is correct - expectedErr := strings.SplitN(unmarshalInternalMsgErr, "%", 2)[0] - _, _, _, _, err = m.decryptMessage(g, msg, publicMsg, timestamp) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("decryptMessage() failed to return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } -} - // Unit test of getCryptKey. func Test_getCryptKey(t *testing.T) { prng := rand.New(rand.NewSource(42)) diff --git a/groupChat/send_test.go b/groupChat/send_test.go index 298e421770ac5d0f3469280504e7f650b148062a..55a956d63a035623d1ca90ad4ac135aa40c6c973 100644 --- a/groupChat/send_test.go +++ b/groupChat/send_test.go @@ -10,7 +10,8 @@ package groupChat import ( "bytes" "encoding/base64" - "gitlab.com/elixxir/client/cmix" + "gitlab.com/elixxir/client/cmix/historical" + "gitlab.com/elixxir/client/cmix/identity/receptionID" gs "gitlab.com/elixxir/client/groupChat/groupStore" "gitlab.com/elixxir/crypto/group" "gitlab.com/elixxir/primitives/format" @@ -22,256 +23,50 @@ import ( "time" ) -// Unit test of Manager.Send. func TestManager_Send(t *testing.T) { + receiveChan := make(chan MessageReceive, 100) + receiveFunc := func(msg MessageReceive) { + receiveChan <- msg + } + prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t) + m, g := newTestManagerWithStore(prng, 1, 0, nil, receiveFunc, t) messageBytes := []byte("Group chat message.") - sender := m.gs.GetUser().DeepCopy() + reception := &receptionProcessor{ + m: m, + g: g, + } - _, _, _, err := m.Send(g.ID, messageBytes) + roundId, _, msgId, err := m.Send(g.ID, messageBytes) if err != nil { t.Errorf("Send() returned an error: %+v", err) } // get messages sent with or return an error if no messages were sent - var messages []cmix.TargetedCmixMessage - if len(m.services.(*testNetworkManager).messages) > 0 { - messages = m.services.(*testNetworkManager).GetMsgList(0) + var messages []format.Message + if len(m.services.(*testNetworkManager).receptionMessages) > 0 { + messages = m.services.(*testNetworkManager).receptionMessages[0] } else { t.Error("No group cMix messages received.") } - timeNow := netTime.Now() - - // Loop through each message and make sure the recipient ID matches a member - // in the group and that each message can be decrypted and have the expected - // values - for _, msg := range messages { - // Check if recipient ID is in member list - var foundMember group.Member - for _, mem := range g.Members { - if msg.Recipient.Cmp(mem.ID) { - foundMember = mem - } - } - - // Error if the recipient ID is not found in the member list - if foundMember == (group.Member{}) { - t.Errorf("Failed to find ID %s in memorship list.", msg.Recipient) - continue - } - - publicMessage, err := unmarshalPublicMsg(msg.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) - } - // Attempt to read the message - result, err := decryptMessage( - g, msg.Message, publicMessage, timeNow) - if err != nil { - t.Errorf("Failed to read message for %s: %+v", msg.Recipient, err) - } - - internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize()) - internalMessage.SetTimestamp(timestamp) - internalMessage.SetSenderID(m.gs.GetUser().ID) - internalMessage.SetPayload(messageBytes) - expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal()) - - if expectedMsgID != messageID { - t.Errorf("Message ID received for %s too different from expected."+ - "\nexpected: %s\nreceived: %s", msg.Recipient, expectedMsgID, messageID) - } - - if !timestamp.Round(5 * time.Second).Equal(timeNow.Round(5 * time.Second)) { - t.Errorf("Timestamp received for %s too different from expected."+ - "\nexpected: %s\nreceived: %s", msg.Recipient, timeNow, timestamp) - } - - if !senderID.Cmp(sender.ID) { - t.Errorf("Sender ID received for %s incorrect."+ - "\nexpected: %s\nreceived: %s", msg.Recipient, sender.ID, senderID) - } - - if !bytes.Equal(readMsg, messageBytes) { - t.Errorf("Message received for %s incorrect."+ - "\nexpected: %q\nreceived: %q", msg.Recipient, messageBytes, readMsg) - } - } -} - -// Error path: error is returned when the message is too large. -func TestManager_Send_CmixMessageError(t *testing.T) { - // Set up new test manager that will make SendManyCMIX error - prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - expectedErr := strings.SplitN(newCmixMsgErr, "%", 2)[0] - - // Send message - _, _, _, err := m.Send(g.ID, make([]byte, 400)) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("Send() failed to return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } -} - -// Error path: SendManyCMIX returns an error. -func TestManager_Send_SendManyCMIXError(t *testing.T) { - // Set up new test manager that will make SendManyCMIX error - prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 1, nil, nil, t) - expectedErr := strings.SplitN(sendManyCmixErr, "%", 2)[0] - - // Send message - _, _, _, err := m.Send(g.ID, []byte("message")) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("Send() failed to return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } - - // If messages were added, then error - if len(m.services.(*testNetworkManager).messages) > 0 { - t.Error("Group cMix messages received when SendManyCMIX errors.") - } -} - -// Tests that Manager.createMessages generates the messages for the correct -// group. -func TestManager_createMessages(t *testing.T) { - prng := rand.New(rand.NewSource(42)) - m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - - testMsg := []byte("Test group message.") - sender := m.gs.GetUser() - messages, _, err := m.createMessages(g.ID, testMsg, netTime.Now()) - if err != nil { - t.Errorf("createMessages() returned an error: %+v", err) - } - - recipients := append(g.Members[:2], g.Members[3:]...) - - i := 0 - for _, msg := range messages { - for _, recipient := range recipients { - if !msg.Recipient.Cmp(recipient.ID) { - continue - } - - publicMessage, err := unmarshalPublicMsg(msg.Message.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) - } - - messageID, timestamp, testSender, testMessage, err := m.decryptMessage( - g, msg.Message, publicMessage, netTime.Now()) - if err != nil { - t.Errorf("Failed to find member to read message %d: %+v", i, err) - } - - internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize()) - internalMessage.SetTimestamp(timestamp) - internalMessage.SetSenderID(m.gs.GetUser().ID) - internalMessage.SetPayload(testMsg) - expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal()) - - if messageID != expectedMsgID { - t.Errorf("Failed to read correct message ID for message %d."+ - "\nexpected: %s\nreceived: %s", i, expectedMsgID, messageID) - } - - if !sender.ID.Cmp(testSender) { - t.Errorf("Failed to read correct sender ID for message %d."+ - "\nexpected: %s\nreceived: %s", i, sender.ID, testSender) - } - - if !bytes.Equal(testMsg, testMessage) { - t.Errorf("Failed to read correct message for message %d."+ - "\nexpected: %s\nreceived: %s", i, testMsg, testMessage) - } - } - i++ - } -} - -// Error path: test that an error is returned when the group ID does not match a -// group in storage. -func TestManager_createMessages_InvalidGroupIdError(t *testing.T) { - expectedErr := strings.SplitN(newNoGroupErr, "%", 2)[0] - - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t) - - // Read message and make sure the error is expected - _, _, err := m.createMessages( - id.NewIdFromString("invalidID", id.Group, t), nil, time.Time{}) - if err == nil || !strings.Contains(err.Error(), expectedErr) { - t.Errorf("createMessages() did not return the expected error."+ - "\nexpected: %s\nreceived: %+v", expectedErr, err) - } -} - -// Tests that Manager.newMessage returns messages with correct data. -func TestGroup_newMessages(t *testing.T) { - prng := rand.New(rand.NewSource(42)) - m, g := newTestManager(prng, t) - - testMsg := []byte("Test group message.") - sender := m.gs.GetUser() - timestamp := netTime.Now() - messages, err := m.newMessages(g, testMsg, timestamp) - if err != nil { - t.Errorf("newMessages() returned an error: %+v", err) - } - - recipients := append(g.Members[:2], g.Members[3:]...) - - i := 0 for _, msg := range messages { - for _, recipient := range recipients { - if !msg.Recipient.Cmp(recipient.ID) { - continue + reception.Process(msg, receptionID.EphemeralIdentity{}, historical.Round{ID: roundId}) + select { + case result := <-receiveChan: + if !result.SenderID.Cmp(m.receptionId) { + t.Errorf("Sender mismatch") } - - publicMessage, err := unmarshalPublicMsg(msg.Message.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal publicMsg: %+v", err) + if result.ID.String() != msgId.String() { + t.Errorf("MsgId mismatch") } - - result, err := decryptMessage( - g, msg.Message, publicMessage, netTime.Now()) - if err != nil { - t.Errorf("Failed to find member to read message %d.", i) + if !bytes.Equal(result.Payload, messageBytes) { + t.Errorf("Payload mismatch") } - - internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize()) - internalMessage.SetTimestamp(timestamp) - internalMessage.SetSenderID(m.gs.GetUser().ID) - internalMessage.SetPayload(testMsg) - expectedMsgID := group.NewMessageID(g.ID, internalMessage.Marshal()) - - if messageID != expectedMsgID { - t.Errorf("Failed to read correct message ID for message %d."+ - "\nexpected: %s\nreceived: %s", i, expectedMsgID, messageID) - } - - if !timestamp.Equal(testTimestamp) { - t.Errorf("Failed to read correct timeout for message %d."+ - "\nexpected: %s\nreceived: %s", i, timestamp, testTimestamp) - } - - if !sender.ID.Cmp(testSender) { - t.Errorf("Failed to read correct sender ID for message %d."+ - "\nexpected: %s\nreceived: %s", i, sender.ID, testSender) - } - - if !bytes.Equal(testMsg, testMessage) { - t.Errorf("Failed to read correct message for message %d."+ - "\nexpected: %s\nreceived: %s", i, testMsg, testMessage) + if result.RoundID != roundId { + t.Errorf("Round mismatch") } } - i++ } } @@ -288,88 +83,6 @@ func TestGroup_newMessages_NewCmixMsgError(t *testing.T) { } } -// Tests that the message returned by newCmixMsg has all the expected parts. -func TestGroup_newCmixMsg(t *testing.T) { - // Create new test Manager and Group - prng := rand.New(rand.NewSource(42)) - m, g := newTestManager(prng, t) - - // Create test parameters - testMsg := []byte("Test group message.") - mem := g.Members[3] - timeNow := netTime.Now() - - // Create cMix message - prng = rand.New(rand.NewSource(42)) - msg, err := newCmixMsg(g, testMsg, timeNow, mem, prng, m.receptionId, m.grp) - if err != nil { - t.Errorf("newCmixMsg() returned an error: %+v", err) - } - - // Create expected salt - prng = rand.New(rand.NewSource(42)) - var salt [group.SaltLen]byte - prng.Read(salt[:]) - - // Create expected key - key, _ := group.NewKdfKey(g.Key, group.ComputeEpoch(timeNow), salt) - - // Create expected messages - cmixMsg := format.NewMessage(m.grp.GetP().ByteLen()) - publicMessage, _ := newPublicMsg(cmixMsg.ContentsSize()) - internalMessage, _ := newInternalMsg(publicMessage.GetPayloadSize()) - internalMessage.SetTimestamp(timeNow) - internalMessage.SetSenderID(m.gs.GetUser().ID) - internalMessage.SetPayload(testMsg) - payload := internalMessage.Marshal() - - // Check if key fingerprint is correct - expectedFp := group.NewKeyFingerprint(g.Key, salt, mem.ID) - if expectedFp != msg.GetKeyFP() { - t.Errorf("newCmixMsg() returned message with wrong key fingerprint."+ - "\nexpected: %s\nreceived: %s", expectedFp, msg.GetKeyFP()) - } - - // Check if key MAC is correct - encryptedPayload := group.Encrypt(key, expectedFp, payload) - expectedMAC := group.NewMAC(key, encryptedPayload, g.DhKeys[*mem.ID]) - if !bytes.Equal(expectedMAC, msg.GetMac()) { - t.Errorf("newCmixMsg() returned message with wrong MAC."+ - "\nexpected: %+v\nreceived: %+v", expectedMAC, msg.GetMac()) - } - - // Attempt to unmarshal public group message - publicMessage, err = unmarshalPublicMsg(msg.GetContents()) - if err != nil { - t.Errorf("Failed to unmarshal cMix message contents: %+v", err) - } - - // Attempt to decrypt payload - decryptedPayload := group.Decrypt(key, expectedFp, publicMessage.GetPayload()) - internalMessage, err = unmarshalInternalMsg(decryptedPayload) - if err != nil { - t.Errorf("Failed to unmarshal decrypted payload contents: %+v", err) - } - - // Check for expected values in internal message - if !internalMessage.GetTimestamp().Equal(timeNow) { - t.Errorf("Internal message has wrong timestamp."+ - "\nexpected: %s\nreceived: %s", timeNow, internalMessage.GetTimestamp()) - } - sid, err := internalMessage.GetSenderID() - if err != nil { - t.Fatalf("Failed to get sender ID from internal message: %+v", err) - } - if !sid.Cmp(m.gs.GetUser().ID) { - t.Errorf("Internal message has wrong sender ID."+ - "\nexpected: %s\nreceived: %s", m.gs.GetUser().ID, sid) - } - if !bytes.Equal(internalMessage.GetPayload(), testMsg) { - t.Errorf("Internal message has wrong payload."+ - "\nexpected: %s\nreceived: %s", testMsg, internalMessage.GetPayload()) - } -} - // Error path: reader returns an error. func TestGroup_newCmixMsg_SaltReaderError(t *testing.T) { expectedErr := strings.SplitN(saltReadErr, "%", 2)[0] diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go index d3d1c1599573f34315aec4b256de615d356f1415..88dc69e1b2e79081c0d4817ef675f41bb39628fb 100644 --- a/groupChat/utils_test.go +++ b/groupChat/utils_test.go @@ -223,8 +223,9 @@ func getGroup() *cyclic.Group { func newTestNetworkManager(sendErr int, t *testing.T) cmix.Client { return &testNetworkManager{ - messages: [][]cmix.TargetedCmixMessage{}, - sendErr: sendErr, + receptionMessages: [][]format.Message{}, + sendMessages: [][]cmix.TargetedCmixMessage{}, + sendErr: sendErr, } } @@ -271,9 +272,10 @@ func (tnm *testE2eManager) GetReceptionID() *id.ID { // testNetworkManager is a test implementation of NetworkManager interface. type testNetworkManager struct { - messages [][]cmix.TargetedCmixMessage - errSkip int - sendErr int + receptionMessages [][]format.Message + sendMessages [][]cmix.TargetedCmixMessage + errSkip int + sendErr int sync.RWMutex } @@ -289,8 +291,17 @@ func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, p c tnm.Lock() defer tnm.Unlock() - tnm.messages = append(tnm.messages, messages) + tnm.sendMessages = append(tnm.sendMessages, messages) + receiveMessages := []format.Message{} + for _, msg := range messages { + receiveMsg := format.Message{} + receiveMsg.SetMac(msg.Mac) + receiveMsg.SetContents(msg.Payload) + receiveMsg.SetKeyFP(msg.Fingerprint) + receiveMessages = append(receiveMessages, receiveMsg) + } + tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages) return 0, nil, nil } @@ -359,7 +370,6 @@ func (*testNetworkManager) IsHealthy() bool { } func (*testNetworkManager) WasHealthy() bool { - //TODO implement me panic("implement me") } @@ -490,12 +500,6 @@ func (*testE2eManager) GetDefaultID() *id.ID { panic("implement me") } -func (tnm *testNetworkManager) GetMsgList(i int) []cmix.TargetedCmixMessage { - tnm.RLock() - defer tnm.RUnlock() - return tnm.messages[i] -} - func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage { tnm.RLock() defer tnm.RUnlock()