//////////////////////////////////////////////////////////////////////////////// // Copyright © 2020 xx network SEZC // // // // Use of this source code is governed by a license that can be found in the // // LICENSE file // //////////////////////////////////////////////////////////////////////////////// package dummy import ( "bytes" "encoding/base64" "gitlab.com/elixxir/client/stoppable" "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" "reflect" "sync/atomic" "testing" "time" ) // Tests that Manager.sendThread sends multiple sets of messages. func TestManager_sendThread(t *testing.T) { m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t) stop := stoppable.NewSingle("sendThreadTest") go m.sendThread(stop) if stat := atomic.LoadUint32(&m.status); stat != notStarted { t.Errorf("Unexpected thread status.\nexpected: %d\nreceived: %d", notStarted, stat) } err := m.SetStatus(true) if err != nil { t.Errorf("Failed to set status to true.") } msgChan := make(chan bool, 10) go func() { var numReceived int for i := 0; i < 2; i++ { for m.net.(*mockCmix).GetMsgListLen() == numReceived { time.Sleep(5 * time.Millisecond) } numReceived = m.net.(*mockCmix).GetMsgListLen() msgChan <- true } }() var numReceived int select { case <-time.NewTimer(3 * m.avgSendDelta).C: t.Errorf("Timed out after %s waiting for messages to be sent.", 3*m.avgSendDelta) case <-msgChan: numReceived += m.net.(*mockCmix).GetMsgListLen() } select { case <-time.NewTimer(3 * m.avgSendDelta).C: t.Errorf("Timed out after %s waiting for messages to be sent.", 3*m.avgSendDelta) case <-msgChan: if m.net.(*mockCmix).GetMsgListLen() <= numReceived { t.Errorf("Failed to receive second send."+ "\nmessages on last receive: %d\nmessages on this receive: %d", numReceived, m.net.(*mockCmix).GetMsgListLen()) } } err = stop.Close() if err != nil { t.Errorf("Failed to close stoppable: %+v", err) } time.Sleep(10 * time.Millisecond) if !stop.IsStopped() { t.Error("Stoppable never stopped.") } if stat := atomic.LoadUint32(&m.status); stat != stopped { t.Errorf("Unexpected thread status.\nexpected: %d\nreceived: %d", stopped, stat) } } // Tests that Manager.sendMessages sends all the messages with the correct // recipient. func TestManager_sendMessages(t *testing.T) { m := newTestManager(100, 0, 0, false, t) prng := NewPrng(42) // Generate map of recipients and messages msgs := make(map[id.ID]format.Message, m.maxNumMessages) for i := 0; i < m.maxNumMessages; i++ { recipient, err := id.NewRandomID(prng, id.User) if err != nil { t.Errorf("Failed to generate random recipient ID (%d): %+v", i, err) } msg, err := m.newRandomCmixMessage(prng) if err != nil { t.Errorf("Failed to generate random cMix message (%d): %+v", i, err) } msgs[*recipient] = msg } // Send the messages err := m.sendMessages(msgs, prng) if err != nil { t.Errorf("sendMessages returned an error: %+v", err) } // get sent messages receivedMsgs := m.net.(*mockCmix).GetMsgList() // Test that all messages were received if len(receivedMsgs) != len(msgs) { t.Errorf("Failed to received all sent messages."+ "\nexpected: %d\nreceived: %d", len(msgs), len(receivedMsgs)) } // Test that all messages were received for the correct recipient for recipient, msg := range msgs { receivedMsg, exists := receivedMsgs[recipient] if !exists { t.Errorf("Failed to receive message from %s: %+v", &recipient, msg) } else if !reflect.DeepEqual(msg, receivedMsg) { t.Errorf("Received unexpected message for recipient %s."+ "\nexpected: %+v\nreceived: %+v", &recipient, msg, receivedMsg) } } } // Tests that Manager.newRandomMessages creates a non-empty map of messages and // that each message is unique. func TestManager_newRandomMessages(t *testing.T) { m := newTestManager(10, 0, 0, false, t) prng := NewPrng(42) msgMap, err := m.newRandomMessages(prng) if err != nil { t.Errorf("newRandomMessages returned an error: %+v", err) } if len(msgMap) == 0 { t.Error("Message map is empty.") } marshalledMsgs := make(map[string]format.Message, len(msgMap)) for _, msg := range msgMap { msgString := base64.StdEncoding.EncodeToString(msg.Marshal()) if _, exists := marshalledMsgs[msgString]; exists { t.Errorf("Message not unique.") } else { marshalledMsgs[msgString] = msg } } } // Tests that Manager.newRandomCmixMessage generates a cMix message with // populated contents, fingerprint, and MAC. func TestManager_newRandomCmixMessage(t *testing.T) { m := newTestManager(0, 0, 0, false, t) prng := NewPrng(42) cMixMsg, err := m.newRandomCmixMessage(prng) if err != nil { t.Errorf("newRandomCmixMessage returned an error: %+v", err) } if bytes.Equal(cMixMsg.GetContents(), make([]byte, len(cMixMsg.GetContents()))) { t.Error("cMix message contents not set.") } if cMixMsg.GetKeyFP() == (format.Fingerprint{}) { t.Error("cMix message fingerprint not set.") } if bytes.Equal(cMixMsg.GetMac(), make([]byte, format.MacLen)) { t.Error("cMix message MAC not set.") } }