tapir/testing/tapir_integration_test.go

128 lines
3.6 KiB
Go
Raw Permalink Normal View History

package testing
2019-05-15 19:45:45 +00:00
import (
"cwtch.im/tapir"
2019-07-16 19:14:42 +00:00
"cwtch.im/tapir/applications"
"cwtch.im/tapir/networks/tor"
"cwtch.im/tapir/primitives"
2019-05-15 19:45:45 +00:00
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/log"
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"golang.org/x/crypto/ed25519"
"runtime"
"sync"
"testing"
2019-05-15 19:45:45 +00:00
"time"
)
2019-05-21 18:28:10 +00:00
// SimpleApp is a trivial implementation of a basic p2p application
2019-05-15 19:45:45 +00:00
type SimpleApp struct {
2019-07-16 19:14:42 +00:00
applications.AuthApp
2019-05-15 19:45:45 +00:00
}
// NewInstance should always return a new instantiation of the application.
2019-09-14 23:44:19 +00:00
func (ea *SimpleApp) NewInstance() tapir.Application {
2019-05-15 19:45:45 +00:00
return new(SimpleApp)
}
// Init is run when the connection is first started.
2019-09-14 23:44:19 +00:00
func (ea *SimpleApp) Init(connection tapir.Connection) {
2019-05-15 19:45:45 +00:00
// First run the Authentication App
ea.AuthApp.Init(connection)
2019-07-16 19:14:42 +00:00
if connection.HasCapability(applications.AuthCapability) {
2019-05-15 19:45:45 +00:00
// The code for out simple application (We just send and receive "Hello"
connection.Send([]byte("Hello"))
message := connection.Expect()
log.Infof("Received: %q", message)
}
}
var AuthSuccess = false
2019-07-16 20:22:30 +00:00
// CheckConnection is a simple test that GetConnection is working.
func CheckConnection(service tapir.Service, hostname string, group *sync.WaitGroup) {
2019-07-16 20:22:30 +00:00
for {
_, err := service.GetConnection(hostname)
if err == nil {
log.Infof("Authed!")
group.Done()
2019-07-16 20:22:30 +00:00
return
}
log.Infof("Waiting for Authentication...%v", err)
time.Sleep(time.Second * 5)
2019-07-16 20:22:30 +00:00
}
}
func TestTapir(t *testing.T) {
2019-05-15 19:45:45 +00:00
numRoutinesStart := runtime.NumGoroutine()
2019-05-15 19:45:45 +00:00
log.SetLevel(log.LevelDebug)
log.Infof("Number of goroutines open at start: %d", runtime.NumGoroutine())
2019-05-15 19:45:45 +00:00
// Connect to Tor
var acn connectivity.ACN
acn, _ = connectivity.StartTor("./", "")
acn.WaitTillBootstrapped()
// Generate Server Keys
2019-08-08 19:07:13 +00:00
id, sk := primitives.InitializeEphemeralIdentity()
2019-05-15 19:45:45 +00:00
2019-06-05 18:44:26 +00:00
// Init the Server running the Simple App.
2019-05-15 19:45:45 +00:00
var service tapir.Service
2019-07-16 19:14:42 +00:00
service = new(tor.BaseOnionService)
service.Init(acn, sk, &id)
// Goroutine Management
sg := new(sync.WaitGroup)
sg.Add(1)
go func() {
2019-09-14 23:44:19 +00:00
service.Listen(new(SimpleApp))
sg.Done()
}()
// Wait for server to come online
time.Sleep(time.Second * 30)
wg := new(sync.WaitGroup)
wg.Add(2)
// Init a Client to Connect to the Server
client, clienthostname := genclient(acn)
go connectclient(client, id.PublicKey(), wg)
CheckConnection(service, clienthostname, wg)
wg.Wait()
// Wait for Server to Sync
time.Sleep(time.Second * 2)
log.Infof("Closing ACN...")
acn.Close()
sg.Wait()
time.Sleep(time.Second * 2)
log.Infof("Number of goroutines open at close: %d", runtime.NumGoroutine())
if numRoutinesStart != runtime.NumGoroutine() {
t.Errorf("Potential goroutine leak: Num Start:%v NumEnd: %v", numRoutinesStart, runtime.NumGoroutine())
}
if !AuthSuccess {
t.Fatalf("Integration Test FAILED, client did not auth with server")
}
2019-05-15 19:45:45 +00:00
}
2019-07-16 20:22:30 +00:00
func genclient(acn connectivity.ACN) (tapir.Service, string) {
2019-08-08 19:07:13 +00:00
id, sk := primitives.InitializeEphemeralIdentity()
2019-05-15 19:45:45 +00:00
var client tapir.Service
2019-07-16 19:14:42 +00:00
client = new(tor.BaseOnionService)
client.Init(acn, sk, &id)
return client, id.Hostname()
2019-07-16 20:22:30 +00:00
}
// Client will Connect and launch it's own Echo App goroutine.
func connectclient(client tapir.Service, key ed25519.PublicKey, group *sync.WaitGroup) {
2019-09-14 23:44:19 +00:00
client.Connect(utils.GetTorV3Hostname(key), new(SimpleApp))
2019-05-15 19:45:45 +00:00
// Once connected, it shouldn't take long to authenticate and run the application. So for the purposes of this demo
// we will wait a little while then exit.
time.Sleep(time.Second * 5)
2019-05-21 18:28:10 +00:00
2019-07-16 20:22:30 +00:00
conn, _ := client.GetConnection(utils.GetTorV3Hostname(key))
2019-07-16 19:14:42 +00:00
log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability))
AuthSuccess = true
group.Done()
2019-05-15 19:45:45 +00:00
}