mirror of
https://github.com/sartoopjj/thefeed.git
synced 2026-05-19 10:14:35 +03:00
136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
package e2e_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/sartoopjj/thefeed/internal/protocol"
|
|
"github.com/sartoopjj/thefeed/internal/server"
|
|
"github.com/sartoopjj/thefeed/internal/web"
|
|
)
|
|
|
|
func findFreePort(t *testing.T, network string) int {
|
|
t.Helper()
|
|
switch network {
|
|
case "udp":
|
|
conn, err := net.ListenPacket("udp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("find free udp port: %v", err)
|
|
}
|
|
defer conn.Close()
|
|
return conn.LocalAddr().(*net.UDPAddr).Port
|
|
default:
|
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("find free tcp port: %v", err)
|
|
}
|
|
defer l.Close()
|
|
return l.Addr().(*net.TCPAddr).Port
|
|
}
|
|
}
|
|
|
|
func startDNSServer(t *testing.T, domain, passphrase string, channels []string, messages map[int][]protocol.Message) (string, context.CancelFunc) {
|
|
addr, _, cancel := startDNSServerEx(t, domain, passphrase, false, channels, messages)
|
|
return addr, cancel
|
|
}
|
|
|
|
func startDNSServerWithManage(t *testing.T, domain, passphrase string, allowManage bool, channels []string, messages map[int][]protocol.Message) (string, context.CancelFunc) {
|
|
addr, _, cancel := startDNSServerEx(t, domain, passphrase, allowManage, channels, messages)
|
|
return addr, cancel
|
|
}
|
|
|
|
// startDNSServerEx starts a DNS server and returns the address, live feed (for updates), and cancel.
|
|
func startDNSServerEx(t *testing.T, domain, passphrase string, allowManage bool, channels []string, messages map[int][]protocol.Message) (string, *server.Feed, context.CancelFunc) {
|
|
t.Helper()
|
|
|
|
qk, rk, err := protocol.DeriveKeys(passphrase)
|
|
if err != nil {
|
|
t.Fatalf("derive keys: %v", err)
|
|
}
|
|
|
|
feed := server.NewFeed(channels)
|
|
for ch, msgs := range messages {
|
|
feed.UpdateChannel(ch, msgs)
|
|
}
|
|
|
|
port := findFreePort(t, "udp")
|
|
addr := fmt.Sprintf("127.0.0.1:%d", port)
|
|
|
|
channelsFile := ""
|
|
if allowManage {
|
|
f, err := os.CreateTemp(t.TempDir(), "channels-*.txt")
|
|
if err != nil {
|
|
t.Fatalf("create temp channels file: %v", err)
|
|
}
|
|
for _, ch := range channels {
|
|
fmt.Fprintf(f, "@%s\n", ch)
|
|
}
|
|
f.Close()
|
|
channelsFile = f.Name()
|
|
}
|
|
|
|
dnsServer := server.NewDNSServer(addr, domain, feed, qk, rk, protocol.DefaultMaxPadding, nil, allowManage, channelsFile, nil, false)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
ready := make(chan struct{})
|
|
go func() {
|
|
close(ready)
|
|
if err := dnsServer.ListenAndServe(ctx); err != nil && ctx.Err() == nil {
|
|
t.Errorf("dns server error: %v", err)
|
|
}
|
|
}()
|
|
<-ready
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
return addr, feed, cancel
|
|
}
|
|
|
|
func startWebServer(t *testing.T) (string, *web.Server) {
|
|
t.Helper()
|
|
dataDir := t.TempDir()
|
|
port := findFreePort(t, "tcp")
|
|
srv, err := web.New(dataDir, port, "127.0.0.1", "")
|
|
if err != nil {
|
|
t.Fatalf("create web server: %v", err)
|
|
}
|
|
go srv.Run()
|
|
time.Sleep(200 * time.Millisecond)
|
|
return fmt.Sprintf("http://127.0.0.1:%d", port), srv
|
|
}
|
|
|
|
func postJSON(t *testing.T, url, body string) *http.Response {
|
|
t.Helper()
|
|
resp, err := http.Post(url, "application/json", strings.NewReader(body))
|
|
if err != nil {
|
|
t.Fatalf("POST %s: %v", url, err)
|
|
}
|
|
return resp
|
|
}
|
|
|
|
func getJSON(t *testing.T, url string) *http.Response {
|
|
t.Helper()
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
t.Fatalf("GET %s: %v", url, err)
|
|
}
|
|
return resp
|
|
}
|
|
|
|
func decodeJSON(t *testing.T, resp *http.Response) map[string]any {
|
|
t.Helper()
|
|
defer resp.Body.Close()
|
|
var m map[string]any
|
|
if err := json.NewDecoder(resp.Body).Decode(&m); err != nil {
|
|
t.Fatalf("decode JSON: %v", err)
|
|
}
|
|
return m
|
|
}
|