101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package discovery
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestResponderIncludesConfigSummaryInReply(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfgPath := filepath.Join(dir, "media-server.json")
|
|
body := []byte(`{"metadata":{"config_id":"cfg-1","config_version":"v1","business_name":"A厂区视觉识别","template":"std_workshop_face_recognition_shoe_alarm","profile":"local_3588_test","overlays":["face_debug"],"instance_names":["cam1"],"instance_display_names":["东门入口"]},"instances":[]}`)
|
|
if err := os.WriteFile(cfgPath, body, 0o644); err != nil {
|
|
t.Fatalf("write config: %v", err)
|
|
}
|
|
|
|
port := freeUDPPort(t)
|
|
resp := &Responder{
|
|
Port: port,
|
|
DeviceID: "dev-1",
|
|
DeviceName: "rk3588_orangepi5plus",
|
|
Hostname: "orangepi5plus",
|
|
AgentPort: 9100,
|
|
MediaPort: 9000,
|
|
Version: "0.1.0",
|
|
BuildID: "20260420.001",
|
|
BuildType: "release",
|
|
GitSHA: "abc1234",
|
|
ConfigPath: cfgPath,
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
go func() {
|
|
_ = resp.Run(ctx)
|
|
}()
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
conn, err := net.DialUDP("udp4", nil, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: port})
|
|
if err != nil {
|
|
t.Fatalf("dial udp: %v", err)
|
|
}
|
|
defer conn.Close()
|
|
if err := conn.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
|
|
t.Fatalf("set deadline: %v", err)
|
|
}
|
|
|
|
req := Magic + "\n" + `{"type":"discover","req_id":"req-1","reply_port":0}` + "\n"
|
|
if _, err := conn.Write([]byte(req)); err != nil {
|
|
t.Fatalf("write req: %v", err)
|
|
}
|
|
|
|
buf := make([]byte, 4096)
|
|
n, err := conn.Read(buf)
|
|
if err != nil {
|
|
t.Fatalf("read reply: %v", err)
|
|
}
|
|
_, line2, ok := split2lines(string(buf[:n]))
|
|
if !ok {
|
|
t.Fatalf("invalid reply: %q", string(buf[:n]))
|
|
}
|
|
|
|
var reply map[string]any
|
|
if err := json.Unmarshal([]byte(line2), &reply); err != nil {
|
|
t.Fatalf("decode reply: %v", err)
|
|
}
|
|
if reply["config_id"] != "cfg-1" {
|
|
t.Fatalf("config_id = %#v", reply["config_id"])
|
|
}
|
|
if reply["template"] != "std_workshop_face_recognition_shoe_alarm" {
|
|
t.Fatalf("template = %#v", reply["template"])
|
|
}
|
|
if reply["profile"] != "local_3588_test" {
|
|
t.Fatalf("profile = %#v", reply["profile"])
|
|
}
|
|
if reply["business_name"] != "A厂区视觉识别" {
|
|
t.Fatalf("business_name = %#v", reply["business_name"])
|
|
}
|
|
if reply["instance_display_name"] != "东门入口" {
|
|
t.Fatalf("instance_display_name = %#v", reply["instance_display_name"])
|
|
}
|
|
overlays, ok := reply["overlays"].([]any)
|
|
if !ok || len(overlays) != 1 || overlays[0] != "face_debug" {
|
|
t.Fatalf("overlays = %#v", reply["overlays"])
|
|
}
|
|
}
|
|
|
|
func freeUDPPort(t *testing.T) int {
|
|
t.Helper()
|
|
l, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
|
if err != nil {
|
|
t.Fatalf("listen udp: %v", err)
|
|
}
|
|
defer l.Close()
|
|
return l.LocalAddr().(*net.UDPAddr).Port
|
|
}
|