aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorMaros Ondrejicka <maros.ondrejicka@pantheon.tech>2023-02-02 08:58:04 +0100
committerFlorin Coras <florin.coras@gmail.com>2023-02-10 05:23:19 +0000
commit2908f8cf07c21f385f80d83fdad826a0eea98977 (patch)
tree6391c5b989f2a7800958489feb1d7f460a87e850 /extras
parent0a192ea93df9d1cd4d7777bcc5418a2f9e861a6c (diff)
hs-test: refactor test cases from ns suite
This converts more tests to configure VPP from test context. Type: test Signed-off-by: Maros Ondrejicka <maros.ondrejicka@pantheon.tech> Change-Id: Idf26b0c16f87e87c97b198412af39b99d947ced6
Diffstat (limited to 'extras')
-rw-r--r--extras/hs-test/actions.go247
-rw-r--r--extras/hs-test/container.go24
-rw-r--r--extras/hs-test/echo_test.go12
-rw-r--r--extras/hs-test/hst_suite.go128
-rw-r--r--extras/hs-test/http_test.go31
-rw-r--r--extras/hs-test/ldp_test.go27
-rw-r--r--extras/hs-test/linux_iperf_test.go4
-rw-r--r--extras/hs-test/main.go11
-rw-r--r--extras/hs-test/netconfig.go122
-rw-r--r--extras/hs-test/proxy_test.go39
-rw-r--r--extras/hs-test/resources/envoy/proxy.yaml3
-rw-r--r--extras/hs-test/suite_ns_test.go37
-rw-r--r--extras/hs-test/suite_tap_test.go3
-rw-r--r--extras/hs-test/suite_veth_test.go16
-rw-r--r--extras/hs-test/topo-containers/ns.yaml2
-rw-r--r--extras/hs-test/topo-network/ns.yaml8
-rw-r--r--extras/hs-test/topo-network/tap.yaml1
-rw-r--r--extras/hs-test/utils.go9
-rw-r--r--extras/hs-test/vcl_test.go65
-rw-r--r--extras/hs-test/vppinstance.go68
20 files changed, 333 insertions, 524 deletions
diff --git a/extras/hs-test/actions.go b/extras/hs-test/actions.go
index 60398704763..9233e2d1ea2 100644
--- a/extras/hs-test/actions.go
+++ b/extras/hs-test/actions.go
@@ -2,20 +2,14 @@ package main
import (
"context"
- "fmt"
"os"
- "path/filepath"
"git.fd.io/govpp.git/api"
- "github.com/edwarnicke/exechelper"
- "github.com/edwarnicke/govpp/binapi/af_packet"
- "github.com/edwarnicke/govpp/binapi/ethernet_types"
interfaces "github.com/edwarnicke/govpp/binapi/interface"
"github.com/edwarnicke/govpp/binapi/interface_types"
ip_types "github.com/edwarnicke/govpp/binapi/ip_types"
"github.com/edwarnicke/govpp/binapi/session"
"github.com/edwarnicke/govpp/binapi/tapv2"
- "github.com/edwarnicke/govpp/binapi/vlib"
"github.com/edwarnicke/vpphelper"
)
@@ -28,247 +22,6 @@ type ConfFn func(context.Context, api.Connection) error
type Actions struct {
}
-func configureProxyTcp(ifName0, ipAddr0, ifName1, ipAddr1 string) ConfFn {
- return func(ctx context.Context,
- vppConn api.Connection) error {
-
- _, err := configureAfPacket(ctx, vppConn, ifName0, ipAddr0)
- if err != nil {
- fmt.Printf("failed to create af packet: %v", err)
- return err
- }
- _, err = configureAfPacket(ctx, vppConn, ifName1, ipAddr1)
- if err != nil {
- fmt.Printf("failed to create af packet: %v", err)
- return err
- }
- return nil
- }
-}
-
-func (a *Actions) ConfigureVppProxy(args []string) *ActionResult {
- ctx, cancel := newVppContext()
- defer cancel()
-
- con, vppErrCh := vpphelper.StartAndDialContext(ctx,
- vpphelper.WithVppConfig(configTemplate),
- vpphelper.WithRootDir(workDir))
- exitOnErrCh(ctx, cancel, vppErrCh)
-
- confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
- err := confFn(ctx, con)
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("configuration failed"))
- }
- writeSyncFile(OkResult())
- <-ctx.Done()
- return nil
-}
-
-func (a *Actions) ConfigureEnvoyProxy(args []string) *ActionResult {
- var startup Stanza
- startup.
- NewStanza("session").
- Append("enable").
- Append("use-app-socket-api").
- Append("evt_qs_memfd_seg").
- Append("event-queue-length 100000").Close()
- ctx, cancel := newVppContext()
- defer cancel()
-
- con, vppErrCh := vpphelper.StartAndDialContext(ctx,
- vpphelper.WithVppConfig(configTemplate+startup.ToString()),
- vpphelper.WithRootDir(workDir))
- exitOnErrCh(ctx, cancel, vppErrCh)
-
- confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
- err := confFn(ctx, con)
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("configuration failed"))
- }
- err0 := exechelper.Run("chmod 777 -R " + workDir)
- if err0 != nil {
- return NewActionResult(err, ActionResultWithDesc("setting permissions failed"))
- }
- writeSyncFile(OkResult())
- <-ctx.Done()
- return nil
-}
-
-func getArgs() string {
- s := ""
- for i := 2; i < len(os.Args); i++ {
- s = s + " " + os.Args[i]
- }
- return s
-}
-
-func ApiCliInband(root, cmd string) *ActionResult {
- ctx, _ := newVppContext()
- con := vpphelper.DialContext(ctx, filepath.Join(root, "/var/run/vpp/api.sock"))
- cliInband := vlib.CliInband{Cmd: cmd}
- cliInbandReply, err := vlib.NewServiceClient(con).CliInband(ctx, &cliInband)
- return NewActionResult(err, ActionResultWithStdout(cliInbandReply.Reply))
-}
-
-func (a *Actions) RunEchoSrvInternal(args []string) *ActionResult {
- cmd := fmt.Sprintf("test echo server %s uri tcp://10.10.10.1/1234", getArgs())
- return ApiCliInband(workDir, cmd)
-}
-
-func (a *Actions) RunEchoClnInternal(args []string) *ActionResult {
- cmd := fmt.Sprintf("test echo client %s uri tcp://10.10.10.1/1234", getArgs())
- return ApiCliInband(workDir, cmd)
-}
-
-func configure2vethsTopo(ifName, interfaceAddress, namespaceId string, secret uint64, optionalHardwareAddress ...string) ConfFn {
- return func(ctx context.Context,
- vppConn api.Connection) error {
-
- var swIfIndex interface_types.InterfaceIndex
- var err error
- if optionalHardwareAddress == nil {
- swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress)
- } else {
- swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress, optionalHardwareAddress[0])
- }
- if err != nil {
- fmt.Printf("failed to create af packet: %v", err)
- }
- _, er := session.NewServiceClient(vppConn).AppNamespaceAddDelV2(ctx, &session.AppNamespaceAddDelV2{
- Secret: secret,
- SwIfIndex: swIfIndex,
- NamespaceID: namespaceId,
- })
- if er != nil {
- fmt.Printf("add app namespace: %v", err)
- return err
- }
-
- _, er1 := session.NewServiceClient(vppConn).SessionEnableDisable(ctx, &session.SessionEnableDisable{
- IsEnable: true,
- })
- if er1 != nil {
- fmt.Printf("session enable %v", err)
- return err
- }
- return nil
- }
-}
-
-func (a *Actions) Configure2Veths(args []string) *ActionResult {
- var startup Stanza
- startup.
- NewStanza("session").
- Append("enable").
- Append("use-app-socket-api").Close()
-
- ctx, cancel := newVppContext()
- defer cancel()
-
- vppConfig, err := deserializeVppConfig(args[2])
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("deserializing configuration failed"))
- }
-
- con, vppErrCh := vpphelper.StartAndDialContext(ctx,
- vpphelper.WithVppConfig(vppConfig.getTemplate()+startup.ToString()),
- vpphelper.WithRootDir(workDir))
- exitOnErrCh(ctx, cancel, vppErrCh)
-
- var fn func(context.Context, api.Connection) error
- switch vppConfig.Variant {
- case "srv":
- fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1)
- case "srv-with-preset-hw-addr":
- fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1, "00:00:5e:00:53:01")
- case "cln":
- fallthrough
- default:
- fn = configure2vethsTopo("vppcln", "10.10.10.2/24", "2", 2)
- }
- err = fn(ctx, con)
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("configuration failed"))
- }
- writeSyncFile(OkResult())
- <-ctx.Done()
- return nil
-}
-
-func configureAfPacket(ctx context.Context, vppCon api.Connection,
- name, interfaceAddress string, optionalHardwareAddress ...string) (interface_types.InterfaceIndex, error) {
- var err error
- ifaceClient := interfaces.NewServiceClient(vppCon)
- afPacketCreate := af_packet.AfPacketCreateV2{
- UseRandomHwAddr: true,
- HostIfName: name,
- NumRxQueues: 1,
- }
- if len(optionalHardwareAddress) > 0 {
- afPacketCreate.HwAddr, err = ethernet_types.ParseMacAddress(optionalHardwareAddress[0])
- if err != nil {
- fmt.Printf("failed to parse mac address: %v", err)
- return 0, err
- }
- afPacketCreate.UseRandomHwAddr = false
- }
- afPacketCreateRsp, err := af_packet.NewServiceClient(vppCon).AfPacketCreateV2(ctx, &afPacketCreate)
- if err != nil {
- fmt.Printf("failed to create af packet: %v", err)
- return 0, err
- }
- _, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
- SwIfIndex: afPacketCreateRsp.SwIfIndex,
- Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
- })
- if err != nil {
- fmt.Printf("set interface state up failed: %v\n", err)
- return 0, err
- }
- ipPrefix, err := ip_types.ParseAddressWithPrefix(interfaceAddress)
- if err != nil {
- fmt.Printf("parse ip address %v\n", err)
- return 0, err
- }
- ipAddress := &interfaces.SwInterfaceAddDelAddress{
- IsAdd: true,
- SwIfIndex: afPacketCreateRsp.SwIfIndex,
- Prefix: ipPrefix,
- }
- _, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
- if errx != nil {
- fmt.Printf("add ip address %v\n", err)
- return 0, err
- }
- return afPacketCreateRsp.SwIfIndex, nil
-}
-
-func (a *Actions) ConfigureHttpTps(args []string) *ActionResult {
- ctx, cancel := newVppContext()
- defer cancel()
- con, vppErrCh := vpphelper.StartAndDialContext(ctx,
- vpphelper.WithVppConfig(configTemplate))
- exitOnErrCh(ctx, cancel, vppErrCh)
-
- confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
- err := confFn(ctx, con)
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("configuration failed"))
- }
-
- _, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
- IsEnable: true,
- })
- if err != nil {
- return NewActionResult(err, ActionResultWithDesc("configuration failed"))
- }
- Vppcli("", "http tps uri tcp://0.0.0.0/8080")
- writeSyncFile(OkResult())
- <-ctx.Done()
- return nil
-}
-
func (a *Actions) ConfigureTap(args []string) *ActionResult {
var startup Stanza
startup.
diff --git a/extras/hs-test/container.go b/extras/hs-test/container.go
index 91ca2c2b0b1..cc2d441f7ec 100644
--- a/extras/hs-test/container.go
+++ b/extras/hs-test/container.go
@@ -84,6 +84,10 @@ func NewContainer(yamlInput ContainerConfig) (*Container, error) {
return container, nil
}
+func (c *Container) Suite() *HstSuite {
+ return c.suite
+}
+
func (c *Container) getWorkDirVolume() (res Volume, exists bool) {
for _, v := range c.volumes {
if v.isDefaultWorkDir {
@@ -227,14 +231,22 @@ func (c *Container) createFile(destFileName string, content string) error {
* Executes in detached mode so that the started application can continue to run
* without blocking execution of test
*/
-func (c *Container) execServer(command string) error {
- return exechelper.Run("docker exec -d" + c.getEnvVarsAsCliOption() + " " + c.name + " " + command)
+func (c *Container) execServer(command string, arguments ...any) {
+ serverCommand := fmt.Sprintf(command, arguments...)
+ containerExecCommand := "docker exec -d" + c.getEnvVarsAsCliOption() +
+ " " + c.name + " " + serverCommand
+ c.Suite().log(containerExecCommand)
+ c.Suite().assertNil(exechelper.Run(containerExecCommand))
}
-func (c *Container) exec(command string) (string, error) {
- cliCommand := "docker exec" + c.getEnvVarsAsCliOption() + " " + c.name + " " + command
- byteOutput, err := exechelper.CombinedOutput(cliCommand)
- return string(byteOutput), err
+func (c *Container) exec(command string, arguments ...any) string {
+ cliCommand := fmt.Sprintf(command, arguments...)
+ containerExecCommand := "docker exec" + c.getEnvVarsAsCliOption() +
+ " " + c.name + " " + cliCommand
+ c.Suite().log(containerExecCommand)
+ byteOutput, err := exechelper.CombinedOutput(containerExecCommand)
+ c.Suite().assertNil(err)
+ return string(byteOutput)
}
func (c *Container) execAction(args string) (string, error) {
diff --git a/extras/hs-test/echo_test.go b/extras/hs-test/echo_test.go
index 1b24e08466d..b32d66ee533 100644
--- a/extras/hs-test/echo_test.go
+++ b/extras/hs-test/echo_test.go
@@ -2,18 +2,16 @@ package main
func (s *VethsSuite) TestEchoBuiltin() {
serverVpp := s.getContainerByName("server-vpp").vppInstance
- serverVeth := s.veths["vppsrv"]
+ serverVeth := s.netInterfaces["vppsrv"]
- _, err := serverVpp.vppctl("test echo server " +
+ serverVpp.vppctl("test echo server " +
" private-segment-size 1g fifo-size 4 no-echo" +
- " uri tcp://" + serverVeth.Address() + "/1234")
- s.assertNil(err)
+ " uri tcp://" + serverVeth.Ip4AddressString() + "/1234")
clientVpp := s.getContainerByName("client-vpp").vppInstance
- o, err := clientVpp.vppctl("test echo client nclients 10000 bytes 1" +
+ o := clientVpp.vppctl("test echo client nclients 10000 bytes 1" +
" syn-timeout 100 test-timeout 100 no-return private-segment-size 1g" +
- " fifo-size 4 uri tcp://" + serverVeth.Address() + "/1234")
- s.assertNil(err)
+ " fifo-size 4 uri tcp://" + serverVeth.Ip4AddressString() + "/1234")
s.log(o)
}
diff --git a/extras/hs-test/hst_suite.go b/extras/hs-test/hst_suite.go
index 9cf38d95895..24b4fc242d4 100644
--- a/extras/hs-test/hst_suite.go
+++ b/extras/hs-test/hst_suite.go
@@ -8,10 +8,13 @@ import (
"github.com/edwarnicke/exechelper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
- "go.fd.io/govpp/binapi/ip_types"
"gopkg.in/yaml.v3"
)
+const (
+ defaultNamespaceName string = "default"
+)
+
func IsPersistent() bool {
return os.Getenv("HST_PERSIST") == "1"
}
@@ -22,14 +25,12 @@ func IsVerbose() bool {
type HstSuite struct {
suite.Suite
- teardownSuite func()
- containers map[string]*Container
- volumes []string
- networkNamespaces map[string]*NetworkNamespace
- veths map[string]*NetworkInterfaceVeth
- taps map[string]*NetworkInterfaceTap
- bridges map[string]*NetworkBridge
- numberOfAddresses int
+ teardownSuite func()
+ containers map[string]*Container
+ volumes []string
+ netConfigs []NetConfig
+ netInterfaces map[string]NetInterface
+ addresser *Addresser
}
func (s *HstSuite) TearDownSuite() {
@@ -138,9 +139,11 @@ func (s *HstSuite) getContainerByName(name string) *Container {
return s.containers[name]
}
-func (s *HstSuite) getContainerCopyByName(name string) *Container {
- // Create a copy and return its address, so that individial tests which call this
- // are not able to modify the original container and affect other tests by doing that
+/*
+ * Create a copy and return its address, so that individial tests which call this
+ * are not able to modify the original container and affect other tests by doing that
+ */
+func (s *HstSuite) getTransientContainerByName(name string) *Container {
containerCopy := *s.containers[name]
return &containerCopy
}
@@ -185,32 +188,32 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) {
s.T().Fatalf("unmarshal error: %v", err)
}
- s.networkNamespaces = make(map[string]*NetworkNamespace)
- s.veths = make(map[string]*NetworkInterfaceVeth)
- s.taps = make(map[string]*NetworkInterfaceTap)
- s.bridges = make(map[string]*NetworkBridge)
+ s.addresser = NewAddresser(s)
+ s.netInterfaces = make(map[string]NetInterface)
for _, elem := range yamlTopo.Devices {
switch elem["type"].(string) {
case NetNs:
{
if namespace, err := NewNetNamespace(elem); err == nil {
- s.networkNamespaces[namespace.Name()] = &namespace
+ s.netConfigs = append(s.netConfigs, &namespace)
} else {
s.T().Fatalf("network config error: %v", err)
}
}
case Veth:
{
- if veth, err := NewVeth(elem); err == nil {
- s.veths[veth.Name()] = &veth
+ if veth, err := NewVeth(elem, s.addresser); err == nil {
+ s.netConfigs = append(s.netConfigs, &veth)
+ s.netInterfaces[veth.Name()] = &veth
} else {
s.T().Fatalf("network config error: %v", err)
}
}
case Tap:
{
- if tap, err := NewTap(elem); err == nil {
- s.taps[tap.Name()] = &tap
+ if tap, err := NewTap(elem, s.addresser); err == nil {
+ s.netConfigs = append(s.netConfigs, &tap)
+ s.netInterfaces[tap.Name()] = &tap
} else {
s.T().Fatalf("network config error: %v", err)
}
@@ -218,7 +221,7 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) {
case Bridge:
{
if bridge, err := NewBridge(elem); err == nil {
- s.bridges[bridge.Name()] = &bridge
+ s.netConfigs = append(s.netConfigs, &bridge)
} else {
s.T().Fatalf("network config error: %v", err)
}
@@ -230,23 +233,8 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) {
func (s *HstSuite) configureNetworkTopology(topologyName string) {
s.loadNetworkTopology(topologyName)
- for _, ns := range s.networkNamespaces {
- if err := ns.Configure(); err != nil {
- s.T().Fatalf("network config error: %v", err)
- }
- }
- for _, veth := range s.veths {
- if err := veth.Configure(); err != nil {
- s.T().Fatalf("network config error: %v", err)
- }
- }
- for _, tap := range s.taps {
- if err := tap.Configure(); err != nil {
- s.T().Fatalf("network config error: %v", err)
- }
- }
- for _, bridge := range s.bridges {
- if err := bridge.Configure(); err != nil {
+ for _, nc := range s.netConfigs {
+ if err := nc.Configure(); err != nil {
s.T().Fatalf("network config error: %v", err)
}
}
@@ -256,34 +244,52 @@ func (s *HstSuite) unconfigureNetworkTopology() {
if IsPersistent() {
return
}
- for _, ns := range s.networkNamespaces {
- ns.Unconfigure()
- }
- for _, veth := range s.veths {
- veth.Unconfigure()
- }
- for _, tap := range s.taps {
- tap.Unconfigure()
- }
- for _, bridge := range s.bridges {
- bridge.Unconfigure()
+ for _, nc := range s.netConfigs {
+ nc.Unconfigure()
}
}
-func (s *HstSuite) NewAddress() (AddressWithPrefix, error) {
- var ipPrefix AddressWithPrefix
- var err error
+type NamespaceAddresses struct {
+ namespace string
+ numberOfAddresses int
+}
- if s.numberOfAddresses == 255 {
- s.T().Fatalf("no available IPv4 addresses")
+type Addresser struct {
+ namespaces []*NamespaceAddresses
+ suite *HstSuite
+}
+
+func (a *Addresser) AddNamespace(name string) {
+ var newNamespace = &NamespaceAddresses{
+ namespace: name,
+ numberOfAddresses: 0,
}
+ a.namespaces = append(a.namespaces, newNamespace)
+}
- address := fmt.Sprintf("10.10.10.%v/24", s.numberOfAddresses+1)
- ipPrefix, err = ip_types.ParseAddressWithPrefix(address)
- if err != nil {
- return AddressWithPrefix{}, err
+func (a *Addresser) NewIp4Address() (string, error) {
+ return a.NewIp4AddressWithNamespace(defaultNamespaceName)
+}
+
+func (a *Addresser) NewIp4AddressWithNamespace(namespace string) (string, error) {
+ for i, val := range a.namespaces {
+ if val.namespace != namespace {
+ continue
+ }
+ if val.numberOfAddresses == 255 {
+ return "", fmt.Errorf("no available IPv4 addresses")
+ }
+ address := fmt.Sprintf("10.10.%v.%v/24", i, val.numberOfAddresses+1)
+ val.numberOfAddresses++
+ return address, nil
}
- s.numberOfAddresses++
+ a.AddNamespace(namespace)
+ return a.NewIp4AddressWithNamespace(namespace)
+}
- return ipPrefix, nil
+func NewAddresser(suite *HstSuite) *Addresser {
+ var addresser = new(Addresser)
+ addresser.suite = suite
+ addresser.AddNamespace(defaultNamespaceName)
+ return addresser
}
diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go
index 52b7c39fa77..912c98283b1 100644
--- a/extras/hs-test/http_test.go
+++ b/extras/hs-test/http_test.go
@@ -9,21 +9,19 @@ import (
)
func (s *NsSuite) TestHttpTps() {
- finished := make(chan error, 1)
- server_ip := "10.0.0.2"
+ iface := s.netInterfaces[clientInterface]
+ client_ip := iface.Ip4AddressString()
port := "8080"
+ finished := make(chan error, 1)
container := s.getContainerByName("vpp")
- s.log("starting vpp..")
-
- // start & configure vpp in the container
- _, err := container.execAction("ConfigureHttpTps")
- s.assertNil(err)
+ // configure vpp in the container
+ container.vppInstance.vppctl("http tps uri tcp://0.0.0.0/8080")
- go startWget(finished, server_ip, port, "test_file_10M", "client")
+ go startWget(finished, client_ip, port, "test_file_10M", "client")
// wait for client
- err = <-finished
+ err := <-finished
s.assertNil(err)
}
@@ -31,16 +29,14 @@ func (s *VethsSuite) TestHttpCli() {
serverContainer := s.getContainerByName("server-vpp")
clientContainer := s.getContainerByName("client-vpp")
- serverVeth := s.veths["vppsrv"]
+ serverVeth := s.netInterfaces[serverInterfaceName]
- _, err := serverContainer.vppInstance.vppctl("http cli server")
- s.assertNil(err)
+ serverContainer.vppInstance.vppctl("http cli server")
- uri := "http://" + serverVeth.Address() + "/80"
+ uri := "http://" + serverVeth.Ip4AddressString() + "/80"
- o, err := clientContainer.vppInstance.vppctl("http cli client" +
+ o := clientContainer.vppInstance.vppctl("http cli client" +
" uri " + uri + " query /show/version")
- s.assertNil(err)
s.log(o)
s.assertContains(o, "<html>", "<html> not found in the result!")
@@ -48,10 +44,7 @@ func (s *VethsSuite) TestHttpCli() {
func waitForApp(vppInst *VppInstance, appName string, timeout int) error {
for i := 0; i < timeout; i++ {
- o, err := vppInst.vppctl("show app")
- if err != nil {
- return fmt.Errorf("Error ocurred during 'show app'")
- }
+ o := vppInst.vppctl("show app")
if strings.Contains(o, appName) {
return nil
}
diff --git a/extras/hs-test/ldp_test.go b/extras/hs-test/ldp_test.go
index cbba227c328..17f78ca4db3 100644
--- a/extras/hs-test/ldp_test.go
+++ b/extras/hs-test/ldp_test.go
@@ -3,17 +3,16 @@ package main
import (
"fmt"
"os"
- "time"
)
func (s *VethsSuite) TestLDPreloadIperfVpp() {
var clnVclConf, srvVclConf Stanza
serverContainer := s.getContainerByName("server-vpp")
- srvVcl := serverContainer.GetHostWorkDir() + "/vcl_srv.conf"
+ serverVclFileName := serverContainer.GetHostWorkDir() + "/vcl_srv.conf"
clientContainer := s.getContainerByName("client-vpp")
- clnVcl := clientContainer.GetHostWorkDir() + "/vcl_cln.conf"
+ clientVclFileName := clientContainer.GetHostWorkDir() + "/vcl_cln.conf"
ldpreload := os.Getenv("HST_LDPRELOAD")
s.assertNotEqual("", ldpreload)
@@ -26,15 +25,9 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
s.log("starting VPPs")
- _, err := serverContainer.execAction("Configure2Veths srv")
- s.assertNil(err)
-
- _, err = clientContainer.execAction("Configure2Veths cln")
- s.assertNil(err)
-
clientAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/2",
clientContainer.GetContainerWorkDir())
- err = clnVclConf.
+ err := clnVclConf.
NewStanza("vcl").
Append("rx-fifo-size 4000000").
Append("tx-fifo-size 4000000").
@@ -42,7 +35,7 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
Append("app-scope-global").
Append("use-mq-eventfd").
Append(clientAppSocketApi).Close().
- SaveToFile(clnVcl)
+ SaveToFile(clientVclFileName)
s.assertNil(err)
serverAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/1",
@@ -55,15 +48,12 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
Append("app-scope-global").
Append("use-mq-eventfd").
Append(serverAppSocketApi).Close().
- SaveToFile(srvVcl)
+ SaveToFile(serverVclFileName)
s.assertNil(err)
s.log("attaching server to vpp")
- // FIXME
- time.Sleep(5 * time.Second)
-
- srvEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+srvVcl)
+ srvEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+serverVclFileName)
go StartServerApp(srvCh, stopServerCh, srvEnv)
err = <-srvCh
@@ -71,8 +61,9 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
s.log("attaching client to vpp")
var clnRes = make(chan string, 1)
- clnEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+clnVcl)
- go StartClientApp(clnEnv, clnCh, clnRes)
+ clnEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+clientVclFileName)
+ serverVethAddress := s.netInterfaces[serverInterfaceName].Ip4AddressString()
+ go StartClientApp(serverVethAddress, clnEnv, clnCh, clnRes)
s.log(<-clnRes)
// wait for client's result
diff --git a/extras/hs-test/linux_iperf_test.go b/extras/hs-test/linux_iperf_test.go
index 833fb2c2c4a..154a9b543b9 100644
--- a/extras/hs-test/linux_iperf_test.go
+++ b/extras/hs-test/linux_iperf_test.go
@@ -13,7 +13,9 @@ func (s *TapSuite) TestLinuxIperf() {
err := <-srvCh
s.assertNil(err)
s.log("server running")
- go StartClientApp(nil, clnCh, clnRes)
+
+ ipAddress := s.netInterfaces["tap0"].Ip4AddressString()
+ go StartClientApp(ipAddress, nil, clnCh, clnRes)
s.log("client running")
s.log(<-clnRes)
err = <-clnCh
diff --git a/extras/hs-test/main.go b/extras/hs-test/main.go
index 98627a53e12..8fa1458767d 100644
--- a/extras/hs-test/main.go
+++ b/extras/hs-test/main.go
@@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"os"
- "os/exec"
"os/signal"
"reflect"
)
@@ -20,16 +19,6 @@ func newVppContext() (context.Context, context.CancelFunc) {
return ctx, cancel
}
-func Vppcli(runDir, command string) (string, error) {
- cmd := exec.Command("vppctl", "-s", fmt.Sprintf("%s/var/run/vpp/cli.sock", runDir), command)
- o, err := cmd.CombinedOutput()
- if err != nil {
- fmt.Printf("failed to execute command: '%v'.\n", err)
- }
- fmt.Printf("Command output %s", string(o))
- return string(o), err
-}
-
func exitOnErrCh(ctx context.Context, cancel context.CancelFunc, errCh <-chan error) {
// If we already have an error, log it and exit
select {
diff --git a/extras/hs-test/netconfig.go b/extras/hs-test/netconfig.go
index b93e460b44d..45ff3790eaf 100644
--- a/extras/hs-test/netconfig.go
+++ b/extras/hs-test/netconfig.go
@@ -12,35 +12,56 @@ import (
)
type (
- AddressWithPrefix = ip_types.AddressWithPrefix
MacAddress = ethernet_types.MacAddress
+ AddressWithPrefix = ip_types.AddressWithPrefix
+ InterfaceIndex = interface_types.InterfaceIndex
- NetConfig struct {
+ LegacyNetConfig struct {
Configure func() error
Unconfigure func()
}
- NetTopology []NetConfig
+ NetTopology []LegacyNetConfig
+
+ NetConfig interface {
+ Configure() error
+ Unconfigure()
+ Name() string
+ Type() string
+ }
NetConfigBase struct {
name string
category string // what else to call this when `type` is reserved?
}
- NetworkInterfaceVeth struct {
+ NetInterface interface {
+ NetConfig
+ SetAddress(string)
+ Ip4AddressWithPrefix() AddressWithPrefix
+ Ip4AddressString() string
+ SetIndex(InterfaceIndex)
+ Index() InterfaceIndex
+ HwAddress() MacAddress
+ }
+
+ NetInterfaceBase struct {
NetConfigBase
- index interface_types.InterfaceIndex
+ addresser *Addresser
+ ip4address string // this will have form 10.10.10.1/24
+ index InterfaceIndex
+ hwAddress MacAddress
+ }
+
+ NetworkInterfaceVeth struct {
+ NetInterfaceBase
peerNetworkNamespace string
peerName string
peerIp4Address string
- ip4Address ip_types.AddressWithPrefix
- hwAddress ethernet_types.MacAddress
}
NetworkInterfaceTap struct {
- NetConfigBase
- index interface_types.InterfaceIndex
- ip4Address string
+ NetInterfaceBase
}
NetworkNamespace struct {
@@ -61,15 +82,40 @@ const (
Bridge string = "bridge"
)
-func (b NetConfigBase) Name() string {
+func (b *NetConfigBase) Name() string {
return b.name
}
-func (b NetConfigBase) Type() string {
+func (b *NetConfigBase) Type() string {
return b.category
}
-func (iface NetworkInterfaceVeth) Configure() error {
+func (b *NetInterfaceBase) SetAddress(address string) {
+ b.ip4address = address
+}
+
+func (b *NetInterfaceBase) SetIndex(index InterfaceIndex) {
+ b.index = index
+}
+
+func (b *NetInterfaceBase) Index() InterfaceIndex {
+ return b.index
+}
+
+func (b *NetInterfaceBase) Ip4AddressWithPrefix() AddressWithPrefix {
+ address, _ := ip_types.ParseAddressWithPrefix(b.ip4address)
+ return address
+}
+
+func (b *NetInterfaceBase) Ip4AddressString() string {
+ return strings.Split(b.ip4address, "/")[0]
+}
+
+func (b *NetInterfaceBase) HwAddress() MacAddress {
+ return b.hwAddress
+}
+
+func (iface *NetworkInterfaceVeth) Configure() error {
err := AddVethPair(iface.name, iface.peerName)
if err != nil {
return err
@@ -91,39 +137,39 @@ func (iface NetworkInterfaceVeth) Configure() error {
return nil
}
-func (iface NetworkInterfaceVeth) Unconfigure() {
+func (iface *NetworkInterfaceVeth) Unconfigure() {
DelLink(iface.name)
}
-func (iface NetworkInterfaceVeth) Address() string {
- return strings.Split(iface.ip4Address.String(), "/")[0]
+func (iface *NetworkInterfaceVeth) PeerIp4AddressString() string {
+ return strings.Split(iface.peerIp4Address, "/")[0]
}
-func (iface NetworkInterfaceTap) Configure() error {
- err := AddTap(iface.name, iface.ip4Address)
+func (iface *NetworkInterfaceTap) Configure() error {
+ err := AddTap(iface.name, iface.Ip4AddressString())
if err != nil {
return err
}
return nil
}
-func (iface NetworkInterfaceTap) Unconfigure() {
+func (iface *NetworkInterfaceTap) Unconfigure() {
DelLink(iface.name)
}
-func (ns NetworkNamespace) Configure() error {
+func (ns *NetworkNamespace) Configure() error {
return addDelNetns(ns.name, true)
}
-func (ns NetworkNamespace) Unconfigure() {
+func (ns *NetworkNamespace) Unconfigure() {
addDelNetns(ns.name, false)
}
-func (b NetworkBridge) Configure() error {
+func (b *NetworkBridge) Configure() error {
return AddBridge(b.name, b.interfaces, b.networkNamespace)
}
-func (b NetworkBridge) Unconfigure() {
+func (b *NetworkBridge) Unconfigure() {
DelBridge(b.name, b.networkNamespace)
}
@@ -176,8 +222,6 @@ func newConfigFn(cfg NetDevConfig) func() error {
}
} else if t == "bridge" {
return func() error { return configureBridge(cfg) }
- } else if t == "tap" {
- return func() error { return configureTap(cfg) }
}
return nil
}
@@ -186,9 +230,7 @@ func newUnconfigFn(cfg NetDevConfig) func() {
t := cfg["type"]
name := cfg["name"].(string)
- if t == "tap" {
- return func() { DelLink(name) }
- } else if t == "netns" {
+ if t == "netns" {
return func() { DelNetns(name) }
} else if t == "veth" {
return func() { DelLink(name) }
@@ -198,8 +240,8 @@ func newUnconfigFn(cfg NetDevConfig) func() {
return nil
}
-func NewNetConfig(cfg NetDevConfig) NetConfig {
- var nc NetConfig
+func NewNetConfig(cfg NetDevConfig) LegacyNetConfig {
+ var nc LegacyNetConfig
nc.Configure = newConfigFn(cfg)
nc.Unconfigure = newUnconfigFn(cfg)
@@ -225,9 +267,10 @@ func NewBridge(cfg NetDevConfig) (NetworkBridge, error) {
return bridge, nil
}
-func NewVeth(cfg NetDevConfig) (NetworkInterfaceVeth, error) {
+func NewVeth(cfg NetDevConfig, a *Addresser) (NetworkInterfaceVeth, error) {
var veth NetworkInterfaceVeth
var err error
+ veth.addresser = a
veth.name = cfg["name"].(string)
veth.category = "veth"
@@ -246,18 +289,27 @@ func NewVeth(cfg NetDevConfig) (NetworkInterfaceVeth, error) {
veth.peerNetworkNamespace = peer["netns"].(string)
}
- if peer["ip4"] != nil {
- veth.peerIp4Address = peer["ip4"].(string)
+ if peer["ip4"] != nil && peer["ip4"].(bool) == true {
+ veth.peerIp4Address, err = veth.addresser.
+ NewIp4AddressWithNamespace(veth.peerNetworkNamespace)
+ if err != nil {
+ return NetworkInterfaceVeth{}, err
+ }
}
return veth, nil
}
-func NewTap(cfg NetDevConfig) (NetworkInterfaceTap, error) {
+func NewTap(cfg NetDevConfig, a *Addresser) (NetworkInterfaceTap, error) {
var tap NetworkInterfaceTap
+ tap.addresser = a
tap.name = cfg["name"].(string)
tap.category = "tap"
- tap.ip4Address = cfg["ip4"].(string)
+ ip4Address, err := tap.addresser.NewIp4Address()
+ if err != nil {
+ return NetworkInterfaceTap{}, err
+ }
+ tap.SetAddress(ip4Address)
return tap, nil
}
diff --git a/extras/hs-test/proxy_test.go b/extras/hs-test/proxy_test.go
index f592426cf47..4c183517c37 100644
--- a/extras/hs-test/proxy_test.go
+++ b/extras/hs-test/proxy_test.go
@@ -18,7 +18,7 @@ func testProxyHttpTcp(s *NsSuite) error {
s.assertNil(err, "failed to run truncate command")
defer func() { os.Remove(srcFile) }()
- s.log("Test file created...")
+ s.log("test file created...")
go startHttpServer(serverRunning, stopServer, ":666", "server")
// TODO better error handling and recovery
@@ -30,7 +30,15 @@ func testProxyHttpTcp(s *NsSuite) error {
s.log("http server started...")
- c := fmt.Sprintf("ip netns exec client wget --no-proxy --retry-connrefused --retry-on-http-error=503 --tries=10 -O %s 10.0.0.2:555/%s", outputFile, srcFile)
+ clientVeth := s.netInterfaces[clientInterface]
+ c := fmt.Sprintf("ip netns exec client wget --no-proxy --retry-connrefused"+
+ " --retry-on-http-error=503 --tries=10"+
+ " -O %s %s:555/%s",
+ outputFile,
+ clientVeth.Ip4AddressString(),
+ srcFile,
+ )
+ s.log(c)
_, err = exechelper.CombinedOutput(c)
s.assertNil(err, "failed to run wget")
stopServer <- struct{}{}
@@ -42,16 +50,17 @@ func testProxyHttpTcp(s *NsSuite) error {
}
func configureVppProxy(s *NsSuite) error {
- container := s.getContainerByName("vpp")
- testVppProxy := NewVppInstance(container)
- testVppProxy.setVppProxy()
- err := testVppProxy.start()
- s.assertNil(err, "failed to start and configure VPP")
- s.log("VPP running and configured...")
-
- output, err := testVppProxy.vppctl("test proxy server server-uri tcp://10.0.0.2/555 client-uri tcp://10.0.1.1/666")
- s.log("Proxy configured...", string(output))
- return err
+ serverVeth := s.netInterfaces[serverInterface].(*NetworkInterfaceVeth)
+ clientVeth := s.netInterfaces[clientInterface]
+
+ testVppProxy := s.getContainerByName("vpp").vppInstance
+ output := testVppProxy.vppctl(
+ "test proxy server server-uri tcp://%s/555 client-uri tcp://%s/666",
+ clientVeth.Ip4AddressString(),
+ serverVeth.PeerIp4AddressString(),
+ )
+ s.log("proxy configured...", output)
+ return nil
}
func (s *NsSuite) TestVppProxyHttpTcp() {
@@ -62,12 +71,6 @@ func (s *NsSuite) TestVppProxyHttpTcp() {
}
func configureEnvoyProxy(s *NsSuite) error {
- vppContainer := s.getContainerByName("vpp")
- testVppForEnvoyProxy := NewVppInstance(vppContainer)
- testVppForEnvoyProxy.setEnvoyProxy()
- err := testVppForEnvoyProxy.start()
- s.assertNil(err, "failed to start and configure VPP")
-
envoyContainer := s.getContainerByName("envoy")
return envoyContainer.run()
}
diff --git a/extras/hs-test/resources/envoy/proxy.yaml b/extras/hs-test/resources/envoy/proxy.yaml
index e4a5b81ff65..2093b5613ae 100644
--- a/extras/hs-test/resources/envoy/proxy.yaml
+++ b/extras/hs-test/resources/envoy/proxy.yaml
@@ -43,7 +43,8 @@ static_resources:
- endpoint:
address:
socket_address:
- address: 10.0.1.1
+ # following address will be generated by Addresser during test run
+ address: 10.10.2.1
port_value: 666
bootstrap_extensions:
- name: envoy.extensions.vcl.vcl_socket_interface
diff --git a/extras/hs-test/suite_ns_test.go b/extras/hs-test/suite_ns_test.go
index cf7f0ec98f1..5bc45c7f80c 100644
--- a/extras/hs-test/suite_ns_test.go
+++ b/extras/hs-test/suite_ns_test.go
@@ -1,10 +1,45 @@
package main
+const (
+ // These correspond to names used in yaml config
+ clientInterface = "hst_client_vpp"
+ serverInterface = "hst_server_vpp"
+)
+
type NsSuite struct {
HstSuite
}
func (s *NsSuite) SetupSuite() {
- s.teardownSuite = setupSuite(&s.Suite, "ns")
+ s.configureNetworkTopology("ns")
+
s.loadContainerTopology("ns")
}
+
+func (s *NsSuite) SetupTest() {
+ s.SetupVolumes()
+ s.SetupContainers()
+
+ // Setup test conditions
+ var startupConfig Stanza
+ startupConfig.
+ NewStanza("session").
+ Append("enable").
+ Append("use-app-socket-api").
+ Append("evt_qs_memfd_seg").
+ Append("event-queue-length 100000").Close()
+
+ container := s.getContainerByName("vpp")
+ vpp, _ := container.newVppInstance(startupConfig)
+ vpp.start()
+
+ idx, err := vpp.createAfPacket(s.netInterfaces[serverInterface])
+ s.assertNil(err)
+ s.assertNotEqual(0, idx)
+
+ idx, err = vpp.createAfPacket(s.netInterfaces[clientInterface])
+ s.assertNil(err)
+ s.assertNotEqual(0, idx)
+
+ container.exec("chmod 777 -R %s", container.GetContainerWorkDir())
+}
diff --git a/extras/hs-test/suite_tap_test.go b/extras/hs-test/suite_tap_test.go
index 26f5224d148..96f475c4c5a 100644
--- a/extras/hs-test/suite_tap_test.go
+++ b/extras/hs-test/suite_tap_test.go
@@ -10,5 +10,6 @@ type TapSuite struct {
func (s *TapSuite) SetupSuite() {
time.Sleep(1 * time.Second)
- s.teardownSuite = setupSuite(&s.Suite, "tap")
+
+ s.configureNetworkTopology("tap")
}
diff --git a/extras/hs-test/suite_veth_test.go b/extras/hs-test/suite_veth_test.go
index 81a21a2ce5f..ff79dfae799 100644
--- a/extras/hs-test/suite_veth_test.go
+++ b/extras/hs-test/suite_veth_test.go
@@ -14,13 +14,6 @@ type VethsSuite struct {
HstSuite
}
-var ConvertedTests = map[string]any{
- "TestVeths/TestEchoBuiltin": "",
- "TestVeths/TestHttpCli": "",
- "TestVeths/TestVclEchoTcp": "",
- "TestVeths/TestVclRetryAttach": "",
-}
-
func (s *VethsSuite) SetupSuite() {
time.Sleep(1 * time.Second)
@@ -33,11 +26,6 @@ func (s *VethsSuite) SetupTest() {
s.SetupVolumes()
s.SetupContainers()
- // TODO remove this after all tests are converted to configuration from test suite
- if _, ok := ConvertedTests[s.T().Name()]; !ok {
- return
- }
-
// Setup test conditions
var startupConfig Stanza
@@ -69,7 +57,7 @@ func (s *VethsSuite) setupServerVpp() {
err := serverVpp.start()
s.assertNil(err)
- serverVeth := s.veths["vppsrv"]
+ serverVeth := s.netInterfaces[serverInterfaceName]
idx, err := serverVpp.createAfPacket(serverVeth)
s.assertNil(err)
s.assertNotEqual(0, idx)
@@ -86,7 +74,7 @@ func (s *VethsSuite) setupClientVpp() {
err := clientVpp.start()
s.assertNil(err)
- clientVeth := s.veths["vppcln"]
+ clientVeth := s.netInterfaces[clientInterfaceName]
idx, err := clientVpp.createAfPacket(clientVeth)
s.assertNil(err)
s.assertNotEqual(0, idx)
diff --git a/extras/hs-test/topo-containers/ns.yaml b/extras/hs-test/topo-containers/ns.yaml
index 9416937fdb6..fddf2d8e37a 100644
--- a/extras/hs-test/topo-containers/ns.yaml
+++ b/extras/hs-test/topo-containers/ns.yaml
@@ -1,7 +1,7 @@
---
volumes:
- volume: &shared-vol
- host-dir: shared-vol
+ host-dir: /tmp/shared-vol
# $HST_DIR will be replaced during runtime by path to hs-test directory
containers:
diff --git a/extras/hs-test/topo-network/ns.yaml b/extras/hs-test/topo-network/ns.yaml
index 2f7ed39d2e2..c01836507a6 100644
--- a/extras/hs-test/topo-network/ns.yaml
+++ b/extras/hs-test/topo-network/ns.yaml
@@ -6,16 +6,16 @@ devices:
- name: "server"
type: "netns"
- - name: "vpp0"
+ - name: "hst_client_vpp"
type: "veth"
peer:
name: "client"
netns: "client"
- ip4: "10.0.0.1/24"
+ ip4: true
- - name: "vpp1"
+ - name: "hst_server_vpp"
type: "veth"
peer:
name: "server"
netns: "server"
- ip4: "10.0.1.1/24"
+ ip4: true
diff --git a/extras/hs-test/topo-network/tap.yaml b/extras/hs-test/topo-network/tap.yaml
index 4cd95d6e48a..6f041325987 100644
--- a/extras/hs-test/topo-network/tap.yaml
+++ b/extras/hs-test/topo-network/tap.yaml
@@ -2,4 +2,3 @@
devices:
- name: "tap0"
type: "tap"
- ip4: "10.10.10.1/24"
diff --git a/extras/hs-test/utils.go b/extras/hs-test/utils.go
index cf30ecec4e0..c5889035c40 100644
--- a/extras/hs-test/utils.go
+++ b/extras/hs-test/utils.go
@@ -98,7 +98,7 @@ func StartServerApp(running chan error, done chan struct{}, env []string) {
cmd.Process.Kill()
}
-func StartClientApp(env []string, clnCh chan error, clnRes chan string) {
+func StartClientApp(ipAddress string, env []string, clnCh chan error, clnRes chan string) {
defer func() {
clnCh <- nil
}()
@@ -106,7 +106,7 @@ func StartClientApp(env []string, clnCh chan error, clnRes chan string) {
nTries := 0
for {
- cmd := exec.Command("iperf3", "-c", "10.10.10.1", "-u", "-l", "1460", "-b", "10g")
+ cmd := exec.Command("iperf3", "-c", ipAddress, "-u", "-l", "1460", "-b", "10g")
if env != nil {
cmd.Env = env
}
@@ -183,12 +183,15 @@ func startWget(finished chan error, server_ip, port, query, netNs string) {
finished <- errors.New("wget error")
}()
- cmd := NewCommand([]string{"wget", "--no-proxy", "--tries=5", "-q", "-O", "/dev/null", server_ip + ":" + port + "/" + query},
+ cmd := NewCommand([]string{"wget", "--timeout=10", "--no-proxy", "--tries=5", "-O", "/dev/null", server_ip + ":" + port + "/" + query},
netNs)
o, err := cmd.CombinedOutput()
if err != nil {
finished <- fmt.Errorf("wget error: '%v\n\n%s'", err, o)
return
+ } else if strings.Contains(string(o), "200 OK") == false {
+ finished <- fmt.Errorf("wget error: response not 200 OK")
+ return
}
finished <- nil
}
diff --git a/extras/hs-test/vcl_test.go b/extras/hs-test/vcl_test.go
index 6c809f4caec..b9ce60afbaf 100644
--- a/extras/hs-test/vcl_test.go
+++ b/extras/hs-test/vcl_test.go
@@ -20,7 +20,7 @@ func (s *VethsSuite) TestVclEchoTcp() {
}
func (s *VethsSuite) testVclEcho(proto string) {
- serverVethAddress := s.veths["vppsrv"].Address()
+ serverVethAddress := s.netInterfaces["vppsrv"].Ip4AddressString()
uri := proto + "://" + serverVethAddress + "/12344"
echoSrvContainer := s.getContainerByName("server-application")
@@ -29,8 +29,7 @@ func (s *VethsSuite) testVclEcho(proto string) {
" use-app-socket-api" +
" uri " + uri
s.log(serverCommand)
- err := echoSrvContainer.execServer(serverCommand)
- s.assertNil(err)
+ echoSrvContainer.execServer(serverCommand)
echoClnContainer := s.getContainerByName("client-application")
@@ -38,8 +37,7 @@ func (s *VethsSuite) testVclEcho(proto string) {
" socket-name " + echoClnContainer.GetContainerWorkDir() + "/var/run/app_ns_sockets/2" +
" use-app-socket-api uri " + uri
s.log(clientCommand)
- o, err := echoClnContainer.exec(clientCommand)
- s.assertNil(err)
+ o := echoClnContainer.exec(clientCommand)
s.log(o)
}
@@ -50,7 +48,7 @@ func (s *VethsSuite) TestVclRetryAttach() {
}
func (s *VethsSuite) testRetryAttach(proto string) {
- srvVppContainer := s.getContainerCopyByName("server-vpp")
+ srvVppContainer := s.getTransientContainerByName("server-vpp")
echoSrvContainer := s.getContainerByName("server-application")
@@ -58,31 +56,28 @@ func (s *VethsSuite) testRetryAttach(proto string) {
echoSrvContainer.createFile("/vcl.conf", serverVclConfContent)
echoSrvContainer.addEnvVar("VCL_CONFIG", "/vcl.conf")
- err := echoSrvContainer.execServer("vcl_test_server -p " + proto + " 12346")
- s.assertNil(err)
+ echoSrvContainer.execServer("vcl_test_server -p " + proto + " 12346")
s.log("This whole test case can take around 3 minutes to run. Please be patient.")
s.log("... Running first echo client test, before disconnect.")
- serverVeth := s.veths[serverInterfaceName]
- serverVethAddress := serverVeth.Address()
+ serverVeth := s.netInterfaces[serverInterfaceName]
+ serverVethAddress := serverVeth.Ip4AddressString()
- echoClnContainer := s.getContainerCopyByName("client-application")
+ echoClnContainer := s.getTransientContainerByName("client-application")
clientVclConfContent := fmt.Sprintf(vclTemplate, echoClnContainer.GetContainerWorkDir(), "2")
echoClnContainer.createFile("/vcl.conf", clientVclConfContent)
testClientCommand := "vcl_test_client -U -p " + proto + " " + serverVethAddress + " 12346"
echoClnContainer.addEnvVar("VCL_CONFIG", "/vcl.conf")
- o, err := echoClnContainer.exec(testClientCommand)
+ o := echoClnContainer.exec(testClientCommand)
s.log(o)
- s.assertNil(err)
s.log("... First test ended. Stopping VPP server now.")
// Stop server-vpp-instance, start it again and then run vcl-test-client once more
srvVppContainer.vppInstance.disconnect()
stopVppCommand := "/bin/bash -c 'ps -C vpp_main -o pid= | xargs kill -9'"
- _, err = srvVppContainer.exec(stopVppCommand)
- s.assertNil(err)
+ srvVppContainer.exec(stopVppCommand)
s.setupServerVpp()
@@ -90,47 +85,33 @@ func (s *VethsSuite) testRetryAttach(proto string) {
time.Sleep(30 * time.Second) // Wait a moment for the re-attachment to happen
s.log("... Running second echo client test, after disconnect and re-attachment.")
- o, err = echoClnContainer.exec(testClientCommand)
+ o = echoClnContainer.exec(testClientCommand)
s.log(o)
- s.assertNil(err)
s.log("Done.")
}
func (s *VethsSuite) TestTcpWithLoss() {
- serverContainer := s.getContainerByName("server-vpp")
+ serverVpp := s.getContainerByName("server-vpp").vppInstance
- serverVpp := NewVppInstance(serverContainer)
- s.assertNotNil(serverVpp)
- serverVpp.set2VethsServer()
- err := serverVpp.start()
- s.assertNil(err, "starting VPP failed")
+ serverVeth := s.netInterfaces[serverInterfaceName]
+ serverVpp.vppctl("test echo server uri tcp://%s/20022",
+ serverVeth.Ip4AddressString())
- serverVeth := s.veths[serverInterfaceName]
- _, err = serverVpp.vppctl("test echo server uri tcp://%s/20022", serverVeth.Address())
- s.assertNil(err, "starting echo server failed")
-
- clientContainer := s.getContainerByName("client-vpp")
-
- clientVpp := NewVppInstance(clientContainer)
- s.assertNotNil(clientVpp)
- clientVpp.set2VethsClient()
- err = clientVpp.start()
- s.assertNil(err, "starting VPP failed")
+ clientVpp := s.getContainerByName("client-vpp").vppInstance
// Ensure that VPP doesn't abort itself with NSIM enabled
// Warning: Removing this ping will make the test fail!
- _, err = serverVpp.vppctl("ping 10.10.10.2")
- s.assertNil(err, "ping failed")
+ clientVpp.vppctl("ping %s", serverVeth.Ip4AddressString())
// Add loss of packets with Network Delay Simulator
- _, err = clientVpp.vppctl("set nsim poll-main-thread delay 0.01 ms bandwidth 40 gbit packet-size 1400 packets-per-drop 1000")
- s.assertNil(err, "configuring NSIM failed")
- _, err = clientVpp.vppctl("nsim output-feature enable-disable host-vppcln")
- s.assertNil(err, "enabling NSIM failed")
+ clientVpp.vppctl("set nsim poll-main-thread delay 0.01 ms bandwidth 40 gbit" +
+ " packet-size 1400 packets-per-drop 1000")
+
+ clientVpp.vppctl("nsim output-feature enable-disable host-vppcln")
// Do echo test from client-vpp container
- output, err := clientVpp.vppctl("test echo client uri tcp://10.10.10.1/20022 mbytes 50")
- s.assertNil(err)
+ output := clientVpp.vppctl("test echo client uri tcp://%s/20022 mbytes 50",
+ serverVeth.Ip4AddressString())
s.assertEqual(true, len(output) != 0)
s.assertNotContains(output, "failed: timeout")
s.log(output)
diff --git a/extras/hs-test/vppinstance.go b/extras/hs-test/vppinstance.go
index 3f9ea871565..257798a4f3d 100644
--- a/extras/hs-test/vppinstance.go
+++ b/extras/hs-test/vppinstance.go
@@ -75,14 +75,8 @@ func (vc *VppConfig) getTemplate() string {
return fmt.Sprintf(vppConfigTemplate, "%[1]s", vc.CliSocketFilePath)
}
-func (vpp *VppInstance) set2VethsServer() {
- vpp.actionFuncName = "Configure2Veths"
- vpp.config.Variant = "srv"
-}
-
-func (vpp *VppInstance) set2VethsClient() {
- vpp.actionFuncName = "Configure2Veths"
- vpp.config.Variant = "cln"
+func (vpp *VppInstance) Suite() *HstSuite {
+ return vpp.container.suite
}
func (vpp *VppInstance) setVppProxy() {
@@ -114,10 +108,6 @@ func (vpp *VppInstance) getEtcDir() string {
}
func (vpp *VppInstance) legacyStart() error {
- if vpp.actionFuncName == "" {
- return fmt.Errorf("vpp start failed: action function name must not be blank")
- }
-
serializedConfig, err := serializeVppConfig(vpp.config)
if err != nil {
return fmt.Errorf("serialize vpp config: %v", err)
@@ -149,9 +139,7 @@ func (vpp *VppInstance) start() error {
vpp.container.createFile(startupFileName, configContent)
// Start VPP
- if err := vpp.container.execServer("vpp -c " + startupFileName); err != nil {
- return err
- }
+ vpp.container.execServer("vpp -c " + startupFileName)
// Connect to VPP and store the connection
sockAddress := vpp.container.GetHostWorkDir() + defaultApiSocketFilePath
@@ -186,16 +174,15 @@ func (vpp *VppInstance) start() error {
return nil
}
-func (vpp *VppInstance) vppctl(command string, arguments ...any) (string, error) {
+func (vpp *VppInstance) vppctl(command string, arguments ...any) string {
vppCliCommand := fmt.Sprintf(command, arguments...)
containerExecCommand := fmt.Sprintf("docker exec --detach=false %[1]s vppctl -s %[2]s %[3]s",
vpp.container.name, vpp.getCliSocket(), vppCliCommand)
+ vpp.Suite().log(containerExecCommand)
output, err := exechelper.CombinedOutput(containerExecCommand)
- if err != nil {
- return "", fmt.Errorf("vppctl failed: %s", err)
- }
+ vpp.Suite().assertNil(err)
- return string(output), nil
+ return string(output)
}
func NewVppInstance(c *Container) *VppInstance {
@@ -228,26 +215,29 @@ func deserializeVppConfig(input string) (VppConfig, error) {
}
func (vpp *VppInstance) createAfPacket(
- veth *NetworkInterfaceVeth,
+ netInterface NetInterface,
) (interface_types.InterfaceIndex, error) {
+ var veth *NetworkInterfaceVeth
+ veth = netInterface.(*NetworkInterfaceVeth)
+
createReq := &af_packet.AfPacketCreateV2{
UseRandomHwAddr: true,
HostIfName: veth.Name(),
}
- if veth.hwAddress != (MacAddress{}) {
+ if veth.HwAddress() != (MacAddress{}) {
createReq.UseRandomHwAddr = false
- createReq.HwAddr = veth.hwAddress
+ createReq.HwAddr = veth.HwAddress()
}
createReply := &af_packet.AfPacketCreateV2Reply{}
if err := vpp.apiChannel.SendRequest(createReq).ReceiveReply(createReply); err != nil {
return 0, err
}
- veth.index = createReply.SwIfIndex
+ veth.SetIndex(createReply.SwIfIndex)
// Set to up
upReq := &interfaces.SwInterfaceSetFlags{
- SwIfIndex: veth.index,
+ SwIfIndex: veth.Index(),
Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
}
upReply := &interfaces.SwInterfaceSetFlagsReply{}
@@ -257,17 +247,29 @@ func (vpp *VppInstance) createAfPacket(
}
// Add address
- if veth.ip4Address == (AddressWithPrefix{}) {
- ipPrefix, err := vpp.container.suite.NewAddress()
- if err != nil {
- return 0, err
+ if veth.Ip4AddressWithPrefix() == (AddressWithPrefix{}) {
+ if veth.peerNetworkNamespace != "" {
+ ip4Address, err := veth.addresser.
+ NewIp4AddressWithNamespace(veth.peerNetworkNamespace)
+ if err == nil {
+ veth.SetAddress(ip4Address)
+ } else {
+ return 0, err
+ }
+ } else {
+ ip4Address, err := veth.addresser.
+ NewIp4Address()
+ if err == nil {
+ veth.SetAddress(ip4Address)
+ } else {
+ return 0, err
+ }
}
- veth.ip4Address = ipPrefix
}
addressReq := &interfaces.SwInterfaceAddDelAddress{
IsAdd: true,
- SwIfIndex: veth.index,
- Prefix: veth.ip4Address,
+ SwIfIndex: veth.Index(),
+ Prefix: veth.Ip4AddressWithPrefix(),
}
addressReply := &interfaces.SwInterfaceAddDelAddressReply{}
@@ -275,7 +277,7 @@ func (vpp *VppInstance) createAfPacket(
return 0, err
}
- return veth.index, nil
+ return veth.Index(), nil
}
func (vpp *VppInstance) addAppNamespace(