hs-test: use relative paths for docker volumes
[vpp.git] / extras / hs-test / hst_suite.go
index d972c9d..7f93b15 100644 (file)
@@ -1,9 +1,12 @@
 package main
 
 import (
+       "errors"
        "flag"
-       "io/ioutil"
+       "fmt"
        "os"
+       "os/exec"
+       "strings"
        "time"
 
        "github.com/edwarnicke/exechelper"
@@ -21,6 +24,7 @@ var isVerbose = flag.Bool("verbose", false, "verbose test output")
 var isUnconfiguring = flag.Bool("unconfigure", false, "remove topology")
 var isVppDebug = flag.Bool("debug", false, "attach gdb to vpp")
 var nConfiguredCpus = flag.Int("cpus", 1, "number of CPUs assigned to vpp")
+var vppSourceFileDir = flag.String("vppsrc", "", "vpp source file directory")
 
 type HstSuite struct {
        suite.Suite
@@ -162,6 +166,20 @@ func (s *HstSuite) SkipIfMultiWorker(args ...any) {
        }
 }
 
+func (s *HstSuite) SkipUnlessExtendedTestsBuilt() {
+       imageName := "hs-test/nginx-http3"
+
+       cmd := exec.Command("docker", "images", imageName)
+       byteOutput, err := cmd.CombinedOutput()
+       if err != nil {
+               s.log("error while searching for docker image")
+               return
+       }
+       if !strings.Contains(string(byteOutput), imageName) {
+               s.skip("extended tests not built")
+       }
+}
+
 func (s *HstSuite) resetContainers() {
        for _, container := range s.containers {
                container.stop()
@@ -190,7 +208,7 @@ func (s *HstSuite) getTransientContainerByName(name string) *Container {
 }
 
 func (s *HstSuite) loadContainerTopology(topologyName string) {
-       data, err := ioutil.ReadFile(containerTopologyDir + topologyName + ".yaml")
+       data, err := os.ReadFile(containerTopologyDir + topologyName + ".yaml")
        if err != nil {
                s.T().Fatalf("read error: %v", err)
        }
@@ -203,13 +221,15 @@ func (s *HstSuite) loadContainerTopology(topologyName string) {
        for _, elem := range yamlTopo.Volumes {
                volumeMap := elem["volume"].(VolumeConfig)
                hostDir := volumeMap["host-dir"].(string)
+               workingVolumeDir := logDir + s.T().Name() + volumeDir
+               volDirReplacer := strings.NewReplacer("$HST_VOLUME_DIR", workingVolumeDir)
+               hostDir = volDirReplacer.Replace(hostDir)
                s.volumes = append(s.volumes, hostDir)
        }
 
        s.containers = make(map[string]*Container)
        for _, elem := range yamlTopo.Containers {
-               newContainer, err := newContainer(elem)
-               newContainer.suite = s
+               newContainer, err := newContainer(s, elem)
                if err != nil {
                        s.T().Fatalf("container config error: %v", err)
                }
@@ -218,7 +238,7 @@ func (s *HstSuite) loadContainerTopology(topologyName string) {
 }
 
 func (s *HstSuite) loadNetworkTopology(topologyName string) {
-       data, err := ioutil.ReadFile(networkTopologyDir + topologyName + ".yaml")
+       data, err := os.ReadFile(networkTopologyDir + topologyName + ".yaml")
        if err != nil {
                s.T().Fatalf("read error: %v", err)
        }
@@ -297,3 +317,81 @@ func (s *HstSuite) getTestId() string {
 
        return s.testIds[testName]
 }
+
+func (s *HstSuite) startServerApp(running chan error, done chan struct{}, env []string) {
+       cmd := exec.Command("iperf3", "-4", "-s")
+       if env != nil {
+               cmd.Env = env
+       }
+       s.log(cmd)
+       err := cmd.Start()
+       if err != nil {
+               msg := fmt.Errorf("failed to start iperf server: %v", err)
+               running <- msg
+               return
+       }
+       running <- nil
+       <-done
+       cmd.Process.Kill()
+}
+
+func (s *HstSuite) startClientApp(ipAddress string, env []string, clnCh chan error, clnRes chan string) {
+       defer func() {
+               clnCh <- nil
+       }()
+
+       nTries := 0
+
+       for {
+               cmd := exec.Command("iperf3", "-c", ipAddress, "-u", "-l", "1460", "-b", "10g")
+               if env != nil {
+                       cmd.Env = env
+               }
+               s.log(cmd)
+               o, err := cmd.CombinedOutput()
+               if err != nil {
+                       if nTries > 5 {
+                               clnCh <- fmt.Errorf("failed to start client app '%s'.\n%s", err, o)
+                               return
+                       }
+                       time.Sleep(1 * time.Second)
+                       nTries++
+                       continue
+               } else {
+                       clnRes <- fmt.Sprintf("Client output: %s", o)
+               }
+               break
+       }
+}
+
+func (s *HstSuite) startHttpServer(running chan struct{}, done chan struct{}, addressPort, netNs string) {
+       cmd := newCommand([]string{"./http_server", addressPort}, netNs)
+       err := cmd.Start()
+       s.log(cmd)
+       if err != nil {
+               fmt.Println("Failed to start http server")
+               return
+       }
+       running <- struct{}{}
+       <-done
+       cmd.Process.Kill()
+}
+
+func (s *HstSuite) startWget(finished chan error, server_ip, port, query, netNs string) {
+       defer func() {
+               finished <- errors.New("wget error")
+       }()
+
+       cmd := newCommand([]string{"wget", "--timeout=10", "--no-proxy", "--tries=5", "-O", "/dev/null", server_ip + ":" + port + "/" + query},
+               netNs)
+       s.log(cmd)
+       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") {
+               finished <- fmt.Errorf("wget error: response not 200 OK")
+               return
+       }
+       finished <- nil
+}