2022-07-24 20:51:42 +00:00
|
|
|
package rest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2023-11-07 14:56:48 +00:00
|
|
|
"net/url"
|
2022-07-24 20:51:42 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2023-02-16 20:18:15 +00:00
|
|
|
"github.com/go-chi/chi/v5"
|
2022-07-24 20:51:42 +00:00
|
|
|
"github.com/multiformats/go-multiaddr"
|
|
|
|
"github.com/stretchr/testify/require"
|
2022-11-09 19:53:01 +00:00
|
|
|
"github.com/waku-org/go-waku/tests"
|
|
|
|
"github.com/waku-org/go-waku/waku/v2/node"
|
2024-08-31 01:22:59 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol"
|
2022-11-09 19:53:01 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/pb"
|
2023-11-07 14:56:48 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
|
2022-11-09 19:53:01 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/utils"
|
2023-11-07 19:48:43 +00:00
|
|
|
"google.golang.org/protobuf/proto"
|
2022-07-24 20:51:42 +00:00
|
|
|
)
|
|
|
|
|
2023-02-16 20:18:15 +00:00
|
|
|
func makeRelayService(t *testing.T, mux *chi.Mux) *RelayService {
|
2022-07-24 20:51:42 +00:00
|
|
|
options := node.WithWakuRelayAndMinPeers(0)
|
2023-01-06 22:37:57 +00:00
|
|
|
n, err := node.New(options)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.NoError(t, err)
|
2023-01-06 22:37:57 +00:00
|
|
|
err = n.Start(context.Background())
|
2022-07-24 20:51:42 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
return NewRelayService(n, mux, 3, utils.Logger())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPostV1Message(t *testing.T) {
|
2023-02-16 20:18:15 +00:00
|
|
|
router := chi.NewRouter()
|
2024-08-31 01:22:59 +00:00
|
|
|
testTopic := "test"
|
2023-02-16 20:18:15 +00:00
|
|
|
|
2024-08-31 01:22:59 +00:00
|
|
|
r := makeRelayService(t, router)
|
2023-11-10 18:31:36 +00:00
|
|
|
msg := &RestWakuMessage{
|
2022-07-24 20:51:42 +00:00
|
|
|
Payload: []byte{1, 2, 3},
|
|
|
|
ContentTopic: "abc",
|
|
|
|
Timestamp: utils.GetUnixEpoch(),
|
|
|
|
}
|
2023-09-11 14:24:05 +00:00
|
|
|
msgJSONBytes, err := json.Marshal(msg)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2024-08-31 01:22:59 +00:00
|
|
|
_, err = r.node.Relay().Subscribe(context.Background(), protocol.NewContentFilter(testTopic))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-07-24 20:51:42 +00:00
|
|
|
rr := httptest.NewRecorder()
|
2024-08-31 01:22:59 +00:00
|
|
|
req, _ := http.NewRequest(http.MethodPost, "/relay/v1/messages/"+testTopic, bytes.NewReader(msgJSONBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRelaySubscription(t *testing.T) {
|
2023-02-16 20:18:15 +00:00
|
|
|
router := chi.NewRouter()
|
|
|
|
|
2023-11-07 14:56:48 +00:00
|
|
|
r := makeRelayService(t, router)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
2023-05-05 17:14:08 +00:00
|
|
|
// Wait for node to start
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
|
2022-07-24 20:51:42 +00:00
|
|
|
topics := []string{"test"}
|
|
|
|
topicsJSONBytes, err := json.Marshal(topics)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
2023-11-07 14:56:48 +00:00
|
|
|
req, _ := http.NewRequest(http.MethodPost, routeRelayV1Subscriptions, bytes.NewReader(topicsJSONBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
|
|
|
|
|
|
|
// Test max messages in subscription
|
2023-11-07 19:48:43 +00:00
|
|
|
now := *utils.GetUnixEpoch()
|
2023-11-07 14:56:48 +00:00
|
|
|
_, err = r.node.Relay().Publish(context.Background(),
|
2023-11-07 19:48:43 +00:00
|
|
|
tests.CreateWakuMessage("test", proto.Int64(now+1)), relay.WithPubSubTopic("test"))
|
2023-11-07 14:56:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
_, err = r.node.Relay().Publish(context.Background(),
|
2023-11-07 19:48:43 +00:00
|
|
|
tests.CreateWakuMessage("test", proto.Int64(now+2)), relay.WithPubSubTopic("test"))
|
2023-11-07 14:56:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
2023-11-07 14:56:48 +00:00
|
|
|
_, err = r.node.Relay().Publish(context.Background(),
|
2023-11-07 19:48:43 +00:00
|
|
|
tests.CreateWakuMessage("test", proto.Int64(now+3)), relay.WithPubSubTopic("test"))
|
2023-11-07 14:56:48 +00:00
|
|
|
require.NoError(t, err)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
2023-11-07 14:56:48 +00:00
|
|
|
// Wait for the messages to be processed
|
|
|
|
time.Sleep(5 * time.Millisecond)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
|
|
|
// Test deletion
|
|
|
|
rr = httptest.NewRecorder()
|
2023-11-07 14:56:48 +00:00
|
|
|
req, _ = http.NewRequest(http.MethodDelete, routeRelayV1Subscriptions, bytes.NewReader(topicsJSONBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRelayGetV1Messages(t *testing.T) {
|
2023-02-16 20:18:15 +00:00
|
|
|
router := chi.NewRouter()
|
2023-11-07 14:56:48 +00:00
|
|
|
router1 := chi.NewRouter()
|
2023-02-16 20:18:15 +00:00
|
|
|
|
|
|
|
serviceA := makeRelayService(t, router)
|
2023-11-07 14:56:48 +00:00
|
|
|
|
|
|
|
serviceB := makeRelayService(t, router1)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
2024-01-12 17:40:27 +00:00
|
|
|
hostInfo, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", serviceB.node.Host().ID().String()))
|
2022-07-24 20:51:42 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
var addr multiaddr.Multiaddr
|
|
|
|
for _, a := range serviceB.node.Host().Addrs() {
|
|
|
|
addr = a.Encapsulate(hostInfo)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
err = serviceA.node.DialPeerWithMultiAddress(context.Background(), addr)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Wait for the dial to complete
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
topics := []string{"test"}
|
|
|
|
topicsJSONBytes, err := json.Marshal(topics)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
2023-11-07 14:56:48 +00:00
|
|
|
req, _ := http.NewRequest(http.MethodPost, routeRelayV1Subscriptions, bytes.NewReader(topicsJSONBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
|
|
|
|
// Wait for the subscription to be started
|
|
|
|
time.Sleep(1 * time.Second)
|
2024-03-26 06:15:59 +00:00
|
|
|
ephemeral := true
|
2023-11-10 18:31:36 +00:00
|
|
|
msg := &RestWakuMessage{
|
2022-07-24 20:51:42 +00:00
|
|
|
Payload: []byte{1, 2, 3},
|
|
|
|
ContentTopic: "test",
|
|
|
|
Timestamp: utils.GetUnixEpoch(),
|
2024-03-26 06:15:59 +00:00
|
|
|
Ephemeral: &ephemeral,
|
2022-07-24 20:51:42 +00:00
|
|
|
}
|
|
|
|
msgJsonBytes, err := json.Marshal(msg)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodPost, "/relay/v1/messages/test", bytes.NewReader(msgJsonBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
|
|
|
|
// Wait for the message to be received
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodGet, "/relay/v1/messages/test", bytes.NewReader([]byte{}))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2022-07-24 20:51:42 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
|
|
|
|
var messages []*pb.WakuMessage
|
|
|
|
err = json.Unmarshal(rr.Body.Bytes(), &messages)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, messages, 1)
|
2024-03-26 06:15:59 +00:00
|
|
|
require.Equal(t, *messages[0].Ephemeral, true)
|
2022-07-24 20:51:42 +00:00
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodGet, "/relay/v1/messages/test", bytes.NewReader([]byte{}))
|
2023-11-07 14:56:48 +00:00
|
|
|
router1.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusNotFound, rr.Code)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPostAutoV1Message(t *testing.T) {
|
|
|
|
router := chi.NewRouter()
|
|
|
|
|
|
|
|
_ = makeRelayService(t, router)
|
2023-11-10 18:31:36 +00:00
|
|
|
msg := &RestWakuMessage{
|
2023-11-07 14:56:48 +00:00
|
|
|
Payload: []byte{1, 2, 3},
|
|
|
|
ContentTopic: "/toychat/1/huilong/proto",
|
|
|
|
Timestamp: utils.GetUnixEpoch(),
|
|
|
|
}
|
|
|
|
msgJSONBytes, err := json.Marshal(msg)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, routeRelayV1AutoMessages, bytes.NewReader(msgJSONBytes))
|
2023-02-16 20:18:15 +00:00
|
|
|
router.ServeHTTP(rr, req)
|
2023-11-07 14:56:48 +00:00
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRelayAutoSubUnsub(t *testing.T) {
|
|
|
|
router := chi.NewRouter()
|
|
|
|
|
|
|
|
r := makeRelayService(t, router)
|
|
|
|
|
|
|
|
// Wait for node to start
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
|
|
|
|
|
|
cTopic1 := "/toychat/1/huilong/proto"
|
|
|
|
|
|
|
|
cTopics := []string{cTopic1}
|
|
|
|
topicsJSONBytes, err := json.Marshal(cTopics)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, routeRelayV1AutoSubscriptions, bytes.NewReader(topicsJSONBytes))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
2023-02-16 20:18:15 +00:00
|
|
|
|
2023-11-07 14:56:48 +00:00
|
|
|
// Test publishing messages after subscription
|
2023-11-07 19:48:43 +00:00
|
|
|
now := *utils.GetUnixEpoch()
|
2023-11-07 14:56:48 +00:00
|
|
|
_, err = r.node.Relay().Publish(context.Background(),
|
2023-11-07 19:48:43 +00:00
|
|
|
tests.CreateWakuMessage(cTopic1, proto.Int64(now+1)))
|
2023-11-07 14:56:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Wait for the messages to be processed
|
|
|
|
time.Sleep(5 * time.Millisecond)
|
|
|
|
|
|
|
|
// Test deletion
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodDelete, routeRelayV1AutoSubscriptions, bytes.NewReader(topicsJSONBytes))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
|
|
|
|
|
|
|
cTopics = append(cTopics, "test")
|
|
|
|
topicsJSONBytes, err = json.Marshal(cTopics)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodPost, routeRelayV1AutoSubscriptions, bytes.NewReader(topicsJSONBytes))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusBadRequest, rr.Code)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRelayGetV1AutoMessages(t *testing.T) {
|
|
|
|
router := chi.NewRouter()
|
|
|
|
router1 := chi.NewRouter()
|
|
|
|
|
|
|
|
serviceA := makeRelayService(t, router)
|
|
|
|
|
|
|
|
serviceB := makeRelayService(t, router1)
|
|
|
|
|
2024-01-12 17:40:27 +00:00
|
|
|
hostInfo, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", serviceB.node.Host().ID().String()))
|
2023-11-07 14:56:48 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
var addr multiaddr.Multiaddr
|
|
|
|
for _, a := range serviceB.node.Host().Addrs() {
|
|
|
|
addr = a.Encapsulate(hostInfo)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
err = serviceA.node.DialPeerWithMultiAddress(context.Background(), addr)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Wait for the dial to complete
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
cTopic1 := "/toychat/1/huilong/proto"
|
|
|
|
|
|
|
|
cTopics := []string{cTopic1}
|
|
|
|
topicsJSONBytes, err := json.Marshal(cTopics)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr := httptest.NewRecorder()
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, routeRelayV1AutoSubscriptions, bytes.NewReader(topicsJSONBytes))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
require.Equal(t, "true", rr.Body.String())
|
|
|
|
|
|
|
|
// Wait for the subscription to be started
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
2023-11-10 18:31:36 +00:00
|
|
|
msg := &RestWakuMessage{
|
2023-11-07 14:56:48 +00:00
|
|
|
Payload: []byte{1, 2, 3},
|
|
|
|
ContentTopic: cTopic1,
|
|
|
|
Timestamp: utils.GetUnixEpoch(),
|
|
|
|
}
|
|
|
|
msgJsonBytes, err := json.Marshal(msg)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodPost, routeRelayV1AutoMessages, bytes.NewReader(msgJsonBytes))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
|
|
|
|
// Wait for the message to be received
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", routeRelayV1AutoMessages, url.QueryEscape(cTopic1)), bytes.NewReader([]byte{}))
|
|
|
|
router.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
|
|
|
|
var messages []*pb.WakuMessage
|
2023-02-16 20:18:15 +00:00
|
|
|
err = json.Unmarshal(rr.Body.Bytes(), &messages)
|
|
|
|
require.NoError(t, err)
|
2023-11-07 14:56:48 +00:00
|
|
|
require.Len(t, messages, 1)
|
|
|
|
|
|
|
|
rr = httptest.NewRecorder()
|
|
|
|
req, _ = http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", routeRelayV1AutoMessages, url.QueryEscape(cTopic1)), bytes.NewReader([]byte{}))
|
|
|
|
router1.ServeHTTP(rr, req)
|
|
|
|
require.Equal(t, http.StatusNotFound, rr.Code)
|
|
|
|
|
2022-07-24 20:51:42 +00:00
|
|
|
}
|