mirror of
https://github.com/Quad4-Software/Reticulum-Go
synced 2026-08-29 23:48:44 -04:00
149 lines
3.4 KiB
Go
149 lines
3.4 KiB
Go
|
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
// Copyright (c) 2024-2026 Quad4.io
|
||
|
|
|
||
|
|
// Live Go-Go HTTPS long-poll interface interop. Set RUN_LIVE_INTEROP=1.
|
||
|
|
|
||
|
|
//go:build !js
|
||
|
|
|
||
|
|
package interop
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"sync"
|
||
|
|
"sync/atomic"
|
||
|
|
"testing"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"quad4/reticulum-go/pkg/common"
|
||
|
|
"quad4/reticulum-go/pkg/interfaces"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestLiveInteropHTTPSGoGoEcho(t *testing.T) {
|
||
|
|
liveOrSkip(t)
|
||
|
|
|
||
|
|
port := freeTCPPort(t)
|
||
|
|
srv, err := interfaces.NewHTTPSServerInterface("live_https_srv", "127.0.0.1", port, interfaces.HTTPSServerOptions{
|
||
|
|
Path: "/rns",
|
||
|
|
LongPoll: 2 * time.Second,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
pin, err := srv.LeafSPKIPinHex()
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
var got atomic.Value
|
||
|
|
var wg sync.WaitGroup
|
||
|
|
wg.Add(1)
|
||
|
|
srv.SetPacketCallback(func(data []byte, _ common.NetworkInterface) {
|
||
|
|
got.Store(append([]byte(nil), data...))
|
||
|
|
wg.Done()
|
||
|
|
})
|
||
|
|
if err := srv.Start(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer srv.Stop()
|
||
|
|
|
||
|
|
cli, err := interfaces.NewHTTPSClientInterfaceWithRetries("live_https_cli", "127.0.0.1", port, true, -1, interfaces.HTTPSClientOptions{
|
||
|
|
PeerKey: pin,
|
||
|
|
Path: "/rns",
|
||
|
|
LongPoll: 2 * time.Second,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer cli.Stop()
|
||
|
|
|
||
|
|
deadline := time.Now().Add(10 * time.Second)
|
||
|
|
for time.Now().Before(deadline) && !cli.IsOnline() {
|
||
|
|
time.Sleep(50 * time.Millisecond)
|
||
|
|
}
|
||
|
|
if !cli.IsOnline() {
|
||
|
|
t.Fatal("HTTPS client not online")
|
||
|
|
}
|
||
|
|
|
||
|
|
payload := []byte{0x48, 0x54, 0x54, 0x50, 0x53}
|
||
|
|
if err := cli.Send(payload, ""); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
done := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
wg.Wait()
|
||
|
|
close(done)
|
||
|
|
}()
|
||
|
|
select {
|
||
|
|
case <-done:
|
||
|
|
case <-time.After(5 * time.Second):
|
||
|
|
t.Fatal("timeout waiting for live HTTPS packet")
|
||
|
|
}
|
||
|
|
if !bytes.Equal(got.Load().([]byte), payload) {
|
||
|
|
t.Fatalf("got %x want %x", got.Load(), payload)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestLiveInteropHTTPSBidirectional(t *testing.T) {
|
||
|
|
liveOrSkip(t)
|
||
|
|
|
||
|
|
port := freeTCPPort(t)
|
||
|
|
srv, err := interfaces.NewHTTPSServerInterface("live_https_bi_srv", "127.0.0.1", port, interfaces.HTTPSServerOptions{
|
||
|
|
LongPoll: 2 * time.Second,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
if err := srv.Start(); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer srv.Stop()
|
||
|
|
|
||
|
|
cli, err := interfaces.NewHTTPSClientInterfaceWithRetries("live_https_bi_cli", "127.0.0.1", port, true, -1, interfaces.HTTPSClientOptions{
|
||
|
|
LongPoll: 2 * time.Second,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
defer cli.Stop()
|
||
|
|
|
||
|
|
deadline := time.Now().Add(10 * time.Second)
|
||
|
|
for time.Now().Before(deadline) && !cli.IsOnline() {
|
||
|
|
time.Sleep(50 * time.Millisecond)
|
||
|
|
}
|
||
|
|
if !cli.IsOnline() {
|
||
|
|
t.Fatal("HTTPS client not online")
|
||
|
|
}
|
||
|
|
deadline = time.Now().Add(5 * time.Second)
|
||
|
|
for time.Now().Before(deadline) && srv.PeerCount() < 1 {
|
||
|
|
time.Sleep(50 * time.Millisecond)
|
||
|
|
}
|
||
|
|
if srv.PeerCount() < 1 {
|
||
|
|
t.Fatal("no HTTPS peers registered")
|
||
|
|
}
|
||
|
|
|
||
|
|
var fromSrv atomic.Value
|
||
|
|
var wg sync.WaitGroup
|
||
|
|
wg.Add(1)
|
||
|
|
cli.SetPacketCallback(func(data []byte, _ common.NetworkInterface) {
|
||
|
|
fromSrv.Store(append([]byte(nil), data...))
|
||
|
|
wg.Done()
|
||
|
|
})
|
||
|
|
time.Sleep(50 * time.Millisecond)
|
||
|
|
payload := []byte("from-https-server")
|
||
|
|
if err := srv.Send(payload, ""); err != nil {
|
||
|
|
t.Fatal(err)
|
||
|
|
}
|
||
|
|
done := make(chan struct{})
|
||
|
|
go func() {
|
||
|
|
wg.Wait()
|
||
|
|
close(done)
|
||
|
|
}()
|
||
|
|
select {
|
||
|
|
case <-done:
|
||
|
|
case <-time.After(5 * time.Second):
|
||
|
|
t.Fatal("timeout waiting for server-to-client HTTPS packet")
|
||
|
|
}
|
||
|
|
if !bytes.Equal(fromSrv.Load().([]byte), payload) {
|
||
|
|
t.Fatalf("got %x want %x", fromSrv.Load(), payload)
|
||
|
|
}
|
||
|
|
}
|