// Test udp.Addr works correctly. func TestUDPAddr(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() t.Log("Given the need to listen on any port and know that bound UDP address.") { // Create a configuration. cfg := udp.Config{ NetType: "udp4", Addr: ":0", // Defer port assignment to OS. ConnHandler: udpConnHandler{}, ReqHandler: udpReqHandler{}, RespHandler: udpRespHandler{}, OptIntPool: udp.OptIntPool{ RecvMinPoolSize: func() int { return 2 }, RecvMaxPoolSize: func() int { return 1000 }, SendMinPoolSize: func() int { return 2 }, SendMaxPoolSize: func() int { return 1000 }, }, } // Create a new UDP value. u, err := udp.New("TEST", "TEST", cfg) if err != nil { t.Fatal("\tShould be able to create a new UDP listener.", tests.Failed, err) } t.Log("\tShould be able to create a new UDP listener.", tests.Success) // Addr should be nil before start. if addr := u.Addr(); addr != nil { t.Fatalf("\tAddr() should be nil before Start; Addr() = %q. %s", addr, tests.Failed) } t.Log("\tAddr() should be nil before Start.", tests.Success) // Start accepting client data. if err := u.Start("TEST"); err != nil { t.Fatal("\tShould be able to start the UDP listener.", tests.Failed, err) } defer u.Stop("TEST") // Addr should be non-nil after Start. addr := u.Addr() if addr == nil { t.Fatal("\tAddr() should be not be nil after Start.", tests.Failed) } t.Log("\tAddr() should be not be nil after Start.", tests.Success) // The OS should assign a random open port, which shouldn't be 0. _, port, err := net.SplitHostPort(addr.String()) if err != nil { t.Fatalf("\tSplitHostPort should not fail. tests.Failed %v. %s", err, tests.Failed) } if port == "0" { t.Fatalf("\tAddr port should not be %q. %s", port, tests.Failed) } t.Logf("\tAddr() should be not be 0 after Start (port = %q). %s", port, tests.Success) } }
func main() { const context = "startup" // Create the configuration. cfg := udp.Config{ NetType: "udp4", Addr: ":6000", ConnHandler: udpConnHandler{}, ReqHandler: udpReqHandler{}, RespHandler: udpRespHandler{}, OptIntPool: udp.OptIntPool{ RecvMinPoolSize: func() int { return 2 }, RecvMaxPoolSize: func() int { return 100 }, SendMinPoolSize: func() int { return 2 }, SendMaxPoolSize: func() int { return 100 }, }, } // Create a new UDP value. u, err := udp.New(context, "Sample", cfg) if err != nil { log.Error(context, "main", err, "Creating udp") return } // Start accepting client data. if err := u.Start(context); err != nil { log.Error(context, "main", err, "Starting udp") return } // Defer the stop on shutdown. defer u.Stop(context) log.User(context, "main", "Waiting for data on: %s", u.Addr()) // Listen for an interrupt signal from the OS. sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, os.Interrupt) <-sigChan // Use netcat to test the server. // nc -4u localhost 6000 < test.hex log.User(context, "main", "Shutting down") }
// TestUDP provide a test of listening for a connection and // echoing the data back. func TestUDP(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() t.Log("Given the need to listen and process UDP data.") { // Create a configuration. cfg := udp.Config{ NetType: "udp4", Addr: ":0", ConnHandler: udpConnHandler{}, ReqHandler: udpReqHandler{}, RespHandler: udpRespHandler{}, OptIntPool: udp.OptIntPool{ RecvMinPoolSize: func() int { return 2 }, RecvMaxPoolSize: func() int { return 1000 }, SendMinPoolSize: func() int { return 2 }, SendMaxPoolSize: func() int { return 1000 }, }, } // Create a new UDP value. u, err := udp.New("TEST", "TEST", cfg) if err != nil { t.Fatal("\tShould be able to create a new UDP listener.", tests.Failed, err) } t.Log("\tShould be able to create a new UDP listener.", tests.Success) // Start accepting client data. if err := u.Start("TEST"); err != nil { t.Fatal("\tShould be able to start the UDP listener.", tests.Failed, err) } t.Log("\tShould be able to start the UDP listener.", tests.Success) defer u.Stop("TEST") // Let's connect back and send a UDP package conn, err := net.Dial("udp4", u.Addr().String()) if err != nil { t.Fatal("\tShould be able to dial a new UDP connection.", tests.Failed, err) } t.Log("\tShould be able to dial a new UDP connection.", tests.Success) // Send some know data to the udp listener. b := bytes.NewBuffer([]byte{0x01, 0x3D, 0x06, 0x00, 0x58, 0x68, 0x9b, 0x9d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x01}) b.WriteTo(conn) // Setup a limit reader to extract the response. lr := io.LimitReader(conn, 6) // Let's read the response. data := make([]byte, 6) if _, err := lr.Read(data); err != nil { t.Fatal("\tShould be able to read the response from the connection.", tests.Failed, err) } t.Log("\tShould be able to read the response from the connection.", tests.Success) response := string(data) if response == "GOT IT" { t.Log("\tShould receive the string \"GOT IT\".", tests.Success) } else { t.Error("\tShould receive the string \"GOT IT\".", tests.Failed, response) } d := atomic.LoadInt64(&dur) duration := time.Duration(d) if duration <= 2*time.Second { t.Log("\tShould be less that 2 seconds.", tests.Success) } else { t.Error("\tShould be less that 2 seconds.", tests.Failed, duration) } } }