Add stress test

This commit is contained in:
aya 2025-03-05 13:30:11 +02:00
parent a0a3e95203
commit c8e6f194e3
4 changed files with 1486 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/cenkalti/backoff/v3"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
"github.com/waku-org/waku-go-bindings/waku/common"
"google.golang.org/protobuf/proto"
@ -94,7 +95,7 @@ func (n *WakuNode) CreateMessage(customMessage ...*pb.WakuMessage) *pb.WakuMessa
Debug("Using default message format on node %s", n.nodeName)
defaultMessage := &pb.WakuMessage{
Payload: []byte("This is a default Waku message payload"),
ContentTopic: "test-content-topic",
ContentTopic: DefaultContentTopic,
Version: proto.Uint32(0),
Timestamp: proto.Int64(time.Now().UnixNano()),
}
@ -215,3 +216,42 @@ func SubscribeNodesToTopic(nodes []*WakuNode, topic string) error {
}
return nil
}
func (n *WakuNode) GetStoredMessages(storeNode *WakuNode, storeRequest *common.StoreQueryRequest) (*common.StoreQueryResponse, error) {
Debug("Starting store query request")
if storeRequest == nil {
Debug("Using DefaultStoreQueryRequest")
storeRequest = &DefaultStoreQueryRequest
}
storeMultiaddr, err := storeNode.ListenAddresses()
if err != nil {
Error("Failed to retrieve listen addresses for store node: %v", err)
return nil, err
}
if len(storeMultiaddr) == 0 {
Error("Store node has no available listen addresses")
return nil, fmt.Errorf("store node has no available listen addresses")
}
storeNodeAddrInfo, err := peer.AddrInfoFromString(storeMultiaddr[0].String())
if err != nil {
Error("Failed to convert store node address to AddrInfo: %v", err)
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
Debug("Querying store node for messages")
res, err := n.StoreQuery(ctx, storeRequest, *storeNodeAddrInfo)
if err != nil {
Error("StoreQuery failed: %v", err)
return nil, err
}
Debug("Store query successful, retrieved %d messages", len(*res.Messages))
return res, nil
}

1288
waku/store_test.go Normal file

File diff suppressed because it is too large Load Diff

74
waku/stress_test.go Normal file
View File

@ -0,0 +1,74 @@
package waku
import (
"fmt"
"runtime"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/waku-org/waku-go-bindings/waku/common"
"google.golang.org/protobuf/proto"
)
func TestStoreQuery5kMessagesWithPagination(t *testing.T) {
Debug("Starting test")
nodeConfig := DefaultWakuConfig
nodeConfig.Relay = true
nodeConfig.Store = true
Debug("Creating 2 nodes")
wakuNode, err := StartWakuNode("node1", &nodeConfig)
require.NoError(t, err, "Failed to start Waku node")
node2, err := StartWakuNode("node2", &nodeConfig)
require.NoError(t, err, "Failed to start Waku node")
node2.ConnectPeer(wakuNode)
defer func() {
Debug("Stopping and destroying Waku node")
wakuNode.StopAndDestroy()
node2.StopAndDestroy()
}()
var memStats runtime.MemStats
iterations := 50
runtime.ReadMemStats(&memStats)
initialHeapAlloc := memStats.HeapAlloc
Debug("Initial memory usage check before publishing %d MB", initialHeapAlloc/1024/1024)
queryTimestamp := proto.Int64(time.Now().UnixNano())
for i := 0; i < iterations; i++ {
message := wakuNode.CreateMessage()
message.Payload = []byte(fmt.Sprintf("Test endurance message payload %d", i))
_, err := wakuNode.RelayPublishNoCTX(DefaultPubsubTopic, message)
require.NoError(t, err, "Failed to publish message")
if i%10 == 0 {
runtime.ReadMemStats(&memStats)
Debug("Memory usage at iteration %d: HeapAlloc=%v MB, NumGC=%v",
i, memStats.HeapAlloc/1024/1024, memStats.NumGC)
storeQueryRequest := &common.StoreQueryRequest{
TimeStart: queryTimestamp,
IncludeData: true,
PaginationLimit: proto.Uint64(50),
}
storedmsgs, err := wakuNode.GetStoredMessages(node2, storeQueryRequest)
require.NoError(t, err, "Failed to query store messages")
require.Greater(t, len(*storedmsgs.Messages), 0, "Expected at least one stored message")
}
}
runtime.ReadMemStats(&memStats)
finalHeapAlloc := memStats.HeapAlloc
Debug("Memory before test: %v KB, Memory after test: %v KB", initialHeapAlloc/1024, finalHeapAlloc/1024)
require.LessOrEqual(t, finalHeapAlloc, initialHeapAlloc*2, "Memory usage has grown too much")
Debug("Test completed successfully")
}

View File

@ -1,12 +1,16 @@
package waku
import (
"fmt"
"time"
"github.com/waku-org/waku-go-bindings/waku/common"
"google.golang.org/protobuf/proto"
)
var DefaultWakuConfig common.WakuConfig
var DefaultStoreQueryRequest common.StoreQueryRequest
var DEFAULT_CLUSTER_ID = 16
func init() {
@ -23,13 +27,92 @@ func init() {
Discv5UdpPort: 0,
TcpPort: 0,
}
DefaultStoreQueryRequest = common.StoreQueryRequest{
IncludeData: true,
ContentTopics: &[]string{"test-content-topic"},
PaginationLimit: proto.Uint64(uint64(50)),
PaginationForward: true,
TimeStart: proto.Int64(time.Now().Add(-5 * time.Minute).UnixNano()), // 5 mins before now
}
}
const ConnectPeerTimeout = 10 * time.Second //default timeout for node to connect to another node
const DefaultTimeOut = 3 * time.Second
var DefaultPubsubTopic = "/waku/2/rs/16/64"
var DefaultContentTopic = "/test/1/default/proto"
var (
MinPort = 1024 // Minimum allowable port (exported)
MaxPort = 65535 // Maximum allowable port (exported)
)
var SAMPLE_INPUTS = []struct {
Description string
Value string
}{
{"A simple string", "Hello World!"},
{"An integer", "1234567890"},
{"A dictionary", `{"key": "value"}`},
{"Chinese characters", "这是一些中文"},
{"Emojis", "🚀🌟✨"},
{"Lorem ipsum text", "Lorem ipsum dolor sit amet"},
{"HTML content", "<html><body>Hello</body></html>"},
{"Cyrillic characters", "\u041f\u0440\u0438\u0432\u0435\u0442"},
{"Base64 encoded string", "Base64==dGVzdA=="},
{"Binary data", "d29ya2luZyB3aXRoIGJpbmFyeSBkYXRh: \x50\x51"},
{"Special characters with whitespace", "\t\nSpecial\tCharacters\n"},
{"Boolean false as a string", "False"},
{"A float number", "3.1415926535"},
{"A list", "[1, 2, 3, 4, 5]"},
{"Hexadecimal number as a string", "0xDEADBEEF"},
{"Email format", "user@example.com"},
{"URL format", "http://example.com"},
{"Date and time in ISO format", "2023-11-01T12:00:00Z"},
{"String with escaped quotes", `"Escaped" \"quotes\"`},
{"A regular expression", "Regular expression: ^[a-z0-9_-]{3,16}$"},
{"A very long string", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
{"A JSON string", `{"name": "John", "age": 30, "city": "New York"}`},
{"A Unix path", "/usr/local/bin"},
{"A Windows path", "C:\\Windows\\System32"},
{"An SQL query", "SELECT * FROM users WHERE id = 1;"},
{"JavaScript code snippet", "function test() { console.log('Hello World'); }"},
{"A CSS snippet", "body { background-color: #fff; }"},
{"A Python one-liner", "print('Hello World')"},
{"An IP address", "192.168.1.1"},
{"A domain name", "www.example.com"},
{"A user agent string", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"},
{"A credit card number", "1234-5678-9012-3456"},
{"A phone number", "+1234567890"},
{"A UUID", "123e4567-e89b-12d3-a456-426614174000"},
{"A hashtag", "#helloWorld"},
{"A Twitter handle", "@username"},
{"A password", "P@ssw0rd!"},
{"A date in common format", "01/11/2023"},
{"A time string", "12:00:00"},
{"A mathematical equation", "E = mc^2"},
}
var PUBSUB_TOPICS_STORE = []string{
fmt.Sprintf("/waku/2/rs/%d/0", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/1", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/2", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/3", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/4", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/5", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/6", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/7", DEFAULT_CLUSTER_ID),
fmt.Sprintf("/waku/2/rs/%d/8", DEFAULT_CLUSTER_ID),
}
var CONTENT_TOPICS_DIFFERENT_SHARDS = []string{
"/myapp/1/latest/proto",
"/waku/2/content/test.js",
"/app/22/sometopic/someencoding",
"/toychat/2/huilong/proto",
"/statusim/1/community/cbor",
"/app/27/sometopic/someencoding",
"/app/29/sometopic/someencoding",
"/app/20/sometopic/someencoding",
}