// SPDX-FileCopyrightText: 2026 Echolot contributors // SPDX-License-Identifier: GPL-3.0-or-later package tcpecho import ( "bufio" "encoding/json" "net" "testing" "time" ) // Plain echo must be server-speaks-first: a client that sends nothing still // gets the greeting (via the peek timeout), then its bytes are echoed. func TestPlainEchoServerSpeaksFirst(t *testing.T) { ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer ln.Close() go (&Server{}).Serve(ln) c, err := net.Dial("tcp", ln.Addr().String()) if err != nil { t.Fatal(err) } defer c.Close() c.SetDeadline(time.Now().Add(3 * time.Second)) line, err := bufio.NewReader(c).ReadBytes('\n') if err != nil { t.Fatalf("no greeting: %v", err) } var g struct { TLS bool `json:"tls"` Src string `json:"observed_src"` } if err := json.Unmarshal(line, &g); err != nil { t.Fatal(err) } if g.TLS { t.Fatal("plain connection reported tls=true") } if g.Src == "" { t.Fatal("greeting missing observed_src") } c.Write([]byte("xyz")) buf := make([]byte, 3) if _, err := c.Read(buf); err != nil || string(buf) != "xyz" { t.Fatalf("echo failed: %q %v", buf, err) } }