Tapir provides a framework for building Anonymous / metadata resistant Services
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.6 KiB

  1. package testing
  2. import (
  3. "cwtch.im/tapir"
  4. "cwtch.im/tapir/applications"
  5. "cwtch.im/tapir/networks/tor"
  6. "cwtch.im/tapir/primitives"
  7. "git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
  8. "git.openprivacy.ca/openprivacy/libricochet-go/log"
  9. "git.openprivacy.ca/openprivacy/libricochet-go/utils"
  10. "golang.org/x/crypto/ed25519"
  11. "runtime"
  12. "sync"
  13. "testing"
  14. "time"
  15. )
  16. // SimpleApp is a trivial implementation of a basic p2p application
  17. type SimpleApp struct {
  18. applications.AuthApp
  19. }
  20. // NewInstance should always return a new instantiation of the application.
  21. func (ea *SimpleApp) NewInstance() tapir.Application {
  22. return new(SimpleApp)
  23. }
  24. // Init is run when the connection is first started.
  25. func (ea *SimpleApp) Init(connection tapir.Connection) {
  26. // First run the Authentication App
  27. ea.AuthApp.Init(connection)
  28. if connection.HasCapability(applications.AuthCapability) {
  29. // The code for out simple application (We just send and receive "Hello"
  30. connection.Send([]byte("Hello"))
  31. message := connection.Expect()
  32. log.Infof("Received: %q", message)
  33. }
  34. }
  35. var AuthSuccess = false
  36. // CheckConnection is a simple test that GetConnection is working.
  37. func CheckConnection(service tapir.Service, hostname string, group *sync.WaitGroup) {
  38. for {
  39. _, err := service.GetConnection(hostname)
  40. if err == nil {
  41. log.Infof("Authed!")
  42. group.Done()
  43. return
  44. }
  45. log.Infof("Waiting for Authentication...%v", err)
  46. time.Sleep(time.Second * 5)
  47. }
  48. }
  49. func TestTapir(t *testing.T) {
  50. numRoutinesStart := runtime.NumGoroutine()
  51. log.SetLevel(log.LevelDebug)
  52. log.Infof("Number of goroutines open at start: %d", runtime.NumGoroutine())
  53. // Connect to Tor
  54. var acn connectivity.ACN
  55. acn, _ = connectivity.StartTor("./", "")
  56. acn.WaitTillBootstrapped()
  57. // Generate Server Keys
  58. id, sk := primitives.InitializeEphemeralIdentity()
  59. // Init the Server running the Simple App.
  60. var service tapir.Service
  61. service = new(tor.BaseOnionService)
  62. service.Init(acn, sk, &id)
  63. // Goroutine Management
  64. sg := new(sync.WaitGroup)
  65. sg.Add(1)
  66. go func() {
  67. service.Listen(new(SimpleApp))
  68. sg.Done()
  69. }()
  70. // Wait for server to come online
  71. time.Sleep(time.Second * 30)
  72. wg := new(sync.WaitGroup)
  73. wg.Add(2)
  74. // Init a Client to Connect to the Server
  75. client, clienthostname := genclient(acn)
  76. go connectclient(client, id.PublicKey(), wg)
  77. CheckConnection(service, clienthostname, wg)
  78. wg.Wait()
  79. // Wait for Server to Sync
  80. time.Sleep(time.Second * 2)
  81. log.Infof("Closing ACN...")
  82. acn.Close()
  83. sg.Wait()
  84. time.Sleep(time.Second * 2)
  85. log.Infof("Number of goroutines open at close: %d", runtime.NumGoroutine())
  86. if numRoutinesStart != runtime.NumGoroutine() {
  87. t.Errorf("Potential goroutine leak: Num Start:%v NumEnd: %v", numRoutinesStart, runtime.NumGoroutine())
  88. }
  89. if !AuthSuccess {
  90. t.Fatalf("Integration Test FAILED, client did not auth with server")
  91. }
  92. }
  93. func genclient(acn connectivity.ACN) (tapir.Service, string) {
  94. id, sk := primitives.InitializeEphemeralIdentity()
  95. var client tapir.Service
  96. client = new(tor.BaseOnionService)
  97. client.Init(acn, sk, &id)
  98. return client, id.Hostname()
  99. }
  100. // Client will Connect and launch it's own Echo App goroutine.
  101. func connectclient(client tapir.Service, key ed25519.PublicKey, group *sync.WaitGroup) {
  102. client.Connect(utils.GetTorV3Hostname(key), new(SimpleApp))
  103. // Once connected, it shouldn't take long to authenticate and run the application. So for the purposes of this demo
  104. // we will wait a little while then exit.
  105. time.Sleep(time.Second * 5)
  106. conn, _ := client.GetConnection(utils.GetTorV3Hostname(key))
  107. log.Debugf("Client has Auth: %v", conn.HasCapability(applications.AuthCapability))
  108. AuthSuccess = true
  109. group.Done()
  110. }