cwtch/app/plugins/contactRetry_test.go

129 lines
4.8 KiB
Go

package plugins
import (
"testing"
"time"
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/protocol/connections"
"git.openprivacy.ca/openprivacy/log"
)
// TestContactRetryQueue simulates some basic connection queueing
// NOTE: This whole test is a race condition, and does flag go's detector
// We are invasively checking the internal state of the retry plugin and accessing pointers from another
// thread.
// We could build an entire thread safe monitoring functonality, but that would dramatically expand the scope of this test.
func TestContactRetryQueue(t *testing.T) {
log.SetLevel(log.LevelDebug)
bus := event.NewEventManager()
cr := NewConnectionRetry(bus, "").(*contactRetry)
cr.ACNUp = true // fake an ACN connection...
cr.protocolEngine = true // fake protocol engine
cr.stallRetries = false // fake not being in offline mode...
go cr.run()
testOnion := "2wgvbza2mbuc72a4u6r6k4hc2blcvrmk4q26bfvlwbqxv2yq5k52fcqd"
t.Logf("contact plugin up and running..sending peer connection...")
// Assert that there is a peer connection identified as "test"
bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: testOnion, event.LastSeen: "test"}))
// Wait until the test actually exists, and is queued
// This is the worst part of this test setup. Ideally we would sleep, or some other yielding, but
// go test scheduling doesn't like that and even sleeping long periods won't cause the event thread to make
// progress...
setup := false
for !setup {
if _, exists := cr.connections.Load(testOnion); exists {
if _, exists := cr.authorizedPeers.Load(testOnion); exists {
t.Logf("authorized")
setup = true
}
}
}
// We should very quickly become connecting...
time.Sleep(time.Second)
pinf, _ := cr.connections.Load(testOnion)
if pinf.(*contact).state != 1 {
t.Fatalf("test connection should be in connecting after update, actually: %v", pinf.(*contact).state)
}
// Asset that "test" is authenticated
cr.handleEvent(testOnion, connections.AUTHENTICATED, peerConn)
// Assert that "test has a valid state"
pinf, _ = cr.connections.Load(testOnion)
if pinf.(*contact).state != 3 {
t.Fatalf("test connection should be in authenticated after update, actually: %v", pinf.(*contact).state)
}
// Publish an unrelated event to trigger the Plugin to go through a queuing cycle
// If we didn't do this we would have to wait 30 seconds for a check-in
bus.Publish(event.NewEvent(event.PeerStateChange, map[event.Field]string{event.RemotePeer: "test2", event.ConnectionState: "Disconnected"}))
bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: testOnion, event.LastSeen: time.Now().Format(time.RFC3339Nano)}))
time.Sleep(time.Second)
pinf, _ = cr.connections.Load(testOnion)
if pinf.(*contact).state != 1 {
t.Fatalf("test connection should be in connecting after update, actually: %v", pinf.(*contact).state)
}
cr.Shutdown()
}
// Takes around 4 min unless you adjust the consts for tickTimeSec and circuitTimeoutSecs
/*
func TestRetryEmission(t *testing.T) {
log.SetLevel(log.LevelDebug)
log.Infof("*** Starting TestRetryEmission! ***")
bus := event.NewEventManager()
testQueue := event.NewQueue()
bus.Subscribe(event.PeerRequest, testQueue)
cr := NewConnectionRetry(bus, "").(*contactRetry)
cr.Start()
time.Sleep(100 * time.Millisecond)
bus.Publish(event.NewEventList(event.ACNStatus, event.Progress, "100"))
bus.Publish(event.NewEventList(event.ProtocolEngineCreated))
pub, _, _ := ed25519.GenerateKey(rand.Reader)
peerAddr := tor.GetTorV3Hostname(pub)
bus.Publish(event.NewEventList(event.QueuePeerRequest, event.RemotePeer, peerAddr, event.LastSeen, time.Now().Format(time.RFC3339Nano)))
log.Infof("Fetching 1st event")
ev := testQueue.Next()
if ev.EventType != event.PeerRequest {
t.Errorf("1st event emitted was %v, expected %v", ev.EventType, event.PeerRequest)
}
log.Infof("1st event: %v", ev)
bus.Publish(event.NewEventList(event.PeerStateChange, event.RemotePeer, peerAddr, event.ConnectionState, connections.ConnectionStateName[connections.DISCONNECTED]))
log.Infof("fetching 2nd event")
ev = testQueue.Next()
log.Infof("2nd event: %v", ev)
if ev.EventType != event.PeerRequest {
t.Errorf("2nd event emitted was %v, expected %v", ev.EventType, event.PeerRequest)
}
bus.Publish(event.NewEventList(event.PeerStateChange, event.RemotePeer, peerAddr, event.ConnectionState, connections.ConnectionStateName[connections.CONNECTED]))
time.Sleep(100 * time.Millisecond)
bus.Publish(event.NewEventList(event.PeerStateChange, event.RemotePeer, peerAddr, event.ConnectionState, connections.ConnectionStateName[connections.DISCONNECTED]))
log.Infof("fetching 3rd event")
ev = testQueue.Next()
log.Infof("3nd event: %v", ev)
if ev.EventType != event.PeerRequest {
t.Errorf("3nd event emitted was %v, expected %v", ev.EventType, event.PeerRequest)
}
cr.Shutdown()
}
*/