Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qa wrappers #19

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Qa wrappers #19

wants to merge 10 commits into from

Conversation

AYAHASSAN287
Copy link
Collaborator

@AYAHASSAN287 AYAHASSAN287 commented Jan 21, 2025

Pull Request Description

This pull request introduces the testlibs framework for Go-Waku Bindings, which provides wrappers, utilities, and test files to simplify the development and testing process of Waku Node functionalities. The testlibs framework focuses on enhancing developer productivity and streamlining common tasks through the use of high-level wrapper APIs.

Advantages of the Wrappers APIs

The wrapper APIs provide several key advantages over directly using internal APIs:

  1. Simplified Inputs:

    • Wrapper APIs abstract away low-level details, making them easier to use. For example:
      • Wrappers_ConnectPeer takes a WakuNode instance as input rather than requiring a peerID, internally constructing the peerID from the provided node.
      • This reduces boilerplate code, such as manually fetching peerID or address details before connecting.
  2. Error Handling and Validation:

    • Wrappers include built-in validation to ensure inputs are valid before invoking internal APIs. For example:
      • Wrappers_GetConnectedPeers checks if the WakuNode is nil and returns an appropriate error message, preventing runtime crashes.
  3. Consistent Logging:

    • Each wrapper API includes debug-level logging to trace execution flow and identify issues. This is particularly helpful during test execution and debugging.
  4. Streamlined Node Lifecycle Management:

    • The wrappers combine multiple operations into intuitive methods, such as:
      • Wrappers_StopAndDestroy: Combines stopping and destroying a Waku node into a single operation.
    • This reduces the need to call multiple methods manually and minimizes cleanup errors.
  5. Enhanced Developer Experience:

    • The high-level wrappers are designed to match common use cases in testing, reducing the cognitive load on developers:
      • Relay protocol management is simplified through methods like Wrappers_RelaySubscribe and Wrappers_RelayUnsubscribe, which handle both subscription and verification.
  6. Dynamic Configuration:

    • Wrapper APIs allow seamless handling of dynamic configurations, such as generating unique ports (GenerateUniquePort) for nodes during testing.

Key Components

1. Wrappers

The wrapper files define abstractions around the WakuNode to streamline node management and interaction during testing. Key functionalities include:

  • Node Lifecycle Management:

    • Wrappers_StartWakuNode: Starts a Waku node with a custom or default configuration.
    • Wrappers_Stop: Stops the Waku node gracefully.
    • Wrappers_Destroy: Cleans up and destroys the Waku node.
    • Wrappers_StopAndDestroy: Combines stop and destroy operations for efficient cleanup.
  • Peer Management:

    • Wrappers_ConnectPeer: Simplifies connecting nodes by taking a WakuNode instance instead of a peerID, constructing the peerID and connection details internally.
    • Wrappers_DisconnectPeer: Disconnects a Waku node from a target peer with validation and error handling.
    • Wrappers_GetConnectedPeers: Retrieves a list of peers connected to the Waku node.
    • Wrappers_GetNumConnectedRelayPeers: Returns the number of relay peers connected for a specific pubsub topic.
  • Relay Subscription:

    • Wrappers_RelaySubscribe: Subscribes the Waku node to a given pubsub topic, ensuring subscription and verifying peer connections.
    • Wrappers_RelayUnsubscribe: Unsubscribes from a specific pubsub topic and validates the unsubscription process.

2. Utilities

The utilities package provides helper functions and constants to facilitate testing. Key highlights include:

  • Default Configuration:

    • DefaultWakuConfig: Provides a baseline Waku node configuration with sensible defaults for testing purposes.
  • Logging Support:

    • Centralized logging via zap for debugging during tests.
    • Debug-level messages are used extensively to trace the flow and identify issues.
  • Port Management:

    • GenerateUniquePort: Dynamically allocates unique ports for Waku nodes during tests to avoid conflicts.
  • Timeout and Error Handling:

    • Constants for peer connection timeouts.
    • Enhanced error messaging for debugging failures in Waku node operations.

3. Test Files

Relay Tests (relay_test.go)

  • Highlights:
    • Tests the behavior of the relay protocol.
    • Example: TestRelaySubscribeToDefaultTopic validates subscription to the default pubsub topic and ensures connected relay peers increase.

Peer Connection Tests (Peers_connection_test.go)

  • Highlights:
    • Simplifies peer connectivity testing using the wrappers.
    • Example: TestConnectMultipleNodesToSingleNode verifies multiple nodes can connect to a single node efficiently.

Basic Node Tests (Nodes_basic_test.go)

  • Highlights:
    • Validates fundamental node lifecycle management using wrapper APIs.
    • Example: TestBasicWakuNodes covers node creation, startup, and cleanup using Wrappers_StartWakuNode and Wrappers_StopAndDestroy.

@AYAHASSAN287 AYAHASSAN287 requested a review from fbarbu15 January 28, 2025 09:08

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what's the best practice in golang but I think filenames should be lowercase.
Anyhow we should have consistency

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -0,0 +1,23 @@
# Testlibs for Go-Waku Bindings

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you should add the Key Components section from PR description here as well, what do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. since the Key Components contain more details it's better to include it in the README file too

Done

return nil
}

func (wrapper *WakuNodeWrapper) Wrappers_StopAndDestroy() error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this function since we already have both Wrappers_Stop and Wrappers_Destroy ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes because we may need to stop the node and resume or start it again without destroying it

func (wrapper *WakuNodeWrapper) Wrappers_GetNumConnectedRelayPeers(optPubsubTopic ...string) (int, error) {
utilities.Debug("Wrappers_GetNumConnectedRelayPeers called")

if wrapper.WakuNode == nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you do the check quite a lot, could it be refactored into a common function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes for better readability
I will do that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

time.Sleep(2 * time.Second)
utilities.Debug("Stopping the first WakuNodeWrapper")

err = node1.Wrappers_StopAndDestroy()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, can we have this as a cleanup/teardown construct? so it gets executed even if the tests fails at an assertion

time.Sleep(3 * time.Second)

// Disconnect Node A from Node B
err = nodeA.Wrappers_DisconnectPeer(nodeB)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in those tests we are no stopping the nodes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at line 22
defer nodeA.Wrappers_StopAndDestroy()
it' sthe teardown way in GO language

utilities.Debug("Successfully created the first WakuNodeWrapper")

utilities.Debug("Starting the second WakuNodeWrapper")
node2, err := testlibs.Wrappers_StartWakuNode(&nodeCfg2, logger.Named("node2"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need 2 nodes here? because you don't connect them
I guess one node is enough

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. node2 removed

"go.uber.org/zap"
)

func TestRelaySubscribeToDefaultTopic(t *testing.T) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should also have a test that runs and connects 2 nodes, sends message from node1 and checks it was received on node2

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was going to do that but currently relay tests failing for internal issue so I'm waiting for the PR to be merged by Gabriel then I will add additional steps

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! The functionality to receive messages is broken in master but we have PRs in place that fix it. We should have them merged soon, and I will update Aya once we merge them :)

@AYAHASSAN287 AYAHASSAN287 requested a review from fbarbu15 January 28, 2025 13:11
Copy link

@fbarbu15 fbarbu15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! LGTM, thanks

Copy link
Collaborator

@gabrielmer gabrielmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wooow, amazing work! 🤩 Thanks so much!

Added just a few comments, let me know if something doesn't make sense!

nodeCfg.Discv5UdpPort = utilities.GenerateUniquePort()
nodeCfg.TcpPort = utilities.GenerateUniquePort()

utilities.Debug("Create node with default config")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this log is misleading? because if customCfg is passed, then it's not being created with the default config

utilities.Debug("Create node with default config")
node, err := waku.NewWakuNode(&nodeCfg, logger)
if err != nil {
utilities.Error("Can't create node")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add the error in the log? something like

utilities.Error("Can't create node", zap.Error(err))

}

// Stops the WakuNode.
func (node *WakuNodeWrapper) Wrappers_Stop() error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a method of WakuNodeWrapper, maybe we can name it Stop() instead of Wrappers_Stop()?

Same for all the methods of WakuNodeWrapper, the Wrappers prefix might be redundant

Comment on lines +25 to +28
numRelayPeers, err := wrapper.Wrappers_GetNumConnectedRelayPeers(pubsubTopic)
if err != nil || numRelayPeers == 0 {
utilities.Error("Subscription verification failed: no connected relay peers found", zap.Error(err))
return errors.New("subscription verification failed: no connected relay peers")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if verifying the number of peers in a pubsub topic is the way to verify that we correctly subscribed to it - we could be subscribed but without peers in the topic.

If we need a way to verify it, we could either add a function in waku-go-bindings that returns the subscribed topics, or we can probably deduce it from the ENR

"go.uber.org/zap"
)

func TestRelaySubscribeToDefaultTopic(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! The functionality to receive messages is broken in master but we have PRs in place that fix it. We should have them merged soon, and I will update Aya once we merge them :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants