Skip to content

Commit

Permalink
improve test stability
Browse files Browse the repository at this point in the history
  • Loading branch information
qfrank committed Apr 9, 2024
1 parent 3672759 commit a238ba3
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 109 deletions.
250 changes: 141 additions & 109 deletions api/messenger_raw_message_resend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import (
"path/filepath"
"testing"

"go.uber.org/zap"

"github.com/status-im/status-go/eth-node/types"
m_common "github.com/status-im/status-go/multiaccounts/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/common/shard"
"github.com/status-im/status-go/protocol/communities"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/protocol/tt"
"github.com/status-im/status-go/services/utils"
"github.com/status-im/status-go/wakuv2"

"github.com/stretchr/testify/suite"
)
Expand All @@ -25,12 +30,148 @@ type MessengerRawMessageResendTest struct {
bobBackend *GethStatusBackend
aliceMessenger *protocol.Messenger
bobMessenger *protocol.Messenger
// add exchangeBootNode to ensure alice and bob can find each other.
// If relying in the fleet, the test will likely be flaky
exchangeBootNode *wakuv2.Waku
}

func TestMessengerRawMessageResendTestSuite(t *testing.T) {
suite.Run(t, new(MessengerRawMessageResendTest))
}

func (s *MessengerRawMessageResendTest) SetupTest() {
logger, err := zap.NewDevelopment()
s.Require().NoError(err)

exchangeNodeConfig := &wakuv2.Config{
Port: 0,
EnableDiscV5: true,
EnablePeerExchangeServer: true,
ClusterID: 16,
UseShardAsDefaultTopic: true,
DefaultShardPubsubTopic: shard.DefaultShardPubsubTopic(),
}
s.exchangeBootNode, err = wakuv2.New("", "", exchangeNodeConfig, logger.Named("pxServerNode"), nil, nil, nil, nil)
s.Require().NoError(err)
s.Require().NoError(s.exchangeBootNode.Start())

s.createAliceBobBackendAndLogin()
community := s.createTestCommunity(s.aliceMessenger, protobuf.CommunityPermissions_MANUAL_ACCEPT)
s.addMutualContact()
advertiseCommunityToUserOldWay(&s.Suite, community, s.aliceMessenger, s.bobMessenger)
requestBob := &requests.RequestToJoinCommunity{
CommunityID: community.ID(),
}
joinOnRequestCommunity(&s.Suite, community, s.aliceMessenger, s.bobMessenger, requestBob)
}

func (s *MessengerRawMessageResendTest) TearDownTest() {
s.Require().NoError(s.aliceBackend.Logout())
s.Require().NoError(s.bobBackend.Logout())
s.Require().NoError(s.exchangeBootNode.Stop())
}

func (s *MessengerRawMessageResendTest) createAliceBobBackendAndLogin() {
s.aliceBackend = NewGethStatusBackend()
s.bobBackend = NewGethStatusBackend()

aliceRootDir := filepath.Join(s.T().TempDir())
s.T().Logf("aliceRootDir: %s", aliceRootDir)
bobRootDir := filepath.Join(s.T().TempDir())
s.T().Logf("bobRootDir: %s", bobRootDir)

aliceCreateAccountRequest := s.setCreateAccountRequest("alice", aliceRootDir, filepath.Join(aliceRootDir, "alice.log"))
bobCreateAccountRequest := s.setCreateAccountRequest("bob66", bobRootDir, filepath.Join(bobRootDir, "bob.log"))

pxServerNodeENR, err := s.exchangeBootNode.GetNodeENRString()
s.Require().NoError(err)

_, err = s.aliceBackend.CreateAccountAndLogin(aliceCreateAccountRequest,
params.WithDiscV5BootstrapNodes([]string{pxServerNodeENR}),
// override fleet nodes
params.WithWakuNodes([]string{}))
s.Require().NoError(err)
s.aliceMessenger = s.aliceBackend.Messenger()
s.Require().NotNil(s.aliceMessenger)
_, err = s.aliceMessenger.Start()
s.Require().NoError(err)

_, err = s.bobBackend.CreateAccountAndLogin(bobCreateAccountRequest,
params.WithDiscV5BootstrapNodes([]string{pxServerNodeENR}),
// override fleet nodes
params.WithWakuNodes([]string{}))
s.Require().NoError(err)
s.bobMessenger = s.bobBackend.Messenger()
s.Require().NotNil(s.bobMessenger)
_, err = s.bobMessenger.Start()
s.Require().NoError(err)
}

func (s *MessengerRawMessageResendTest) setCreateAccountRequest(displayName, backupDisabledDataDir, logFilePath string) *requests.CreateAccount {
nameServer := "1.1.1.1"
verifyENSContractAddress := "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
verifyTransactionChainID := int64(1)
verifyURL := "https://eth-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"
logLevel := "DEBUG"
networkID := uint64(1)
password := "qwerty"
return &requests.CreateAccount{
UpstreamConfig: verifyURL,
WakuV2Nameserver: &nameServer,
VerifyENSContractAddress: &verifyENSContractAddress,
BackupDisabledDataDir: backupDisabledDataDir,
Password: password,
DisplayName: displayName,
LogEnabled: true,
VerifyTransactionChainID: &verifyTransactionChainID,
VerifyTransactionURL: &verifyURL,
VerifyENSURL: &verifyURL,
LogLevel: &logLevel,
LogFilePath: logFilePath,
NetworkID: &networkID,
CustomizationColor: string(m_common.CustomizationColorPrimary),
}
}

// TestMessageSent tests if ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN is in state `sent` without resending
func (s *MessengerRawMessageResendTest) TestMessageSent() {
ids, err := s.bobMessenger.RawMessagesIDsByType(protobuf.ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN)
s.Require().NoError(err)
s.Require().Len(ids, 1)
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
s.Require().True(rawMessage.Sent)
}

// TestMessageResend tests if ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN is resent
func (s *MessengerRawMessageResendTest) TestMessageResend() {
ids, err := s.bobMessenger.RawMessagesIDsByType(protobuf.ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN)
s.Require().NoError(err)
s.Require().Len(ids, 1)
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
s.Require().NoError(s.bobMessenger.UpdateRawMessageSent(rawMessage.ID, false, 0))
err = tt.RetryWithBackOff(func() error {
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
if !rawMessage.Sent {
return errors.New("message ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN was not resent yet")
}
return nil
})
s.Require().NoError(err)

waitOnMessengerResponse(&s.Suite, func(r *protocol.MessengerResponse) error {
if len(r.RequestsToJoinCommunity()) > 0 {
return nil
}
return errors.New("community request to join not received")
}, s.aliceMessenger)
}

// To be removed in https://github.com/status-im/status-go/issues/4437
func advertiseCommunityToUserOldWay(s *suite.Suite, community *communities.Community, alice *protocol.Messenger, bob *protocol.Messenger) {
chat := protocol.CreateOneToOneChat(bob.IdentityPublicKeyString(), bob.IdentityPublicKey(), bob.GetTransport())
Expand Down Expand Up @@ -94,17 +235,6 @@ func (s *MessengerRawMessageResendTest) addMutualContact() {
}, s.aliceMessenger)
}

func (s *MessengerRawMessageResendTest) SetupTest() {
s.createAliceBobBackendAndLogin()
community := s.createTestCommunity(s.aliceMessenger, protobuf.CommunityPermissions_MANUAL_ACCEPT)
s.addMutualContact()
advertiseCommunityToUserOldWay(&s.Suite, community, s.aliceMessenger, s.bobMessenger)
requestBob := &requests.RequestToJoinCommunity{
CommunityID: community.ID(),
}
joinOnRequestCommunity(&s.Suite, community, s.aliceMessenger, s.bobMessenger, requestBob)
}

type MessageResponseValidator func(*protocol.MessengerResponse) error

func waitOnMessengerResponse(s *suite.Suite, fnWait MessageResponseValidator, user *protocol.Messenger) {
Expand Down Expand Up @@ -190,39 +320,6 @@ func joinOnRequestCommunity(s *suite.Suite, community *communities.Community, co
s.Require().NoError(err)
}

func (s *MessengerRawMessageResendTest) TearDownTest() {
s.Require().NoError(s.aliceBackend.Logout())
s.Require().NoError(s.bobBackend.Logout())

}

func (s *MessengerRawMessageResendTest) createAliceBobBackendAndLogin() {
s.aliceBackend = NewGethStatusBackend()
s.bobBackend = NewGethStatusBackend()

aliceRootDir := filepath.Join(s.T().TempDir())
s.T().Logf("aliceRootDir: %s", aliceRootDir)
bobRootDir := filepath.Join(s.T().TempDir())
s.T().Logf("bobRootDir: %s", bobRootDir)

aliceCreateAccountRequest := s.setCreateAccountRequest("alice", aliceRootDir, filepath.Join(aliceRootDir, "alice.log"))
bobCreateAccountRequest := s.setCreateAccountRequest("bob66", bobRootDir, filepath.Join(bobRootDir, "bob.log"))

_, err := s.aliceBackend.CreateAccountAndLogin(aliceCreateAccountRequest)
s.Require().NoError(err)
_, err = s.bobBackend.CreateAccountAndLogin(bobCreateAccountRequest)
s.Require().NoError(err)

s.aliceMessenger = s.aliceBackend.Messenger()
s.Require().NotNil(s.aliceMessenger)
s.bobMessenger = s.bobBackend.Messenger()
s.Require().NotNil(s.bobMessenger)
_, err = s.aliceMessenger.Start()
s.Require().NoError(err)
_, err = s.bobMessenger.Start()
s.Require().NoError(err)
}

func (s *MessengerRawMessageResendTest) createTestCommunity(controlNode *protocol.Messenger, membershipType protobuf.CommunityPermissions_Access) *communities.Community {
description := &requests.CreateCommunity{
Membership: membershipType,
Expand All @@ -238,68 +335,3 @@ func (s *MessengerRawMessageResendTest) createTestCommunity(controlNode *protoco
s.Require().Len(response.Chats(), 1)
return response.Communities()[0]
}

func (s *MessengerRawMessageResendTest) setCreateAccountRequest(displayName, backupDisabledDataDir, logFilePath string) *requests.CreateAccount {
nameServer := "1.1.1.1"
verifyENSContractAddress := "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
verifyTransactionChainID := int64(1)
verifyURL := "https://eth-archival.rpc.grove.city/v1/3ef2018191814b7e1009b8d9"
logLevel := "DEBUG"
networkID := uint64(1)
password := "qwerty"
return &requests.CreateAccount{
UpstreamConfig: verifyURL,
WakuV2Nameserver: &nameServer,
VerifyENSContractAddress: &verifyENSContractAddress,
BackupDisabledDataDir: backupDisabledDataDir,
Password: password,
DisplayName: displayName,
LogEnabled: true,
VerifyTransactionChainID: &verifyTransactionChainID,
VerifyTransactionURL: &verifyURL,
VerifyENSURL: &verifyURL,
LogLevel: &logLevel,
LogFilePath: logFilePath,
NetworkID: &networkID,
CustomizationColor: string(m_common.CustomizationColorPrimary),
}
}

// TestMessageSent tests if ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN is in state `sent` without resending
func (s *MessengerRawMessageResendTest) TestMessageSent() {
ids, err := s.bobMessenger.RawMessagesIDsByType(protobuf.ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN)
s.Require().NoError(err)
s.Require().Len(ids, 1)
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
s.Require().True(rawMessage.Sent)
}

// TestMessageResend tests if ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN is resent
func (s *MessengerRawMessageResendTest) TestMessageResend() {
ids, err := s.bobMessenger.RawMessagesIDsByType(protobuf.ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN)
s.Require().NoError(err)
s.Require().Len(ids, 1)
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
s.Require().NoError(s.bobMessenger.UpdateRawMessageSent(rawMessage.ID, false, 0))
err = tt.RetryWithBackOff(func() error {
rawMessage, err := s.bobMessenger.RawMessageByID(ids[0])
s.Require().NoError(err)
s.Require().NotNil(rawMessage)
if !rawMessage.Sent {
return errors.New("message ApplicationMetadataMessage_COMMUNITY_REQUEST_TO_JOIN was not resent yet")
}
return nil
})
s.Require().NoError(err)

waitOnMessengerResponse(&s.Suite, func(r *protocol.MessengerResponse) error {
if len(r.RequestsToJoinCommunity()) > 0 {
return nil
}
return errors.New("community request to join not received")
}, s.aliceMessenger)
}
14 changes: 14 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,20 @@ func WithMailserver() Option {
}
}

func WithDiscV5BootstrapNodes(nodes []string) Option {
return func(c *NodeConfig) error {
c.ClusterConfig.DiscV5BootstrapNodes = nodes
return nil
}
}

func WithWakuNodes(nodes []string) Option {
return func(c *NodeConfig) error {
c.ClusterConfig.WakuNodes = nodes
return nil
}
}

// NewNodeConfigWithDefaults creates new node configuration object
// with some defaults suitable for adhoc use.
func NewNodeConfigWithDefaults(dataDir string, networkID uint64, opts ...Option) (*NodeConfig, error) {
Expand Down
7 changes: 7 additions & 0 deletions wakuv2/waku.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ func (w *Waku) SubscribeToConnStatusChanges() *types.ConnStatusSubscription {
return subscription
}

func (w *Waku) GetNodeENRString() (string, error) {
if w.node == nil {
return "", errors.New("node not initialized")
}
return w.node.ENR().String(), nil
}

func (w *Waku) getDiscV5BootstrapNodes(ctx context.Context, addresses []string) ([]*enode.Node, error) {
wg := sync.WaitGroup{}
mu := sync.Mutex{}
Expand Down

0 comments on commit a238ba3

Please sign in to comment.