2018-03-31 19:33:32 +00:00
package testing
2018-03-30 21:16:51 +00:00
import (
2020-10-13 18:53:18 +00:00
"crypto/rand"
2019-05-15 20:12:11 +00:00
app2 "cwtch.im/cwtch/app"
2019-09-19 23:14:35 +00:00
"cwtch.im/cwtch/event"
2018-05-28 18:05:06 +00:00
"cwtch.im/cwtch/model"
2020-03-07 07:41:00 +00:00
"cwtch.im/cwtch/model/attr"
2021-10-15 19:38:22 +00:00
"cwtch.im/cwtch/model/constants"
2018-05-28 18:05:06 +00:00
"cwtch.im/cwtch/peer"
2019-01-04 21:44:21 +00:00
"cwtch.im/cwtch/protocol/connections"
2020-10-13 18:53:18 +00:00
"encoding/base64"
2021-11-16 23:06:30 +00:00
"encoding/json"
2022-12-05 07:28:24 +00:00
"fmt"
2022-10-11 17:58:10 +00:00
"git.openprivacy.ca/cwtch.im/tapir/primitives/privacypass"
2020-02-10 22:09:24 +00:00
"git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/log"
2021-11-17 22:34:13 +00:00
_ "github.com/mutecomm/go-sqlcipher/v4"
2020-10-13 18:53:18 +00:00
mrand "math/rand"
2018-11-10 22:14:12 +00:00
"os"
2020-02-03 18:46:15 +00:00
"os/user"
"path"
2022-10-11 17:58:10 +00:00
"path/filepath"
2018-05-30 18:42:17 +00:00
"runtime"
2019-01-04 21:44:21 +00:00
"runtime/pprof"
2022-12-05 06:11:32 +00:00
"strconv"
2018-05-20 19:58:16 +00:00
"testing"
"time"
2018-03-30 21:16:51 +00:00
)
2018-04-27 19:20:33 +00:00
var (
2018-06-05 22:06:38 +00:00
aliceLines = [ ] string { "Hello, I'm Alice" , "bye" }
bobLines = [ ] string { "Hi, my name is Bob." , "toodles" , "welcome" }
carolLines = [ ] string { "Howdy, thanks!" }
2018-04-27 19:20:33 +00:00
)
2021-11-17 22:34:13 +00:00
func waitForConnection ( t * testing . T , peer peer . CwtchPeer , addr string , target connections . ConnectionState ) {
2021-10-15 19:38:22 +00:00
peerName , _ := peer . GetScopedZonedAttribute ( attr . LocalScope , attr . ProfileZone , constants . Name )
2018-06-03 19:36:20 +00:00
for {
2021-12-17 00:07:08 +00:00
log . Infof ( "%v checking connection...\n" , peerName )
2021-11-17 22:34:13 +00:00
state := peer . GetPeerState ( addr )
2022-12-03 00:23:11 +00:00
log . Infof ( "Waiting for Peer %v to %v - state: %v\n" , peerName , addr , connections . ConnectionStateName [ state ] )
2021-11-17 22:34:13 +00:00
if state == connections . FAILED {
t . Fatalf ( "%v could not connect to %v" , peer . GetOnion ( ) , addr )
2020-02-03 18:46:15 +00:00
}
2021-11-17 22:34:13 +00:00
if state != target {
2021-12-17 00:07:08 +00:00
log . Infof ( "peer %v %v waiting connect %v, currently: %v\n" , peerName , peer . GetOnion ( ) , addr , connections . ConnectionStateName [ state ] )
2021-11-17 22:34:13 +00:00
time . Sleep ( time . Second * 5 )
continue
} else {
2021-12-17 00:07:08 +00:00
log . Infof ( "peer %v %v CONNECTED to %v\n" , peerName , peer . GetOnion ( ) , addr )
2021-11-17 22:34:13 +00:00
break
2020-02-03 18:46:15 +00:00
}
2018-11-10 22:14:12 +00:00
}
}
2022-12-05 06:48:14 +00:00
func waitForRetVal ( peer peer . CwtchPeer , convId int , szp attr . ScopedZonedPath ) {
for {
_ , err := peer . GetConversationAttribute ( convId , szp )
if err == nil {
return
}
time . Sleep ( time . Second * 5 )
}
}
2022-10-11 17:58:10 +00:00
func checkAndLoadTokens ( ) [ ] * privacypass . Token {
var tokens [ ] * privacypass . Token
data , err := os . ReadFile ( "../tokens" )
if err == nil {
err := json . Unmarshal ( data , & tokens )
if err != nil {
log . Errorf ( "could not load tokens from file" )
}
}
return tokens
}
2018-03-30 21:16:51 +00:00
func TestCwtchPeerIntegration ( t * testing . T ) {
2018-04-27 19:20:33 +00:00
2022-01-12 20:47:04 +00:00
// Goroutine Monitoring Start..
numGoRoutinesStart := runtime . NumGoroutine ( )
2019-02-04 22:18:24 +00:00
log . AddEverythingFromPattern ( "connectivity" )
2019-06-21 21:50:43 +00:00
log . SetLevel ( log . LevelDebug )
log . ExcludeFromPattern ( "connection/connection" )
log . ExcludeFromPattern ( "outbound/3dhauthchannel" )
log . ExcludeFromPattern ( "event/eventmanager" )
2020-02-03 18:46:15 +00:00
log . ExcludeFromPattern ( "tapir" )
2022-10-11 17:58:10 +00:00
// checking if we should use the token cache
cachedTokens := checkAndLoadTokens ( )
if len ( cachedTokens ) > 7 {
log . Infof ( "using cached tokens" )
}
2020-10-29 21:22:33 +00:00
os . Mkdir ( "tordir" , 0700 )
2020-10-13 18:53:18 +00:00
dataDir := path . Join ( "tordir" , "tor" )
2020-09-21 22:39:15 +00:00
os . MkdirAll ( dataDir , 0700 )
2020-10-13 18:53:18 +00:00
// we don't need real randomness for the port, just to avoid a possible conflict...
mrand . Seed ( int64 ( time . Now ( ) . Nanosecond ( ) ) )
2020-10-29 21:22:33 +00:00
socksPort := mrand . Intn ( 1000 ) + 9051
controlPort := mrand . Intn ( 1000 ) + 9052
2020-10-13 18:53:18 +00:00
// generate a random password
key := make ( [ ] byte , 64 )
_ , err := rand . Read ( key )
if err != nil {
panic ( err )
}
2022-10-11 17:58:10 +00:00
useCache := os . Getenv ( "TORCACHE" ) == "true"
2022-01-20 21:27:35 +00:00
torDataDir := ""
2022-10-11 17:58:10 +00:00
if useCache {
log . Infof ( "using tor cache" )
torDataDir = filepath . Join ( dataDir , "data-dir-torcache" )
os . MkdirAll ( torDataDir , 0700 )
} else {
log . Infof ( "using clean tor data dir" )
if torDataDir , err = os . MkdirTemp ( dataDir , "data-dir-" ) ; err != nil {
t . Fatalf ( "could not create data dir" )
}
2022-01-20 21:27:35 +00:00
}
2020-10-13 18:53:18 +00:00
tor . NewTorrc ( ) . WithSocksPort ( socksPort ) . WithOnionTrafficOnly ( ) . WithHashedPassword ( base64 . StdEncoding . EncodeToString ( key ) ) . WithControlPort ( controlPort ) . Build ( "tordir/tor/torrc" )
2022-01-20 21:27:35 +00:00
acn , err := tor . NewTorACNWithAuth ( "./tordir" , path . Join ( ".." , "tor" ) , torDataDir , controlPort , tor . HashedPasswordAuthenticator { Password : base64 . StdEncoding . EncodeToString ( key ) } )
2018-11-10 22:14:12 +00:00
if err != nil {
t . Fatalf ( "Could not start Tor: %v" , err )
}
2022-12-03 00:23:11 +00:00
log . Infof ( "Waiting for tor to bootstrap..." )
2021-11-16 23:06:30 +00:00
acn . WaitTillBootstrapped ( )
defer acn . Close ( )
2021-11-19 22:04:43 +00:00
2019-01-28 20:09:25 +00:00
// ***** Cwtch Server management *****
2021-06-29 21:38:53 +00:00
const ServerKeyBundleBase64 = "eyJLZXlzIjp7ImJ1bGxldGluX2JvYXJkX29uaW9uIjoibmZoeHp2enhpbnJpcGdkaDR0Mm00eGN5M2NyZjZwNGNiaGVjdGdja3VqM2lkc2pzYW90Z293YWQiLCJwcml2YWN5X3Bhc3NfcHVibGljX2tleSI6IjVwd2hQRGJ0c0EvdFI3ZHlUVUkzakpZZnM1L3Jaai9iQ1ZWZEpTc0Jtbk09IiwidG9rZW5fc2VydmljZV9vbmlvbiI6ImVvd25mcTRsNTZxMmU0NWs0bW03MjdsanJod3Z0aDZ5ZWN0dWV1bXB4emJ5cWxnbXVhZm1qdXFkIn0sIlNpZ25hdHVyZSI6IlY5R3NPMHNZWFJ1bGZxdzdmbGdtclVxSTBXS0JlSFIzNjIvR3hGbWZPekpEZjJaRks2ck9jNVRRR1ZxVWIrbXIwV2xId0pwdXh0UW1JRU9KNkplYkNRPT0ifQ=="
const ServerAddr = "nfhxzvzxinripgdh4t2m4xcy3crf6p4cbhectgckuj3idsjsaotgowad"
serverKeyBundle , _ := base64 . StdEncoding . DecodeString ( ServerKeyBundleBase64 )
2018-04-27 19:20:33 +00:00
2023-02-28 18:13:11 +00:00
app := app2 . NewApp ( acn , "./storage" , app2 . LoadAppSettings ( "./storage" ) )
2019-05-15 20:12:11 +00:00
2020-02-03 18:46:15 +00:00
usr , _ := user . Current ( )
cwtchDir := path . Join ( usr . HomeDir , ".cwtch" )
os . Mkdir ( cwtchDir , 0700 )
os . RemoveAll ( path . Join ( cwtchDir , "testing" ) )
os . Mkdir ( path . Join ( cwtchDir , "testing" ) , 0700 )
2019-06-05 20:40:55 +00:00
numGoRoutinesPostAppStart := runtime . NumGoroutine ( )
2018-05-28 18:36:04 +00:00
2019-06-05 20:40:55 +00:00
// ***** cwtchPeer setup *****
2019-01-04 21:44:21 +00:00
2021-12-17 00:07:08 +00:00
log . Infoln ( "Creating Alice..." )
2023-02-21 23:55:14 +00:00
app . CreateProfile ( "Alice" , "asdfasdf" , true )
2018-04-27 19:20:33 +00:00
2021-12-17 00:07:08 +00:00
log . Infoln ( "Creating Bob..." )
2023-02-21 23:55:14 +00:00
app . CreateProfile ( "Bob" , "asdfasdf" , true )
2018-05-28 18:36:04 +00:00
2021-12-17 00:07:08 +00:00
log . Infoln ( "Creating Carol..." )
2023-02-21 23:55:14 +00:00
app . CreateProfile ( "Carol" , "asdfasdf" , true )
2019-06-05 20:40:55 +00:00
2022-07-05 22:31:44 +00:00
alice := app2 . WaitGetPeer ( app , "Alice" )
2022-12-05 06:11:32 +00:00
aliceBus := app . GetEventBus ( alice . GetOnion ( ) )
2023-02-21 23:55:14 +00:00
app . ActivatePeerEngine ( alice . GetOnion ( ) )
2021-12-17 00:07:08 +00:00
log . Infoln ( "Alice created:" , alice . GetOnion ( ) )
2023-04-03 19:44:28 +00:00
// alice.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Alice") <- This is now done automatically by ProfileValueExtension, keeping this here for clarity
2020-04-17 00:00:17 +00:00
alice . AutoHandleEvents ( [ ] event . Type { event . PeerStateChange , event . ServerStateChange , event . NewGroupInvite , event . NewRetValMessageFromPeer } )
2019-06-05 20:40:55 +00:00
2022-07-05 22:31:44 +00:00
bob := app2 . WaitGetPeer ( app , "Bob" )
2022-12-05 06:11:32 +00:00
bobBus := app . GetEventBus ( bob . GetOnion ( ) )
2023-02-21 23:55:14 +00:00
app . ActivatePeerEngine ( bob . GetOnion ( ) )
2021-12-17 00:07:08 +00:00
log . Infoln ( "Bob created:" , bob . GetOnion ( ) )
2023-04-03 19:44:28 +00:00
// bob.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Bob") <- This is now done automatically by ProfileValueExtension, keeping this here for clarity
2020-04-17 00:00:17 +00:00
bob . AutoHandleEvents ( [ ] event . Type { event . PeerStateChange , event . ServerStateChange , event . NewGroupInvite , event . NewRetValMessageFromPeer } )
2019-06-05 20:40:55 +00:00
2022-07-05 22:31:44 +00:00
carol := app2 . WaitGetPeer ( app , "Carol" )
2022-12-05 06:11:32 +00:00
carolBus := app . GetEventBus ( carol . GetOnion ( ) )
2023-02-21 23:55:14 +00:00
app . ActivatePeerEngine ( carol . GetOnion ( ) )
2021-12-17 00:07:08 +00:00
log . Infoln ( "Carol created:" , carol . GetOnion ( ) )
2023-04-03 19:44:28 +00:00
// carol.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Carol") <- This is now done automatically by ProfileValueExtension, keeping this here for clarity
2020-04-17 00:00:17 +00:00
carol . AutoHandleEvents ( [ ] event . Type { event . PeerStateChange , event . ServerStateChange , event . NewGroupInvite , event . NewRetValMessageFromPeer } )
2018-06-05 22:06:38 +00:00
2020-06-16 00:16:04 +00:00
waitTime := time . Duration ( 60 ) * time . Second
2022-12-03 00:23:11 +00:00
log . Infof ( "** Waiting for Alice, Bob, and Carol to register their onion hidden service on the network... (%v)\n" , waitTime )
2020-06-16 00:16:04 +00:00
time . Sleep ( waitTime )
2018-05-30 18:42:17 +00:00
numGoRoutinesPostPeerStart := runtime . NumGoroutine ( )
2021-12-17 00:07:08 +00:00
log . Infof ( "** Wait Done!" )
2018-05-28 18:36:04 +00:00
2018-06-05 22:06:38 +00:00
// ***** Peering, server joining, group creation / invite *****
2018-05-28 18:36:04 +00:00
2022-07-30 00:24:22 +00:00
log . Infoln ( "Alice and Bob creating conversations..." )
2021-11-16 23:06:30 +00:00
// Simulate Alice Adding Bob
2022-07-30 00:24:22 +00:00
log . Infof ( " alice.NewConvo(bob)..." )
2021-11-16 23:06:30 +00:00
alice2bobConversationID , err := alice . NewContactConversation ( bob . GetOnion ( ) , model . DefaultP2PAccessControl ( ) , true )
if err != nil {
t . Fatalf ( "error adding conversaiton %v" , alice2bobConversationID )
}
2022-07-30 00:24:22 +00:00
log . Infof ( " bob.NewConvo(alice)..." )
2021-11-17 22:34:13 +00:00
bob2aliceConversationID , err := bob . NewContactConversation ( alice . GetOnion ( ) , model . DefaultP2PAccessControl ( ) , true )
if err != nil {
t . Fatalf ( "error adding conversaiton %v" , bob2aliceConversationID )
}
2020-02-03 18:46:15 +00:00
2022-07-30 00:24:22 +00:00
log . Infof ( "Alice and Carol creating conversations..." )
2021-11-16 23:06:30 +00:00
// Simulate Alice Adding Carol
alice2carolConversationID , err := alice . NewContactConversation ( carol . GetOnion ( ) , model . DefaultP2PAccessControl ( ) , true )
if err != nil {
t . Fatalf ( "error adding conversaiton %v" , alice2carolConversationID )
}
carol2aliceConversationID , err := carol . NewContactConversation ( alice . GetOnion ( ) , model . DefaultP2PAccessControl ( ) , true )
if err != nil {
t . Fatalf ( "error adding conversaiton %v" , carol2aliceConversationID )
}
2020-03-07 07:41:00 +00:00
2022-07-30 00:24:22 +00:00
log . Infof ( "Alice peering with Bob..." )
2021-11-17 22:34:13 +00:00
alice . PeerWithOnion ( bob . GetOnion ( ) )
2022-07-30 00:24:22 +00:00
log . Infof ( "Alice Peering with Carol..." )
2021-11-17 22:34:13 +00:00
alice . PeerWithOnion ( carol . GetOnion ( ) )
2020-03-07 07:41:00 +00:00
2021-12-17 21:58:54 +00:00
// Test that we can rekey alice without issues...
err = alice . ChangePassword ( "asdfasdf" , "password 1 2 3" , "password 1 2 3" )
if err != nil {
t . Fatalf ( "error changing password for Alice: %v" , err )
}
if ! alice . CheckPassword ( "password 1 2 3" ) {
t . Fatalf ( "Alice password did not change..." )
}
2021-11-17 22:34:13 +00:00
waitForConnection ( t , alice , bob . GetOnion ( ) , connections . AUTHENTICATED )
waitForConnection ( t , alice , carol . GetOnion ( ) , connections . AUTHENTICATED )
waitForConnection ( t , bob , alice . GetOnion ( ) , connections . AUTHENTICATED )
waitForConnection ( t , carol , alice . GetOnion ( ) , connections . AUTHENTICATED )
2020-03-07 07:41:00 +00:00
2021-12-17 00:07:08 +00:00
log . Infof ( "Alice and Bob getVal public.name..." )
2021-11-17 22:34:13 +00:00
alice . SendScopedZonedGetValToContact ( alice2bobConversationID , attr . PublicScope , attr . ProfileZone , constants . Name )
bob . SendScopedZonedGetValToContact ( bob2aliceConversationID , attr . PublicScope , attr . ProfileZone , constants . Name )
alice . SendScopedZonedGetValToContact ( alice2carolConversationID , attr . PublicScope , attr . ProfileZone , constants . Name )
carol . SendScopedZonedGetValToContact ( carol2aliceConversationID , attr . PublicScope , attr . ProfileZone , constants . Name )
2020-03-07 07:41:00 +00:00
2021-10-30 00:44:16 +00:00
// This used to be 10, but increasing it to 30 because this is now causing frequent issues
// Probably related to latency/throughput problems in the underlying tor network.
time . Sleep ( 30 * time . Second )
2020-03-07 07:41:00 +00:00
2022-12-05 06:48:14 +00:00
waitForRetVal ( bob , bob2aliceConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-16 23:06:30 +00:00
aliceName , err := bob . GetConversationAttribute ( bob2aliceConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-09 23:47:33 +00:00
if err != nil || aliceName != "Alice" {
t . Fatalf ( "Bob: alice GetKeyVal error on alice peer.name %v: %v\n" , aliceName , err )
2020-03-07 07:41:00 +00:00
}
2021-12-17 00:07:08 +00:00
log . Infof ( "Bob has alice's name as '%v'\n" , aliceName )
2020-03-07 07:41:00 +00:00
2022-12-05 06:48:14 +00:00
waitForRetVal ( alice , alice2bobConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-16 23:06:30 +00:00
bobName , err := alice . GetConversationAttribute ( alice2bobConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-09 23:47:33 +00:00
if err != nil || bobName != "Bob" {
t . Fatalf ( "Alice: bob GetKeyVal error on bob peer.name %v: %v \n" , bobName , err )
2020-03-07 07:41:00 +00:00
}
2021-12-17 00:07:08 +00:00
log . Infof ( "Alice has bob's name as '%v'\n" , bobName )
2020-03-07 07:41:00 +00:00
2022-12-05 06:48:14 +00:00
waitForRetVal ( carol , carol2aliceConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-16 23:06:30 +00:00
aliceName , err = carol . GetConversationAttribute ( carol2aliceConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-09 23:47:33 +00:00
if err != nil || aliceName != "Alice" {
t . Fatalf ( "carol GetKeyVal error for alice peer.name %v: %v\n" , aliceName , err )
2020-03-07 07:41:00 +00:00
}
2022-12-05 06:48:14 +00:00
waitForRetVal ( alice , alice2carolConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-16 23:06:30 +00:00
carolName , err := alice . GetConversationAttribute ( alice2carolConversationID , attr . PublicScope . ConstructScopedZonedPath ( attr . ProfileZone . ConstructZonedPath ( constants . Name ) ) )
2021-11-09 23:47:33 +00:00
if err != nil || carolName != "Carol" {
t . Fatalf ( "alice GetKeyVal error, carol peer.name: %v: %v\n" , carolName , err )
2020-03-07 07:41:00 +00:00
}
2021-12-17 00:07:08 +00:00
log . Infof ( "Alice has carol's name as '%v'\n" , carolName )
2018-11-10 22:14:12 +00:00
2021-11-17 22:34:13 +00:00
// Group Testing
2022-10-11 17:58:10 +00:00
usedTokens := len ( aliceLines )
2021-11-17 22:34:13 +00:00
// Simulate Alice Creating a Group
2021-12-17 00:07:08 +00:00
log . Infoln ( "Alice joining server..." )
2022-10-11 17:58:10 +00:00
if serverOnion , err := alice . AddServer ( string ( serverKeyBundle ) ) ; err != nil {
if len ( cachedTokens ) > len ( aliceLines ) {
2022-11-30 15:58:37 +00:00
alice . StoreCachedTokens ( serverOnion , cachedTokens [ 0 : len ( aliceLines ) ] )
2022-10-11 17:58:10 +00:00
}
2021-11-17 22:34:13 +00:00
t . Fatalf ( "Failed to Add Server Bundle %v" , err )
}
// Creating a Group
2021-12-17 00:07:08 +00:00
log . Infof ( "Creating group on %v..." , ServerAddr )
2021-11-17 22:34:13 +00:00
aliceGroupConversationID , err := alice . StartGroup ( "Our Cool Testing Group" , ServerAddr )
2021-12-17 00:07:08 +00:00
log . Infof ( "Created group: %v!\n" , aliceGroupConversationID )
2021-11-17 22:34:13 +00:00
if err != nil {
t . Errorf ( "Failed to init group: %v" , err )
return
}
// Invites
2021-12-17 00:07:08 +00:00
log . Infoln ( "Alice inviting Bob to group..." )
2022-03-23 21:08:30 +00:00
_ , err = alice . SendInviteToConversation ( alice2bobConversationID , aliceGroupConversationID )
2018-05-28 18:36:04 +00:00
if err != nil {
t . Fatalf ( "Error for Alice inviting Bob to group: %v" , err )
}
2020-02-03 18:46:15 +00:00
time . Sleep ( time . Second * 5 )
2018-04-27 19:20:33 +00:00
2021-11-16 23:06:30 +00:00
// Alice invites Bob to the Group...
2021-11-19 22:04:43 +00:00
message , _ , err := bob . GetChannelMessage ( bob2aliceConversationID , 0 , 1 )
2021-12-17 00:07:08 +00:00
log . Infof ( "Alice message to Bob %v %v" , message , err )
2021-11-16 23:06:30 +00:00
var overlayMessage model . MessageWrapper
json . Unmarshal ( [ ] byte ( message ) , & overlayMessage )
2021-12-17 00:07:08 +00:00
log . Infof ( "Parsed Overlay Message: %v" , overlayMessage )
2021-11-16 23:06:30 +00:00
err = bob . ImportBundle ( overlayMessage . Data )
2021-12-17 00:07:08 +00:00
log . Infof ( "Result of Bob Importing the Bundle from Alice: %v" , err )
2022-10-11 17:58:10 +00:00
if len ( cachedTokens ) > ( usedTokens + len ( bobLines ) ) {
2022-11-30 15:58:37 +00:00
bob . StoreCachedTokens ( ServerAddr , cachedTokens [ usedTokens : usedTokens + len ( bobLines ) ] )
2022-10-11 17:58:10 +00:00
usedTokens += len ( bobLines )
}
2021-11-16 23:06:30 +00:00
2022-12-04 19:06:50 +00:00
log . Infof ( "Waiting for alice to join server..." )
waitForConnection ( t , alice , ServerAddr , connections . SYNCED )
2021-12-17 00:07:08 +00:00
log . Infof ( "Waiting for Bob to join connect to group server..." )
2021-11-17 22:34:13 +00:00
waitForConnection ( t , bob , ServerAddr , connections . SYNCED )
2020-02-10 22:09:24 +00:00
2022-04-20 20:10:07 +00:00
// 1 = Alice
// 2 = Server
// 3 = Group...
bobGroupConversationID := 3
2018-06-05 22:06:38 +00:00
numGoRoutinesPostServerConnect := runtime . NumGoroutine ( )
2018-05-30 18:42:17 +00:00
2018-05-28 18:36:04 +00:00
// ***** Conversation *****
2021-12-17 00:07:08 +00:00
log . Infof ( "Starting conversation in group..." )
2022-12-05 06:11:32 +00:00
checkSendMessageToGroup ( t , alice , aliceBus , aliceGroupConversationID , aliceLines [ 0 ] )
checkSendMessageToGroup ( t , bob , bobBus , bobGroupConversationID , bobLines [ 0 ] )
checkSendMessageToGroup ( t , alice , aliceBus , aliceGroupConversationID , aliceLines [ 1 ] )
checkSendMessageToGroup ( t , bob , bobBus , bobGroupConversationID , bobLines [ 1 ] )
2021-11-16 23:06:30 +00:00
2022-10-11 17:58:10 +00:00
// Pretend that Carol Acquires the Overlay Message through some other means...
2021-11-19 22:04:43 +00:00
json . Unmarshal ( [ ] byte ( message ) , & overlayMessage )
2021-12-17 00:07:08 +00:00
log . Infof ( "Parsed Overlay Message: %v" , overlayMessage )
2021-11-19 22:04:43 +00:00
err = carol . ImportBundle ( overlayMessage . Data )
2021-12-17 00:07:08 +00:00
log . Infof ( "Result of Carol Importing the Bundle from Alice: %v" , err )
log . Infof ( "Waiting for Carol to join connect to group server..." )
2021-11-19 22:04:43 +00:00
carolGroupConversationID := 3
2022-10-11 17:58:10 +00:00
if len ( cachedTokens ) > ( usedTokens + len ( carolLines ) ) {
2022-11-30 15:58:37 +00:00
carol . StoreCachedTokens ( ServerAddr , cachedTokens [ usedTokens : usedTokens + len ( carolLines ) ] )
2022-10-11 17:58:10 +00:00
}
2021-11-19 22:04:43 +00:00
waitForConnection ( t , carol , ServerAddr , connections . SYNCED )
2021-11-16 23:06:30 +00:00
numGoRoutinesPostCarolConnect := runtime . NumGoroutine ( )
2021-11-19 22:04:43 +00:00
// Check Alice Timeline
2022-04-20 20:10:07 +00:00
log . Infof ( "Checking Alice's Timeline..." )
2021-11-16 23:06:30 +00:00
checkMessage ( t , alice , aliceGroupConversationID , 1 , aliceLines [ 0 ] )
checkMessage ( t , alice , aliceGroupConversationID , 2 , bobLines [ 0 ] )
checkMessage ( t , alice , aliceGroupConversationID , 3 , aliceLines [ 1 ] )
checkMessage ( t , alice , aliceGroupConversationID , 4 , bobLines [ 1 ] )
2018-06-05 22:06:38 +00:00
2021-12-17 00:07:08 +00:00
log . Infof ( "Shutting down Alice..." )
2021-11-19 22:04:43 +00:00
app . ShutdownPeer ( alice . GetOnion ( ) )
time . Sleep ( time . Second * 3 )
numGoRoutinesPostAlice := runtime . NumGoroutine ( )
2022-12-05 06:11:32 +00:00
checkSendMessageToGroup ( t , carol , carolBus , carolGroupConversationID , carolLines [ 0 ] )
checkSendMessageToGroup ( t , bob , bobBus , bobGroupConversationID , bobLines [ 2 ] )
2022-04-20 20:10:07 +00:00
// Time to Sync
time . Sleep ( time . Second * 10 )
2018-04-27 19:20:33 +00:00
2021-11-19 22:04:43 +00:00
// Check Bob Timeline
2022-04-20 20:10:07 +00:00
log . Infof ( "Checking Bob's Timeline..." )
2021-11-16 23:06:30 +00:00
checkMessage ( t , bob , bobGroupConversationID , 1 , aliceLines [ 0 ] )
checkMessage ( t , bob , bobGroupConversationID , 2 , bobLines [ 0 ] )
checkMessage ( t , bob , bobGroupConversationID , 3 , aliceLines [ 1 ] )
checkMessage ( t , bob , bobGroupConversationID , 4 , bobLines [ 1 ] )
2021-11-19 22:04:43 +00:00
checkMessage ( t , bob , bobGroupConversationID , 5 , carolLines [ 0 ] )
checkMessage ( t , bob , bobGroupConversationID , 6 , bobLines [ 2 ] )
// Check Carol Timeline
2022-04-20 20:10:07 +00:00
log . Infof ( "Checking Carols's Timeline..." )
2021-11-19 22:04:43 +00:00
checkMessage ( t , carol , carolGroupConversationID , 1 , aliceLines [ 0 ] )
checkMessage ( t , carol , carolGroupConversationID , 2 , bobLines [ 0 ] )
checkMessage ( t , carol , carolGroupConversationID , 3 , aliceLines [ 1 ] )
checkMessage ( t , carol , carolGroupConversationID , 4 , bobLines [ 1 ] )
checkMessage ( t , carol , carolGroupConversationID , 5 , carolLines [ 0 ] )
checkMessage ( t , carol , carolGroupConversationID , 6 , bobLines [ 2 ] )
2021-12-17 00:07:08 +00:00
log . Infof ( "Shutting down Bob..." )
2020-02-03 18:46:15 +00:00
app . ShutdownPeer ( bob . GetOnion ( ) )
2018-05-30 18:42:17 +00:00
time . Sleep ( time . Second * 3 )
numGoRoutinesPostBob := runtime . NumGoroutine ( )
2018-06-05 22:06:38 +00:00
2021-12-17 00:07:08 +00:00
log . Infof ( "Shutting down Carol..." )
2021-11-03 18:38:42 +00:00
app . ShutdownPeer ( carol . GetOnion ( ) )
2018-05-30 18:42:17 +00:00
time . Sleep ( time . Second * 3 )
2018-06-05 22:06:38 +00:00
numGoRoutinesPostCarol := runtime . NumGoroutine ( )
2018-05-30 18:42:17 +00:00
2021-12-17 00:07:08 +00:00
log . Infof ( "Shutting down apps..." )
log . Infof ( "app Shutdown: %v\n" , runtime . NumGoroutine ( ) )
2019-06-05 20:40:55 +00:00
app . Shutdown ( )
2019-07-19 17:27:50 +00:00
time . Sleep ( 2 * time . Second )
2021-12-17 00:07:08 +00:00
log . Infof ( "Done shutdown: %v\n" , runtime . NumGoroutine ( ) )
2019-06-05 20:40:55 +00:00
2021-12-17 00:07:08 +00:00
log . Infof ( "Shutting down ACN..." )
2022-01-12 20:47:04 +00:00
acn . Close ( )
2023-04-03 21:33:25 +00:00
time . Sleep ( time . Second * 60 ) // the network status / heartbeat plugin might keep goroutines alive for a minute before killing them
2019-02-04 22:18:24 +00:00
2021-12-01 21:57:56 +00:00
numGoRoutinesPostAppShutdown := runtime . NumGoroutine ( )
2019-01-04 21:44:21 +00:00
// Printing out the current goroutines
// Very useful if we are leaking any.
pprof . Lookup ( "goroutine" ) . WriteTo ( os . Stdout , 1 )
2022-12-05 07:28:24 +00:00
fmt . Println ( "" )
2021-12-17 00:07:08 +00:00
log . Infof ( "numGoRoutinesStart: %v\nnumGoRoutinesPostAppStart: %v\nnumGoRoutinesPostPeerStart: %v\nnumGoRoutinesPostPeerAndServerConnect: %v\n" +
2023-03-06 21:06:15 +00:00
"numGoRoutinesPostAlice: %v\nnumGoRoutinesPostCarolConnect: %v\nnumGoRoutinesPostBob: %v\nnumGoRoutinesPostCarol: %v\nnumGoRoutinesPostAppShutdown: %v" ,
2021-06-29 23:12:58 +00:00
numGoRoutinesStart , numGoRoutinesPostAppStart , numGoRoutinesPostPeerStart , numGoRoutinesPostServerConnect ,
2021-11-19 22:04:43 +00:00
numGoRoutinesPostAlice , numGoRoutinesPostCarolConnect , numGoRoutinesPostBob , numGoRoutinesPostCarol , numGoRoutinesPostAppShutdown )
2018-05-30 18:42:17 +00:00
2021-11-19 22:04:43 +00:00
if numGoRoutinesStart != numGoRoutinesPostAppShutdown {
t . Errorf ( "Number of GoRoutines at start (%v) does not match number of goRoutines after cleanup of peers and servers (%v), clean up failed, v detected!" , numGoRoutinesStart , numGoRoutinesPostAppShutdown )
2018-05-30 18:42:17 +00:00
}
2021-11-16 23:06:30 +00:00
}
2021-11-19 22:04:43 +00:00
// Utility function for sending a message from a peer to a group
2022-12-05 06:11:32 +00:00
func checkSendMessageToGroup ( t * testing . T , profile peer . CwtchPeer , bus event . Manager , id int , message string ) {
2021-11-16 23:06:30 +00:00
name , _ := profile . GetScopedZonedAttribute ( attr . PublicScope , attr . ProfileZone , constants . Name )
2021-12-17 00:07:08 +00:00
log . Infof ( "%v> %v\n" , name , message )
2022-12-05 06:11:32 +00:00
queue := event . NewQueue ( )
bus . Subscribe ( event . IndexedAcknowledgement , queue )
mid , err := profile . SendMessage ( id , message )
2021-11-16 23:06:30 +00:00
if err != nil {
2022-08-04 06:06:58 +00:00
log . Errorf ( "Alice failed to send a message to the group: %v" , err )
t . Fatalf ( "Alice failed to send a message to the group: %v\n" , err )
2021-11-16 23:06:30 +00:00
}
2022-12-05 06:11:32 +00:00
log . Infof ( "Sent message with mid: %v, waiting for ack..." , mid )
ev := queue . Next ( )
switch ev . EventType {
case event . IndexedAcknowledgement :
if evid , err := strconv . Atoi ( ev . Data [ event . Index ] ) ; err == nil && evid == mid {
log . Infof ( "Message mid acked!" )
break
}
}
queue . Shutdown ( )
2021-11-16 23:06:30 +00:00
time . Sleep ( time . Second * 10 )
}
2021-11-19 22:04:43 +00:00
// Utility function for testing that a message in a conversation is as expected
2021-11-16 23:06:30 +00:00
func checkMessage ( t * testing . T , profile peer . CwtchPeer , id int , messageID int , expected string ) {
message , _ , err := profile . GetChannelMessage ( id , 0 , messageID )
2022-12-03 00:23:11 +00:00
log . Debugf ( " checking if expected: %v is actual: %v" , expected , message )
2021-11-16 23:06:30 +00:00
if err != nil {
2022-08-04 06:06:58 +00:00
log . Errorf ( "unexpected message %v expected: %v got error: %v" , profile . GetOnion ( ) , expected , err )
t . Fatalf ( "unexpected message %v expected: %v got error: %v\n" , profile . GetOnion ( ) , expected , err )
2021-11-16 23:06:30 +00:00
}
if message != expected {
2022-08-04 06:06:58 +00:00
log . Errorf ( "unexpected message %v expected: %v got: [%v]" , profile . GetOnion ( ) , expected , message )
t . Fatalf ( "unexpected message %v expected: %v got: [%v]\n" , profile . GetOnion ( ) , expected , message )
2021-11-16 23:06:30 +00:00
}
2018-03-30 21:16:51 +00:00
}