From 56bfc63b289cbf7e7f8ebf5bee97d7f2ec78ae1a Mon Sep 17 00:00:00 2001 From: Maros Ondrejicka Date: Tue, 21 Feb 2023 13:42:35 +0100 Subject: [PATCH] hs-test: update hs-test documentation Type: docs Signed-off-by: Maros Ondrejicka Change-Id: I123898923afa382ff0d4410652f4a17a8740d711 --- extras/hs-test/README.rst | 87 ++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 51 deletions(-) diff --git a/extras/hs-test/README.rst b/extras/hs-test/README.rst index 8d1ee3537b8..2b1dd2d5713 100644 --- a/extras/hs-test/README.rst +++ b/extras/hs-test/README.rst @@ -46,23 +46,20 @@ For adding a new suite, please see `Modifying the framework`_ below. #. Declare method whose name starts with ``Test`` and specifies its receiver as a pointer to the suite's struct (defined in ``framework_test.go``) #. Implement test behaviour inside the test method. This typically includes the following: - #. Retrieve a running container in which to run some action. Function ``getContainerByName(name string)`` + #. Retrieve a running container in which to run some action. Method ``getContainerByName`` from ``HstSuite`` struct serves this purpose - an object representing a container and start it with ``run()`` method - #. Execute *hs-test* action(s) inside any of the running containers. - Function ``execAction(args string)`` from ``container.go`` does this by using ``docker exec`` command to run ``hs-test`` executable. - For starting an VPP instance inside a container, the ``VppInstance`` struct can be used instead - #. Run arbitrary commands inside the containers with ``exec(cmd string)`` + #. 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 + 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 **Example test case** -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 ``./test -run TestMySuite``. +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 ``./test -run TestMySuite/TestMyCase``. :: @@ -73,21 +70,13 @@ This can be put in file ``extras/hs-test/my_test.go`` and run with command ``./t ) func (s *MySuite) TestMyCase() { - serverVppContainer := s.getContainerByName("server-vpp") + clientVpp := s.getContainerByName("client-vpp").vppInstance - serverVpp := NewVppInstance(serverContainer) - serverVpp.set2VethsServer() - serverVpp.start() + serverVethAddress := s.netInterfaces["server-iface"].AddressString() - clientVppContainer := s.getContainerByName("client-vpp") - - clientVpp:= NewVppInstance(clientContainer) - serverVpp.set2VethsClient() - clientVpp.start() - - result, err := clientVpp.vppctl("ping 10.10.10.2") - s.assertNil(err, "ping resulted in error") - fmt.Println(result) + result := clientVpp.vppctl("ping " + serverVethAddress) + s.assertNotNil(result) + s.log(result) } Modifying the framework @@ -98,10 +87,10 @@ Modifying the framework .. _test-convention: #. Adding a new suite takes place in ``framework_test.go`` and by creating a new file for the suite. - Naming convention for the suite files is ``suite-name-test.go`` where *name* will be replaced + Naming convention for the suite files is ``suite_name_test.go`` where *name* will be replaced by the actual name -#. Make a ``struct`` with at least ``HstSuite`` struct as its member. +#. 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 :: @@ -110,12 +99,12 @@ Modifying the framework HstSuite } -#. Implement SetupSuite method which testify runs before running the tests. - It's important here to call ``setupSuite(s *suite.Suite, topologyName string)`` and assign its result to the suite's ``teardownSuite`` member. - Pass the topology name to the function in the form of file name of one of the *yaml* files in ``topo-network`` folder. +#. In suite file, implement ``SetupSuite`` method which testify runs once before starting any of the tests. + 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(topologyName string)`` 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 @@ -124,12 +113,22 @@ Modifying the framework func (s *MySuite) SetupSuite() { // Add custom setup code here - s.teardownSuite = setupSuite(&s.Suite, "myTopology") + s.configureNetworkTopology("myTopology") s.loadContainerTopology("2peerVeth") } +#. In suite file, implement ``SetupTest`` method which gets executed before each test. Starting containers and + configuring VPP is usually placed here + + :: + + func (s *MySuite) SetupTest() { + s.SetupVolumes() + s.SetupContainers() + } + #. In order for ``go test`` to run this suite, we need to create a normal test function and pass our suite to ``suite.Run``. - This is being at the end of ``framework_test.go`` + These functions are placed at the end of ``framework_test.go`` :: @@ -144,9 +143,9 @@ Modifying the framework Topology configuration exists as ``yaml`` files in the ``extras/hs-test/topo-network`` and ``extras/hs-test/topo-containers`` folders. Processing of a network topology file for a particular test suite -is started by the ``setupSuite`` function depending on which file's name is passed to it. -Specified file is loaded by ``LoadTopology()`` function and converted into internal data structures which represent various elements of the topology. -After parsing the configuration, ``Configure()`` method loops over array of topology elements and configures them one by one. +is started by the ``configureNetworkTopology`` method depending on which file's name is passed to it. +Specified file is loaded and converted into internal data structures which represent various elements of the topology. +After parsing the configuration, framework loops over the elements and configures them one by one on the host system. These are currently supported types of network elements. @@ -174,22 +173,8 @@ want to communicate there are typically two ways this can be done within *hs-tes * Shared folders. Containers are being created with ``-v`` option to create shared `volumes`_ between host system and containers or just between containers -**Adding a hs-test action** - -Executing more complex or long running jobs is made easier by *hs-test* actions. -These are functions that compartmentalize configuration and execution together for a specific task. -For example, starting up VPP or running VCL echo client. - -The actions are located in ``extras/hs-test/actions.go``. To add one, create a new method that has its receiver as a pointer to ``Actions`` struct. - -Run it from test case with container's method ``execAction(args)`` where ``args`` is the action method's name. -This then executes the ``hs-test`` binary inside of the container and it then runs selected action. -Action is specified by its name as first argument for the binary. - -*Note*: When ``execAction(args)`` runs some action from a test case, the execution of ``hs-test`` inside the container -is asynchronous. The action might take many seconds to finish, while the test case execution context continues to run. -To mitigate this, ``execAction(args)`` waits pre-defined arbitrary number of seconds for a *sync file* to be written by ``hs-test`` -at the end of its run. The test case context and container use Docker volume to share the file. +Host system connects to VPP instances running in containers using a shared folder +where binary API socket is accessible by both sides. **Adding an external tool** @@ -203,8 +188,8 @@ Alternatively copy the executable from host system to the Docker image, similarl * Linux tools ``ip``, ``brctl`` * Standalone programs ``wget``, ``iperf3`` - since these are downloaded when Docker image is made, they are reasonably up-to-date automatically -* Programs in Docker images - see ``envoyproxy/envoy-contrib`` in ``utils.go`` -* ``http_server`` - homegrown application that listens on specified address and sends a test file in response +* Programs in Docker images - ``envoyproxy/envoy-contrib`` and ``nginx`` +* ``http_server`` - homegrown application that listens on specified port and sends a test file in response * Non-standard Go libraries - see ``extras/hs-test/go.mod`` Generally, these will be updated on a per-need basis, for example when a bug is discovered -- 2.16.6