hs-test: add runtime options

Options
 "-p" to not remove topology elements after the test finishes
 "-v" from now on extra output from tests is hidden by default,
      this will show it again

Type: test
Signed-off-by: Maros Ondrejicka <maros.ondrejicka@pantheon.tech>
Change-Id: I626188561c883534e9004d5130ee2a972d12b4e2
This commit is contained in:
Maros Ondrejicka
2022-12-19 20:35:27 +01:00
committed by Florin Coras
parent 8c626b41ea
commit 8753180a80
10 changed files with 95 additions and 62 deletions

View File

@ -71,19 +71,23 @@ func NewContainer(yamlInput ContainerConfig) (*Container, error) {
return container, nil return container, nil
} }
func (c *Container) run() error { func (c *Container) getRunCommand() string {
if c.name == "" {
return fmt.Errorf("create volume failed: container name is blank")
}
exechelper.Run(fmt.Sprintf("mkdir -p /tmp/%s/sync", c.name))
syncPath := fmt.Sprintf(" -v %s:/tmp/sync", c.getSyncPath()) syncPath := fmt.Sprintf(" -v %s:/tmp/sync", c.getSyncPath())
cmd := "docker run --cap-add=all -d --privileged --network host --rm" cmd := "docker run --cap-add=all -d --privileged --network host --rm"
cmd += syncPath cmd += syncPath
cmd += c.getVolumesAsCliOption() cmd += c.getVolumesAsCliOption()
cmd += c.getEnvVarsAsCliOption() cmd += c.getEnvVarsAsCliOption()
cmd += " --name " + c.name + " " + c.image cmd += " --name " + c.name + " " + c.image
fmt.Println(cmd) return cmd
}
func (c *Container) run() error {
if c.name == "" {
return fmt.Errorf("run container failed: name is blank")
}
exechelper.Run(fmt.Sprintf("mkdir -p /tmp/%s/sync", c.name))
cmd := c.getRunCommand()
err := exechelper.Run(cmd) err := exechelper.Run(cmd)
if err != nil { if err != nil {
return fmt.Errorf("container run failed: %s", err) return fmt.Errorf("container run failed: %s", err)

View File

@ -1,9 +1,5 @@
package main package main
import (
"fmt"
)
func (s *VethsSuite) TestEchoBuiltin() { func (s *VethsSuite) TestEchoBuiltin() {
serverContainer := s.getContainerByName("server-vpp") serverContainer := s.getContainerByName("server-vpp")
_, err := serverContainer.execAction("Configure2Veths srv") _, err := serverContainer.execAction("Configure2Veths srv")
@ -18,5 +14,5 @@ func (s *VethsSuite) TestEchoBuiltin() {
o, err := clientContainer.execAction("RunEchoClnInternal nclients 10000 bytes 1 syn-timeout 100 test-timeout 100 no-return private-segment-size 1g fifo-size 4") o, err := clientContainer.execAction("RunEchoClnInternal nclients 10000 bytes 1 syn-timeout 100 test-timeout 100 no-return private-segment-size 1g fifo-size 4")
s.assertNil(err) s.assertNil(err)
fmt.Println(o) s.log(o)
} }

View File

@ -1,9 +1,9 @@
package main package main
import ( import (
"fmt"
"testing" "testing"
"io/ioutil" "io/ioutil"
"os"
"github.com/edwarnicke/exechelper" "github.com/edwarnicke/exechelper"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -11,6 +11,20 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
func IsPersistent() bool {
if os.Getenv("HST_PERSIST") == "1" {
return true
}
return false
}
func IsVerbose() bool {
if os.Getenv("HST_VERBOSE") == "1" {
return true
}
return false
}
type HstSuite struct { type HstSuite struct {
suite.Suite suite.Suite
teardownSuite func() teardownSuite func()
@ -23,6 +37,9 @@ func (s *HstSuite) TearDownSuite() {
} }
func (s *HstSuite) TearDownTest() { func (s *HstSuite) TearDownTest() {
if IsPersistent() {
return
}
s.ResetContainers() s.ResetContainers()
s.RemoveVolumes() s.RemoveVolumes()
} }
@ -30,7 +47,7 @@ func (s *HstSuite) TearDownTest() {
func (s *HstSuite) SetupTest() { func (s *HstSuite) SetupTest() {
for _, volume := range s.volumes { for _, volume := range s.volumes {
cmd := "docker volume create --name=" + volume cmd := "docker volume create --name=" + volume
fmt.Println(cmd) s.log(cmd)
exechelper.Run(cmd) exechelper.Run(cmd)
} }
for _, container := range s.containers { for _, container := range s.containers {
@ -80,22 +97,23 @@ func (s *HstSuite) assertNotContains(testString, contains interface{}, msgAndArg
} }
} }
func (s *HstSuite) log(args ...any) {
if IsVerbose() {
s.T().Log(args...)
}
}
func (s *HstSuite) skip(args ...any) {
s.log(args...)
s.T().SkipNow()
}
func (s *HstSuite) ResetContainers() { func (s *HstSuite) ResetContainers() {
for _, container := range s.containers { for _, container := range s.containers {
container.stop() container.stop()
} }
} }
func (s *HstSuite) NewVolume(name string) error {
err := exechelper.Run(fmt.Sprintf("docker volume create --name=%s", name))
if err != nil {
return err
}
s.volumes = append(s.volumes, name)
return nil
}
func (s *HstSuite) RemoveVolumes() { func (s *HstSuite) RemoveVolumes() {
for _, volumeName := range s.volumes { for _, volumeName := range s.volumes {
cmd := "docker volume rm " + volumeName cmd := "docker volume rm " + volumeName
@ -128,6 +146,7 @@ func (s *HstSuite) loadContainerTopology(topologyName string) {
if err != nil { if err != nil {
s.T().Fatalf("config error: %v", err) s.T().Fatalf("config error: %v", err)
} }
s.log(newContainer.getRunCommand())
s.containers[newContainer.name] = newContainer s.containers[newContainer.name] = newContainer
} }
} }
@ -143,8 +162,10 @@ func setupSuite(s *suite.Suite, topologyName string) func() {
t.Fatalf("failed to configure %s: %v", topologyName, err) t.Fatalf("failed to configure %s: %v", topologyName, err)
} }
t.Logf("topo %s loaded", topologyName)
return func() { return func() {
if IsPersistent() {
return
}
topology.Unconfigure() topology.Unconfigure()
} }
} }

View File

@ -1,14 +1,13 @@
package main package main
func (s *NsSuite) TestHttpTps() { func (s *NsSuite) TestHttpTps() {
t := s.T()
finished := make(chan error, 1) finished := make(chan error, 1)
server_ip := "10.0.0.2" server_ip := "10.0.0.2"
port := "8080" port := "8080"
container := s.getContainerByName("vpp") container := s.getContainerByName("vpp")
t.Log("starting vpp..") s.log("starting vpp..")
// start & configure vpp in the container // start & configure vpp in the container
_, err := container.execAction("ConfigureHttpTps") _, err := container.execAction("ConfigureHttpTps")
@ -21,8 +20,6 @@ func (s *NsSuite) TestHttpTps() {
} }
func (s *VethsSuite) TestHttpCli() { func (s *VethsSuite) TestHttpCli() {
t := s.T()
serverContainer := s.getContainerByName("server-vpp") serverContainer := s.getContainerByName("server-vpp")
clientContainer := s.getContainerByName("client-vpp") clientContainer := s.getContainerByName("client-vpp")
@ -32,12 +29,12 @@ func (s *VethsSuite) TestHttpCli() {
_, err = clientContainer.execAction("Configure2Veths cln") _, err = clientContainer.execAction("Configure2Veths cln")
s.assertNil(err) s.assertNil(err)
t.Log("configured IPs...") s.log("configured IPs...")
_, err = serverContainer.execAction("RunHttpCliSrv") _, err = serverContainer.execAction("RunHttpCliSrv")
s.assertNil(err) s.assertNil(err)
t.Log("configured http server") s.log("configured http server")
o, err := clientContainer.execAction("RunHttpCliCln /show/version") o, err := clientContainer.execAction("RunHttpCliCln /show/version")
s.assertNil(err) s.assertNil(err)

View File

@ -26,7 +26,7 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
srvCh := make(chan error, 1) srvCh := make(chan error, 1)
clnCh := make(chan error) clnCh := make(chan error)
fmt.Println("starting VPPs") s.log("starting VPPs")
originalWorkDir := serverContainer.workDir originalWorkDir := serverContainer.workDir
serverContainer.workDir = serverVolume.containerDir serverContainer.workDir = serverVolume.containerDir
@ -66,7 +66,7 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
SaveToFile(srvVcl) SaveToFile(srvVcl)
s.assertNil(err) s.assertNil(err)
fmt.Printf("attaching server to vpp") s.log("attaching server to vpp")
// FIXME // FIXME
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
@ -77,9 +77,11 @@ func (s *VethsSuite) TestLDPreloadIperfVpp() {
err = <-srvCh err = <-srvCh
s.assertNil(err) s.assertNil(err)
fmt.Println("attaching client to vpp") s.log("attaching client to vpp")
var clnRes = make(chan string, 1)
clnEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+clnVcl) clnEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+clnVcl)
go StartClientApp(clnEnv, clnCh) go StartClientApp(clnEnv, clnCh, clnRes)
s.log(<- clnRes)
// wait for client's result // wait for client's result
err = <-clnCh err = <-clnCh

View File

@ -1,10 +1,10 @@
package main package main
func (s *TapSuite) TestLinuxIperf() { func (s *TapSuite) TestLinuxIperf() {
t := s.T()
clnCh := make(chan error) clnCh := make(chan error)
stopServerCh := make(chan struct{}) stopServerCh := make(chan struct{})
srvCh := make(chan error, 1) srvCh := make(chan error, 1)
clnRes := make(chan string, 1)
defer func() { defer func() {
stopServerCh <- struct{}{} stopServerCh <- struct{}{}
}() }()
@ -12,10 +12,11 @@ func (s *TapSuite) TestLinuxIperf() {
go StartServerApp(srvCh, stopServerCh, nil) go StartServerApp(srvCh, stopServerCh, nil)
err := <-srvCh err := <-srvCh
s.assertNil(err) s.assertNil(err)
t.Log("server running") s.log("server running")
go StartClientApp(nil, clnCh) go StartClientApp(nil, clnCh, clnRes)
t.Log("client running") s.log("client running")
s.log(<- clnRes)
err = <-clnCh err = <-clnCh
s.assertNil(err) s.assertNil(err)
t.Log("Test completed") s.log("Test completed")
} }

View File

@ -20,7 +20,7 @@ func testProxyHttpTcp(s *NsSuite, proxySetup func() error) error {
s.assertNil(err, "failed to run truncate command") s.assertNil(err, "failed to run truncate command")
defer func() { os.Remove(srcFile) }() defer func() { os.Remove(srcFile) }()
fmt.Println("Test file created...") s.log("Test file created...")
go startHttpServer(serverRunning, stopServer, ":666", "server") go startHttpServer(serverRunning, stopServer, ":666", "server")
// TODO better error handling and recovery // TODO better error handling and recovery
@ -30,7 +30,7 @@ func testProxyHttpTcp(s *NsSuite, proxySetup func() error) error {
stopServer <- struct{}{} stopServer <- struct{}{}
}(stopServer) }(stopServer)
fmt.Println("http server started...") s.log("http server started...")
c := fmt.Sprintf("ip netns exec client wget --retry-connrefused --retry-on-http-error=503 --tries=10 -O %s 10.0.0.2:555/%s", outputFile, srcFile) c := fmt.Sprintf("ip netns exec client wget --retry-connrefused --retry-on-http-error=503 --tries=10 -O %s 10.0.0.2:555/%s", outputFile, srcFile)
_, err = exechelper.CombinedOutput(c) _, err = exechelper.CombinedOutput(c)
@ -49,10 +49,10 @@ func configureVppProxy(s *NsSuite) error {
testVppProxy.setVppProxy() testVppProxy.setVppProxy()
err := testVppProxy.start() err := testVppProxy.start()
s.assertNil(err, "failed to start and configure VPP") s.assertNil(err, "failed to start and configure VPP")
fmt.Println("VPP running and configured...") 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") output, err := testVppProxy.vppctl("test proxy server server-uri tcp://10.0.0.2/555 client-uri tcp://10.0.1.1/666")
fmt.Println("Proxy configured...", string(output)) s.log("Proxy configured...", string(output))
return nil return nil
} }
@ -73,7 +73,7 @@ func configureEnvoyProxy(s *NsSuite) error {
envoyContainer := s.getContainerByName("envoy") envoyContainer := s.getContainerByName("envoy")
envoyContainer.run() envoyContainer.run()
fmt.Println("VPP running and configured...") s.log("VPP running and configured...")
return nil return nil
} }

View File

@ -1,4 +1,18 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source vars source vars
for ARG in "$@"
do
if [[ "$ARG" = "-p" ]]
then
export HST_PERSIST=1
shift
elif [[ "$ARG" = "-v" ]]
then
export HST_VERBOSE=1
shift
fi
done
sudo -E go test -buildvcs=false -v $@ sudo -E go test -buildvcs=false -v $@

View File

@ -96,7 +96,7 @@ func StartServerApp(running chan error, done chan struct{}, env []string) {
cmd.Process.Kill() cmd.Process.Kill()
} }
func StartClientApp(env []string, clnCh chan error) { func StartClientApp(env []string, clnCh chan error, clnRes chan string) {
defer func() { defer func() {
clnCh <- nil clnCh <- nil
}() }()
@ -118,7 +118,7 @@ func StartClientApp(env []string, clnCh chan error) {
nTries++ nTries++
continue continue
} else { } else {
fmt.Printf("Client output: %s", o) clnRes <- fmt.Sprintf("Client output: %s", o)
} }
break break
} }
@ -186,10 +186,9 @@ func startWget(finished chan error, server_ip, port string, netNs string) {
netNs) netNs)
o, err := cmd.CombinedOutput() o, err := cmd.CombinedOutput()
if err != nil { if err != nil {
fmt.Printf("wget error: '%s'.\n%s", err, o) finished <- errors.New(fmt.Sprintf("wget error: '%s'.\n%s", err, o))
return return
} }
fmt.Printf("Client output: %s", o)
finished <- nil finished <- nil
} }

View File

@ -1,17 +1,16 @@
package main package main
import ( import (
"fmt"
"time" "time"
) )
func (s *VethsSuite) TestVclEchoQuic() { func (s *VethsSuite) TestVclEchoQuic() {
s.T().Skip("quic test skipping..") s.skip("quic test skipping..")
s.testVclEcho("quic") s.testVclEcho("quic")
} }
func (s *VethsSuite) TestVclEchoUdp() { func (s *VethsSuite) TestVclEchoUdp() {
s.T().Skip("udp echo currently broken in vpp, skipping..") s.skip("udp echo currently broken in vpp, skipping..")
s.testVclEcho("udp") s.testVclEcho("udp")
} }
@ -41,11 +40,11 @@ func (s *VethsSuite) testVclEcho(proto string) {
o, err := echoClnContainer.execAction("RunEchoClient "+proto) o, err := echoClnContainer.execAction("RunEchoClient "+proto)
s.assertNil(err) s.assertNil(err)
fmt.Println(o) s.log(o)
} }
func (s *VethsSuite) TestVclRetryAttach() { func (s *VethsSuite) TestVclRetryAttach() {
s.T().Skip() s.skip()
s.testRetryAttach("tcp") s.testRetryAttach("tcp")
} }
@ -64,12 +63,12 @@ func (s *VethsSuite) testRetryAttach(proto string) {
_, err = echoSrvContainer.execAction("RunVclEchoServer "+proto) _, err = echoSrvContainer.execAction("RunVclEchoServer "+proto)
s.assertNil(err) s.assertNil(err)
fmt.Println("This whole test case can take around 3 minutes to run. Please be patient.") s.log("This whole test case can take around 3 minutes to run. Please be patient.")
fmt.Println("... Running first echo client test, before disconnect.") s.log("... Running first echo client test, before disconnect.")
echoClnContainer := s.getContainerByName("client-application") echoClnContainer := s.getContainerByName("client-application")
_, err = echoClnContainer.execAction("RunVclEchoClient "+proto) _, err = echoClnContainer.execAction("RunVclEchoClient "+proto)
s.assertNil(err) s.assertNil(err)
fmt.Println("... First test ended. Stopping VPP server now.") s.log("... First test ended. Stopping VPP server now.")
// Stop server-vpp-instance, start it again and then run vcl-test-client once more // Stop server-vpp-instance, start it again and then run vcl-test-client once more
stopVppCommand := "/bin/bash -c 'ps -C vpp_main -o pid= | xargs kill -9'" stopVppCommand := "/bin/bash -c 'ps -C vpp_main -o pid= | xargs kill -9'"
@ -82,13 +81,13 @@ func (s *VethsSuite) testRetryAttach(proto string) {
_, err = srvVppContainer.execAction("Configure2Veths srv-with-preset-hw-addr") _, err = srvVppContainer.execAction("Configure2Veths srv-with-preset-hw-addr")
s.assertNil(err) s.assertNil(err)
fmt.Println("... VPP server is starting again, so waiting for a bit.") s.log("... VPP server is starting again, so waiting for a bit.")
time.Sleep(30 * time.Second) // Wait a moment for the re-attachment to happen time.Sleep(30 * time.Second) // Wait a moment for the re-attachment to happen
fmt.Println("... Running second echo client test, after disconnect and re-attachment.") s.log("... Running second echo client test, after disconnect and re-attachment.")
_, err = echoClnContainer.execAction("RunVclEchoClient "+proto) _, err = echoClnContainer.execAction("RunVclEchoClient "+proto)
s.assertNil(err) s.assertNil(err)
fmt.Println("Done.") s.log("Done.")
} }
func (s *VethsSuite) TestTcpWithLoss() { func (s *VethsSuite) TestTcpWithLoss() {
@ -127,5 +126,5 @@ func (s *VethsSuite) TestTcpWithLoss() {
s.assertNil(err) s.assertNil(err)
s.assertEqual(true, len(output) != 0) s.assertEqual(true, len(output) != 0)
s.assertNotContains(output, "failed: timeout") s.assertNotContains(output, "failed: timeout")
fmt.Println(output) s.log(output)
} }