2020-02-11 00:26:04 +00:00
|
|
|
package integration
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
2024-01-09 16:00:07 +00:00
|
|
|
"testing"
|
2020-02-11 00:26:04 +00:00
|
|
|
"time"
|
|
|
|
|
2024-01-10 09:47:44 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2024-01-09 16:00:07 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/stretchr/testify/suite"
|
2023-02-03 14:24:05 +00:00
|
|
|
"github.com/traefik/traefik/v3/integration/try"
|
2020-02-11 00:26:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type UDPSuite struct{ BaseSuite }
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func TestUDPSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(UDPSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *UDPSuite) SetupSuite() {
|
|
|
|
s.BaseSuite.SetupSuite()
|
|
|
|
|
|
|
|
s.createComposeProject("udp")
|
|
|
|
s.composeUp()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *UDPSuite) TearDownSuite() {
|
|
|
|
s.BaseSuite.TearDownSuite()
|
2020-02-11 00:26:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func guessWhoUDP(addr string) (string, error) {
|
|
|
|
var conn net.Conn
|
|
|
|
var err error
|
|
|
|
|
|
|
|
udpAddr, err2 := net.ResolveUDPAddr("udp", addr)
|
|
|
|
if err2 != nil {
|
|
|
|
return "", err2
|
|
|
|
}
|
|
|
|
|
|
|
|
conn, err = net.DialUDP("udp", nil, udpAddr)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = conn.Write([]byte("WHO"))
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
out := make([]byte, 2048)
|
|
|
|
n, err := conn.Read(out)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return string(out[:n]), nil
|
|
|
|
}
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
func (s *UDPSuite) TestWRR() {
|
|
|
|
file := s.adaptFile("fixtures/udp/wrr.toml", struct {
|
2020-02-11 00:26:04 +00:00
|
|
|
WhoamiAIP string
|
|
|
|
WhoamiBIP string
|
|
|
|
WhoamiCIP string
|
|
|
|
WhoamiDIP string
|
|
|
|
}{
|
2024-01-09 16:00:07 +00:00
|
|
|
WhoamiAIP: s.getComposeServiceIP("whoami-a"),
|
|
|
|
WhoamiBIP: s.getComposeServiceIP("whoami-b"),
|
|
|
|
WhoamiCIP: s.getComposeServiceIP("whoami-c"),
|
|
|
|
WhoamiDIP: s.getComposeServiceIP("whoami-d"),
|
2020-02-11 00:26:04 +00:00
|
|
|
})
|
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
s.traefikCmd(withConfigFile(file))
|
2020-02-11 00:26:04 +00:00
|
|
|
|
2024-01-09 16:00:07 +00:00
|
|
|
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("whoami-a"))
|
|
|
|
require.NoError(s.T(), err)
|
2020-02-11 00:26:04 +00:00
|
|
|
|
|
|
|
err = try.GetRequest("http://127.0.0.1:8093/who", 5*time.Second, try.StatusCodeIs(http.StatusOK))
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2020-02-11 00:26:04 +00:00
|
|
|
|
|
|
|
stop := make(chan struct{})
|
|
|
|
go func() {
|
|
|
|
call := map[string]int{}
|
2022-09-14 12:42:08 +00:00
|
|
|
for i := 0; i < 8; i++ {
|
2020-02-11 00:26:04 +00:00
|
|
|
out, err := guessWhoUDP("127.0.0.1:8093")
|
2024-01-09 16:00:07 +00:00
|
|
|
require.NoError(s.T(), err)
|
2020-02-11 00:26:04 +00:00
|
|
|
switch {
|
|
|
|
case strings.Contains(out, "whoami-a"):
|
|
|
|
call["whoami-a"]++
|
|
|
|
case strings.Contains(out, "whoami-b"):
|
|
|
|
call["whoami-b"]++
|
|
|
|
case strings.Contains(out, "whoami-c"):
|
|
|
|
call["whoami-c"]++
|
|
|
|
default:
|
|
|
|
call["unknown"]++
|
|
|
|
}
|
|
|
|
}
|
2024-01-09 16:00:07 +00:00
|
|
|
assert.EqualValues(s.T(), call, map[string]int{"whoami-a": 3, "whoami-b": 2, "whoami-c": 3})
|
2020-02-11 00:26:04 +00:00
|
|
|
close(stop)
|
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-stop:
|
2020-03-18 13:50:06 +00:00
|
|
|
case <-time.Tick(5 * time.Second):
|
2024-01-10 09:47:44 +00:00
|
|
|
log.Info().Msg("Timeout")
|
2020-02-11 00:26:04 +00:00
|
|
|
}
|
|
|
|
}
|