diff options
author | Adrian Villin <avillin@cisco.com> | 2024-06-14 09:32:39 +0200 |
---|---|---|
committer | Dave Wallace <dwallacelf@gmail.com> | 2024-06-14 18:10:26 +0000 |
commit | 4677d920c0b0ff1f1aae81fb2f0052d939a2e89c (patch) | |
tree | 9c1adf90f6c1a977b622c1d0211e0e86d1bef985 /extras | |
parent | 2aa0f0da5dedcf6301c74a39b5e3749359e07e6d (diff) |
hs-test: separate infra from tests
- most functions and vars now start with a capital letter:
needed to access them outside the package that declares
them
- updated README.md
- very minor changes in MAKEFILE
Type: test
Change-Id: I4b5a194f08f09d59e372e57da6451fbb5a1de4da
Signed-off-by: Adrian Villin <avillin@cisco.com>
Diffstat (limited to 'extras')
-rw-r--r-- | extras/hs-test/Makefile | 34 | ||||
-rw-r--r-- | extras/hs-test/README.rst | 176 | ||||
-rw-r--r-- | extras/hs-test/echo_test.go | 53 | ||||
-rw-r--r-- | extras/hs-test/framework_test.go | 9 | ||||
-rw-r--r-- | extras/hs-test/http_test.go | 661 | ||||
-rw-r--r-- | extras/hs-test/infra/address_allocator.go (renamed from extras/hs-test/address_allocator.go) | 4 | ||||
-rw-r--r-- | extras/hs-test/infra/container.go (renamed from extras/hs-test/container.go) | 196 | ||||
-rw-r--r-- | extras/hs-test/infra/cpu.go (renamed from extras/hs-test/cpu.go) | 2 | ||||
-rw-r--r-- | extras/hs-test/infra/hst_suite.go (renamed from extras/hs-test/hst_suite.go) | 319 | ||||
-rw-r--r-- | extras/hs-test/infra/netconfig.go (renamed from extras/hs-test/netconfig.go) | 82 | ||||
-rw-r--r-- | extras/hs-test/infra/suite_nginx.go (renamed from extras/hs-test/suite_nginx_test.go) | 62 | ||||
-rw-r--r-- | extras/hs-test/infra/suite_no_topo.go (renamed from extras/hs-test/suite_no_topo_test.go) | 40 | ||||
-rw-r--r-- | extras/hs-test/infra/suite_ns.go (renamed from extras/hs-test/suite_ns_test.go) | 52 | ||||
-rw-r--r-- | extras/hs-test/infra/suite_tap.go (renamed from extras/hs-test/suite_tap_test.go) | 16 | ||||
-rw-r--r-- | extras/hs-test/infra/suite_veth.go (renamed from extras/hs-test/suite_veth_test.go) | 64 | ||||
-rw-r--r-- | extras/hs-test/infra/topo.go (renamed from extras/hs-test/topo.go) | 2 | ||||
-rw-r--r-- | extras/hs-test/infra/utils.go (renamed from extras/hs-test/utils.go) | 22 | ||||
-rw-r--r-- | extras/hs-test/infra/vppinstance.go (renamed from extras/hs-test/vppinstance.go) | 203 | ||||
-rw-r--r-- | extras/hs-test/ldp_test.go | 71 | ||||
-rw-r--r-- | extras/hs-test/linux_iperf_test.go | 22 | ||||
-rw-r--r-- | extras/hs-test/mirroring_test.go | 15 | ||||
-rw-r--r-- | extras/hs-test/proxy_test.go | 66 | ||||
-rw-r--r-- | extras/hs-test/raw_session_test.go | 32 | ||||
-rw-r--r-- | extras/hs-test/vcl_test.go | 155 |
24 files changed, 1179 insertions, 1179 deletions
diff --git a/extras/hs-test/Makefile b/extras/hs-test/Makefile index 7fab6dca514..07423e527ed 100644 --- a/extras/hs-test/Makefile +++ b/extras/hs-test/Makefile @@ -53,28 +53,25 @@ ifeq ($(ARCH),) ARCH=$(shell dpkg --print-architecture) endif -list_tests = @go run github.com/onsi/ginkgo/v2/ginkgo --dry-run -v --no-color --seed=2 | head -n -1 | grep 'Test' | \ - sed 's/^/* /; s/\(Suite\) /\1\//g' - .PHONY: help help: @echo "Make targets:" - @echo " test - run tests" - @echo " test-debug - run tests (vpp debug image)" - @echo " build - build test infra" - @echo " build-cov - coverage build of VPP and Docker images" - @echo " build-debug - build test infra (vpp debug image)" - @echo " build-go - just build golang files" - @echo " checkstyle-go - check style of .go source files" - @echo " fixstyle-go - format .go source files" - @echo " cleanup-hst - stops and removes all docker contaiers and namespaces" - @echo " list-tests - list all tests" + @echo " test - run tests" + @echo " test-debug - run tests (vpp debug image)" + @echo " build - build test infra" + @echo " build-cov - coverage build of VPP and Docker images" + @echo " build-debug - build test infra (vpp debug image)" + @echo " build-go - just build golang files" + @echo " checkstyle-go - check style of .go source files" + @echo " fixstyle-go - format .go source files" + @echo " cleanup-hst - stops and removes all docker contaiers and namespaces" + @echo " list-tests - list all tests" @echo - @echo "make build arguments:" + @echo "'make build' arguments:" @echo " UBUNTU_VERSION - ubuntu version for docker image" - @echo " HST_EXTENDED_TESTS - build extended tests" + @echo " HST_EXTENDED_TESTS - build extended tests" @echo - @echo "make test arguments:" + @echo "'make test' arguments:" @echo " PERSIST=[true|false] - whether clean up topology and dockers after test" @echo " VERBOSE=[true|false] - verbose output" @echo " UNCONFIGURE=[true|false] - unconfigure selected test" @@ -86,11 +83,12 @@ help: @echo " REPEAT=[n] - repeat tests up to N times or until a failure occurs" @echo @echo "List of all tests:" - $(call list_tests) + @$(MAKE) list-tests .PHONY: list-tests list-tests: - $(call list_tests) + @go run github.com/onsi/ginkgo/v2/ginkgo --dry-run -v --no-color --seed=2 | head -n -1 | grep 'Test' | \ + sed 's/^/* /; s/\(Suite\) /\1\//g' .PHONY: build-vpp-release build-vpp-release: diff --git a/extras/hs-test/README.rst b/extras/hs-test/README.rst index a88251af617..7841211e3ab 100644 --- a/extras/hs-test/README.rst +++ b/extras/hs-test/README.rst @@ -26,15 +26,15 @@ Anatomy of a test case **Action flow when running a test case**: -#. It starts with running ``make test``. Optional arguments are VERBOSE, PERSIST (topology configuration isn't cleaned up after test run), +#. It starts with running ``make test``. Optional arguments are VERBOSE, PERSIST (topology configuration isn't cleaned up after test run, use ``make cleanup-hst`` to clean up), TEST=<test-name> to run a specific test and PARALLEL=[n-cpus]. -#. ``make list-tests`` (or ``make help``) shows all tests. The current `list of tests`_ is at the bottom of this document. -#. ``Ginkgo`` looks for a spec suite in the current directory and then compiles it to a .test binary -#. The Ginkgo test framework runs each function that was registered manually using ``registerMySuiteTest(s *MySuite)``. Each of these functions correspond to a suite +#. ``make list-tests`` (or ``make help``) shows all tests. +#. ``Ginkgo`` looks for a spec suite in the current directory and then compiles it to a .test binary. +#. The Ginkgo test framework runs each function that was registered manually using ``Register[SuiteName]Test()``. Each of these functions correspond to a suite. #. Ginkgo's ``RunSpecs(t, "Suite description")`` function is the entry point and does the following: #. Ginkgo compiles the spec, builds a spec tree - #. ``Describe`` container nodes in suite\_\*_test.go files are run (in series by default, or in parallel with the argument PARALLEL=[n-cpus]) + #. ``Describe`` container nodes in suite\_\*.go files are run (in series by default, or in parallel with the argument PARALLEL=[n-cpus]) #. Suite is initialized. The topology is loaded and configured in this step #. Registered tests are run in generated ``It`` subject nodes #. Execute tear-down functions, which currently consists of stopping running containers @@ -47,46 +47,47 @@ This describes adding a new test case to an existing suite. For adding a new suite, please see `Modifying the framework`_ below. #. To write a new test case, create a file whose name ends with ``_test.go`` or pick one that already exists -#. Declare method whose name ends with ``Test`` and specifies its parameter as a pointer to the suite's struct (defined in ``suite_*_test.go``) +#. Declare method whose name ends with ``Test`` and specifies its parameter as a pointer to the suite's struct (defined in ``infra/suite_*.go``) #. Implement test behaviour inside the test method. This typically includes the following: - #. Retrieve a running container in which to run some action. Method ``getContainerByName`` + #. Import ``. "fd.io/hs-test/infra"`` + #. Retrieve a running container in which to run some action. Method ``GetContainerByName`` from ``HstSuite`` struct serves this purpose - #. Interact with VPP through the ``VppInstance`` struct embedded in container. It provides ``vppctl`` method to access debug CLI - #. Run arbitrary commands inside the containers with ``exec`` method - #. Run other external tool with one of the preexisting functions in the ``utils.go`` file. - For example, use ``wget`` with ``startWget`` function + #. Interact with VPP through the ``VppInstance`` struct embedded in container. It provides ``Vppctl`` method to access debug CLI + #. Run arbitrary commands inside the containers with ``Exec`` method + #. Run other external tool with one of the preexisting functions in the ``infra/utils.go`` file. + For example, use ``wget`` with ``StartWget`` function #. Use ``exechelper`` or just plain ``exec`` packages to run whatever else - #. Verify results of your tests using ``assert`` methods provided by the test suite, implemented by HstSuite struct or use ``Gomega`` assert functions. + #. Verify results of your tests using ``Assert`` methods provided by the test suite. -#. Create an ``init()`` function and register the test using ``register*SuiteTests(testCaseFunction)`` +#. Create an ``init()`` function and register the test using ``Register[SuiteName]Tests(testCaseFunction)`` **Example test case** Assumed are two docker containers, each with its own VPP instance running. One VPP then pings the other. -This can be put in file ``extras/hs-test/my_test.go`` and run with command ``make test TEST=MyTest`` or ``ginkgo -v --trace --focus MyTest``. +This can be put in file ``extras/hs-test/my_test.go`` and run with command ``make test TEST=MyTest``. :: package main import ( - "fmt" + . "fd.io/hs-test/infra" ) func init(){ - registerMySuiteTest(MyTest) + RegisterMySuiteTest(MyTest) } func MyTest(s *MySuite) { - clientVpp := s.getContainerByName("client-vpp").vppInstance + clientVpp := s.GetContainerByName("client-vpp").VppInstance - serverVethAddress := s.netInterfaces["server-iface"].AddressString() + serverVethAddress := s.NetInterfaces["server-iface"].Ip4AddressString() - result := clientVpp.vppctl("ping " + serverVethAddress) - s.assertNotNil(result) - s.log(result) + result := clientVpp.Vppctl("ping " + serverVethAddress) + s.Log(result) + s.AssertNotNil(result) } @@ -94,23 +95,28 @@ Filtering test cases -------------------- The framework allows us to filter test cases in a few different ways, using ``make test TEST=``: -* Suite name -* File name -* Test name -* All of the above as long as they are ordered properly, e.g. ``make test TEST=VethsSuite.http_test.go.HeaderServerTest`` + + * Suite name + * File name + * Test name + * All of the above as long as they are ordered properly, e.g. ``make test TEST=VethsSuite.http_test.go.HeaderServerTest`` **Names are case sensitive!** Names don't have to be complete, as long as they are last: This is valid and will run all tests in every ``http`` file (if there is more than one): -``make test TEST=VethsSuite.http`` + +* ``make test TEST=VethsSuite.http`` + This is not valid: -``make test TEST=Veths.http`` + +* ``make test TEST=Veths.http`` They can also be left out: -``make test TEST=http_test.go`` will run every test in ``http_test.go`` -``make test TEST=Nginx`` will run everything that has 'Nginx' in its name - suites, files and tests. -``make test TEST=HeaderServerTest`` will only run the header server test + +* ``make test TEST=http_test.go`` will run every test in ``http_test.go`` +* ``make test TEST=Nginx`` will run everything that has 'Nginx' in its name - suites, files and tests. +* ``make test TEST=HeaderServerTest`` will only run the header server test Modifying the framework @@ -120,34 +126,37 @@ Modifying the framework .. _test-convention: -#. To add a new suite, create a new file. Naming convention for the suite files is ``suite_name_test.go`` where *name* will be replaced - by the actual name +#. To add a new suite, create a new file in the ``infra/`` folder. Naming convention for the suite files is ``suite_[name].go``. #. Make a ``struct``, in the suite file, with at least ``HstSuite`` struct as its member. HstSuite provides functionality that can be shared for all suites, like starting containers +#. Create a new map that will contain a file name where a test is located and test functions with a pointer to the suite's struct: ``var myTests = map[string][]func(s *MySuite){}`` + :: + var myTests = map[string][]func(s *MySuite){} + type MySuite struct { HstSuite } -#. Create a new slice that will contain test functions with a pointer to the suite's struct: ``var myTests = []func(s *MySuite){}`` -#. Then create a new function that will append test functions to that slice: +#. Then create a new function that will add tests to that map: :: - func registerMySuiteTests(tests ...func(s *MySuite)) { - nginxTests = append(myTests, tests...) + func RegisterMyTests(tests ...func(s *MySuite)) { + myTests[getTestFilename()] = tests } + #. In suite file, implement ``SetupSuite`` method which Ginkgo runs once before starting any of the tests. - It's important here to call ``configureNetworkTopology`` method, + It's important here to call ``ConfigureNetworkTopology()`` method, pass the topology name to the function in a form of file name of one of the *yaml* files in ``topo-network`` folder. Without the extension. In this example, *myTopology* corresponds to file ``extras/hs-test/topo-network/myTopology.yaml`` This will ensure network topology, such as network interfaces and namespaces, will be created. - Another important method to call is ``loadContainerTopology()`` which will load + Another important method to call is ``LoadContainerTopology()`` which will load containers and shared volumes used by the suite. This time the name passed to method corresponds to file in ``extras/hs-test/topo-containers`` folder @@ -158,8 +167,8 @@ Modifying the framework // Add custom setup code here - s.configureNetworkTopology("myTopology") - s.loadContainerTopology("2peerVeth") + s.ConfigureNetworkTopology("myTopology") + s.LoadContainerTopology("2peerVeth") } #. In suite file, implement ``SetupTest`` method which gets executed before each test. Starting containers and @@ -184,44 +193,50 @@ Modifying the framework :: var _ = Describe("MySuite", Ordered, ContinueOnFailure, func() { - var s MySuite - BeforeAll(func() { - s.SetupSuite() - }) - BeforeEach(func() { - s.SetupTest() - }) - AfterAll(func() { - s.TearDownSuite() - }) - AfterEach(func() { - s.TearDownTest() + var s MySuite + BeforeAll(func() { + s.SetupSuite() }) - for _, test := range mySuiteTests { - test := test - pc := reflect.ValueOf(test).Pointer() - funcValue := runtime.FuncForPC(pc) - It(strings.Split(funcValue.Name(), ".")[2], func(ctx SpecContext) { - test(&s) - }, SpecTimeout(time.Minute*5)) - } + BeforeEach(func() { + s.SetupTest() + }) + AfterAll(func() { + s.TearDownSuite() + }) + AfterEach(func() { + s.TearDownTest() + }) + + for filename, tests := range myTests { + 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(SuiteTimeout)) + } + } }) #. Notice the loop - it will generate multiple ``It`` nodes, each running a different test. ``test := test`` is necessary, otherwise only the last test in a suite will run. For a more detailed description, check Ginkgo's documentation: https://onsi.github.io/ginkgo/#dynamically-generating-specs\. -#. ``funcValue.Name()`` returns the full name of a function (e.g. ``fd.io/hs-test.MyTest``), however, we only need the test name (``MyTest``). +#. ``testName`` contains the test name in the following format: ``[name]_test.go/MyTest``. -#. To run certain tests solo, create a new slice that will only contain tests that have to run solo and a new register function. +#. To run certain tests solo, create a register function and a map that will only contain tests that have to run solo. Add a ``Serial`` decorator to the container node and ``Label("SOLO")`` to the ``It`` subject node: :: var _ = Describe("MySuiteSolo", Ordered, ContinueOnFailure, Serial, func() { ... - It(strings.Split(funcValue.Name(), ".")[2], Label("SOLO"), func(ctx SpecContext) { - test(&s) + It(testName, Label("SOLO"), func(ctx SpecContext) { + s.Log(testName + ": BEGIN") + test(&s) }, SpecTimeout(time.Minute*5)) }) @@ -308,36 +323,3 @@ or a new version incompatibility issue occurs. .. _ginkgo: https://onsi.github.io/ginkgo/ .. _volumes: https://docs.docker.com/storage/volumes/ - -**List of tests** - -.. _list of tests: - -Please update this list whenever you add a new test by pasting the output below. - -* NsSuite/HttpTpsTest -* NsSuite/VppProxyHttpTcpTest -* NsSuite/VppProxyHttpTlsTest -* NsSuite/EnvoyProxyHttpTcpTest -* NginxSuite/MirroringTest -* VethsSuiteSolo TcpWithLossTest [SOLO] -* NoTopoSuiteSolo HttpStaticPromTest [SOLO] -* TapSuite/LinuxIperfTest -* NoTopoSuite/NginxHttp3Test -* NoTopoSuite/NginxAsServerTest -* NoTopoSuite/NginxPerfCpsTest -* NoTopoSuite/NginxPerfRpsTest -* NoTopoSuite/NginxPerfWrkTest -* VethsSuite/EchoBuiltinTest -* VethsSuite/HttpCliTest -* VethsSuite/LDPreloadIperfVppTest -* VethsSuite/VppEchoQuicTest -* VethsSuite/VppEchoTcpTest -* VethsSuite/VppEchoUdpTest -* VethsSuite/XEchoVclClientUdpTest -* VethsSuite/XEchoVclClientTcpTest -* VethsSuite/XEchoVclServerUdpTest -* VethsSuite/XEchoVclServerTcpTest -* VethsSuite/VclEchoTcpTest -* VethsSuite/VclEchoUdpTest -* VethsSuite/VclRetryAttachTest diff --git a/extras/hs-test/echo_test.go b/extras/hs-test/echo_test.go index ce852bea3e0..6b4739a5457 100644 --- a/extras/hs-test/echo_test.go +++ b/extras/hs-test/echo_test.go @@ -1,51 +1,56 @@ package main +import ( + . "fd.io/hs-test/infra" +) + func init() { - registerVethTests(EchoBuiltinTest) - registerSoloVethTests(TcpWithLossTest) + RegisterVethTests(EchoBuiltinTest) + RegisterSoloVethTests(TcpWithLossTest) } func EchoBuiltinTest(s *VethsSuite) { - serverVpp := s.getContainerByName("server-vpp").vppInstance - serverVeth := s.getInterfaceByName(serverInterfaceName) + serverVpp := s.GetContainerByName("server-vpp").VppInstance + serverVeth := s.GetInterfaceByName(ServerInterfaceName) - serverVpp.vppctl("test echo server " + - " uri tcp://" + serverVeth.ip4AddressString() + "/1234") + serverVpp.Vppctl("test echo server " + + " uri tcp://" + serverVeth.Ip4AddressString() + "/1234") - clientVpp := s.getContainerByName("client-vpp").vppInstance + clientVpp := s.GetContainerByName("client-vpp").VppInstance - o := clientVpp.vppctl("test echo client nclients 100 bytes 1 verbose" + + o := clientVpp.Vppctl("test echo client nclients 100 bytes 1 verbose" + " syn-timeout 100 test-timeout 100" + - " uri tcp://" + serverVeth.ip4AddressString() + "/1234") - s.log(o) - s.assertNotContains(o, "failed:") + " uri tcp://" + serverVeth.Ip4AddressString() + "/1234") + s.Log(o) + s.AssertNotContains(o, "failed:") } // unstable with multiple workers func TcpWithLossTest(s *VethsSuite) { s.SkipIfMultiWorker() - serverVpp := s.getContainerByName("server-vpp").vppInstance + serverVpp := s.GetContainerByName("server-vpp").VppInstance - serverVeth := s.getInterfaceByName(serverInterfaceName) - serverVpp.vppctl("test echo server uri tcp://%s/20022", - serverVeth.ip4AddressString()) + serverVeth := s.GetInterfaceByName(ServerInterfaceName) + serverVpp.Vppctl("test echo server uri tcp://%s/20022", + serverVeth.Ip4AddressString()) - clientVpp := s.getContainerByName("client-vpp").vppInstance + clientVpp := s.GetContainerByName("client-vpp").VppInstance // Ensure that VPP doesn't abort itself with NSIM enabled // Warning: Removing this ping will make VPP crash! - clientVpp.vppctl("ping %s", serverVeth.ip4AddressString()) + clientVpp.Vppctl("ping %s", serverVeth.Ip4AddressString()) // Add loss of packets with Network Delay Simulator - clientVpp.vppctl("set nsim poll-main-thread delay 0.01 ms bandwidth 40 gbit" + + 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-" + s.getInterfaceByName(clientInterfaceName).name) + name := s.GetInterfaceByName(ClientInterfaceName).Name() + clientVpp.Vppctl("nsim output-feature enable-disable host-" + name) // Do echo test from client-vpp container - output := clientVpp.vppctl("test echo client uri tcp://%s/20022 verbose echo-bytes mbytes 50", - serverVeth.ip4AddressString()) - s.log(output) - s.assertNotEqual(len(output), 0) - s.assertNotContains(output, "failed", output) + output := clientVpp.Vppctl("test echo client uri tcp://%s/20022 verbose echo-bytes mbytes 50", + serverVeth.Ip4AddressString()) + s.Log(output) + s.AssertNotEqual(len(output), 0) + s.AssertNotContains(output, "failed", output) } diff --git a/extras/hs-test/framework_test.go b/extras/hs-test/framework_test.go index b992659a4af..a086f75a5fc 100644 --- a/extras/hs-test/framework_test.go +++ b/extras/hs-test/framework_test.go @@ -8,23 +8,22 @@ import ( "testing" "time" + . "fd.io/hs-test/infra" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) -var suiteTimeout time.Duration - func getTestFilename() string { _, filename, _, _ := runtime.Caller(2) return filepath.Base(filename) } func TestHst(t *testing.T) { - if *isVppDebug { + if *IsVppDebug { // 30 minute timeout so that the framework won't timeout while debugging - suiteTimeout = time.Minute * 30 + SuiteTimeout = time.Minute * 30 } else { - suiteTimeout = time.Minute * 5 + SuiteTimeout = time.Minute * 5 } // creates a file with PPID, used for 'make cleanup-hst' diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go index ca8b618a7b2..d83f2d10ffb 100644 --- a/extras/hs-test/http_test.go +++ b/extras/hs-test/http_test.go @@ -10,12 +10,13 @@ import ( "strings" "time" + . "fd.io/hs-test/infra" . "github.com/onsi/ginkgo/v2" ) func init() { - registerVethTests(HttpCliTest, HttpCliConnectErrorTest) - registerNoTopoTests(NginxHttp3Test, NginxAsServerTest, + RegisterVethTests(HttpCliTest, HttpCliConnectErrorTest) + RegisterNoTopoTests(NginxHttp3Test, NginxAsServerTest, NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest, HeaderServerTest, HttpStaticMovedTest, HttpStaticNotFoundTest, HttpCliMethodNotAllowedTest, HttpCliBadRequestTest, HttpStaticBuildInUrlGetIfStatsTest, HttpStaticBuildInUrlPostIfStatsTest, @@ -24,561 +25,561 @@ func init() { HttpStaticMacTimeTest, HttpStaticBuildInUrlGetVersionVerboseTest, HttpVersionNotSupportedTest, HttpInvalidContentLengthTest, HttpInvalidTargetSyntaxTest, HttpStaticPathTraversalTest, HttpUriDecodeTest, HttpHeadersTest) - registerNoTopoSoloTests(HttpStaticPromTest, HttpTpsTest) + RegisterNoTopoSoloTests(HttpStaticPromTest, HttpTpsTest) } const wwwRootPath = "/tmp/www_root" func httpDownloadBenchmark(s *HstSuite, experiment *gmeasure.Experiment, data interface{}) { url, isValid := data.(string) - s.assertEqual(true, isValid) - client := newHttpClient() + s.AssertEqual(true, isValid) + client := NewHttpClient() req, err := http.NewRequest("GET", url, nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) t := time.Now() resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) _, err = io.ReadAll(resp.Body) duration := time.Since(t) experiment.RecordValue("Download Speed", (float64(resp.ContentLength)/1024/1024)/duration.Seconds(), gmeasure.Units("MB/s"), gmeasure.Precision(2)) } func HttpTpsTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() url := "http://" + serverAddress + ":8080/test_file_10M" - vpp.vppctl("http tps uri tcp://0.0.0.0/8080") + vpp.Vppctl("http tps uri tcp://0.0.0.0/8080") - s.runBenchmark("HTTP tps 10M", 10, 0, httpDownloadBenchmark, url) + s.RunBenchmark("HTTP tps 10M", 10, 0, httpDownloadBenchmark, url) } func HttpCliTest(s *VethsSuite) { - serverContainer := s.getContainerByName("server-vpp") - clientContainer := s.getContainerByName("client-vpp") + serverContainer := s.GetContainerByName("server-vpp") + clientContainer := s.GetContainerByName("client-vpp") - serverVeth := s.getInterfaceByName(serverInterfaceName) + serverVeth := s.GetInterfaceByName(ServerInterfaceName) - serverContainer.vppInstance.vppctl("http cli server") + serverContainer.VppInstance.Vppctl("http cli server") - uri := "http://" + serverVeth.ip4AddressString() + "/80" + uri := "http://" + serverVeth.Ip4AddressString() + "/80" - o := clientContainer.vppInstance.vppctl("http cli client" + + o := clientContainer.VppInstance.Vppctl("http cli client" + " uri " + uri + " query /show/vlib/graph") - s.log(o) - s.assertContains(o, "<html>", "<html> not found in the result!") + s.Log(o) + s.AssertContains(o, "<html>", "<html> not found in the result!") } func HttpCliConnectErrorTest(s *VethsSuite) { - clientContainer := s.getContainerByName("client-vpp") + clientContainer := s.GetContainerByName("client-vpp") - serverVeth := s.getInterfaceByName(serverInterfaceName) + serverVeth := s.GetInterfaceByName(ServerInterfaceName) - uri := "http://" + serverVeth.ip4AddressString() + "/80" + uri := "http://" + serverVeth.Ip4AddressString() + "/80" - o := clientContainer.vppInstance.vppctl("http cli client" + + o := clientContainer.VppInstance.Vppctl("http cli client" + " uri " + uri + " query /show/vlib/graph") - s.log(o) - s.assertContains(o, "failed to connect") + s.Log(o) + s.AssertContains(o, "failed to connect") } func NginxHttp3Test(s *NoTopoSuite) { s.SkipUnlessExtendedTestsBuilt() query := "index.html" - nginxCont := s.getContainerByName("nginx-http3") - s.assertNil(nginxCont.run()) + nginxCont := s.GetContainerByName("nginx-http3") + s.AssertNil(nginxCont.Run()) - vpp := s.getContainerByName("vpp").vppInstance - vpp.waitForApp("nginx-", 5) - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() + vpp := s.GetContainerByName("vpp").VppInstance + vpp.WaitForApp("nginx-", 5) + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() defer func() { os.Remove(query) }() - curlCont := s.getContainerByName("curl") + curlCont := s.GetContainerByName("curl") args := fmt.Sprintf("curl --noproxy '*' --local-port 55444 --http3-only -k https://%s:8443/%s", serverAddress, query) - curlCont.extraRunningArgs = args - o, err := curlCont.combinedOutput() - s.log(o) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(o, "<http>", "<http> not found in the result!") + curlCont.ExtraRunningArgs = args + o, err := curlCont.CombinedOutput() + s.Log(o) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(o, "<http>", "<http> not found in the result!") } func HttpStaticPromTest(s *NoTopoSuite) { finished := make(chan error, 1) query := "stats.prom" - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers")) - s.log(vpp.vppctl("prom enable")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers")) + s.Log(vpp.Vppctl("prom enable")) time.Sleep(time.Second * 5) go func() { defer GinkgoRecover() - s.startWget(finished, serverAddress, "80", query, "") + s.StartWget(finished, serverAddress, "80", query, "") }() err := <-finished - s.assertNil(err) + s.AssertNil(err) } func HttpStaticPathTraversalTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - vpp.container.exec("mkdir -p " + wwwRootPath) - vpp.container.exec("mkdir -p " + "/tmp/secret_folder") - vpp.container.createFile("/tmp/secret_folder/secret_file.txt", "secret") - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) - - client := newHttpClient() + vpp := s.GetContainerByName("vpp").VppInstance + vpp.Container.Exec("mkdir -p " + wwwRootPath) + vpp.Container.Exec("mkdir -p " + "/tmp/secret_folder") + vpp.Container.CreateFile("/tmp/secret_folder/secret_file.txt", "secret") + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) + + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/../secret_folder/secret_file.txt", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(404, resp.StatusCode) + s.AssertEqual(404, resp.StatusCode) } func HttpStaticMovedTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - vpp.container.exec("mkdir -p " + wwwRootPath + "/tmp.aaa") - vpp.container.createFile(wwwRootPath+"/tmp.aaa/index.html", "<http><body><p>Hello</p></body></http>") - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) + vpp := s.GetContainerByName("vpp").VppInstance + vpp.Container.Exec("mkdir -p " + wwwRootPath + "/tmp.aaa") + vpp.Container.CreateFile(wwwRootPath+"/tmp.aaa/index.html", "<http><body><p>Hello</p></body></http>") + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/tmp.aaa", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(301, resp.StatusCode) - s.assertNotEqual("", resp.Header.Get("Location")) + s.AssertEqual(301, resp.StatusCode) + s.AssertNotEqual("", resp.Header.Get("Location")) } func HttpStaticNotFoundTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - vpp.container.exec("mkdir -p " + wwwRootPath) - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) + vpp := s.GetContainerByName("vpp").VppInstance + vpp.Container.Exec("mkdir -p " + wwwRootPath) + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server www-root " + wwwRootPath + " uri tcp://" + serverAddress + "/80 debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/notfound.html", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(404, resp.StatusCode) + s.AssertEqual(404, resp.StatusCode) } func HttpCliMethodNotAllowedTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(405, resp.StatusCode) + s.AssertEqual(405, resp.StatusCode) // TODO: need to be fixed in http code - //s.assertNotEqual("", resp.Header.Get("Allow")) + //s.AssertNotEqual("", resp.Header.Get("Allow")) } func HttpCliBadRequestTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(400, resp.StatusCode) + s.AssertEqual(400, resp.StatusCode) } func HttpStaticBuildInUrlGetVersionTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(string(data), "vpp_details") - s.assertContains(string(data), "version") - s.assertContains(string(data), "build_date") - s.assertNotContains(string(data), "build_by") - s.assertNotContains(string(data), "build_host") - s.assertNotContains(string(data), "build_dir") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(string(data), "vpp_details") + s.AssertContains(string(data), "version") + s.AssertContains(string(data), "build_date") + s.AssertNotContains(string(data), "build_by") + s.AssertNotContains(string(data), "build_host") + s.AssertNotContains(string(data), "build_dir") } func HttpStaticBuildInUrlGetVersionVerboseTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/version.json?verbose=true", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(string(data), "vpp_details") - s.assertContains(string(data), "version") - s.assertContains(string(data), "build_date") - s.assertContains(string(data), "build_by") - s.assertContains(string(data), "build_host") - s.assertContains(string(data), "build_dir") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(string(data), "vpp_details") + s.AssertContains(string(data), "version") + s.AssertContains(string(data), "build_date") + s.AssertContains(string(data), "build_by") + s.AssertContains(string(data), "build_host") + s.AssertContains(string(data), "build_dir") } func HttpStaticBuildInUrlGetIfListTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_list.json", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(string(data), "interface_list") - s.assertContains(string(data), s.getInterfaceByName(tapInterfaceName).peer.Name()) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(string(data), "interface_list") + s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name()) } func HttpStaticBuildInUrlGetIfStatsTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/interface_stats.json", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(string(data), "interface_stats") - s.assertContains(string(data), "local0") - s.assertContains(string(data), s.getInterfaceByName(tapInterfaceName).peer.Name()) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(string(data), "interface_stats") + s.AssertContains(string(data), "local0") + s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Peer.Name()) } func validatePostInterfaceStats(s *NoTopoSuite, data string) { - s.assertContains(data, "interface_stats") - s.assertContains(data, s.getInterfaceByName(tapInterfaceName).peer.Name()) - s.assertNotContains(data, "error") - s.assertNotContains(data, "local0") + s.AssertContains(data, "interface_stats") + s.AssertContains(data, s.GetInterfaceByName(TapInterfaceName).Peer.Name()) + s.AssertNotContains(data, "error") + s.AssertNotContains(data, "local0") } func HttpStaticBuildInUrlPostIfStatsTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - body := []byte(s.getInterfaceByName(tapInterfaceName).peer.Name()) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + body := []byte(s.GetInterfaceByName(TapInterfaceName).Peer.Name()) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("POST", "http://"+serverAddress+":80/interface_stats.json", bytes.NewBuffer(body)) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) validatePostInterfaceStats(s, string(data)) } func HttpStaticMacTimeTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - s.log(vpp.vppctl("mactime enable-disable " + s.getInterfaceByName(tapInterfaceName).peer.Name())) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + s.Log(vpp.Vppctl("mactime enable-disable " + s.GetInterfaceByName(TapInterfaceName).Peer.Name())) - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/mactime.json", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(string(data), "mactime") - s.assertContains(string(data), s.getInterfaceByName(tapInterfaceName).ip4AddressString()) - s.assertContains(string(data), s.getInterfaceByName(tapInterfaceName).hwAddress.String()) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(string(data), "mactime") + s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).Ip4AddressString()) + s.AssertContains(string(data), s.GetInterfaceByName(TapInterfaceName).HwAddress.String()) } func HttpInvalidRequestLineTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - resp, err := tcpSendReceive(serverAddress+":80", "GET / HTTP/1.1") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed") + resp, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/1.1\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid framing not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "HTTP-version must be present") + resp, err = TcpSendReceive(serverAddress+":80", "GET /\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "HTTP-version must be present") - resp, err = tcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present") + resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present") - resp, err = tcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present") + resp, err = TcpSendReceive(serverAddress+":80", "GET HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "request-target must be present") - resp, err = tcpSendReceive(serverAddress+":80", "GET / HTTP/x\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP/x' invalid http version not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP/x\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP/x' invalid http version not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET / HTTP1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP1.1' invalid http version not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET / HTTP1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'HTTP1.1' invalid http version not allowed") } func HttpInvalidTargetSyntaxTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - resp, err := tcpSendReceive(serverAddress+":80", "GET /interface|stats.json HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'|' not allowed in target path") + resp, err := TcpSendReceive(serverAddress+":80", "GET /interface|stats.json HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'|' not allowed in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /interface#stats.json HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'#' not allowed in target path") + resp, err = TcpSendReceive(serverAddress+":80", "GET /interface#stats.json HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'#' not allowed in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /interface%stats.json HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /interface%1stats.json HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%1stats.json HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /interface%Bstats.json HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%Bstats.json HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /interface%stats.json%B HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /interface%stats.json%B HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target path") - resp, err = tcpSendReceive(serverAddress+":80", "GET /version.json?verbose>true HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'>' not allowed in target query") + resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose>true HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'>' not allowed in target query") - resp, err = tcpSendReceive(serverAddress+":80", "GET /version.json?verbose%true HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose%true HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target query") - resp, err = tcpSendReceive(serverAddress+":80", "GET /version.json?verbose=%1 HTTP/1.1\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /version.json?verbose=%1 HTTP/1.1\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "after '%' there must be two hex-digit characters in target query") } func HttpInvalidContentLengthTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - resp, err := tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length:\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present") + resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length:\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: \r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: \r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value must be present") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: a\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nContent-Length: a\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Content-Length value other than digit not allowed") } func HttpContentLengthTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - s.log(vpp.vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) - ifName := s.getInterfaceByName(tapInterfaceName).peer.Name() + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + s.Log(vpp.Vppctl("http static server uri tcp://" + serverAddress + "/80 url-handlers debug")) + ifName := s.GetInterfaceByName(TapInterfaceName).Peer.Name() - resp, err := tcpSendReceive(serverAddress+":80", + resp, err := TcpSendReceive(serverAddress+":80", "POST /interface_stats.json HTTP/1.1\r\nContent-Length:4\r\n\r\n"+ifName) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) validatePostInterfaceStats(s, resp) - resp, err = tcpSendReceive(serverAddress+":80", + resp, err = TcpSendReceive(serverAddress+":80", "POST /interface_stats.json HTTP/1.1\r\n Content-Length: 4 \r\n\r\n"+ifName) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) validatePostInterfaceStats(s, resp) - resp, err = tcpSendReceive(serverAddress+":80", + resp, err = TcpSendReceive(serverAddress+":80", "POST /interface_stats.json HTTP/1.1\r\n\tContent-Length:\t\t4\r\n\r\n"+ifName) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) validatePostInterfaceStats(s, resp) } func HttpMethodNotImplementedTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("OPTIONS", "http://"+serverAddress+":80/show/version", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(501, resp.StatusCode) + s.AssertEqual(501, resp.StatusCode) } func HttpVersionNotSupportedTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - resp, err := tcpSendReceive(serverAddress+":80", "GET / HTTP/2\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 505 HTTP Version Not Supported") + resp, err := TcpSendReceive(serverAddress+":80", "GET / HTTP/2\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 505 HTTP Version Not Supported") } func HttpUriDecodeTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/sh%6fw%20versio%6E%20verbose", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual(200, resp.StatusCode) + s.AssertEqual(200, resp.StatusCode) data, err := io.ReadAll(resp.Body) - s.assertNil(err, fmt.Sprint(err)) - s.log(string(data)) - s.assertNotContains(string(data), "unknown input") - s.assertContains(string(data), "Compiler") + s.AssertNil(err, fmt.Sprint(err)) + s.Log(string(data)) + s.AssertNotContains(string(data), "unknown input") + s.AssertContains(string(data), "Compiler") } func HttpHeadersTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - resp, err := tcpSendReceive( + resp, err := TcpSendReceive( serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:test\r\nAccept:text/xml\r\nAccept:\ttext/plain\t \r\nAccept:text/html\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 200 OK") - s.assertContains(resp, "Content-Type: text / plain") - s.assertNotContains(resp, "<html>", "html content received instead of plain text") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 200 OK") + s.AssertContains(resp, "Content-Type: text / plain") + s.AssertNotContains(resp, "<html>", "html content received instead of plain text") } func HttpInvalidHeadersTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - resp, err := tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nUser-Agent: test\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "Header section must end with CRLF CRLF") + resp, err := TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nUser-Agent: test\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "Header section must end with CRLF CRLF") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser@Agent:test\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "'@' not allowed in field name") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser@Agent:test\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "'@' not allowed in field name") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "incomplete field line not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "incomplete field line not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\n: test\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "empty field name not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\n: test\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field name not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\rUser-Agent:test\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\rUser-Agent:test\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\nUser-Agent:test\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\nUser-Agent:test\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "invalid field line end not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:\r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent:\r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed") - resp, err = tcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent: \r\n\r\n") - s.assertNil(err, fmt.Sprint(err)) - s.assertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed") + resp, err = TcpSendReceive(serverAddress+":80", "GET /show/version HTTP/1.1\r\nHost:"+serverAddress+":80\r\nUser-Agent: \r\n\r\n") + s.AssertNil(err, fmt.Sprint(err)) + s.AssertContains(resp, "HTTP/1.1 400 Bad Request", "empty field value not allowed") } func HeaderServerTest(s *NoTopoSuite) { - vpp := s.getContainerByName("vpp").vppInstance - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() - vpp.vppctl("http cli server") + vpp := s.GetContainerByName("vpp").VppInstance + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() + vpp.Vppctl("http cli server") - client := newHttpClient() + client := NewHttpClient() req, err := http.NewRequest("GET", "http://"+serverAddress+":80/show/version", nil) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) resp, err := client.Do(req) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) defer resp.Body.Close() - s.assertEqual("http_cli_server", resp.Header.Get("Server")) + s.AssertEqual("http_cli_server", resp.Header.Get("Server")) } func NginxAsServerTest(s *NoTopoSuite) { query := "return_ok" finished := make(chan error, 1) - nginxCont := s.getContainerByName("nginx") - s.assertNil(nginxCont.run()) + nginxCont := s.GetContainerByName("nginx") + s.AssertNil(nginxCont.Run()) - vpp := s.getContainerByName("vpp").vppInstance - vpp.waitForApp("nginx-", 5) + vpp := s.GetContainerByName("vpp").VppInstance + vpp.WaitForApp("nginx-", 5) - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() defer func() { os.Remove(query) }() go func() { defer GinkgoRecover() - s.startWget(finished, serverAddress, "80", query, "") + s.StartWget(finished, serverAddress, "80", query, "") }() - s.assertNil(<-finished) + s.AssertNil(<-finished) } func parseString(s, pattern string) string { @@ -595,16 +596,16 @@ func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error { nRequests := 1000000 nClients := 1000 - serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString() + serverAddress := s.GetInterfaceByName(TapInterfaceName).Peer.Ip4AddressString() - vpp := s.getContainerByName("vpp").vppInstance + vpp := s.GetContainerByName("vpp").VppInstance - nginxCont := s.getContainerByName(singleTopoContainerNginx) - s.assertNil(nginxCont.run()) - vpp.waitForApp("nginx-", 5) + nginxCont := s.GetContainerByName(SingleTopoContainerNginx) + s.AssertNil(nginxCont.Run()) + vpp.WaitForApp("nginx-", 5) if ab_or_wrk == "ab" { - abCont := s.getContainerByName("ab") + abCont := s.GetContainerByName("ab") args := fmt.Sprintf("-n %d -c %d", nRequests, nClients) if mode == "rps" { args += " -k" @@ -614,22 +615,22 @@ func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error { // don't exit on socket receive errors args += " -r" args += " http://" + serverAddress + ":80/64B.json" - abCont.extraRunningArgs = args - o, err := abCont.combinedOutput() + abCont.ExtraRunningArgs = args + o, err := abCont.CombinedOutput() rps := parseString(o, "Requests per second:") - s.log(rps) - s.log(err) - s.assertNil(err, "err: '%s', output: '%s'", err, o) + s.Log(rps) + s.Log(err) + s.AssertNil(err, "err: '%s', output: '%s'", err, o) } else { - wrkCont := s.getContainerByName("wrk") + wrkCont := s.GetContainerByName("wrk") args := fmt.Sprintf("-c %d -t 2 -d 30 http://%s:80/64B.json", nClients, serverAddress) - wrkCont.extraRunningArgs = args - o, err := wrkCont.combinedOutput() + wrkCont.ExtraRunningArgs = args + o, err := wrkCont.CombinedOutput() rps := parseString(o, "requests") - s.log(rps) - s.log(err) - s.assertNil(err, "err: '%s', output: '%s'", err, o) + s.Log(rps) + s.Log(err) + s.AssertNil(err, "err: '%s', output: '%s'", err, o) } return nil } @@ -637,13 +638,13 @@ func runNginxPerf(s *NoTopoSuite, mode, ab_or_wrk string) error { // unstable with multiple workers func NginxPerfCpsTest(s *NoTopoSuite) { s.SkipIfMultiWorker() - s.assertNil(runNginxPerf(s, "cps", "ab")) + s.AssertNil(runNginxPerf(s, "cps", "ab")) } func NginxPerfRpsTest(s *NoTopoSuite) { - s.assertNil(runNginxPerf(s, "rps", "ab")) + s.AssertNil(runNginxPerf(s, "rps", "ab")) } func NginxPerfWrkTest(s *NoTopoSuite) { - s.assertNil(runNginxPerf(s, "", "wrk")) + s.AssertNil(runNginxPerf(s, "", "wrk")) } diff --git a/extras/hs-test/address_allocator.go b/extras/hs-test/infra/address_allocator.go index e05ea76b9bb..cb647024412 100644 --- a/extras/hs-test/address_allocator.go +++ b/extras/hs-test/infra/address_allocator.go @@ -1,4 +1,4 @@ -package main +package hst import ( "errors" @@ -84,7 +84,7 @@ func (a *Ip4AddressAllocator) createIpAddress(networkNumber int, numberOfAddress return address, nil } -func (a *Ip4AddressAllocator) deleteIpAddresses() { +func (a *Ip4AddressAllocator) DeleteIpAddresses() { for ip := range a.assignedIps { os.Remove(a.assignedIps[ip]) } diff --git a/extras/hs-test/container.go b/extras/hs-test/infra/container.go index 97b71b5385f..1dd82809f8a 100644 --- a/extras/hs-test/container.go +++ b/extras/hs-test/infra/container.go @@ -1,4 +1,4 @@ -package main +package hst import ( "fmt" @@ -22,22 +22,22 @@ var ( ) type Volume struct { - hostDir string - containerDir string - isDefaultWorkDir bool + HostDir string + ContainerDir string + IsDefaultWorkDir bool } type Container struct { - suite *HstSuite - isOptional bool - runDetached bool - name string - image string - extraRunningArgs string - volumes map[string]Volume - envVars map[string]string - vppInstance *VppInstance - allocatedCpus []int + Suite *HstSuite + IsOptional bool + RunDetached bool + Name string + Image string + ExtraRunningArgs string + Volumes map[string]Volume + EnvVars map[string]string + VppInstance *VppInstance + AllocatedCpus []int } func newContainer(suite *HstSuite, yamlInput ContainerConfig) (*Container, error) { @@ -48,37 +48,37 @@ func newContainer(suite *HstSuite, yamlInput ContainerConfig) (*Container, error } var container = new(Container) - container.volumes = make(map[string]Volume) - container.envVars = make(map[string]string) - container.name = containerName - container.suite = suite + container.Volumes = make(map[string]Volume) + container.EnvVars = make(map[string]string) + container.Name = containerName + container.Suite = suite - if image, ok := yamlInput["image"]; ok { - container.image = image.(string) + if Image, ok := yamlInput["image"]; ok { + container.Image = Image.(string) } else { - container.image = "hs-test/vpp" + container.Image = "hs-test/vpp" } if args, ok := yamlInput["extra-args"]; ok { - container.extraRunningArgs = args.(string) + container.ExtraRunningArgs = args.(string) } else { - container.extraRunningArgs = "" + container.ExtraRunningArgs = "" } if isOptional, ok := yamlInput["is-optional"]; ok { - container.isOptional = isOptional.(bool) + container.IsOptional = isOptional.(bool) } else { - container.isOptional = false + container.IsOptional = false } if runDetached, ok := yamlInput["run-detached"]; ok { - container.runDetached = runDetached.(bool) + container.RunDetached = runDetached.(bool) } else { - container.runDetached = true + container.RunDetached = true } if _, ok := yamlInput["volumes"]; ok { - workingVolumeDir := logDir + suite.getCurrentTestName() + volumeDir + workingVolumeDir := logDir + suite.GetCurrentTestName() + volumeDir workDirReplacer := strings.NewReplacer("$HST_DIR", workDir) volDirReplacer := strings.NewReplacer("$HST_VOLUME_DIR", workingVolumeDir) for _, volu := range yamlInput["volumes"].([]interface{}) { @@ -100,15 +100,15 @@ func newContainer(suite *HstSuite, yamlInput ContainerConfig) (*Container, error envVarMap := envVar.(ContainerConfig) name := envVarMap["name"].(string) value := envVarMap["value"].(string) - container.addEnvVar(name, value) + container.AddEnvVar(name, value) } } return container, nil } func (c *Container) getWorkDirVolume() (res Volume, exists bool) { - for _, v := range c.volumes { - if v.isDefaultWorkDir { + for _, v := range c.Volumes { + if v.IsDefaultWorkDir { res = v exists = true return @@ -117,16 +117,16 @@ func (c *Container) getWorkDirVolume() (res Volume, exists bool) { return } -func (c *Container) getHostWorkDir() (res string) { +func (c *Container) GetHostWorkDir() (res string) { if v, ok := c.getWorkDirVolume(); ok { - res = v.hostDir + res = v.HostDir } return } -func (c *Container) getContainerWorkDir() (res string) { +func (c *Container) GetContainerWorkDir() (res string) { if v, ok := c.getWorkDirVolume(); ok { - res = v.containerDir + res = v.ContainerDir } return } @@ -134,14 +134,14 @@ func (c *Container) getContainerWorkDir() (res string) { func (c *Container) getContainerArguments() string { args := "--ulimit nofile=90000:90000 --cap-add=all --privileged --network host" c.allocateCpus() - args += fmt.Sprintf(" --cpuset-cpus=\"%d-%d\"", c.allocatedCpus[0], c.allocatedCpus[len(c.allocatedCpus)-1]) + args += fmt.Sprintf(" --cpuset-cpus=\"%d-%d\"", c.AllocatedCpus[0], c.AllocatedCpus[len(c.AllocatedCpus)-1]) args += c.getVolumesAsCliOption() args += c.getEnvVarsAsCliOption() - if *vppSourceFileDir != "" { - args += fmt.Sprintf(" -v %s:%s", *vppSourceFileDir, *vppSourceFileDir) + if *VppSourceFileDir != "" { + args += fmt.Sprintf(" -v %s:%s", *VppSourceFileDir, *VppSourceFileDir) } - args += " --name " + c.name + " " + c.image - args += " " + c.extraRunningArgs + args += " --name " + c.Name + " " + c.Image + args += " " + c.ExtraRunningArgs return args } @@ -157,41 +157,41 @@ func (c *Container) runWithRetry(cmd string) error { return fmt.Errorf("failed to run container command") } -func (c *Container) create() error { +func (c *Container) Create() error { cmd := "docker create " + c.getContainerArguments() - c.suite.log(cmd) + c.Suite.Log(cmd) return exechelper.Run(cmd) } func (c *Container) allocateCpus() { - c.suite.startedContainers = append(c.suite.startedContainers, c) - c.allocatedCpus = c.suite.AllocateCpus() - c.suite.log("Allocated CPUs " + fmt.Sprint(c.allocatedCpus) + " to container " + c.name) + c.Suite.StartedContainers = append(c.Suite.StartedContainers, c) + c.AllocatedCpus = c.Suite.AllocateCpus() + c.Suite.Log("Allocated CPUs " + fmt.Sprint(c.AllocatedCpus) + " to container " + c.Name) } -func (c *Container) start() error { - cmd := "docker start " + c.name - c.suite.log(cmd) +func (c *Container) Start() error { + cmd := "docker start " + c.Name + c.Suite.Log(cmd) return c.runWithRetry(cmd) } func (c *Container) prepareCommand() (string, error) { - if c.name == "" { + if c.Name == "" { return "", fmt.Errorf("run container failed: name is blank") } cmd := "docker run " - if c.runDetached { + if c.RunDetached { cmd += " -d" } cmd += " " + c.getContainerArguments() - c.suite.log(cmd) + c.Suite.Log(cmd) return cmd, nil } -func (c *Container) combinedOutput() (string, error) { +func (c *Container) CombinedOutput() (string, error) { cmd, err := c.prepareCommand() if err != nil { return "", err @@ -201,7 +201,7 @@ func (c *Container) combinedOutput() (string, error) { return string(byteOutput), err } -func (c *Container) run() error { +func (c *Container) Run() error { cmd, err := c.prepareCommand() if err != nil { return err @@ -211,35 +211,35 @@ func (c *Container) run() error { func (c *Container) addVolume(hostDir string, containerDir string, isDefaultWorkDir bool) { var volume Volume - volume.hostDir = hostDir - volume.containerDir = containerDir - volume.isDefaultWorkDir = isDefaultWorkDir - c.volumes[hostDir] = volume + volume.HostDir = hostDir + volume.ContainerDir = containerDir + volume.IsDefaultWorkDir = isDefaultWorkDir + c.Volumes[hostDir] = volume } func (c *Container) getVolumesAsCliOption() string { cliOption := "" - if len(c.volumes) > 0 { - for _, volume := range c.volumes { - cliOption += fmt.Sprintf(" -v %s:%s", volume.hostDir, volume.containerDir) + if len(c.Volumes) > 0 { + for _, volume := range c.Volumes { + cliOption += fmt.Sprintf(" -v %s:%s", volume.HostDir, volume.ContainerDir) } } return cliOption } -func (c *Container) addEnvVar(name string, value string) { - c.envVars[name] = value +func (c *Container) AddEnvVar(name string, value string) { + c.EnvVars[name] = value } func (c *Container) getEnvVarsAsCliOption() string { cliOption := "" - if len(c.envVars) == 0 { + if len(c.EnvVars) == 0 { return cliOption } - for name, value := range c.envVars { + for name, value := range c.EnvVars { cliOption += fmt.Sprintf(" -e %s=%s", name, value) } return cliOption @@ -247,20 +247,20 @@ func (c *Container) getEnvVarsAsCliOption() string { func (c *Container) newVppInstance(cpus []int, additionalConfigs ...Stanza) (*VppInstance, error) { vpp := new(VppInstance) - vpp.container = c - vpp.cpus = cpus - vpp.additionalConfig = append(vpp.additionalConfig, additionalConfigs...) - c.vppInstance = vpp + vpp.Container = c + vpp.Cpus = cpus + vpp.AdditionalConfig = append(vpp.AdditionalConfig, additionalConfigs...) + c.VppInstance = vpp return vpp, nil } func (c *Container) copy(sourceFileName string, targetFileName string) error { - cmd := exec.Command("docker", "cp", sourceFileName, c.name+":"+targetFileName) + cmd := exec.Command("docker", "cp", sourceFileName, c.Name+":"+targetFileName) return cmd.Run() } -func (c *Container) createFile(destFileName string, content string) error { - f, err := os.CreateTemp("/tmp", "hst-config"+c.suite.ppid) +func (c *Container) CreateFile(destFileName string, content string) error { + f, err := os.CreateTemp("/tmp", "hst-config"+c.Suite.Ppid) if err != nil { return err } @@ -280,29 +280,29 @@ 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, arguments ...any) { +func (c *Container) ExecServer(command string, arguments ...any) { serverCommand := fmt.Sprintf(command, arguments...) containerExecCommand := "docker exec -d" + c.getEnvVarsAsCliOption() + - " " + c.name + " " + serverCommand + " " + c.Name + " " + serverCommand GinkgoHelper() - c.suite.log(containerExecCommand) - c.suite.assertNil(exechelper.Run(containerExecCommand)) + c.Suite.Log(containerExecCommand) + c.Suite.AssertNil(exechelper.Run(containerExecCommand)) } -func (c *Container) exec(command string, arguments ...any) string { +func (c *Container) Exec(command string, arguments ...any) string { cliCommand := fmt.Sprintf(command, arguments...) containerExecCommand := "docker exec" + c.getEnvVarsAsCliOption() + - " " + c.name + " " + cliCommand + " " + c.Name + " " + cliCommand GinkgoHelper() - c.suite.log(containerExecCommand) + c.Suite.Log(containerExecCommand) byteOutput, err := exechelper.CombinedOutput(containerExecCommand) - c.suite.assertNil(err, fmt.Sprint(err)) + c.Suite.AssertNil(err, fmt.Sprint(err)) return string(byteOutput) } func (c *Container) getLogDirPath() string { - testId := c.suite.getTestId() - testName := c.suite.getCurrentTestName() + testId := c.Suite.GetTestId() + testName := c.Suite.GetCurrentTestName() logDirPath := logDir + testName + "/" + testId + "/" cmd := exec.Command("mkdir", "-p", logDirPath) @@ -314,13 +314,13 @@ func (c *Container) getLogDirPath() string { } func (c *Container) saveLogs() { - testLogFilePath := c.getLogDirPath() + "container-" + c.name + ".log" + testLogFilePath := c.getLogDirPath() + "container-" + c.Name + ".log" - cmd := exec.Command("docker", "logs", "--details", "-t", c.name) - c.suite.log(cmd) + cmd := exec.Command("docker", "logs", "--details", "-t", c.Name) + c.Suite.Log(cmd) output, err := cmd.CombinedOutput() if err != nil { - c.suite.log(err) + c.Suite.Log(err) } f, err := os.Create(testLogFilePath) @@ -335,39 +335,39 @@ func (c *Container) saveLogs() { func (c *Container) log(maxLines int) (string, error) { var cmd string if maxLines == 0 { - cmd = "docker logs " + c.name + cmd = "docker logs " + c.Name } else { - cmd = fmt.Sprintf("docker logs --tail %d %s", maxLines, c.name) + cmd = fmt.Sprintf("docker logs --tail %d %s", maxLines, c.Name) } - c.suite.log(cmd) + c.Suite.Log(cmd) o, err := exechelper.CombinedOutput(cmd) return string(o), err } func (c *Container) stop() error { - if c.vppInstance != nil && c.vppInstance.apiStream != nil { - c.vppInstance.saveLogs() - c.vppInstance.disconnect() + if c.VppInstance != nil && c.VppInstance.ApiStream != nil { + c.VppInstance.saveLogs() + c.VppInstance.Disconnect() } - c.vppInstance = nil + c.VppInstance = nil c.saveLogs() - c.suite.log("docker stop " + c.name + " -t 0") - return exechelper.Run("docker stop " + c.name + " -t 0") + c.Suite.Log("docker stop " + c.Name + " -t 0") + return exechelper.Run("docker stop " + c.Name + " -t 0") } -func (c *Container) createConfig(targetConfigName string, templateName string, values any) { +func (c *Container) CreateConfig(targetConfigName string, templateName string, values any) { template := template.Must(template.ParseFiles(templateName)) f, err := os.CreateTemp(logDir, "hst-config") - c.suite.assertNil(err, err) + c.Suite.AssertNil(err, err) defer os.Remove(f.Name()) err = template.Execute(f, values) - c.suite.assertNil(err, err) + c.Suite.AssertNil(err, err) err = f.Close() - c.suite.assertNil(err, err) + c.Suite.AssertNil(err, err) c.copy(f.Name(), targetConfigName) } diff --git a/extras/hs-test/cpu.go b/extras/hs-test/infra/cpu.go index 49a7dfb02f8..b5555d85b98 100644 --- a/extras/hs-test/cpu.go +++ b/extras/hs-test/infra/cpu.go @@ -1,4 +1,4 @@ -package main +package hst import ( "bufio" diff --git a/extras/hs-test/hst_suite.go b/extras/hs-test/infra/hst_suite.go index 0bdaad28ef5..46aede7b7ef 100644 --- a/extras/hs-test/hst_suite.go +++ b/extras/hs-test/infra/hst_suite.go @@ -1,19 +1,22 @@ -package main +package hst import ( "bufio" "errors" "flag" "fmt" - "github.com/onsi/gomega/gmeasure" - "gopkg.in/yaml.v3" "io" "log" "os" "os/exec" + "path/filepath" + "runtime" "strings" "time" + "github.com/onsi/gomega/gmeasure" + "gopkg.in/yaml.v3" + "github.com/edwarnicke/exechelper" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -23,112 +26,118 @@ const ( DEFAULT_NETWORK_NUM int = 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") -var vppSourceFileDir = flag.String("vppsrc", "", "vpp source file directory") +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") +var VppSourceFileDir = flag.String("vppsrc", "", "vpp source file directory") +var SuiteTimeout time.Duration type HstSuite struct { - containers map[string]*Container - startedContainers []*Container - volumes []string - netConfigs []NetConfig - netInterfaces map[string]*NetInterface - ip4AddrAllocator *Ip4AddressAllocator - testIds map[string]string - cpuAllocator *CpuAllocatorT - cpuContexts []*CpuContext - cpuPerVpp int - ppid string - processIndex string - logger *log.Logger - logFile *os.File + Containers map[string]*Container + StartedContainers []*Container + Volumes []string + NetConfigs []NetConfig + NetInterfaces map[string]*NetInterface + Ip4AddrAllocator *Ip4AddressAllocator + TestIds map[string]string + CpuAllocator *CpuAllocatorT + CpuContexts []*CpuContext + CpuPerVpp int + Ppid string + ProcessIndex string + Logger *log.Logger + LogFile *os.File +} + +func getTestFilename() string { + _, filename, _, _ := runtime.Caller(2) + return filepath.Base(filename) } func (s *HstSuite) SetupSuite() { - s.createLogger() - s.log("Suite Setup") + s.CreateLogger() + s.Log("Suite Setup") RegisterFailHandler(func(message string, callerSkip ...int) { - s.hstFail() + s.HstFail() Fail(message, callerSkip...) }) var err error - s.ppid = fmt.Sprint(os.Getppid()) + s.Ppid = fmt.Sprint(os.Getppid()) // remove last number so we have space to prepend a process index (interfaces have a char limit) - s.ppid = s.ppid[:len(s.ppid)-1] - s.processIndex = fmt.Sprint(GinkgoParallelProcess()) - s.cpuAllocator, err = CpuAllocator() + s.Ppid = s.Ppid[:len(s.Ppid)-1] + s.ProcessIndex = fmt.Sprint(GinkgoParallelProcess()) + s.CpuAllocator, err = CpuAllocator() if err != nil { Fail("failed to init cpu allocator: " + fmt.Sprint(err)) } - s.cpuPerVpp = *nConfiguredCpus + s.CpuPerVpp = *NConfiguredCpus } func (s *HstSuite) AllocateCpus() []int { - cpuCtx, err := s.cpuAllocator.Allocate(len(s.startedContainers), s.cpuPerVpp) - s.assertNil(err) + cpuCtx, err := s.CpuAllocator.Allocate(len(s.StartedContainers), s.CpuPerVpp) + s.AssertNil(err) s.AddCpuContext(cpuCtx) return cpuCtx.cpus } func (s *HstSuite) AddCpuContext(cpuCtx *CpuContext) { - s.cpuContexts = append(s.cpuContexts, cpuCtx) + s.CpuContexts = append(s.CpuContexts, cpuCtx) } func (s *HstSuite) TearDownSuite() { - defer s.logFile.Close() - s.log("Suite Teardown") - s.unconfigureNetworkTopology() + defer s.LogFile.Close() + s.Log("Suite Teardown") + s.UnconfigureNetworkTopology() } func (s *HstSuite) TearDownTest() { - s.log("Test Teardown") - if *isPersistent { + s.Log("Test Teardown") + if *IsPersistent { return } - s.resetContainers() - s.removeVolumes() - s.ip4AddrAllocator.deleteIpAddresses() + s.ResetContainers() + s.RemoveVolumes() + s.Ip4AddrAllocator.DeleteIpAddresses() } -func (s *HstSuite) skipIfUnconfiguring() { - if *isUnconfiguring { - s.skip("skipping to unconfigure") +func (s *HstSuite) SkipIfUnconfiguring() { + if *IsUnconfiguring { + s.Skip("skipping to unconfigure") } } func (s *HstSuite) SetupTest() { - s.log("Test Setup") - s.startedContainers = s.startedContainers[:0] - s.skipIfUnconfiguring() - s.setupVolumes() - s.setupContainers() + s.Log("Test Setup") + s.StartedContainers = s.StartedContainers[:0] + s.SkipIfUnconfiguring() + s.SetupVolumes() + s.SetupContainers() } -func (s *HstSuite) setupVolumes() { - for _, volume := range s.volumes { +func (s *HstSuite) SetupVolumes() { + for _, volume := range s.Volumes { cmd := "docker volume create --name=" + volume - s.log(cmd) + s.Log(cmd) exechelper.Run(cmd) } } -func (s *HstSuite) setupContainers() { - for _, container := range s.containers { - if !container.isOptional { - container.run() +func (s *HstSuite) SetupContainers() { + for _, container := range s.Containers { + if !container.IsOptional { + container.Run() } } } -func (s *HstSuite) logVppInstance(container *Container, maxLines int) { - if container.vppInstance == nil { +func (s *HstSuite) LogVppInstance(container *Container, maxLines int) { + if container.VppInstance == nil { return } - logSource := container.getHostWorkDir() + defaultLogFilePath + logSource := container.GetHostWorkDir() + defaultLogFilePath file, err := os.Open(logSource) if err != nil { @@ -149,86 +158,86 @@ func (s *HstSuite) logVppInstance(container *Container, maxLines int) { } } - s.log("vvvvvvvvvvvvvvv " + container.name + " [VPP instance]:") + s.Log("vvvvvvvvvvvvvvv " + container.Name + " [VPP instance]:") for _, line := range lines { - s.log(line) + s.Log(line) } - s.log("^^^^^^^^^^^^^^^\n\n") + s.Log("^^^^^^^^^^^^^^^\n\n") } -func (s *HstSuite) hstFail() { - for _, container := range s.startedContainers { +func (s *HstSuite) HstFail() { + for _, container := range s.StartedContainers { out, err := container.log(20) if err != nil { - s.log("An error occured while obtaining '" + container.name + "' container logs: " + fmt.Sprint(err)) - s.log("The container might not be running - check logs in " + container.getLogDirPath()) + s.Log("An error occured while obtaining '" + container.Name + "' container logs: " + fmt.Sprint(err)) + s.Log("The container might not be running - check logs in " + container.getLogDirPath()) continue } - s.log("\nvvvvvvvvvvvvvvv " + - container.name + ":\n" + + s.Log("\nvvvvvvvvvvvvvvv " + + container.Name + ":\n" + out + "^^^^^^^^^^^^^^^\n\n") - s.logVppInstance(container, 20) + s.LogVppInstance(container, 20) } } -func (s *HstSuite) assertNil(object interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertNil(object interface{}, msgAndArgs ...interface{}) { Expect(object).To(BeNil(), msgAndArgs...) } -func (s *HstSuite) assertNotNil(object interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertNotNil(object interface{}, msgAndArgs ...interface{}) { Expect(object).ToNot(BeNil(), msgAndArgs...) } -func (s *HstSuite) assertEqual(expected, actual interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertEqual(expected, actual interface{}, msgAndArgs ...interface{}) { Expect(actual).To(Equal(expected), msgAndArgs...) } -func (s *HstSuite) assertNotEqual(expected, actual interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertNotEqual(expected, actual interface{}, msgAndArgs ...interface{}) { Expect(actual).ToNot(Equal(expected), msgAndArgs...) } -func (s *HstSuite) assertContains(testString, contains interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertContains(testString, contains interface{}, msgAndArgs ...interface{}) { Expect(testString).To(ContainSubstring(fmt.Sprint(contains)), msgAndArgs...) } -func (s *HstSuite) assertNotContains(testString, contains interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertNotContains(testString, contains interface{}, msgAndArgs ...interface{}) { Expect(testString).ToNot(ContainSubstring(fmt.Sprint(contains)), msgAndArgs...) } -func (s *HstSuite) assertNotEmpty(object interface{}, msgAndArgs ...interface{}) { +func (s *HstSuite) AssertNotEmpty(object interface{}, msgAndArgs ...interface{}) { Expect(object).ToNot(BeEmpty(), msgAndArgs...) } -func (s *HstSuite) createLogger() { - suiteName := s.getCurrentSuiteName() +func (s *HstSuite) CreateLogger() { + suiteName := s.GetCurrentSuiteName() var err error - s.logFile, err = os.Create("summary/" + suiteName + ".log") + s.LogFile, err = os.Create("summary/" + suiteName + ".log") if err != nil { Fail("Unable to create log file.") } - s.logger = log.New(io.Writer(s.logFile), "", log.LstdFlags) + s.Logger = log.New(io.Writer(s.LogFile), "", log.LstdFlags) } // Logs to files by default, logs to stdout when VERBOSE=true with GinkgoWriter // to keep console tidy -func (s *HstSuite) log(arg any) { +func (s *HstSuite) Log(arg any) { logs := strings.Split(fmt.Sprint(arg), "\n") for _, line := range logs { - s.logger.Println(line) + s.Logger.Println(line) } - if *isVerbose { + if *IsVerbose { GinkgoWriter.Println(arg) } } -func (s *HstSuite) skip(args string) { +func (s *HstSuite) Skip(args string) { Skip(args) } func (s *HstSuite) SkipIfMultiWorker(args ...any) { - if *nConfiguredCpus > 1 { - s.skip("test case not supported with multiple vpp workers") + if *NConfiguredCpus > 1 { + s.Skip("test case not supported with multiple vpp workers") } } @@ -238,51 +247,51 @@ func (s *HstSuite) SkipUnlessExtendedTestsBuilt() { cmd := exec.Command("docker", "images", imageName) byteOutput, err := cmd.CombinedOutput() if err != nil { - s.log("error while searching for docker image") + s.Log("error while searching for docker image") return } if !strings.Contains(string(byteOutput), imageName) { - s.skip("extended tests not built") + s.Skip("extended tests not built") } } -func (s *HstSuite) resetContainers() { - for _, container := range s.startedContainers { +func (s *HstSuite) ResetContainers() { + for _, container := range s.StartedContainers { container.stop() - exechelper.Run("docker rm " + container.name) + exechelper.Run("docker rm " + container.Name) } } -func (s *HstSuite) removeVolumes() { - for _, volumeName := range s.volumes { +func (s *HstSuite) RemoveVolumes() { + for _, volumeName := range s.Volumes { cmd := "docker volume rm " + volumeName exechelper.Run(cmd) os.RemoveAll(volumeName) } } -func (s *HstSuite) getNetNamespaceByName(name string) string { - return s.processIndex + name + s.ppid +func (s *HstSuite) GetNetNamespaceByName(name string) string { + return s.ProcessIndex + name + s.Ppid } -func (s *HstSuite) getInterfaceByName(name string) *NetInterface { - return s.netInterfaces[s.processIndex+name+s.ppid] +func (s *HstSuite) GetInterfaceByName(name string) *NetInterface { + return s.NetInterfaces[s.ProcessIndex+name+s.Ppid] } -func (s *HstSuite) getContainerByName(name string) *Container { - return s.containers[s.processIndex+name+s.ppid] +func (s *HstSuite) GetContainerByName(name string) *Container { + return s.Containers[s.ProcessIndex+name+s.Ppid] } /* * 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[s.processIndex+name+s.ppid] +func (s *HstSuite) GetTransientContainerByName(name string) *Container { + containerCopy := *s.Containers[s.ProcessIndex+name+s.Ppid] return &containerCopy } -func (s *HstSuite) loadContainerTopology(topologyName string) { +func (s *HstSuite) LoadContainerTopology(topologyName string) { data, err := os.ReadFile(containerTopologyDir + topologyName + ".yaml") if err != nil { Fail("read error: " + fmt.Sprint(err)) @@ -296,25 +305,25 @@ func (s *HstSuite) loadContainerTopology(topologyName string) { for _, elem := range yamlTopo.Volumes { volumeMap := elem["volume"].(VolumeConfig) hostDir := volumeMap["host-dir"].(string) - workingVolumeDir := logDir + s.getCurrentTestName() + volumeDir + workingVolumeDir := logDir + s.GetCurrentTestName() + volumeDir volDirReplacer := strings.NewReplacer("$HST_VOLUME_DIR", workingVolumeDir) hostDir = volDirReplacer.Replace(hostDir) - s.volumes = append(s.volumes, hostDir) + s.Volumes = append(s.Volumes, hostDir) } - s.containers = make(map[string]*Container) + s.Containers = make(map[string]*Container) for _, elem := range yamlTopo.Containers { newContainer, err := newContainer(s, elem) - newContainer.suite = s - newContainer.name = newContainer.suite.processIndex + newContainer.name + newContainer.suite.ppid + newContainer.Suite = s + newContainer.Name = newContainer.Suite.ProcessIndex + newContainer.Name + newContainer.Suite.Ppid if err != nil { Fail("container config error: " + fmt.Sprint(err)) } - s.containers[newContainer.name] = newContainer + s.Containers[newContainer.Name] = newContainer } } -func (s *HstSuite) loadNetworkTopology(topologyName string) { +func (s *HstSuite) LoadNetworkTopology(topologyName string) { data, err := os.ReadFile(networkTopologyDir + topologyName + ".yaml") if err != nil { Fail("read error: " + fmt.Sprint(err)) @@ -325,31 +334,31 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { Fail("unmarshal error: " + fmt.Sprint(err)) } - s.ip4AddrAllocator = NewIp4AddressAllocator() - s.netInterfaces = make(map[string]*NetInterface) + s.Ip4AddrAllocator = NewIp4AddressAllocator() + s.NetInterfaces = make(map[string]*NetInterface) for _, elem := range yamlTopo.Devices { if _, ok := elem["name"]; ok { - elem["name"] = s.processIndex + elem["name"].(string) + s.ppid + elem["name"] = s.ProcessIndex + elem["name"].(string) + s.Ppid } if peer, ok := elem["peer"].(NetDevConfig); ok { if peer["name"].(string) != "" { - peer["name"] = s.processIndex + peer["name"].(string) + s.ppid + peer["name"] = s.ProcessIndex + peer["name"].(string) + s.Ppid } if _, ok := peer["netns"]; ok { - peer["netns"] = s.processIndex + peer["netns"].(string) + s.ppid + peer["netns"] = s.ProcessIndex + peer["netns"].(string) + s.Ppid } } if _, ok := elem["netns"]; ok { - elem["netns"] = s.processIndex + elem["netns"].(string) + s.ppid + elem["netns"] = s.ProcessIndex + elem["netns"].(string) + s.Ppid } if _, ok := elem["interfaces"]; ok { interfaceCount := len(elem["interfaces"].([]interface{})) for i := 0; i < interfaceCount; i++ { - elem["interfaces"].([]interface{})[i] = s.processIndex + elem["interfaces"].([]interface{})[i].(string) + s.ppid + elem["interfaces"].([]interface{})[i] = s.ProcessIndex + elem["interfaces"].([]interface{})[i].(string) + s.Ppid } } @@ -357,16 +366,16 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { case NetNs: { if namespace, err := newNetNamespace(elem); err == nil { - s.netConfigs = append(s.netConfigs, &namespace) + s.NetConfigs = append(s.NetConfigs, &namespace) } else { Fail("network config error: " + fmt.Sprint(err)) } } case Veth, Tap: { - if netIf, err := newNetworkInterface(elem, s.ip4AddrAllocator); err == nil { - s.netConfigs = append(s.netConfigs, netIf) - s.netInterfaces[netIf.Name()] = netIf + if netIf, err := newNetworkInterface(elem, s.Ip4AddrAllocator); err == nil { + s.NetConfigs = append(s.NetConfigs, netIf) + s.NetInterfaces[netIf.Name()] = netIf } else { Fail("network config error: " + fmt.Sprint(err)) } @@ -374,7 +383,7 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { case Bridge: { if bridge, err := newBridge(elem); err == nil { - s.netConfigs = append(s.netConfigs, &bridge) + s.NetConfigs = append(s.NetConfigs, &bridge) } else { Fail("network config error: " + fmt.Sprint(err)) } @@ -383,67 +392,67 @@ func (s *HstSuite) loadNetworkTopology(topologyName string) { } } -func (s *HstSuite) configureNetworkTopology(topologyName string) { - s.loadNetworkTopology(topologyName) +func (s *HstSuite) ConfigureNetworkTopology(topologyName string) { + s.LoadNetworkTopology(topologyName) - if *isUnconfiguring { + if *IsUnconfiguring { return } - for _, nc := range s.netConfigs { - s.log(nc.Name()) + for _, nc := range s.NetConfigs { + s.Log(nc.Name()) if err := nc.configure(); err != nil { Fail("Network config error: " + fmt.Sprint(err)) } } } -func (s *HstSuite) unconfigureNetworkTopology() { - if *isPersistent { +func (s *HstSuite) UnconfigureNetworkTopology() { + if *IsPersistent { return } - for _, nc := range s.netConfigs { + for _, nc := range s.NetConfigs { nc.unconfigure() } } -func (s *HstSuite) getTestId() string { - testName := s.getCurrentTestName() +func (s *HstSuite) GetTestId() string { + testName := s.GetCurrentTestName() - if s.testIds == nil { - s.testIds = map[string]string{} + 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") + if _, ok := s.TestIds[testName]; !ok { + s.TestIds[testName] = time.Now().Format("2006-01-02_15-04-05") } - return s.testIds[testName] + return s.TestIds[testName] } -func (s *HstSuite) getCurrentTestName() string { +func (s *HstSuite) GetCurrentTestName() string { return strings.Split(CurrentSpecReport().LeafNodeText, "/")[1] } -func (s *HstSuite) getCurrentSuiteName() string { +func (s *HstSuite) GetCurrentSuiteName() string { return CurrentSpecReport().ContainerHierarchyTexts[0] } // Returns last 3 digits of PID + Ginkgo process index as the 4th digit -func (s *HstSuite) getPortFromPpid() string { - port := s.ppid +func (s *HstSuite) GetPortFromPpid() string { + port := s.Ppid for len(port) < 3 { port += "0" } - return port[len(port)-3:] + s.processIndex + return port[len(port)-3:] + s.ProcessIndex } -func (s *HstSuite) startServerApp(running chan error, done chan struct{}, env []string) { - cmd := exec.Command("iperf3", "-4", "-s", "-p", s.getPortFromPpid()) +func (s *HstSuite) StartServerApp(running chan error, done chan struct{}, env []string) { + cmd := exec.Command("iperf3", "-4", "-s", "-p", s.GetPortFromPpid()) if env != nil { cmd.Env = env } - s.log(cmd) + s.Log(cmd) err := cmd.Start() if err != nil { msg := fmt.Errorf("failed to start iperf server: %v", err) @@ -455,7 +464,7 @@ func (s *HstSuite) startServerApp(running chan error, done chan struct{}, env [] cmd.Process.Kill() } -func (s *HstSuite) startClientApp(ipAddress string, env []string, clnCh chan error, clnRes chan string) { +func (s *HstSuite) StartClientApp(ipAddress string, env []string, clnCh chan error, clnRes chan string) { defer func() { clnCh <- nil }() @@ -463,11 +472,11 @@ func (s *HstSuite) startClientApp(ipAddress string, env []string, clnCh chan err nTries := 0 for { - cmd := exec.Command("iperf3", "-c", ipAddress, "-u", "-l", "1460", "-b", "10g", "-p", s.getPortFromPpid()) + cmd := exec.Command("iperf3", "-c", ipAddress, "-u", "-l", "1460", "-b", "10g", "-p", s.GetPortFromPpid()) if env != nil { cmd.Env = env } - s.log(cmd) + s.Log(cmd) o, err := cmd.CombinedOutput() if err != nil { if nTries > 5 { @@ -484,12 +493,12 @@ func (s *HstSuite) startClientApp(ipAddress string, env []string, clnCh chan err } } -func (s *HstSuite) startHttpServer(running chan struct{}, done chan struct{}, addressPort, netNs string) { - cmd := newCommand([]string{"./http_server", addressPort, s.ppid, s.processIndex}, netNs) +func (s *HstSuite) StartHttpServer(running chan struct{}, done chan struct{}, addressPort, netNs string) { + cmd := newCommand([]string{"./http_server", addressPort, s.Ppid, s.ProcessIndex}, netNs) err := cmd.Start() - s.log(cmd) + s.Log(cmd) if err != nil { - s.log("Failed to start http server: " + fmt.Sprint(err)) + s.Log("Failed to start http server: " + fmt.Sprint(err)) return } running <- struct{}{} @@ -497,14 +506,14 @@ func (s *HstSuite) startHttpServer(running chan struct{}, done chan struct{}, ad cmd.Process.Kill() } -func (s *HstSuite) startWget(finished chan error, server_ip, port, query, netNs string) { +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) + s.Log(cmd) o, err := cmd.CombinedOutput() if err != nil { finished <- fmt.Errorf("wget error: '%v\n\n%s'", err, o) @@ -524,7 +533,7 @@ You can also instruct runBenchmark to run with multiple concurrent workers. You can record multiple named measurements (float64 or duration) within passed-in callback. runBenchmark then produces report to show statistical distribution of measurements. */ -func (s *HstSuite) runBenchmark(name string, samplesNum, parallelNum int, callback func(s *HstSuite, e *gmeasure.Experiment, data interface{}), data interface{}) { +func (s *HstSuite) RunBenchmark(name string, samplesNum, parallelNum int, callback func(s *HstSuite, e *gmeasure.Experiment, data interface{}), data interface{}) { experiment := gmeasure.NewExperiment(name) experiment.Sample(func(idx int) { diff --git a/extras/hs-test/netconfig.go b/extras/hs-test/infra/netconfig.go index c76a0fda5f5..3f3d3e3e84c 100644 --- a/extras/hs-test/netconfig.go +++ b/extras/hs-test/infra/netconfig.go @@ -1,4 +1,4 @@ -package main +package hst import ( "errors" @@ -32,13 +32,13 @@ type ( NetInterface struct { NetConfigBase - ip4AddrAllocator *Ip4AddressAllocator - ip4Address string - index InterfaceIndex - hwAddress MacAddress - networkNamespace string - networkNumber int - peer *NetInterface + Ip4AddrAllocator *Ip4AddressAllocator + Ip4Address string + Index InterfaceIndex + HwAddress MacAddress + NetworkNamespace string + NetworkNumber int + Peer *NetInterface } NetworkNamespace struct { @@ -47,8 +47,8 @@ type ( NetworkBridge struct { NetConfigBase - networkNamespace string - interfaces []string + NetworkNamespace string + Interfaces []string } ) @@ -64,7 +64,7 @@ type InterfaceAdder func(n *NetInterface) *Cmd var ( ipCommandMap = map[string]InterfaceAdder{ Veth: func(n *NetInterface) *Cmd { - return exec.Command("ip", "link", "add", n.name, "type", "veth", "peer", "name", n.peer.name) + return exec.Command("ip", "link", "add", n.name, "type", "veth", "peer", "name", n.Peer.name) }, Tap: func(n *NetInterface) *Cmd { return exec.Command("ip", "tuntap", "add", n.name, "mode", "tap") @@ -75,31 +75,31 @@ var ( func newNetworkInterface(cfg NetDevConfig, a *Ip4AddressAllocator) (*NetInterface, error) { var newInterface *NetInterface = &NetInterface{} var err error - newInterface.ip4AddrAllocator = a + newInterface.Ip4AddrAllocator = a newInterface.name = cfg["name"].(string) - newInterface.networkNumber = DEFAULT_NETWORK_NUM + newInterface.NetworkNumber = DEFAULT_NETWORK_NUM if interfaceType, ok := cfg["type"]; ok { newInterface.category = interfaceType.(string) } if presetHwAddress, ok := cfg["preset-hw-address"]; ok { - newInterface.hwAddress, err = ethernet_types.ParseMacAddress(presetHwAddress.(string)) + newInterface.HwAddress, err = ethernet_types.ParseMacAddress(presetHwAddress.(string)) if err != nil { return &NetInterface{}, err } } if netns, ok := cfg["netns"]; ok { - newInterface.networkNamespace = netns.(string) + newInterface.NetworkNamespace = netns.(string) } if ip, ok := cfg["ip4"]; ok { if n, ok := ip.(NetDevConfig)["network"]; ok { - newInterface.networkNumber = n.(int) + newInterface.NetworkNumber = n.(int) } - newInterface.ip4Address, err = newInterface.ip4AddrAllocator.NewIp4InterfaceAddress( - newInterface.networkNumber, + newInterface.Ip4Address, err = newInterface.Ip4AddrAllocator.NewIp4InterfaceAddress( + newInterface.NetworkNumber, ) if err != nil { return &NetInterface{}, err @@ -112,7 +112,7 @@ func newNetworkInterface(cfg NetDevConfig, a *Ip4AddressAllocator) (*NetInterfac peer := cfg["peer"].(NetDevConfig) - if newInterface.peer, err = newNetworkInterface(peer, a); err != nil { + if newInterface.Peer, err = newNetworkInterface(peer, a); err != nil { return &NetInterface{}, err } @@ -128,8 +128,8 @@ func (n *NetInterface) configureUpState() error { } func (n *NetInterface) configureNetworkNamespace() error { - if n.networkNamespace != "" { - err := linkSetNetns(n.name, n.networkNamespace) + if n.NetworkNamespace != "" { + err := linkSetNetns(n.name, n.NetworkNamespace) if err != nil { return err } @@ -138,11 +138,11 @@ func (n *NetInterface) configureNetworkNamespace() error { } func (n *NetInterface) configureAddress() error { - if n.ip4Address != "" { + if n.Ip4Address != "" { if err := addAddress( n.Name(), - n.ip4Address, - n.networkNamespace, + n.Ip4Address, + n.NetworkNamespace, ); err != nil { return err } @@ -170,16 +170,16 @@ func (n *NetInterface) configure() error { return err } - if n.peer != nil && n.peer.name != "" { - if err := n.peer.configureUpState(); err != nil { + if n.Peer != nil && n.Peer.name != "" { + if err := n.Peer.configureUpState(); err != nil { return err } - if err := n.peer.configureNetworkNamespace(); err != nil { + if err := n.Peer.configureNetworkNamespace(); err != nil { return err } - if err := n.peer.configureAddress(); err != nil { + if err := n.Peer.configureAddress(); err != nil { return err } } @@ -199,19 +199,19 @@ func (n *NetInterface) Type() string { return n.category } -func (n *NetInterface) addressWithPrefix() AddressWithPrefix { - address, _ := ip_types.ParseAddressWithPrefix(n.ip4Address) +func (n *NetInterface) AddressWithPrefix() AddressWithPrefix { + address, _ := ip_types.ParseAddressWithPrefix(n.Ip4Address) return address } -func (n *NetInterface) ip4AddressWithPrefix() IP4AddressWithPrefix { - ip4Prefix, _ := ip_types.ParseIP4Prefix(n.ip4Address) - ip4AddressWithPrefix := ip_types.IP4AddressWithPrefix(ip4Prefix) - return ip4AddressWithPrefix +func (n *NetInterface) Ip4AddressWithPrefix() IP4AddressWithPrefix { + ip4Prefix, _ := ip_types.ParseIP4Prefix(n.Ip4Address) + Ip4AddressWithPrefix := ip_types.IP4AddressWithPrefix(ip4Prefix) + return Ip4AddressWithPrefix } -func (n *NetInterface) ip4AddressString() string { - return strings.Split(n.ip4Address, "/")[0] +func (n *NetInterface) Ip4AddressString() string { + return strings.Split(n.Ip4Address, "/")[0] } func (b *NetConfigBase) Name() string { @@ -242,22 +242,22 @@ func newBridge(cfg NetDevConfig) (NetworkBridge, error) { bridge.name = cfg["name"].(string) bridge.category = Bridge for _, v := range cfg["interfaces"].([]interface{}) { - bridge.interfaces = append(bridge.interfaces, v.(string)) + bridge.Interfaces = append(bridge.Interfaces, v.(string)) } - bridge.networkNamespace = "" + bridge.NetworkNamespace = "" if netns, ok := cfg["netns"]; ok { - bridge.networkNamespace = netns.(string) + bridge.NetworkNamespace = netns.(string) } return bridge, nil } func (b *NetworkBridge) configure() error { - return addBridge(b.name, b.interfaces, b.networkNamespace) + return addBridge(b.name, b.Interfaces, b.NetworkNamespace) } func (b *NetworkBridge) unconfigure() { - delBridge(b.name, b.networkNamespace) + delBridge(b.name, b.NetworkNamespace) } func delBridge(brName, ns string) error { diff --git a/extras/hs-test/suite_nginx_test.go b/extras/hs-test/infra/suite_nginx.go index 7caf16ef432..f835262d591 100644 --- a/extras/hs-test/suite_nginx_test.go +++ b/extras/hs-test/infra/suite_nginx.go @@ -1,4 +1,4 @@ -package main +package hst import ( "reflect" @@ -10,11 +10,11 @@ import ( // These correspond to names used in yaml config const ( - vppProxyContainerName = "vpp-proxy" - nginxProxyContainerName = "nginx-proxy" - nginxServerContainerName = "nginx-server" - mirroringClientInterfaceName = "hstcln" - mirroringServerInterfaceName = "hstsrv" + VppProxyContainerName = "vpp-proxy" + NginxProxyContainerName = "nginx-proxy" + NginxServerContainerName = "nginx-server" + MirroringClientInterfaceName = "hstcln" + MirroringServerInterfaceName = "hstsrv" ) var nginxTests = map[string][]func(s *NginxSuite){} @@ -24,17 +24,17 @@ type NginxSuite struct { HstSuite } -func registerNginxTests(tests ...func(s *NginxSuite)) { +func RegisterNginxTests(tests ...func(s *NginxSuite)) { nginxTests[getTestFilename()] = tests } -func registerNginxSoloTests(tests ...func(s *NginxSuite)) { +func RegisterNginxSoloTests(tests ...func(s *NginxSuite)) { nginxSoloTests[getTestFilename()] = tests } func (s *NginxSuite) SetupSuite() { s.HstSuite.SetupSuite() - s.loadNetworkTopology("2taps") - s.loadContainerTopology("nginxProxyAndServer") + s.LoadNetworkTopology("2taps") + s.LoadContainerTopology("nginxProxyAndServer") } func (s *NginxSuite) SetupTest() { @@ -43,39 +43,39 @@ func (s *NginxSuite) SetupTest() { // Setup test conditions var sessionConfig Stanza sessionConfig. - newStanza("session"). - append("enable"). - append("use-app-socket-api").close() + NewStanza("session"). + Append("enable"). + Append("use-app-socket-api").Close() // ... for proxy - vppProxyContainer := s.getContainerByName(vppProxyContainerName) - proxyVpp, _ := vppProxyContainer.newVppInstance(vppProxyContainer.allocatedCpus, sessionConfig) - s.assertNil(proxyVpp.start()) + vppProxyContainer := s.GetContainerByName(VppProxyContainerName) + proxyVpp, _ := vppProxyContainer.newVppInstance(vppProxyContainer.AllocatedCpus, sessionConfig) + s.AssertNil(proxyVpp.Start()) - clientInterface := s.getInterfaceByName(mirroringClientInterfaceName) - s.assertNil(proxyVpp.createTap(clientInterface, 1)) + clientInterface := s.GetInterfaceByName(MirroringClientInterfaceName) + s.AssertNil(proxyVpp.createTap(clientInterface, 1)) - serverInterface := s.getInterfaceByName(mirroringServerInterfaceName) - s.assertNil(proxyVpp.createTap(serverInterface, 2)) + serverInterface := s.GetInterfaceByName(MirroringServerInterfaceName) + s.AssertNil(proxyVpp.createTap(serverInterface, 2)) - nginxContainer := s.getTransientContainerByName(nginxProxyContainerName) - nginxContainer.create() + nginxContainer := s.GetTransientContainerByName(NginxProxyContainerName) + nginxContainer.Create() values := struct { Proxy string Server string }{ - Proxy: clientInterface.peer.ip4AddressString(), - Server: serverInterface.ip4AddressString(), + Proxy: clientInterface.Peer.Ip4AddressString(), + Server: serverInterface.Ip4AddressString(), } - nginxContainer.createConfig( + nginxContainer.CreateConfig( "/nginx.conf", "./resources/nginx/nginx_proxy_mirroring.conf", values, ) - s.assertNil(nginxContainer.start()) + s.AssertNil(nginxContainer.Start()) - proxyVpp.waitForApp("nginx-", 5) + proxyVpp.WaitForApp("nginx-", 5) } var _ = Describe("NginxSuite", Ordered, ContinueOnFailure, func() { @@ -100,9 +100,9 @@ var _ = Describe("NginxSuite", Ordered, ContinueOnFailure, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) @@ -129,9 +129,9 @@ var _ = Describe("NginxSuiteSolo", Ordered, ContinueOnFailure, Serial, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, Label("SOLO"), func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) diff --git a/extras/hs-test/suite_no_topo_test.go b/extras/hs-test/infra/suite_no_topo.go index af0cf9a197a..c48e6fb1845 100644 --- a/extras/hs-test/suite_no_topo_test.go +++ b/extras/hs-test/infra/suite_no_topo.go @@ -1,4 +1,4 @@ -package main +package hst import ( "reflect" @@ -9,9 +9,9 @@ import ( ) const ( - singleTopoContainerVpp = "vpp" - singleTopoContainerNginx = "nginx" - tapInterfaceName = "htaphost" + SingleTopoContainerVpp = "vpp" + SingleTopoContainerNginx = "nginx" + TapInterfaceName = "htaphost" ) var noTopoTests = map[string][]func(s *NoTopoSuite){} @@ -21,17 +21,17 @@ type NoTopoSuite struct { HstSuite } -func registerNoTopoTests(tests ...func(s *NoTopoSuite)) { +func RegisterNoTopoTests(tests ...func(s *NoTopoSuite)) { noTopoTests[getTestFilename()] = tests } -func registerNoTopoSoloTests(tests ...func(s *NoTopoSuite)) { +func RegisterNoTopoSoloTests(tests ...func(s *NoTopoSuite)) { noTopoSoloTests[getTestFilename()] = tests } func (s *NoTopoSuite) SetupSuite() { s.HstSuite.SetupSuite() - s.loadNetworkTopology("tap") - s.loadContainerTopology("single") + s.LoadNetworkTopology("tap") + s.LoadContainerTopology("single") } func (s *NoTopoSuite) SetupTest() { @@ -40,17 +40,17 @@ func (s *NoTopoSuite) SetupTest() { // Setup test conditions var sessionConfig Stanza sessionConfig. - newStanza("session"). - append("enable"). - append("use-app-socket-api").close() + NewStanza("session"). + Append("enable"). + Append("use-app-socket-api").Close() - container := s.getContainerByName(singleTopoContainerVpp) - vpp, _ := container.newVppInstance(container.allocatedCpus, sessionConfig) - s.assertNil(vpp.start()) + container := s.GetContainerByName(SingleTopoContainerVpp) + vpp, _ := container.newVppInstance(container.AllocatedCpus, sessionConfig) + s.AssertNil(vpp.Start()) - tapInterface := s.getInterfaceByName(tapInterfaceName) + tapInterface := s.GetInterfaceByName(TapInterfaceName) - s.assertNil(vpp.createTap(tapInterface), "failed to create tap interface") + s.AssertNil(vpp.createTap(tapInterface), "failed to create tap interface") } var _ = Describe("NoTopoSuite", Ordered, ContinueOnFailure, func() { @@ -75,9 +75,9 @@ var _ = Describe("NoTopoSuite", Ordered, ContinueOnFailure, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) @@ -104,9 +104,9 @@ var _ = Describe("NoTopoSuiteSolo", Ordered, ContinueOnFailure, Serial, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, Label("SOLO"), func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) diff --git a/extras/hs-test/suite_ns_test.go b/extras/hs-test/infra/suite_ns.go index b4fa7718041..d88730b1c0b 100644 --- a/extras/hs-test/suite_ns_test.go +++ b/extras/hs-test/infra/suite_ns.go @@ -1,4 +1,4 @@ -package main +package hst import ( "fmt" @@ -11,8 +11,8 @@ import ( // These correspond to names used in yaml config const ( - clientInterface = "hclnvpp" - serverInterface = "hsrvvpp" + ClientInterface = "hclnvpp" + ServerInterface = "hsrvvpp" ) var nsTests = map[string][]func(s *NsSuite){} @@ -22,17 +22,17 @@ type NsSuite struct { HstSuite } -func registerNsTests(tests ...func(s *NsSuite)) { +func RegisterNsTests(tests ...func(s *NsSuite)) { nsTests[getTestFilename()] = tests } -func registerNsSoloTests(tests ...func(s *NsSuite)) { +func RegisterNsSoloTests(tests ...func(s *NsSuite)) { nsSoloTests[getTestFilename()] = tests } func (s *NsSuite) SetupSuite() { s.HstSuite.SetupSuite() - s.configureNetworkTopology("ns") - s.loadContainerTopology("ns") + s.ConfigureNetworkTopology("ns") + s.LoadContainerTopology("ns") } func (s *NsSuite) SetupTest() { @@ -41,25 +41,25 @@ func (s *NsSuite) SetupTest() { // Setup test conditions var sessionConfig Stanza sessionConfig. - newStanza("session"). - append("enable"). - append("use-app-socket-api"). - append("evt_qs_memfd_seg"). - append("event-queue-length 100000").close() + 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(container.allocatedCpus, sessionConfig) - s.assertNil(vpp.start()) + container := s.GetContainerByName("vpp") + vpp, _ := container.newVppInstance(container.AllocatedCpus, sessionConfig) + s.AssertNil(vpp.Start()) - idx, err := vpp.createAfPacket(s.getInterfaceByName(serverInterface)) - s.assertNil(err, fmt.Sprint(err)) - s.assertNotEqual(0, idx) + idx, err := vpp.createAfPacket(s.GetInterfaceByName(ServerInterface)) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) - idx, err = vpp.createAfPacket(s.getInterfaceByName(clientInterface)) - s.assertNil(err, fmt.Sprint(err)) - s.assertNotEqual(0, idx) + idx, err = vpp.createAfPacket(s.GetInterfaceByName(ClientInterface)) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) - container.exec("chmod 777 -R %s", container.getContainerWorkDir()) + container.Exec("chmod 777 -R %s", container.GetContainerWorkDir()) } var _ = Describe("NsSuite", Ordered, ContinueOnFailure, func() { @@ -84,9 +84,9 @@ var _ = Describe("NsSuite", Ordered, ContinueOnFailure, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) @@ -113,9 +113,9 @@ var _ = Describe("NsSuiteSolo", Ordered, ContinueOnFailure, Serial, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, Label("SOLO"), func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) diff --git a/extras/hs-test/suite_tap_test.go b/extras/hs-test/infra/suite_tap.go index bb7082de480..c02ab8e8535 100644 --- a/extras/hs-test/suite_tap_test.go +++ b/extras/hs-test/infra/suite_tap.go @@ -1,4 +1,4 @@ -package main +package hst import ( "reflect" @@ -16,17 +16,17 @@ type TapSuite struct { var tapTests = map[string][]func(s *TapSuite){} var tapSoloTests = map[string][]func(s *TapSuite){} -func registerTapTests(tests ...func(s *TapSuite)) { +func RegisterTapTests(tests ...func(s *TapSuite)) { tapTests[getTestFilename()] = tests } -func registerTapSoloTests(tests ...func(s *TapSuite)) { +func RegisterTapSoloTests(tests ...func(s *TapSuite)) { tapSoloTests[getTestFilename()] = tests } func (s *TapSuite) SetupSuite() { time.Sleep(1 * time.Second) s.HstSuite.SetupSuite() - s.configureNetworkTopology("tap") + s.ConfigureNetworkTopology("tap") } var _ = Describe("TapSuite", Ordered, ContinueOnFailure, func() { @@ -51,9 +51,9 @@ var _ = Describe("TapSuite", Ordered, ContinueOnFailure, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) @@ -80,9 +80,9 @@ var _ = Describe("TapSuiteSolo", Ordered, ContinueOnFailure, Serial, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, Label("SOLO"), func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) diff --git a/extras/hs-test/suite_veth_test.go b/extras/hs-test/infra/suite_veth.go index 49a36cacb83..d7bfa55acd0 100644 --- a/extras/hs-test/suite_veth_test.go +++ b/extras/hs-test/infra/suite_veth.go @@ -1,4 +1,4 @@ -package main +package hst import ( "fmt" @@ -12,8 +12,8 @@ import ( // These correspond to names used in yaml config const ( - serverInterfaceName = "srv" - clientInterfaceName = "cln" + ServerInterfaceName = "srv" + ClientInterfaceName = "cln" ) var vethTests = map[string][]func(s *VethsSuite){} @@ -23,18 +23,18 @@ type VethsSuite struct { HstSuite } -func registerVethTests(tests ...func(s *VethsSuite)) { +func RegisterVethTests(tests ...func(s *VethsSuite)) { vethTests[getTestFilename()] = tests } -func registerSoloVethTests(tests ...func(s *VethsSuite)) { +func RegisterSoloVethTests(tests ...func(s *VethsSuite)) { vethSoloTests[getTestFilename()] = tests } func (s *VethsSuite) SetupSuite() { time.Sleep(1 * time.Second) s.HstSuite.SetupSuite() - s.configureNetworkTopology("2peerVeth") - s.loadContainerTopology("2peerVeth") + s.ConfigureNetworkTopology("2peerVeth") + s.LoadContainerTopology("2peerVeth") } func (s *VethsSuite) SetupTest() { @@ -43,45 +43,45 @@ func (s *VethsSuite) SetupTest() { // Setup test conditions var sessionConfig Stanza sessionConfig. - newStanza("session"). - append("enable"). - append("use-app-socket-api").close() + NewStanza("session"). + Append("enable"). + Append("use-app-socket-api").Close() // ... For server - serverContainer := s.getContainerByName("server-vpp") + serverContainer := s.GetContainerByName("server-vpp") - serverVpp, err := serverContainer.newVppInstance(serverContainer.allocatedCpus, sessionConfig) - s.assertNotNil(serverVpp, fmt.Sprint(err)) + serverVpp, err := serverContainer.newVppInstance(serverContainer.AllocatedCpus, sessionConfig) + s.AssertNotNil(serverVpp, fmt.Sprint(err)) - s.setupServerVpp() + s.SetupServerVpp() // ... For client - clientContainer := s.getContainerByName("client-vpp") + clientContainer := s.GetContainerByName("client-vpp") - clientVpp, err := clientContainer.newVppInstance(clientContainer.allocatedCpus, sessionConfig) - s.assertNotNil(clientVpp, fmt.Sprint(err)) + clientVpp, err := clientContainer.newVppInstance(clientContainer.AllocatedCpus, sessionConfig) + s.AssertNotNil(clientVpp, fmt.Sprint(err)) s.setupClientVpp() } -func (s *VethsSuite) setupServerVpp() { - serverVpp := s.getContainerByName("server-vpp").vppInstance - s.assertNil(serverVpp.start()) +func (s *VethsSuite) SetupServerVpp() { + serverVpp := s.GetContainerByName("server-vpp").VppInstance + s.AssertNil(serverVpp.Start()) - serverVeth := s.getInterfaceByName(serverInterfaceName) + serverVeth := s.GetInterfaceByName(ServerInterfaceName) idx, err := serverVpp.createAfPacket(serverVeth) - s.assertNil(err, fmt.Sprint(err)) - s.assertNotEqual(0, idx) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) } func (s *VethsSuite) setupClientVpp() { - clientVpp := s.getContainerByName("client-vpp").vppInstance - s.assertNil(clientVpp.start()) + clientVpp := s.GetContainerByName("client-vpp").VppInstance + s.AssertNil(clientVpp.Start()) - clientVeth := s.getInterfaceByName(clientInterfaceName) + clientVeth := s.GetInterfaceByName(ClientInterfaceName) idx, err := clientVpp.createAfPacket(clientVeth) - s.assertNil(err, fmt.Sprint(err)) - s.assertNotEqual(0, idx) + s.AssertNil(err, fmt.Sprint(err)) + s.AssertNotEqual(0, idx) } var _ = Describe("VethsSuite", Ordered, ContinueOnFailure, func() { @@ -108,9 +108,9 @@ var _ = Describe("VethsSuite", Ordered, ContinueOnFailure, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) @@ -138,9 +138,9 @@ var _ = Describe("VethsSuiteSolo", Ordered, ContinueOnFailure, Serial, func() { funcValue := runtime.FuncForPC(pc) testName := filename + "/" + strings.Split(funcValue.Name(), ".")[2] It(testName, Label("SOLO"), func(ctx SpecContext) { - s.log(testName + ": BEGIN") + s.Log(testName + ": BEGIN") test(&s) - }, SpecTimeout(suiteTimeout)) + }, SpecTimeout(SuiteTimeout)) } } }) diff --git a/extras/hs-test/topo.go b/extras/hs-test/infra/topo.go index 6cb294511b3..f9c6528ba93 100644 --- a/extras/hs-test/topo.go +++ b/extras/hs-test/infra/topo.go @@ -1,4 +1,4 @@ -package main +package hst import ( "fmt" diff --git a/extras/hs-test/utils.go b/extras/hs-test/infra/utils.go index b61ac4271d6..9619efbbf63 100644 --- a/extras/hs-test/utils.go +++ b/extras/hs-test/infra/utils.go @@ -1,4 +1,4 @@ -package main +package hst import ( "fmt" @@ -32,7 +32,7 @@ type JsonResult struct { StdOutput string } -func assertFileSize(f1, f2 string) error { +func AssertFileSize(f1, f2 string) error { fi1, err := os.Stat(f1) if err != nil { return err @@ -49,29 +49,29 @@ func assertFileSize(f1, f2 string) error { return nil } -func (c *Stanza) newStanza(name string) *Stanza { - c.append("\n" + name + " {") +func (c *Stanza) NewStanza(name string) *Stanza { + c.Append("\n" + name + " {") c.pad += 2 return c } -func (c *Stanza) append(name string) *Stanza { +func (c *Stanza) Append(name string) *Stanza { c.content += strings.Repeat(" ", c.pad) c.content += name + "\n" return c } -func (c *Stanza) close() *Stanza { +func (c *Stanza) Close() *Stanza { c.content += "}\n" c.pad -= 2 return c } -func (s *Stanza) toString() string { +func (s *Stanza) ToString() string { return s.content } -func (s *Stanza) saveToFile(fileName string) error { +func (s *Stanza) SaveToFile(fileName string) error { fo, err := os.Create(fileName) if err != nil { return err @@ -82,8 +82,8 @@ func (s *Stanza) saveToFile(fileName string) error { return err } -// newHttpClient creates [http.Client] with disabled proxy and redirects, it also sets timeout to 30seconds. -func newHttpClient() *http.Client { +// NewHttpClient creates [http.Client] with disabled proxy and redirects, it also sets timeout to 30seconds. +func NewHttpClient() *http.Client { transport := http.DefaultTransport transport.(*http.Transport).Proxy = nil transport.(*http.Transport).DisableKeepAlives = true @@ -96,7 +96,7 @@ func newHttpClient() *http.Client { return client } -func tcpSendReceive(address, data string) (string, error) { +func TcpSendReceive(address, data string) (string, error) { conn, err := net.DialTimeout("tcp", address, time.Second*30) if err != nil { return "", err diff --git a/extras/hs-test/vppinstance.go b/extras/hs-test/infra/vppinstance.go index 4b2c7551034..5164a54aa9a 100644 --- a/extras/hs-test/vppinstance.go +++ b/extras/hs-test/infra/vppinstance.go @@ -1,4 +1,4 @@ -package main +package hst import ( "context" @@ -83,45 +83,45 @@ const ( ) type VppInstance struct { - container *Container - additionalConfig []Stanza - connection *core.Connection - apiStream api.Stream - cpus []int + Container *Container + AdditionalConfig []Stanza + Connection *core.Connection + ApiStream api.Stream + Cpus []int } func (vpp *VppInstance) getSuite() *HstSuite { - return vpp.container.suite + return vpp.Container.Suite } func (vpp *VppInstance) getCliSocket() string { - return fmt.Sprintf("%s%s", vpp.container.getContainerWorkDir(), defaultCliSocketFilePath) + return fmt.Sprintf("%s%s", vpp.Container.GetContainerWorkDir(), defaultCliSocketFilePath) } func (vpp *VppInstance) getRunDir() string { - return vpp.container.getContainerWorkDir() + "/var/run/vpp" + return vpp.Container.GetContainerWorkDir() + "/var/run/vpp" } func (vpp *VppInstance) getLogDir() string { - return vpp.container.getContainerWorkDir() + "/var/log/vpp" + return vpp.Container.GetContainerWorkDir() + "/var/log/vpp" } func (vpp *VppInstance) getEtcDir() string { - return vpp.container.getContainerWorkDir() + "/etc/vpp" + return vpp.Container.GetContainerWorkDir() + "/etc/vpp" } -func (vpp *VppInstance) start() error { +func (vpp *VppInstance) Start() error { maxReconnectAttempts := 3 // Replace default logger in govpp with our own govppLogger := logrus.New() - govppLogger.SetOutput(io.MultiWriter(vpp.getSuite().logger.Writer(), GinkgoWriter)) + govppLogger.SetOutput(io.MultiWriter(vpp.getSuite().Logger.Writer(), GinkgoWriter)) core.SetLogger(govppLogger) // Create folders - containerWorkDir := vpp.container.getContainerWorkDir() + containerWorkDir := vpp.Container.GetContainerWorkDir() - vpp.container.exec("mkdir --mode=0700 -p " + vpp.getRunDir()) - vpp.container.exec("mkdir --mode=0700 -p " + vpp.getLogDir()) - vpp.container.exec("mkdir --mode=0700 -p " + vpp.getEtcDir()) + vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getRunDir()) + vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getLogDir()) + vpp.Container.Exec("mkdir --mode=0700 -p " + vpp.getEtcDir()) // Create startup.conf inside the container configContent := fmt.Sprintf( @@ -132,20 +132,20 @@ func (vpp *VppInstance) start() error { defaultLogFilePath, ) configContent += vpp.generateCpuConfig() - for _, c := range vpp.additionalConfig { - configContent += c.toString() + for _, c := range vpp.AdditionalConfig { + configContent += c.ToString() } startupFileName := vpp.getEtcDir() + "/startup.conf" - vpp.container.createFile(startupFileName, configContent) + vpp.Container.CreateFile(startupFileName, configContent) // create wrapper script for vppctl with proper CLI socket path cliContent := "#!/usr/bin/bash\nvppctl -s " + vpp.getRunDir() + "/cli.sock" vppcliFileName := "/usr/bin/vppcli" - vpp.container.createFile(vppcliFileName, cliContent) - vpp.container.exec("chmod 0755 " + vppcliFileName) + vpp.Container.CreateFile(vppcliFileName, cliContent) + vpp.Container.Exec("chmod 0755 " + vppcliFileName) - vpp.getSuite().log("starting vpp") - if *isVppDebug { + vpp.getSuite().Log("starting vpp") + if *IsVppDebug { // default = 3; VPP will timeout while debugging if there are not enough attempts maxReconnectAttempts = 5000 sig := make(chan os.Signal, 1) @@ -156,34 +156,34 @@ func (vpp *VppInstance) start() error { cont <- true }() - vpp.container.execServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"") + vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"") fmt.Println("run following command in different terminal:") - fmt.Println("docker exec -it " + vpp.container.name + " gdb -ex \"attach $(docker exec " + vpp.container.name + " pidof vpp)\"") + fmt.Println("docker exec -it " + vpp.Container.Name + " gdb -ex \"attach $(docker exec " + vpp.Container.Name + " pidof vpp)\"") fmt.Println("Afterwards press CTRL+\\ to continue") <-cont fmt.Println("continuing...") } else { // Start VPP - vpp.container.execServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"") + vpp.Container.ExecServer("su -c \"vpp -c " + startupFileName + " &> /proc/1/fd/1\"") } - vpp.getSuite().log("connecting to vpp") + vpp.getSuite().Log("connecting to vpp") // Connect to VPP and store the connection - sockAddress := vpp.container.getHostWorkDir() + defaultApiSocketFilePath + sockAddress := vpp.Container.GetHostWorkDir() + defaultApiSocketFilePath conn, connEv, err := govpp.AsyncConnect( sockAddress, maxReconnectAttempts, core.DefaultReconnectInterval) if err != nil { - vpp.getSuite().log("async connect error: " + fmt.Sprint(err)) + vpp.getSuite().Log("async connect error: " + fmt.Sprint(err)) return err } - vpp.connection = conn + vpp.Connection = conn // ... wait for Connected event e := <-connEv if e.State != core.Connected { - vpp.getSuite().log("connecting to VPP failed: " + fmt.Sprint(e.Error)) + vpp.getSuite().Log("connecting to VPP failed: " + fmt.Sprint(e.Error)) } ch, err := conn.NewStream( @@ -192,28 +192,28 @@ func (vpp *VppInstance) start() error { core.WithReplySize(50), core.WithReplyTimeout(time.Second*5)) if err != nil { - vpp.getSuite().log("creating stream failed: " + fmt.Sprint(err)) + vpp.getSuite().Log("creating stream failed: " + fmt.Sprint(err)) return err } - vpp.apiStream = ch + vpp.ApiStream = ch return nil } -func (vpp *VppInstance) vppctl(command string, arguments ...any) string { +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.getSuite().log(containerExecCommand) + vpp.Container.Name, vpp.getCliSocket(), vppCliCommand) + vpp.getSuite().Log(containerExecCommand) output, err := exechelper.CombinedOutput(containerExecCommand) - vpp.getSuite().assertNil(err) + vpp.getSuite().AssertNil(err) return string(output) } func (vpp *VppInstance) GetSessionStat(stat string) int { - o := vpp.vppctl("show session stats") - vpp.getSuite().log(o) + o := vpp.Vppctl("show session stats") + vpp.getSuite().Log(o) for _, line := range strings.Split(o, "\n") { if strings.Contains(line, stat) { tokens := strings.Split(strings.TrimSpace(line), " ") @@ -228,16 +228,16 @@ func (vpp *VppInstance) GetSessionStat(stat string) int { return 0 } -func (vpp *VppInstance) waitForApp(appName string, timeout int) { - vpp.getSuite().log("waiting for app " + appName) +func (vpp *VppInstance) WaitForApp(appName string, timeout int) { + vpp.getSuite().Log("waiting for app " + appName) for i := 0; i < timeout; i++ { - o := vpp.vppctl("show app") + o := vpp.Vppctl("show app") if strings.Contains(o, appName) { return } time.Sleep(1 * time.Second) } - vpp.getSuite().assertNil(1, "Timeout while waiting for app '%s'", appName) + vpp.getSuite().AssertNil(1, "Timeout while waiting for app '%s'", appName) } func (vpp *VppInstance) createAfPacket( @@ -249,17 +249,17 @@ func (vpp *VppInstance) createAfPacket( HostIfName: veth.Name(), Flags: af_packet.AfPacketFlags(11), } - if veth.hwAddress != (MacAddress{}) { + if veth.HwAddress != (MacAddress{}) { createReq.UseRandomHwAddr = false - createReq.HwAddr = veth.hwAddress + createReq.HwAddr = veth.HwAddress } - vpp.getSuite().log("create af-packet interface " + veth.Name()) - if err := vpp.apiStream.SendMsg(createReq); err != nil { - vpp.getSuite().hstFail() + vpp.getSuite().Log("create af-packet interface " + veth.Name()) + if err := vpp.ApiStream.SendMsg(createReq); err != nil { + vpp.getSuite().HstFail() return 0, err } - replymsg, err := vpp.apiStream.RecvMsg() + replymsg, err := vpp.ApiStream.RecvMsg() if err != nil { return 0, err } @@ -269,19 +269,19 @@ func (vpp *VppInstance) createAfPacket( return 0, err } - veth.index = reply.SwIfIndex + veth.Index = reply.SwIfIndex // Set to up upReq := &interfaces.SwInterfaceSetFlags{ - SwIfIndex: veth.index, + SwIfIndex: veth.Index, Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP, } - vpp.getSuite().log("set af-packet interface " + veth.Name() + " up") - if err := vpp.apiStream.SendMsg(upReq); err != nil { + vpp.getSuite().Log("set af-packet interface " + veth.Name() + " up") + if err := vpp.ApiStream.SendMsg(upReq); err != nil { return 0, err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return 0, err } @@ -291,26 +291,26 @@ func (vpp *VppInstance) createAfPacket( } // Add address - if veth.addressWithPrefix() == (AddressWithPrefix{}) { + if veth.AddressWithPrefix() == (AddressWithPrefix{}) { var err error var ip4Address string - if ip4Address, err = veth.ip4AddrAllocator.NewIp4InterfaceAddress(veth.peer.networkNumber); err == nil { - veth.ip4Address = ip4Address + if ip4Address, err = veth.Ip4AddrAllocator.NewIp4InterfaceAddress(veth.Peer.NetworkNumber); err == nil { + veth.Ip4Address = ip4Address } else { return 0, err } } addressReq := &interfaces.SwInterfaceAddDelAddress{ IsAdd: true, - SwIfIndex: veth.index, - Prefix: veth.addressWithPrefix(), + SwIfIndex: veth.Index, + Prefix: veth.AddressWithPrefix(), } - vpp.getSuite().log("af-packet interface " + veth.Name() + " add address " + veth.ip4Address) - if err := vpp.apiStream.SendMsg(addressReq); err != nil { + vpp.getSuite().Log("af-packet interface " + veth.Name() + " add address " + veth.Ip4Address) + if err := vpp.ApiStream.SendMsg(addressReq); err != nil { return 0, err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return 0, err } @@ -320,7 +320,7 @@ func (vpp *VppInstance) createAfPacket( return 0, err } - return veth.index, nil + return veth.Index, nil } func (vpp *VppInstance) addAppNamespace( @@ -336,11 +336,11 @@ func (vpp *VppInstance) addAppNamespace( SockName: defaultApiSocketFilePath, } - vpp.getSuite().log("add app namespace " + namespaceId) - if err := vpp.apiStream.SendMsg(req); err != nil { + vpp.getSuite().Log("add app namespace " + namespaceId) + if err := vpp.ApiStream.SendMsg(req); err != nil { return err } - replymsg, err := vpp.apiStream.RecvMsg() + replymsg, err := vpp.ApiStream.RecvMsg() if err != nil { return err } @@ -353,11 +353,11 @@ func (vpp *VppInstance) addAppNamespace( IsEnable: true, } - vpp.getSuite().log("enable app namespace " + namespaceId) - if err := vpp.apiStream.SendMsg(sessionReq); err != nil { + vpp.getSuite().Log("enable app namespace " + namespaceId) + if err := vpp.ApiStream.SendMsg(sessionReq); err != nil { return err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return err } @@ -382,15 +382,15 @@ func (vpp *VppInstance) createTap( HostIfNameSet: true, HostIfName: tap.Name(), HostIP4PrefixSet: true, - HostIP4Prefix: tap.ip4AddressWithPrefix(), + HostIP4Prefix: tap.Ip4AddressWithPrefix(), } - vpp.getSuite().log("create tap interface " + tap.Name()) + vpp.getSuite().Log("create tap interface " + tap.Name()) // Create tap interface - if err := vpp.apiStream.SendMsg(createTapReq); err != nil { + if err := vpp.ApiStream.SendMsg(createTapReq); err != nil { return err } - replymsg, err := vpp.apiStream.RecvMsg() + replymsg, err := vpp.ApiStream.RecvMsg() if err != nil { return err } @@ -398,34 +398,34 @@ func (vpp *VppInstance) createTap( if err = api.RetvalToVPPApiError(reply.Retval); err != nil { return err } - tap.peer.index = reply.SwIfIndex + tap.Peer.Index = reply.SwIfIndex // Get name and mac - if err := vpp.apiStream.SendMsg(&interfaces.SwInterfaceDump{ + if err := vpp.ApiStream.SendMsg(&interfaces.SwInterfaceDump{ SwIfIndex: reply.SwIfIndex, }); err != nil { return err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return err } ifDetails := replymsg.(*interfaces.SwInterfaceDetails) - tap.peer.name = ifDetails.InterfaceName - tap.peer.hwAddress = ifDetails.L2Address + tap.Peer.name = ifDetails.InterfaceName + tap.Peer.HwAddress = ifDetails.L2Address // Add address addAddressReq := &interfaces.SwInterfaceAddDelAddress{ IsAdd: true, SwIfIndex: reply.SwIfIndex, - Prefix: tap.peer.addressWithPrefix(), + Prefix: tap.Peer.AddressWithPrefix(), } - vpp.getSuite().log("tap interface " + tap.Name() + " add address " + tap.peer.ip4Address) - if err := vpp.apiStream.SendMsg(addAddressReq); err != nil { + vpp.getSuite().Log("tap interface " + tap.Name() + " add address " + tap.Peer.Ip4Address) + if err := vpp.ApiStream.SendMsg(addAddressReq); err != nil { return err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return err } @@ -439,11 +439,12 @@ func (vpp *VppInstance) createTap( SwIfIndex: reply.SwIfIndex, Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP, } - vpp.getSuite().log("set tap interface " + tap.Name() + " up") - if err := vpp.apiStream.SendMsg(upReq); err != nil { + + vpp.getSuite().Log("set tap interface " + tap.Name() + " up") + if err := vpp.ApiStream.SendMsg(upReq); err != nil { return err } - replymsg, err = vpp.apiStream.RecvMsg() + replymsg, err = vpp.ApiStream.RecvMsg() if err != nil { return err } @@ -455,35 +456,35 @@ func (vpp *VppInstance) createTap( // Get host mac netIntf, err := net.InterfaceByName(tap.Name()) if err == nil { - tap.hwAddress, _ = ethernet_types.ParseMacAddress(netIntf.HardwareAddr.String()) + tap.HwAddress, _ = ethernet_types.ParseMacAddress(netIntf.HardwareAddr.String()) } return nil } func (vpp *VppInstance) saveLogs() { - logTarget := vpp.container.getLogDirPath() + "vppinstance-" + vpp.container.name + ".log" - logSource := vpp.container.getHostWorkDir() + defaultLogFilePath + logTarget := vpp.Container.getLogDirPath() + "vppinstance-" + vpp.Container.Name + ".log" + logSource := vpp.Container.GetHostWorkDir() + defaultLogFilePath cmd := exec.Command("cp", logSource, logTarget) - vpp.getSuite().log(cmd.String()) + vpp.getSuite().Log(cmd.String()) cmd.Run() } -func (vpp *VppInstance) disconnect() { - vpp.connection.Disconnect() - vpp.apiStream.Close() +func (vpp *VppInstance) Disconnect() { + vpp.Connection.Disconnect() + vpp.ApiStream.Close() } func (vpp *VppInstance) generateCpuConfig() string { var c Stanza var s string - if len(vpp.cpus) < 1 { + if len(vpp.Cpus) < 1 { return "" } - c.newStanza("cpu"). - append(fmt.Sprintf("main-core %d", vpp.cpus[0])) - vpp.getSuite().log(fmt.Sprintf("main-core %d", vpp.cpus[0])) - workers := vpp.cpus[1:] + c.NewStanza("cpu"). + Append(fmt.Sprintf("main-core %d", vpp.Cpus[0])) + vpp.getSuite().Log(fmt.Sprintf("main-core %d", vpp.Cpus[0])) + workers := vpp.Cpus[1:] if len(workers) > 0 { for i := 0; i < len(workers); i++ { @@ -492,8 +493,8 @@ func (vpp *VppInstance) generateCpuConfig() string { } s = s + fmt.Sprintf("%d", workers[i]) } - c.append(fmt.Sprintf("corelist-workers %s", s)) - vpp.getSuite().log("corelist-workers " + s) + c.Append(fmt.Sprintf("corelist-workers %s", s)) + vpp.getSuite().Log("corelist-workers " + s) } - return c.close().toString() + return c.Close().ToString() } diff --git a/extras/hs-test/ldp_test.go b/extras/hs-test/ldp_test.go index 24d2de39485..fc195f1572a 100644 --- a/extras/hs-test/ldp_test.go +++ b/extras/hs-test/ldp_test.go @@ -4,21 +4,22 @@ import ( "fmt" "os" + . "fd.io/hs-test/infra" . "github.com/onsi/ginkgo/v2" ) func init() { - registerVethTests(LDPreloadIperfVppTest) + RegisterVethTests(LDPreloadIperfVppTest) } func LDPreloadIperfVppTest(s *VethsSuite) { var clnVclConf, srvVclConf Stanza - serverContainer := s.getContainerByName("server-vpp") - serverVclFileName := serverContainer.getHostWorkDir() + "/vcl_srv.conf" + serverContainer := s.GetContainerByName("server-vpp") + serverVclFileName := serverContainer.GetHostWorkDir() + "/vcl_srv.conf" - clientContainer := s.getContainerByName("client-vpp") - clientVclFileName := clientContainer.getHostWorkDir() + "/vcl_cln.conf" + clientContainer := s.GetContainerByName("client-vpp") + clientVclFileName := clientContainer.GetHostWorkDir() + "/vcl_cln.conf" ldpreload := "LD_PRELOAD=../../build-root/build-vpp-native/vpp/lib/x86_64-linux-gnu/libvcl_ldpreload.so" @@ -26,58 +27,58 @@ func LDPreloadIperfVppTest(s *VethsSuite) { srvCh := make(chan error, 1) clnCh := make(chan error) - s.log("starting VPPs") + s.Log("starting VPPs") clientAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default", - clientContainer.getHostWorkDir()) + clientContainer.GetHostWorkDir()) err := clnVclConf. - newStanza("vcl"). - append("rx-fifo-size 4000000"). - append("tx-fifo-size 4000000"). - append("app-scope-local"). - append("app-scope-global"). - append("use-mq-eventfd"). - append(clientAppSocketApi).close(). - saveToFile(clientVclFileName) - s.assertNil(err, fmt.Sprint(err)) + NewStanza("vcl"). + Append("rx-fifo-size 4000000"). + Append("tx-fifo-size 4000000"). + Append("app-scope-local"). + Append("app-scope-global"). + Append("use-mq-eventfd"). + Append(clientAppSocketApi).Close(). + SaveToFile(clientVclFileName) + s.AssertNil(err, fmt.Sprint(err)) serverAppSocketApi := fmt.Sprintf("app-socket-api %s/var/run/app_ns_sockets/default", - serverContainer.getHostWorkDir()) + serverContainer.GetHostWorkDir()) err = srvVclConf. - newStanza("vcl"). - append("rx-fifo-size 4000000"). - append("tx-fifo-size 4000000"). - append("app-scope-local"). - append("app-scope-global"). - append("use-mq-eventfd"). - append(serverAppSocketApi).close(). - saveToFile(serverVclFileName) - s.assertNil(err, fmt.Sprint(err)) - - s.log("attaching server to vpp") + NewStanza("vcl"). + Append("rx-fifo-size 4000000"). + Append("tx-fifo-size 4000000"). + Append("app-scope-local"). + Append("app-scope-global"). + Append("use-mq-eventfd"). + Append(serverAppSocketApi).Close(). + SaveToFile(serverVclFileName) + s.AssertNil(err, fmt.Sprint(err)) + + s.Log("attaching server to vpp") srvEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+serverVclFileName) go func() { defer GinkgoRecover() - s.startServerApp(srvCh, stopServerCh, srvEnv) + s.StartServerApp(srvCh, stopServerCh, srvEnv) }() err = <-srvCh - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) - s.log("attaching client to vpp") + s.Log("attaching client to vpp") var clnRes = make(chan string, 1) clnEnv := append(os.Environ(), ldpreload, "VCL_CONFIG="+clientVclFileName) - serverVethAddress := s.getInterfaceByName(serverInterfaceName).ip4AddressString() + serverVethAddress := s.GetInterfaceByName(ServerInterfaceName).Ip4AddressString() go func() { defer GinkgoRecover() - s.startClientApp(serverVethAddress, clnEnv, clnCh, clnRes) + s.StartClientApp(serverVethAddress, clnEnv, clnCh, clnRes) }() - s.log(<-clnRes) + s.Log(<-clnRes) // wait for client's result err = <-clnCh - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) // stop server stopServerCh <- struct{}{} diff --git a/extras/hs-test/linux_iperf_test.go b/extras/hs-test/linux_iperf_test.go index e323f7fb721..f49d9bcf227 100644 --- a/extras/hs-test/linux_iperf_test.go +++ b/extras/hs-test/linux_iperf_test.go @@ -1,13 +1,13 @@ package main import ( + . "fd.io/hs-test/infra" "fmt" - . "github.com/onsi/ginkgo/v2" ) func init() { - registerTapTests(LinuxIperfTest) + RegisterTapTests(LinuxIperfTest) } func LinuxIperfTest(s *TapSuite) { @@ -21,20 +21,20 @@ func LinuxIperfTest(s *TapSuite) { go func() { defer GinkgoRecover() - s.startServerApp(srvCh, stopServerCh, nil) + s.StartServerApp(srvCh, stopServerCh, nil) }() err := <-srvCh - s.assertNil(err, fmt.Sprint(err)) - s.log("server running") + s.AssertNil(err, fmt.Sprint(err)) + s.Log("server running") - ipAddress := s.getInterfaceByName(tapInterfaceName).ip4AddressString() + ipAddress := s.GetInterfaceByName(TapInterfaceName).Ip4AddressString() go func() { defer GinkgoRecover() - s.startClientApp(ipAddress, nil, clnCh, clnRes) + s.StartClientApp(ipAddress, nil, clnCh, clnRes) }() - s.log("client running") - s.log(<-clnRes) + s.Log("client running") + s.Log(<-clnRes) err = <-clnCh - s.assertNil(err, "err: '%s', ip: '%s'", err, ipAddress) - s.log("Test completed") + s.AssertNil(err, "err: '%s', ip: '%s'", err, ipAddress) + s.Log("Test completed") } diff --git a/extras/hs-test/mirroring_test.go b/extras/hs-test/mirroring_test.go index 1fd15dde2f4..57099b73d98 100644 --- a/extras/hs-test/mirroring_test.go +++ b/extras/hs-test/mirroring_test.go @@ -1,26 +1,27 @@ package main import ( + . "fd.io/hs-test/infra" "github.com/edwarnicke/exechelper" ) func init() { - registerNginxTests(MirroringTest) + RegisterNginxTests(MirroringTest) } // broken when CPUS > 1 func MirroringTest(s *NginxSuite) { s.SkipIfMultiWorker() - proxyAddress := s.getInterfaceByName(mirroringClientInterfaceName).peer.ip4AddressString() + proxyAddress := s.GetInterfaceByName(MirroringClientInterfaceName).Peer.Ip4AddressString() path := "/64B.json" testCommand := "wrk -c 20 -t 10 -d 10 http://" + proxyAddress + ":80" + path - s.log(testCommand) + s.Log(testCommand) o, _ := exechelper.Output(testCommand) - s.log(string(o)) - s.assertNotEmpty(o) + s.Log(string(o)) + s.AssertNotEmpty(o) - vppProxyContainer := s.getContainerByName(vppProxyContainerName) - s.assertEqual(0, vppProxyContainer.vppInstance.GetSessionStat("no lcl port")) + vppProxyContainer := s.GetContainerByName(VppProxyContainerName) + s.AssertEqual(0, vppProxyContainer.VppInstance.GetSessionStat("no lcl port")) } diff --git a/extras/hs-test/proxy_test.go b/extras/hs-test/proxy_test.go index c57b927846e..5f7eb45be38 100644 --- a/extras/hs-test/proxy_test.go +++ b/extras/hs-test/proxy_test.go @@ -1,37 +1,37 @@ package main import ( + . "fd.io/hs-test/infra" "fmt" - "os" - "github.com/edwarnicke/exechelper" . "github.com/onsi/ginkgo/v2" + "os" ) func init() { - registerNsTests(VppProxyHttpTcpTest, VppProxyHttpTlsTest, EnvoyProxyHttpTcpTest) + RegisterNsTests(VppProxyHttpTcpTest, VppProxyHttpTlsTest, EnvoyProxyHttpTcpTest) } func testProxyHttpTcp(s *NsSuite, proto string) error { - var outputFile string = s.processIndex + "test" + s.ppid + ".data" - var srcFilePpid string = s.processIndex + "httpTestFile" + s.ppid + var outputFile string = s.ProcessIndex + "test" + s.Ppid + ".data" + var srcFilePpid string = s.ProcessIndex + "httpTestFile" + s.Ppid const srcFileNoPpid = "httpTestFile" const fileSize string = "10M" stopServer := make(chan struct{}, 1) serverRunning := make(chan struct{}, 1) - serverNetns := s.getNetNamespaceByName("srv") - clientNetns := s.getNetNamespaceByName("cln") + serverNetns := s.GetNetNamespaceByName("srv") + clientNetns := s.GetNetNamespaceByName("cln") // create test file err := exechelper.Run(fmt.Sprintf("ip netns exec %s truncate -s %s %s", serverNetns, fileSize, srcFilePpid)) - s.assertNil(err, "failed to run truncate command: "+fmt.Sprint(err)) + s.AssertNil(err, "failed to run truncate command: "+fmt.Sprint(err)) defer func() { os.Remove(srcFilePpid) }() - s.log("test file created...") + s.Log("test file created...") go func() { defer GinkgoRecover() - s.startHttpServer(serverRunning, stopServer, ":666", serverNetns) + s.StartHttpServer(serverRunning, stopServer, ":666", serverNetns) }() // TODO better error handling and recovery <-serverRunning @@ -40,76 +40,76 @@ func testProxyHttpTcp(s *NsSuite, proto string) error { stopServer <- struct{}{} }(stopServer) - s.log("http server started...") + s.Log("http server started...") - clientVeth := s.getInterfaceByName(clientInterface) + clientVeth := s.GetInterfaceByName(ClientInterface) c := fmt.Sprintf("ip netns exec %s wget --no-proxy --retry-connrefused"+ " --retry-on-http-error=503 --tries=10 -O %s ", clientNetns, outputFile) if proto == "tls" { c += " --secure-protocol=TLSv1_3 --no-check-certificate https://" } - c += fmt.Sprintf("%s:555/%s", clientVeth.ip4AddressString(), srcFileNoPpid) - s.log(c) + c += fmt.Sprintf("%s:555/%s", clientVeth.Ip4AddressString(), srcFileNoPpid) + s.Log(c) _, err = exechelper.CombinedOutput(c) defer func() { os.Remove(outputFile) }() - s.assertNil(err, "failed to run wget: '%s', cmd: %s", err, c) + s.AssertNil(err, "failed to run wget: '%s', cmd: %s", err, c) stopServer <- struct{}{} - s.assertNil(assertFileSize(outputFile, srcFilePpid)) + s.AssertNil(AssertFileSize(outputFile, srcFilePpid)) return nil } func configureVppProxy(s *NsSuite, proto string) { - serverVeth := s.getInterfaceByName(serverInterface) - clientVeth := s.getInterfaceByName(clientInterface) + serverVeth := s.GetInterfaceByName(ServerInterface) + clientVeth := s.GetInterfaceByName(ClientInterface) - testVppProxy := s.getContainerByName("vpp").vppInstance - output := testVppProxy.vppctl( + testVppProxy := s.GetContainerByName("vpp").VppInstance + output := testVppProxy.Vppctl( "test proxy server server-uri %s://%s/555 client-uri tcp://%s/666", proto, - clientVeth.ip4AddressString(), - serverVeth.peer.ip4AddressString(), + clientVeth.Ip4AddressString(), + serverVeth.Peer.Ip4AddressString(), ) - s.log("proxy configured: " + output) + s.Log("proxy configured: " + output) } func VppProxyHttpTcpTest(s *NsSuite) { proto := "tcp" configureVppProxy(s, proto) err := testProxyHttpTcp(s, proto) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) } func VppProxyHttpTlsTest(s *NsSuite) { proto := "tls" configureVppProxy(s, proto) err := testProxyHttpTcp(s, proto) - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) } func configureEnvoyProxy(s *NsSuite) { - envoyContainer := s.getContainerByName("envoy") - err := envoyContainer.create() - s.assertNil(err, "Error creating envoy container: %s", err) + envoyContainer := s.GetContainerByName("envoy") + err := envoyContainer.Create() + s.AssertNil(err, "Error creating envoy container: %s", err) - serverVeth := s.getInterfaceByName(serverInterface) + serverVeth := s.GetInterfaceByName(ServerInterface) address := struct { Server string }{ - Server: serverVeth.peer.ip4AddressString(), + Server: serverVeth.Peer.Ip4AddressString(), } - envoyContainer.createConfig( + envoyContainer.CreateConfig( "/etc/envoy/envoy.yaml", "resources/envoy/proxy.yaml", address, ) - s.assertNil(envoyContainer.start()) + s.AssertNil(envoyContainer.Start()) } func EnvoyProxyHttpTcpTest(s *NsSuite) { configureEnvoyProxy(s) err := testProxyHttpTcp(s, "tcp") - s.assertNil(err, fmt.Sprint(err)) + s.AssertNil(err, fmt.Sprint(err)) } diff --git a/extras/hs-test/raw_session_test.go b/extras/hs-test/raw_session_test.go index 5c66df0b1ce..438b7ba03a5 100644 --- a/extras/hs-test/raw_session_test.go +++ b/extras/hs-test/raw_session_test.go @@ -1,40 +1,42 @@ package main +import . "fd.io/hs-test/infra" + func init() { - registerVethTests(VppEchoQuicTest, VppEchoTcpTest) + RegisterVethTests(VppEchoQuicTest, VppEchoTcpTest) } func VppEchoQuicTest(s *VethsSuite) { - s.testVppEcho("quic") + testVppEcho(s, "quic") } // TODO: udp echo currently broken in vpp func VppEchoUdpTest(s *VethsSuite) { - s.testVppEcho("udp") + testVppEcho(s, "udp") } func VppEchoTcpTest(s *VethsSuite) { - s.testVppEcho("tcp") + testVppEcho(s, "tcp") } -func (s *VethsSuite) testVppEcho(proto string) { - serverVethAddress := s.getInterfaceByName(serverInterfaceName).ip4AddressString() +func testVppEcho(s *VethsSuite, proto string) { + serverVethAddress := s.GetInterfaceByName(ServerInterfaceName).Ip4AddressString() uri := proto + "://" + serverVethAddress + "/12344" - echoSrvContainer := s.getContainerByName("server-app") + echoSrvContainer := s.GetContainerByName("server-app") serverCommand := "vpp_echo server TX=RX" + - " socket-name " + echoSrvContainer.getContainerWorkDir() + "/var/run/app_ns_sockets/default" + + " socket-name " + echoSrvContainer.GetContainerWorkDir() + "/var/run/app_ns_sockets/default" + " use-app-socket-api" + " uri " + uri - s.log(serverCommand) - echoSrvContainer.execServer(serverCommand) + s.Log(serverCommand) + echoSrvContainer.ExecServer(serverCommand) - echoClnContainer := s.getContainerByName("client-app") + echoClnContainer := s.GetContainerByName("client-app") clientCommand := "vpp_echo client" + - " socket-name " + echoClnContainer.getContainerWorkDir() + "/var/run/app_ns_sockets/default" + + " socket-name " + echoClnContainer.GetContainerWorkDir() + "/var/run/app_ns_sockets/default" + " use-app-socket-api uri " + uri - s.log(clientCommand) - o := echoClnContainer.exec(clientCommand) - s.log(o) + s.Log(clientCommand) + o := echoClnContainer.Exec(clientCommand) + s.Log(o) } diff --git a/extras/hs-test/vcl_test.go b/extras/hs-test/vcl_test.go index fdcd60ad503..3b413b26bed 100644 --- a/extras/hs-test/vcl_test.go +++ b/extras/hs-test/vcl_test.go @@ -1,12 +1,13 @@ package main import ( + . "fd.io/hs-test/infra" "fmt" "time" ) func init() { - registerVethTests(XEchoVclClientUdpTest, XEchoVclClientTcpTest, XEchoVclServerUdpTest, + RegisterVethTests(XEchoVclClientUdpTest, XEchoVclClientTcpTest, XEchoVclServerUdpTest, XEchoVclServerTcpTest, VclEchoTcpTest, VclEchoUdpTest, VclRetryAttachTest) } @@ -16,141 +17,141 @@ func getVclConfig(c *Container, ns_id_optional ...string) string { if len(ns_id_optional) > 0 { ns_id = ns_id_optional[0] } - s.newStanza("vcl"). - append(fmt.Sprintf("app-socket-api %[1]s/var/run/app_ns_sockets/%[2]s", c.getContainerWorkDir(), ns_id)). - append("app-scope-global"). - append("app-scope-local"). - append("use-mq-eventfd") + s.NewStanza("vcl"). + Append(fmt.Sprintf("app-socket-api %[1]s/var/run/app_ns_sockets/%[2]s", c.GetContainerWorkDir(), ns_id)). + Append("app-scope-global"). + Append("app-scope-local"). + Append("use-mq-eventfd") if len(ns_id_optional) > 0 { - s.append(fmt.Sprintf("namespace-id %[1]s", ns_id)). - append(fmt.Sprintf("namespace-secret %[1]s", ns_id)) + s.Append(fmt.Sprintf("namespace-id %[1]s", ns_id)). + Append(fmt.Sprintf("namespace-secret %[1]s", ns_id)) } - return s.close().toString() + return s.Close().ToString() } func XEchoVclClientUdpTest(s *VethsSuite) { - s.testXEchoVclClient("udp") + testXEchoVclClient(s, "udp") } func XEchoVclClientTcpTest(s *VethsSuite) { - s.testXEchoVclClient("tcp") + testXEchoVclClient(s, "tcp") } -func (s *VethsSuite) testXEchoVclClient(proto string) { +func testXEchoVclClient(s *VethsSuite, proto string) { port := "12345" - serverVpp := s.getContainerByName("server-vpp").vppInstance + serverVpp := s.GetContainerByName("server-vpp").VppInstance - serverVeth := s.getInterfaceByName(serverInterfaceName) - serverVpp.vppctl("test echo server uri %s://%s/%s fifo-size 64k", proto, serverVeth.ip4AddressString(), port) + serverVeth := s.GetInterfaceByName(ServerInterfaceName) + serverVpp.Vppctl("test echo server uri %s://%s/%s fifo-size 64k", proto, serverVeth.Ip4AddressString(), port) - echoClnContainer := s.getTransientContainerByName("client-app") - echoClnContainer.createFile("/vcl.conf", getVclConfig(echoClnContainer)) + echoClnContainer := s.GetTransientContainerByName("client-app") + echoClnContainer.CreateFile("/vcl.conf", getVclConfig(echoClnContainer)) - testClientCommand := "vcl_test_client -N 100 -p " + proto + " " + serverVeth.ip4AddressString() + " " + port - s.log(testClientCommand) - echoClnContainer.addEnvVar("VCL_CONFIG", "/vcl.conf") - o := echoClnContainer.exec(testClientCommand) - s.log(o) - s.assertContains(o, "CLIENT RESULTS") + testClientCommand := "vcl_test_client -N 100 -p " + proto + " " + serverVeth.Ip4AddressString() + " " + port + s.Log(testClientCommand) + echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf") + o := echoClnContainer.Exec(testClientCommand) + s.Log(o) + s.AssertContains(o, "CLIENT RESULTS") } func XEchoVclServerUdpTest(s *VethsSuite) { - s.testXEchoVclServer("udp") + testXEchoVclServer(s, "udp") } func XEchoVclServerTcpTest(s *VethsSuite) { - s.testXEchoVclServer("tcp") + testXEchoVclServer(s, "tcp") } -func (s *VethsSuite) testXEchoVclServer(proto string) { +func testXEchoVclServer(s *VethsSuite, proto string) { port := "12345" - srvVppCont := s.getContainerByName("server-vpp") - srvAppCont := s.getContainerByName("server-app") + srvVppCont := s.GetContainerByName("server-vpp") + srvAppCont := s.GetContainerByName("server-app") - srvAppCont.createFile("/vcl.conf", getVclConfig(srvVppCont)) - srvAppCont.addEnvVar("VCL_CONFIG", "/vcl.conf") + srvAppCont.CreateFile("/vcl.conf", getVclConfig(srvVppCont)) + srvAppCont.AddEnvVar("VCL_CONFIG", "/vcl.conf") vclSrvCmd := fmt.Sprintf("vcl_test_server -p %s %s", proto, port) - srvAppCont.execServer(vclSrvCmd) + srvAppCont.ExecServer(vclSrvCmd) - serverVeth := s.getInterfaceByName(serverInterfaceName) - serverVethAddress := serverVeth.ip4AddressString() + serverVeth := s.GetInterfaceByName(ServerInterfaceName) + serverVethAddress := serverVeth.Ip4AddressString() - clientVpp := s.getContainerByName("client-vpp").vppInstance - o := clientVpp.vppctl("test echo client uri %s://%s/%s fifo-size 64k verbose mbytes 2", proto, serverVethAddress, port) - s.log(o) - s.assertContains(o, "Test finished at") + clientVpp := s.GetContainerByName("client-vpp").VppInstance + o := clientVpp.Vppctl("test echo client uri %s://%s/%s fifo-size 64k verbose mbytes 2", proto, serverVethAddress, port) + s.Log(o) + s.AssertContains(o, "Test finished at") } -func (s *VethsSuite) testVclEcho(proto string) { +func testVclEcho(s *VethsSuite, proto string) { port := "12345" - srvVppCont := s.getContainerByName("server-vpp") - srvAppCont := s.getContainerByName("server-app") + srvVppCont := s.GetContainerByName("server-vpp") + srvAppCont := s.GetContainerByName("server-app") - srvAppCont.createFile("/vcl.conf", getVclConfig(srvVppCont)) - srvAppCont.addEnvVar("VCL_CONFIG", "/vcl.conf") - srvAppCont.execServer("vcl_test_server " + port) + srvAppCont.CreateFile("/vcl.conf", getVclConfig(srvVppCont)) + srvAppCont.AddEnvVar("VCL_CONFIG", "/vcl.conf") + srvAppCont.ExecServer("vcl_test_server " + port) - serverVeth := s.getInterfaceByName(serverInterfaceName) - serverVethAddress := serverVeth.ip4AddressString() + serverVeth := s.GetInterfaceByName(ServerInterfaceName) + serverVethAddress := serverVeth.Ip4AddressString() - echoClnContainer := s.getTransientContainerByName("client-app") - echoClnContainer.createFile("/vcl.conf", getVclConfig(echoClnContainer)) + echoClnContainer := s.GetTransientContainerByName("client-app") + echoClnContainer.CreateFile("/vcl.conf", getVclConfig(echoClnContainer)) testClientCommand := "vcl_test_client -p " + proto + " " + serverVethAddress + " " + port - echoClnContainer.addEnvVar("VCL_CONFIG", "/vcl.conf") - o := echoClnContainer.exec(testClientCommand) - s.log(o) + echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf") + o := echoClnContainer.Exec(testClientCommand) + s.Log(o) } func VclEchoTcpTest(s *VethsSuite) { - s.testVclEcho("tcp") + testVclEcho(s, "tcp") } func VclEchoUdpTest(s *VethsSuite) { - s.testVclEcho("udp") + testVclEcho(s, "udp") } func VclRetryAttachTest(s *VethsSuite) { - s.testRetryAttach("tcp") + testRetryAttach(s, "tcp") } -func (s *VethsSuite) testRetryAttach(proto string) { - srvVppContainer := s.getTransientContainerByName("server-vpp") +func testRetryAttach(s *VethsSuite, proto string) { + srvVppContainer := s.GetTransientContainerByName("server-vpp") - echoSrvContainer := s.getContainerByName("server-app") + echoSrvContainer := s.GetContainerByName("server-app") - echoSrvContainer.createFile("/vcl.conf", getVclConfig(echoSrvContainer)) + echoSrvContainer.CreateFile("/vcl.conf", getVclConfig(echoSrvContainer)) - echoSrvContainer.addEnvVar("VCL_CONFIG", "/vcl.conf") - echoSrvContainer.execServer("vcl_test_server -p " + proto + " 12346") + echoSrvContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf") + 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.") + 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.getInterfaceByName(serverInterfaceName) - serverVethAddress := serverVeth.ip4AddressString() + serverVeth := s.GetInterfaceByName(ServerInterfaceName) + serverVethAddress := serverVeth.Ip4AddressString() - echoClnContainer := s.getTransientContainerByName("client-app") - echoClnContainer.createFile("/vcl.conf", getVclConfig(echoClnContainer)) + echoClnContainer := s.GetTransientContainerByName("client-app") + echoClnContainer.CreateFile("/vcl.conf", getVclConfig(echoClnContainer)) testClientCommand := "vcl_test_client -U -p " + proto + " " + serverVethAddress + " 12346" - echoClnContainer.addEnvVar("VCL_CONFIG", "/vcl.conf") - o := echoClnContainer.exec(testClientCommand) - s.log(o) - s.log("... First test ended. Stopping VPP server now.") + echoClnContainer.AddEnvVar("VCL_CONFIG", "/vcl.conf") + o := echoClnContainer.Exec(testClientCommand) + s.Log(o) + 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() + srvVppContainer.VppInstance.Disconnect() stopVppCommand := "/bin/bash -c 'ps -C vpp_main -o pid= | xargs kill -9'" - srvVppContainer.exec(stopVppCommand) + srvVppContainer.Exec(stopVppCommand) - s.setupServerVpp() + s.SetupServerVpp() - s.log("... 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 - s.log("... Running second echo client test, after disconnect and re-attachment.") - o = echoClnContainer.exec(testClientCommand) - s.log(o) - s.log("Done.") + s.Log("... Running second echo client test, after disconnect and re-attachment.") + o = echoClnContainer.Exec(testClientCommand) + s.Log(o) + s.Log("Done.") } |