From: Matus Fabian Date: Fri, 1 Aug 2025 16:08:59 +0000 (-0400) Subject: hs-test: add hsi and transparent proxy test X-Git-Tag: v26.02-rc0~125 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F11%2F43511%2F3;p=vpp.git hs-test: add hsi and transparent proxy test Type: test Change-Id: Ie7fdc987ee300cf0d3dc5aed31dd28a972f0c394 Signed-off-by: Matus Fabian --- diff --git a/extras/hs-test/Makefile b/extras/hs-test/Makefile index b264795d232..5406b691200 100644 --- a/extras/hs-test/Makefile +++ b/extras/hs-test/Makefile @@ -88,7 +88,8 @@ endif FORCE_BUILD?=true BUILD_AS:=$(strip $(shell echo $${SUDO_USER:-$${USER:-root}})) -DOCKER_CAPABILITIES:=--cap-add=NET_ADMIN --cap-add=SYS_RESOURCE --cap-add=IPC_LOCK +# privileged is needed for "ip netns" otherwise we are not able to create namespace +DOCKER_CAPABILITIES:=--privileged DOCKER_DEVICES:=--device /dev/vhost-net:/dev/vhost-net --device /dev/net/tun:/dev/net/tun DOCKER_VOLUMES:=-v $(WS_ROOT):$(WS_ROOT) -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/hs-test:/tmp/hs-test \ -v /etc/localtime:/etc/localtime:ro $(CORE_VOLUME) -v $(HS_ROOT)/.go_cache/mod:/root/go/pkg/mod \ diff --git a/extras/hs-test/docker/Dockerfile.vpp b/extras/hs-test/docker/Dockerfile.vpp index 1e69e2cf2f4..cf620ee1141 100644 --- a/extras/hs-test/docker/Dockerfile.vpp +++ b/extras/hs-test/docker/Dockerfile.vpp @@ -17,6 +17,7 @@ COPY \ $DIR/unittest_plugin.so \ $DIR/quic_plugin.so \ $DIR/quic_quicly_plugin.so \ + $DIR/hsi_plugin.so \ $DIR/http_static_plugin.so \ $DIR/ping_plugin.so \ $DIR/nsim_plugin.so \ diff --git a/extras/hs-test/hsi_test.go b/extras/hs-test/hsi_test.go new file mode 100644 index 00000000000..b5a8e61f340 --- /dev/null +++ b/extras/hs-test/hsi_test.go @@ -0,0 +1,31 @@ +package main + +import ( + "os" + "strconv" + + . "fd.io/hs-test/infra" + . "github.com/onsi/ginkgo/v2" +) + +func init() { + RegisterHsiSoloTests(HsiTransparentProxyTest) +} + +func HsiTransparentProxyTest(s *HsiSuite) { + s.SetupNginxServer() + vpp := s.Containers.Vpp.VppInstance + s.Log(vpp.Vppctl("set interface feature host-" + s.Interfaces.Client.Name() + " hsi4-in arc ip4-unicast")) + s.Log(vpp.Vppctl("set interface feature host-" + s.Interfaces.Server.Name() + " hsi4-in arc ip4-unicast")) + s.Log(vpp.Vppctl("test proxy server server-uri tcp://0.0.0.0:%d client-uri tcp://%s:%d", + s.Ports.Server, s.ServerAddr(), s.Ports.Server)) + + query := "httpTestFile" + finished := make(chan error, 1) + defer os.Remove(query) + go func() { + defer GinkgoRecover() + s.StartWget(finished, s.ServerAddr(), strconv.Itoa(int(s.Ports.Server)), query, s.NetNamespaces.Client) + }() + s.AssertNil(<-finished) +} diff --git a/extras/hs-test/infra/suite_hsi.go b/extras/hs-test/infra/suite_hsi.go new file mode 100644 index 00000000000..05755770478 --- /dev/null +++ b/extras/hs-test/infra/suite_hsi.go @@ -0,0 +1,223 @@ +package hst + +import ( + "fmt" + "os/exec" + "reflect" + "runtime" + "strings" + + . "fd.io/hs-test/infra/common" + . "github.com/onsi/ginkgo/v2" +) + +type HsiSuite struct { + HstSuite + maxTimeout int + Interfaces struct { + Client *NetInterface + Server *NetInterface + } + Containers struct { + Vpp *Container + NginxServerTransient *Container + } + Ports struct { + Server uint16 + ServerSsl uint16 + } + NetNamespaces struct { + Client string + } +} + +var hsiTests = map[string][]func(s *HsiSuite){} +var hsiSoloTests = map[string][]func(s *HsiSuite){} +var hsiMWTests = map[string][]func(s *HsiSuite){} + +func RegisterHsiTests(tests ...func(s *HsiSuite)) { + hsiTests[GetTestFilename()] = tests +} + +func RegisterHsiSoloTests(tests ...func(s *HsiSuite)) { + hsiSoloTests[GetTestFilename()] = tests +} + +func RegisterHsiMWTests(tests ...func(s *HsiSuite)) { + hsiMWTests[GetTestFilename()] = tests +} + +func (s *HsiSuite) SetupSuite() { + s.HstSuite.SetupSuite() + s.ConfigureNetworkTopology("ns") + s.LoadContainerTopology("single") + s.Ports.Server = s.GeneratePortAsInt() + s.Ports.ServerSsl = s.GeneratePortAsInt() + + if *IsVppDebug { + s.maxTimeout = 600 + } else { + s.maxTimeout = 60 + } + s.Interfaces.Client = s.GetInterfaceByName("hclnvpp") + s.Interfaces.Server = s.GetInterfaceByName("hsrvvpp") + s.NetNamespaces.Client = s.GetNetNamespaceByName("cln") + s.Containers.NginxServerTransient = s.GetTransientContainerByName("nginx-server") + s.Containers.Vpp = s.GetContainerByName("vpp") +} + +func (s *HsiSuite) SetupTest() { + s.HstSuite.SetupTest() + + vpp, err := s.Containers.Vpp.newVppInstance(s.Containers.Vpp.AllocatedCpus) + s.AssertNotNil(vpp, fmt.Sprint(err)) + + s.AssertNil(vpp.Start()) + idx, err := vpp.createAfPacket(s.Interfaces.Client, false) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) + idx, err = vpp.createAfPacket(s.Interfaces.Server, false) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) + + s.Log(vpp.Vppctl("set interface feature host-" + s.Interfaces.Client.Name() + " hsi4-in arc ip4-unicast")) + s.Log(vpp.Vppctl("set interface feature host-" + s.Interfaces.Server.Name() + " hsi4-in arc ip4-unicast")) + + // let the host know howto get to the server + cmd := exec.Command("ip", "netns", "exec", s.NetNamespaces.Client, "ip", "route", "add", + s.ServerAddr(), "via", s.Interfaces.Client.Ip4AddressString()) + s.Log(cmd.String()) + _, err = cmd.CombinedOutput() + s.AssertNil(err, fmt.Sprint(err)) + + if *DryRun { + s.LogStartedContainers() + s.Skip("Dry run mode = true") + } +} + +func (s *HsiSuite) TeardownTest() { + defer s.HstSuite.TeardownTest() + vpp := s.Containers.Vpp.VppInstance + if CurrentSpecReport().Failed() { + s.Log(vpp.Vppctl("show session verbose 2")) + s.Log(vpp.Vppctl("show error")) + s.CollectNginxLogs(s.Containers.NginxServerTransient) + } +} + +func (s *HsiSuite) SetupNginxServer() { + s.AssertNil(s.Containers.NginxServerTransient.Create()) + nginxSettings := struct { + LogPrefix string + Address string + Port uint16 + PortSsl uint16 + Http2 string + Timeout int + }{ + LogPrefix: s.Containers.NginxServerTransient.Name, + Address: s.ServerAddr(), + Port: s.Ports.Server, + PortSsl: s.Ports.ServerSsl, + Http2: "off", + Timeout: s.maxTimeout, + } + s.Containers.NginxServerTransient.CreateConfigFromTemplate( + "/nginx.conf", + "./resources/nginx/nginx_server.conf", + nginxSettings, + ) + s.AssertNil(s.Containers.NginxServerTransient.Start()) +} + +func (s *HsiSuite) ServerAddr() string { + return s.Interfaces.Server.Peer.Ip4AddressString() +} + +var _ = Describe("HsiSuite", Ordered, ContinueOnFailure, func() { + var s HsiSuite + BeforeAll(func() { + s.SetupSuite() + }) + BeforeEach(func() { + s.SetupTest() + }) + AfterAll(func() { + s.TeardownSuite() + }) + AfterEach(func() { + s.TeardownTest() + }) + + for filename, tests := range hsiTests { + for _, test := range tests { + test := test + pc := reflect.ValueOf(test).Pointer() + funcValue := runtime.FuncForPC(pc) + testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] + It(testName, func(ctx SpecContext) { + s.Log(testName + ": BEGIN") + test(&s) + }, SpecTimeout(TestTimeout)) + } + } +}) + +var _ = Describe("HsiSoloSuite", Ordered, ContinueOnFailure, Serial, func() { + var s HsiSuite + BeforeAll(func() { + s.SetupSuite() + }) + BeforeEach(func() { + s.SetupTest() + }) + AfterAll(func() { + s.TeardownSuite() + }) + AfterEach(func() { + s.TeardownTest() + }) + + for filename, tests := range hsiSoloTests { + for _, test := range tests { + test := test + pc := reflect.ValueOf(test).Pointer() + funcValue := runtime.FuncForPC(pc) + testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] + It(testName, Label("SOLO"), func(ctx SpecContext) { + s.Log(testName + ": BEGIN") + test(&s) + }, SpecTimeout(TestTimeout)) + } + } +}) + +var _ = Describe("HsiMWSuite", Ordered, ContinueOnFailure, Serial, func() { + var s HsiSuite + BeforeAll(func() { + s.SetupSuite() + }) + BeforeEach(func() { + s.SkipIfNotEnoguhCpus = true + }) + AfterAll(func() { + s.TeardownSuite() + }) + AfterEach(func() { + s.TeardownTest() + }) + + for filename, tests := range hsiMWTests { + for _, test := range tests { + test := test + pc := reflect.ValueOf(test).Pointer() + funcValue := runtime.FuncForPC(pc) + testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] + It(testName, Label("SOLO", "VPP Multi-Worker"), func(ctx SpecContext) { + s.Log(testName + ": BEGIN") + test(&s) + }, SpecTimeout(TestTimeout)) + } + } +}) diff --git a/extras/hs-test/infra/vppinstance.go b/extras/hs-test/infra/vppinstance.go index b601e46feff..2e9c7567aa8 100644 --- a/extras/hs-test/infra/vppinstance.go +++ b/extras/hs-test/infra/vppinstance.go @@ -63,6 +63,7 @@ plugins { plugin quic_quicly_plugin.so { enable } plugin af_packet_plugin.so { enable } plugin hs_apps_plugin.so { enable } + plugin hsi_plugin.so { enable } plugin http_plugin.so { enable } plugin http_unittest_plugin.so { enable } plugin http_static_plugin.so { enable } diff --git a/extras/hs-test/topo-network/ns.yaml b/extras/hs-test/topo-network/ns.yaml index 018c329f77e..233ab498dd6 100644 --- a/extras/hs-test/topo-network/ns.yaml +++ b/extras/hs-test/topo-network/ns.yaml @@ -3,9 +3,6 @@ devices: - name: "cln" type: "netns" - - name: "srv" - type: "netns" - - name: "hclnvpp" type: "veth" peer: @@ -18,6 +15,5 @@ devices: type: "veth" peer: name: "srv" - netns: "srv" ip4: network: 2