X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=extras%2Fhs-test%2Fhst_suite.go;h=1fcffa42e0045a5ed2366fa465e460bf73ae2732;hb=608d0069d98579b0635be978dea8e316f77a8841;hp=9cd9aea5f24c97cc2f9379207de3dffac801254c;hpb=2ddb2fdaaf1233248c236cbe3d617c90f7fae20e;p=vpp.git diff --git a/extras/hs-test/hst_suite.go b/extras/hs-test/hst_suite.go index 9cd9aea5f24..1fcffa42e00 100644 --- a/extras/hs-test/hst_suite.go +++ b/extras/hs-test/hst_suite.go @@ -1,9 +1,11 @@ package main import ( + "flag" "fmt" "io/ioutil" "os" + "time" "github.com/edwarnicke/exechelper" "github.com/stretchr/testify/assert" @@ -12,24 +14,46 @@ import ( ) const ( - defaultNamespaceName string = "default" + DEFAULT_NETWORK_NUM int = 1 ) -func IsPersistent() bool { - return os.Getenv("HST_PERSIST") == "1" -} - -func IsVerbose() bool { - return os.Getenv("HST_VERBOSE") == "1" -} +var isPersistent = flag.Bool("persist", false, "persists topology config") +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") type HstSuite struct { suite.Suite containers map[string]*Container volumes []string netConfigs []NetConfig - netInterfaces map[string]NetInterface + netInterfaces map[string]*NetInterface addresser *Addresser + testIds map[string]string + cpuAllocator *CpuAllocatorT + cpuContexts []*CpuContext + cpuPerVpp int +} + +func (s *HstSuite) SetupSuite() { + var err error + s.cpuAllocator, err = CpuAllocator() + if err != nil { + s.FailNow("failed to init cpu allocator: %v", err) + } + s.cpuPerVpp = *nConfiguredCpus +} + +func (s *HstSuite) AllocateCpus() []int { + cpuCtx, err := s.cpuAllocator.Allocate(s.cpuPerVpp) + s.assertNil(err) + s.AddCpuContext(cpuCtx) + return cpuCtx.cpus +} + +func (s *HstSuite) AddCpuContext(cpuCtx *CpuContext) { + s.cpuContexts = append(s.cpuContexts, cpuCtx) } func (s *HstSuite) TearDownSuite() { @@ -37,19 +61,29 @@ func (s *HstSuite) TearDownSuite() { } func (s *HstSuite) TearDownTest() { - if IsPersistent() { + if *isPersistent { return } - s.ResetContainers() - s.RemoveVolumes() + for _, c := range s.cpuContexts { + c.Release() + } + s.resetContainers() + s.removeVolumes() +} + +func (s *HstSuite) skipIfUnconfiguring() { + if *isUnconfiguring { + s.skip("skipping to unconfigure") + } } func (s *HstSuite) SetupTest() { - s.SetupVolumes() - s.SetupContainers() + s.skipIfUnconfiguring() + s.setupVolumes() + s.setupContainers() } -func (s *HstSuite) SetupVolumes() { +func (s *HstSuite) setupVolumes() { for _, volume := range s.volumes { cmd := "docker volume create --name=" + volume s.log(cmd) @@ -57,9 +91,9 @@ func (s *HstSuite) SetupVolumes() { } } -func (s *HstSuite) SetupContainers() { +func (s *HstSuite) setupContainers() { for _, container := range s.containers { - if container.isOptional == false { + if !container.isOptional { container.run() } } @@ -112,7 +146,8 @@ func (s *HstSuite) assertNotEmpty(object interface{}, msgAndArgs ...interface{}) } func (s *HstSuite) log(args ...any) { - if IsVerbose() { + if *isVerbose { + s.T().Helper() s.T().Log(args...) } } @@ -122,13 +157,19 @@ func (s *HstSuite) skip(args ...any) { s.T().SkipNow() } -func (s *HstSuite) ResetContainers() { +func (s *HstSuite) SkipIfMultiWorker(args ...any) { + if *nConfiguredCpus > 1 { + s.skip("test case not supported with multiple vpp workers") + } +} + +func (s *HstSuite) resetContainers() { for _, container := range s.containers { container.stop() } } -func (s *HstSuite) RemoveVolumes() { +func (s *HstSuite) removeVolumes() { for _, volumeName := range s.volumes { cmd := "docker volume rm " + volumeName exechelper.Run(cmd) @@ -150,7 +191,7 @@ func (s *HstSuite) getTransientContainerByName(name string) *Container { } func (s *HstSuite) loadContainerTopology(topologyName string) { - data, err := ioutil.ReadFile(ContainerTopologyDir + topologyName + ".yaml") + data, err := ioutil.ReadFile(containerTopologyDir + topologyName + ".yaml") if err != nil { s.T().Fatalf("read error: %v", err) } @@ -168,18 +209,17 @@ func (s *HstSuite) loadContainerTopology(topologyName string) { s.containers = make(map[string]*Container) for _, elem := range yamlTopo.Containers { - newContainer, err := NewContainer(elem) + newContainer, err := newContainer(elem) newContainer.suite = s if err != nil { s.T().Fatalf("container config error: %v", err) } - s.log(newContainer.getRunCommand()) s.containers[newContainer.name] = newContainer } } func (s *HstSuite) loadNetworkTopology(topologyName string) { - data, err := ioutil.ReadFile(NetworkTopologyDir + topologyName + ".yaml") + data, err := ioutil.ReadFile(networkTopologyDir + topologyName + ".yaml") if err != nil { s.T().Fatalf("read error: %v", err) } @@ -189,39 +229,30 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { s.T().Fatalf("unmarshal error: %v", err) } - s.addresser = NewAddresser(s) - s.netInterfaces = make(map[string]NetInterface) + 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 { + if namespace, err := newNetNamespace(elem); err == nil { s.netConfigs = append(s.netConfigs, &namespace) } else { s.T().Fatalf("network config error: %v", err) } } - case 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: + case Veth, Tap: { - if tap, err := NewTap(elem, s.addresser); err == nil { - s.netConfigs = append(s.netConfigs, &tap) - s.netInterfaces[tap.Name()] = &tap + if netIf, err := newNetworkInterface(elem, s.addresser); err == nil { + s.netConfigs = append(s.netConfigs, netIf) + s.netInterfaces[netIf.Name()] = netIf } else { s.T().Fatalf("network config error: %v", err) } } case Bridge: { - if bridge, err := NewBridge(elem); err == nil { + if bridge, err := newBridge(elem); err == nil { s.netConfigs = append(s.netConfigs, &bridge) } else { s.T().Fatalf("network config error: %v", err) @@ -234,63 +265,77 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { func (s *HstSuite) configureNetworkTopology(topologyName string) { s.loadNetworkTopology(topologyName) + if *isUnconfiguring { + return + } + for _, nc := range s.netConfigs { - if err := nc.Configure(); err != nil { + if err := nc.configure(); err != nil { s.T().Fatalf("network config error: %v", err) } } } func (s *HstSuite) unconfigureNetworkTopology() { - if IsPersistent() { + if *isPersistent { return } for _, nc := range s.netConfigs { - nc.Unconfigure() + nc.unconfigure() } } -type NamespaceAddresses struct { - namespace string - numberOfAddresses int +func (s *HstSuite) getTestId() string { + testName := s.T().Name() + + if s.testIds == nil { + s.testIds = map[string]string{} + } + + if _, ok := s.testIds[testName]; !ok { + s.testIds[testName] = time.Now().Format("2006-01-02_15-04-05") + } + + return s.testIds[testName] } +type AddressCounter = int + type Addresser struct { - namespaces []*NamespaceAddresses - suite *HstSuite + networks map[int]AddressCounter + suite *HstSuite } -func (a *Addresser) AddNamespace(name string) { - var newNamespace = &NamespaceAddresses{ - namespace: name, - numberOfAddresses: 0, - } - a.namespaces = append(a.namespaces, newNamespace) +func (a *Addresser) addNetwork(networkNumber int) { + a.networks[networkNumber] = 1 } -func (a *Addresser) NewIp4Address() (string, error) { - return a.NewIp4AddressWithNamespace(defaultNamespaceName) -} +func (a *Addresser) newIp4Address(inputNetworkNumber ...int) (string, error) { + var networkNumber int = 0 + if len(inputNetworkNumber) > 0 { + networkNumber = inputNetworkNumber[0] + } -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 + if _, ok := a.networks[networkNumber]; !ok { + a.addNetwork(networkNumber) } - a.AddNamespace(namespace) - return a.NewIp4AddressWithNamespace(namespace) + + numberOfAddresses := a.networks[networkNumber] + + if numberOfAddresses == 254 { + return "", fmt.Errorf("no available IPv4 addresses") + } + + address := fmt.Sprintf("10.10.%v.%v/24", networkNumber, numberOfAddresses) + a.networks[networkNumber] = numberOfAddresses + 1 + + return address, nil } -func NewAddresser(suite *HstSuite) *Addresser { +func newAddresser(suite *HstSuite) *Addresser { var addresser = new(Addresser) addresser.suite = suite - addresser.AddNamespace(defaultNamespaceName) + addresser.networks = make(map[int]AddressCounter) + addresser.addNetwork(0) return addresser }