Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 1 | .. _unittest: https://docs.python.org/2/library/unittest.html |
| 2 | .. _TestCase: https://docs.python.org/2/library/unittest.html#unittest.TestCase |
| 3 | .. _AssertionError: https://docs.python.org/2/library/exceptions.html#exceptions.AssertionError |
| 4 | .. _SkipTest: https://docs.python.org/2/library/unittest.html#unittest.SkipTest |
| 5 | .. _virtualenv: http://docs.python-guide.org/en/latest/dev/virtualenvs/ |
| 6 | .. _scapy: http://www.secdev.org/projects/scapy/ |
Klement Sekera | f62ae12 | 2016-10-11 11:47:09 +0200 | [diff] [blame] | 7 | |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 8 | .. |vtf| replace:: VPP Test Framework |
Klement Sekera | f62ae12 | 2016-10-11 11:47:09 +0200 | [diff] [blame] | 9 | |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 10 | |vtf| |
| 11 | ===== |
Klement Sekera | f62ae12 | 2016-10-11 11:47:09 +0200 | [diff] [blame] | 12 | |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 13 | Overview |
| 14 | ######## |
| 15 | |
| 16 | The goal of the |vtf| is to ease writing, running and debugging |
| 17 | unit tests for the VPP. For this, python was chosen as a high level language |
| 18 | allowing rapid development with scapy_ providing the necessary tool for creating |
| 19 | and dissecting packets. |
| 20 | |
| 21 | Anatomy of a test case |
| 22 | ###################### |
| 23 | |
| 24 | Python's unittest_ is used as the base framework upon which the VPP test |
Matej Klotton | 86d87c4 | 2016-11-11 11:38:55 +0100 | [diff] [blame^] | 25 | framework is built. A test suite in the |vtf| consists of multiple classes |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 26 | derived from `VppTestCase`, which is itself derived from TestCase_. |
| 27 | The test class defines one or more test functions, which act as test cases. |
| 28 | |
| 29 | Function flow when running a test case is: |
| 30 | |
| 31 | 1. `setUpClass <VppTestCase.setUpClass>`: |
| 32 | This function is called once for each test class, allowing a one-time test |
| 33 | setup to be executed. If this functions throws an exception, |
| 34 | none of the test functions are executed. |
| 35 | 2. `setUp <VppTestCase.setUp>`: |
| 36 | The setUp function runs before each of the test functions. If this function |
| 37 | throws an exception other than AssertionError_ or SkipTest_, then this is |
| 38 | considered an error, not a test failure. |
| 39 | 3. *test_<name>*: |
| 40 | This is the guts of the test case. It should execute the test scenario |
| 41 | and use the various assert functions from the unittest framework to check |
| 42 | necessary. |
| 43 | 4. `tearDown <VppTestCase.tearDown>`: |
| 44 | The tearDown function is called after each test function with the purpose |
| 45 | of doing partial cleanup. |
| 46 | 5. `tearDownClass <VppTestCase.tearDownClass>`: |
Matej Klotton | 86d87c4 | 2016-11-11 11:38:55 +0100 | [diff] [blame^] | 47 | Method called once after running all of the test functions to perform |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 48 | the final cleanup. |
| 49 | |
| 50 | Test temporary directory and VPP life cycle |
Matej Klotton | 86d87c4 | 2016-11-11 11:38:55 +0100 | [diff] [blame^] | 51 | ########################################### |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 52 | |
| 53 | Test separation is achieved by separating the test files and vpp instances. |
| 54 | Each test creates a temporary directory and it's name is used to create |
| 55 | a shared memory prefix which is used to run a VPP instance. |
| 56 | This way, there is no conflict between any other VPP instances running |
| 57 | on the box and the test VPP. Any temporary files created by the test case |
| 58 | are stored in this temporary test directory. |
| 59 | |
| 60 | Virtual environment |
| 61 | ################### |
| 62 | |
Matej Klotton | 86d87c4 | 2016-11-11 11:38:55 +0100 | [diff] [blame^] | 63 | Virtualenv_ is a python module which provides a means to create an environment |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 64 | containing the dependencies required by the |vtf|, allowing a separation |
| 65 | from any existing system-wide packages. |vtf|'s Makefile automatically |
| 66 | creates a virtualenv_ inside build-root and installs the required packages |
| 67 | in that environment. The environment is entered whenever executing a test |
| 68 | via one of the make test targets. |
| 69 | |
| 70 | Naming conventions |
| 71 | ################## |
| 72 | |
| 73 | Most unit tests do some kind of packet manipulation - sending and receiving |
| 74 | packets between VPP and virtual hosts connected to the VPP. Referring |
Matej Klotton | 86d87c4 | 2016-11-11 11:38:55 +0100 | [diff] [blame^] | 75 | to the sides, addresses, etc. is always done as if looking from the VPP side, |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 76 | thus: |
| 77 | |
| 78 | * *local_* prefix is used for the VPP side. |
| 79 | So e.g. `local_ip4 <VppInterface.local_ip4>` address is the IPv4 address |
| 80 | assigned to the VPP interface. |
| 81 | * *remote_* prefix is used for the virtual host side. |
| 82 | So e.g. `remote_mac <VppInterface.remote_mac>` address is the MAC address |
| 83 | assigned to the virtual host connected to the VPP. |
| 84 | |
| 85 | Packet flow in the |vtf| |
| 86 | ######################## |
| 87 | |
| 88 | Test framework -> VPP |
| 89 | ~~~~~~~~~~~~~~~~~~~~~ |
| 90 | |
| 91 | |vtf| doesn't send any packets to VPP directly. Traffic is instead injected |
| 92 | using packet-generator interfaces, represented by the `VppPGInterface` class. |
| 93 | Packets are written into a temporary .pcap file, which is then read by the VPP |
| 94 | and the packets are injected into the VPP world. |
| 95 | |
| 96 | VPP -> test framework |
| 97 | ~~~~~~~~~~~~~~~~~~~~~ |
| 98 | |
| 99 | Similarly, VPP doesn't send any packets to |vtf| directly. Instead, packet |
| 100 | capture feature is used to capture and write traffic to a temporary .pcap file, |
| 101 | which is then read and analyzed by the |vtf|. |
| 102 | |
| 103 | Test framework objects |
| 104 | ###################### |
| 105 | |
| 106 | The following objects provide VPP abstraction and provide a means to do |
| 107 | common tasks easily in the test cases. |
| 108 | |
| 109 | * `VppInterface`: abstract class representing generic VPP interface |
| 110 | and contains some common functionality, which is then used by derived classes |
| 111 | * `VppPGInterface`: class representing VPP packet-generator interface. |
| 112 | The interface is created/destroyed when the object is created/destroyed. |
| 113 | * `VppSubInterface`: VPP sub-interface abstract class, containing common |
| 114 | functionality for e.g. `VppDot1QSubint` and `VppDot1ADSubint` classes |
| 115 | |
| 116 | How VPP API/CLI is called |
| 117 | ######################### |
| 118 | |
| 119 | Vpp provides python bindings in a python module called vpp-papi, which the test |
| 120 | framework installs in the virtual environment. A shim layer represented by |
| 121 | the `VppPapiProvider` class is built on top of the vpp-papi, serving these |
| 122 | purposes: |
| 123 | |
| 124 | 1. Automatic return value checks: |
| 125 | After each API is called, the return value is checked against the expected |
| 126 | return value (by default 0, but can be overridden) and an exception |
| 127 | is raised if the check fails. |
| 128 | 2. Automatic call of hooks: |
| 129 | |
| 130 | a. `before_cli <Hook.before_cli>` and `before_api <Hook.before_api>` hooks |
| 131 | are used for debug logging and stepping through the test |
| 132 | b. `after_cli <Hook.after_cli>` and `after_api <Hook.after_api>` hooks |
| 133 | are used for monitoring the vpp process for crashes |
| 134 | 3. Simplification of API calls: |
| 135 | Many of the VPP APIs take a lot of parameters and by providing sane defaults |
| 136 | for these, the API is much easier to use in the common case and the code is |
| 137 | more readable. E.g. ip_add_del_route API takes ~25 parameters, of which |
| 138 | in the common case, only 3 are needed. |
| 139 | |
| 140 | Example: how to add a new test |
| 141 | ############################## |
| 142 | |
| 143 | In this example, we will describe how to add a new test case which tests VPP... |
| 144 | |
| 145 | 1. Add a new file called... |
| 146 | 2. Add a setUpClass function containing... |
| 147 | 3. Add the test code in test... |
| 148 | 4. Run the test... |
| 149 | |
| 150 | |vtf| module documentation |
| 151 | ########################## |
| 152 | |
Klement Sekera | f62ae12 | 2016-10-11 11:47:09 +0200 | [diff] [blame] | 153 | .. toctree:: |
| 154 | :maxdepth: 2 |
Klement Sekera | 778c276 | 2016-11-08 02:00:28 +0100 | [diff] [blame] | 155 | :glob: |
Klement Sekera | f62ae12 | 2016-10-11 11:47:09 +0200 | [diff] [blame] | 156 | |
| 157 | modules.rst |
| 158 | |
| 159 | Indices and tables |
| 160 | ================== |
| 161 | |
| 162 | * :ref:`genindex` |
| 163 | * :ref:`modindex` |
| 164 | * :ref:`search` |
| 165 | |