1*053f45beSAndroid Build Coastguard Workertdc - Linux Traffic Control (tc) unit testing suite 2*053f45beSAndroid Build Coastguard Worker 3*053f45beSAndroid Build Coastguard WorkerAuthor: Lucas Bates - [email protected] 4*053f45beSAndroid Build Coastguard Worker 5*053f45beSAndroid Build Coastguard Workertdc is a Python script to load tc unit tests from a separate JSON file and 6*053f45beSAndroid Build Coastguard Workerexecute them inside a network namespace dedicated to the task. 7*053f45beSAndroid Build Coastguard Worker 8*053f45beSAndroid Build Coastguard Worker 9*053f45beSAndroid Build Coastguard WorkerREQUIREMENTS 10*053f45beSAndroid Build Coastguard Worker------------ 11*053f45beSAndroid Build Coastguard Worker 12*053f45beSAndroid Build Coastguard Worker* Minimum Python version of 3.4. Earlier 3.X versions may work but are not 13*053f45beSAndroid Build Coastguard Worker guaranteed. 14*053f45beSAndroid Build Coastguard Worker 15*053f45beSAndroid Build Coastguard Worker* The kernel must have network namespace support if using nsPlugin 16*053f45beSAndroid Build Coastguard Worker 17*053f45beSAndroid Build Coastguard Worker* The kernel must have veth support available, as a veth pair is created 18*053f45beSAndroid Build Coastguard Worker prior to running the tests when using nsPlugin. 19*053f45beSAndroid Build Coastguard Worker 20*053f45beSAndroid Build Coastguard Worker* The kernel must have the appropriate infrastructure enabled to run all tdc 21*053f45beSAndroid Build Coastguard Worker unit tests. See the config file in this directory for minimum required 22*053f45beSAndroid Build Coastguard Worker features. As new tests will be added, config options list will be updated. 23*053f45beSAndroid Build Coastguard Worker 24*053f45beSAndroid Build Coastguard Worker* All tc-related features being tested must be built in or available as 25*053f45beSAndroid Build Coastguard Worker modules. To check what is required in current setup run: 26*053f45beSAndroid Build Coastguard Worker ./tdc.py -c 27*053f45beSAndroid Build Coastguard Worker 28*053f45beSAndroid Build Coastguard Worker Note: 29*053f45beSAndroid Build Coastguard Worker In the current release, tdc run will abort due to a failure in setup or 30*053f45beSAndroid Build Coastguard Worker teardown commands - which includes not being able to run a test simply 31*053f45beSAndroid Build Coastguard Worker because the kernel did not support a specific feature. (This will be 32*053f45beSAndroid Build Coastguard Worker handled in a future version - the current workaround is to run the tests 33*053f45beSAndroid Build Coastguard Worker on specific test categories that your kernel supports) 34*053f45beSAndroid Build Coastguard Worker 35*053f45beSAndroid Build Coastguard Worker 36*053f45beSAndroid Build Coastguard WorkerBEFORE YOU RUN 37*053f45beSAndroid Build Coastguard Worker-------------- 38*053f45beSAndroid Build Coastguard Worker 39*053f45beSAndroid Build Coastguard WorkerThe path to the tc executable that will be most commonly tested can be defined 40*053f45beSAndroid Build Coastguard Workerin the tdc_config.py file. Find the 'TC' entry in the NAMES dictionary and 41*053f45beSAndroid Build Coastguard Workerdefine the path. 42*053f45beSAndroid Build Coastguard Worker 43*053f45beSAndroid Build Coastguard WorkerIf you need to test a different tc executable on the fly, you can do so by 44*053f45beSAndroid Build Coastguard Workerusing the -p option when running tdc: 45*053f45beSAndroid Build Coastguard Worker ./tdc.py -p /path/to/tc 46*053f45beSAndroid Build Coastguard Worker 47*053f45beSAndroid Build Coastguard Worker 48*053f45beSAndroid Build Coastguard WorkerRUNNING TDC 49*053f45beSAndroid Build Coastguard Worker----------- 50*053f45beSAndroid Build Coastguard Worker 51*053f45beSAndroid Build Coastguard WorkerTo use tdc, root privileges are required. This is because the 52*053f45beSAndroid Build Coastguard Workercommands being tested must be run as root. The code that enforces 53*053f45beSAndroid Build Coastguard Workerexecution by root uid has been moved into a plugin (see PLUGIN 54*053f45beSAndroid Build Coastguard WorkerARCHITECTURE, below). 55*053f45beSAndroid Build Coastguard Worker 56*053f45beSAndroid Build Coastguard WorkerTests that use a network device should have nsPlugin.py listed as a 57*053f45beSAndroid Build Coastguard Workerrequirement for that test. nsPlugin executes all commands within a 58*053f45beSAndroid Build Coastguard Workernetwork namespace and creates a veth pair which may be used in those test 59*053f45beSAndroid Build Coastguard Workercases. To disable execution within the namespace, pass the -N option 60*053f45beSAndroid Build Coastguard Workerto tdc when starting a test run; the veth pair will still be created 61*053f45beSAndroid Build Coastguard Workerby the plugin. 62*053f45beSAndroid Build Coastguard Worker 63*053f45beSAndroid Build Coastguard WorkerRunning tdc without any arguments will run all tests. Refer to the section 64*053f45beSAndroid Build Coastguard Workeron command line arguments for more information, or run: 65*053f45beSAndroid Build Coastguard Worker ./tdc.py -h 66*053f45beSAndroid Build Coastguard Worker 67*053f45beSAndroid Build Coastguard Workertdc will list the test names as they are being run, and print a summary in 68*053f45beSAndroid Build Coastguard WorkerTAP (Test Anything Protocol) format when they are done. If tests fail, 69*053f45beSAndroid Build Coastguard Workeroutput captured from the failing test will be printed immediately following 70*053f45beSAndroid Build Coastguard Workerthe failed test in the TAP output. 71*053f45beSAndroid Build Coastguard Worker 72*053f45beSAndroid Build Coastguard Worker 73*053f45beSAndroid Build Coastguard WorkerOVERVIEW OF TDC EXECUTION 74*053f45beSAndroid Build Coastguard Worker------------------------- 75*053f45beSAndroid Build Coastguard Worker 76*053f45beSAndroid Build Coastguard WorkerOne run of tests is considered a "test suite" (this will be refined in the 77*053f45beSAndroid Build Coastguard Workerfuture). A test suite has one or more test cases in it. 78*053f45beSAndroid Build Coastguard Worker 79*053f45beSAndroid Build Coastguard WorkerA test case has four stages: 80*053f45beSAndroid Build Coastguard Worker 81*053f45beSAndroid Build Coastguard Worker - setup 82*053f45beSAndroid Build Coastguard Worker - execute 83*053f45beSAndroid Build Coastguard Worker - verify 84*053f45beSAndroid Build Coastguard Worker - teardown 85*053f45beSAndroid Build Coastguard Worker 86*053f45beSAndroid Build Coastguard WorkerThe setup and teardown stages can run zero or more commands. The setup 87*053f45beSAndroid Build Coastguard Workerstage does some setup if the test needs it. The teardown stage undoes 88*053f45beSAndroid Build Coastguard Workerthe setup and returns the system to a "neutral" state so any other test 89*053f45beSAndroid Build Coastguard Workercan be run next. These two stages require any commands run to return 90*053f45beSAndroid Build Coastguard Workersuccess, but do not otherwise verify the results. 91*053f45beSAndroid Build Coastguard Worker 92*053f45beSAndroid Build Coastguard WorkerThe execute and verify stages each run one command. The execute stage 93*053f45beSAndroid Build Coastguard Workertests the return code against one or more acceptable values. The 94*053f45beSAndroid Build Coastguard Workerverify stage checks the return code for success, and also compares 95*053f45beSAndroid Build Coastguard Workerthe stdout with a regular expression. 96*053f45beSAndroid Build Coastguard Worker 97*053f45beSAndroid Build Coastguard WorkerEach of the commands in any stage will run in a shell instance. 98*053f45beSAndroid Build Coastguard Worker 99*053f45beSAndroid Build Coastguard Worker 100*053f45beSAndroid Build Coastguard WorkerUSER-DEFINED CONSTANTS 101*053f45beSAndroid Build Coastguard Worker---------------------- 102*053f45beSAndroid Build Coastguard Worker 103*053f45beSAndroid Build Coastguard WorkerThe tdc_config.py file contains multiple values that can be altered to suit 104*053f45beSAndroid Build Coastguard Workeryour needs. Any value in the NAMES dictionary can be altered without affecting 105*053f45beSAndroid Build Coastguard Workerthe tests to be run. These values are used in the tc commands that will be 106*053f45beSAndroid Build Coastguard Workerexecuted as part of the test. More will be added as test cases require. 107*053f45beSAndroid Build Coastguard Worker 108*053f45beSAndroid Build Coastguard WorkerExample: 109*053f45beSAndroid Build Coastguard Worker $TC qdisc add dev $DEV1 ingress 110*053f45beSAndroid Build Coastguard Worker 111*053f45beSAndroid Build Coastguard WorkerThe NAMES values are used to substitute into the commands in the test cases. 112*053f45beSAndroid Build Coastguard Worker 113*053f45beSAndroid Build Coastguard Worker 114*053f45beSAndroid Build Coastguard WorkerCOMMAND LINE ARGUMENTS 115*053f45beSAndroid Build Coastguard Worker---------------------- 116*053f45beSAndroid Build Coastguard Worker 117*053f45beSAndroid Build Coastguard WorkerRun tdc.py -h to see the full list of available arguments. 118*053f45beSAndroid Build Coastguard Worker 119*053f45beSAndroid Build Coastguard Workerusage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]] 120*053f45beSAndroid Build Coastguard Worker [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] [-N] 121*053f45beSAndroid Build Coastguard Worker [-d DEVICE] [-P] [-n] [-V] 122*053f45beSAndroid Build Coastguard Worker 123*053f45beSAndroid Build Coastguard WorkerLinux TC unit tests 124*053f45beSAndroid Build Coastguard Worker 125*053f45beSAndroid Build Coastguard Workeroptional arguments: 126*053f45beSAndroid Build Coastguard Worker -h, --help show this help message and exit 127*053f45beSAndroid Build Coastguard Worker -p PATH, --path PATH The full path to the tc executable to use 128*053f45beSAndroid Build Coastguard Worker -v, --verbose Show the commands that are being run 129*053f45beSAndroid Build Coastguard Worker -N, --notap Suppress tap results for command under test 130*053f45beSAndroid Build Coastguard Worker -d DEVICE, --device DEVICE 131*053f45beSAndroid Build Coastguard Worker Execute test cases that use a physical device, where 132*053f45beSAndroid Build Coastguard Worker DEVICE is its name. (If not defined, tests that require 133*053f45beSAndroid Build Coastguard Worker a physical device will be skipped) 134*053f45beSAndroid Build Coastguard Worker -P, --pause Pause execution just before post-suite stage 135*053f45beSAndroid Build Coastguard Worker 136*053f45beSAndroid Build Coastguard Workerselection: 137*053f45beSAndroid Build Coastguard Worker select which test cases: files plus directories; filtered by categories 138*053f45beSAndroid Build Coastguard Worker plus testids 139*053f45beSAndroid Build Coastguard Worker 140*053f45beSAndroid Build Coastguard Worker -D DIR [DIR ...], --directory DIR [DIR ...] 141*053f45beSAndroid Build Coastguard Worker Collect tests from the specified directory(ies) 142*053f45beSAndroid Build Coastguard Worker (default [tc-tests]) 143*053f45beSAndroid Build Coastguard Worker -f FILE [FILE ...], --file FILE [FILE ...] 144*053f45beSAndroid Build Coastguard Worker Run tests from the specified file(s) 145*053f45beSAndroid Build Coastguard Worker -c [CATG [CATG ...]], --category [CATG [CATG ...]] 146*053f45beSAndroid Build Coastguard Worker Run tests only from the specified category/ies, or if 147*053f45beSAndroid Build Coastguard Worker no category/ies is/are specified, list known 148*053f45beSAndroid Build Coastguard Worker categories. 149*053f45beSAndroid Build Coastguard Worker -e ID [ID ...], --execute ID [ID ...] 150*053f45beSAndroid Build Coastguard Worker Execute the specified test cases with specified IDs 151*053f45beSAndroid Build Coastguard Worker 152*053f45beSAndroid Build Coastguard Workeraction: 153*053f45beSAndroid Build Coastguard Worker select action to perform on selected test cases 154*053f45beSAndroid Build Coastguard Worker 155*053f45beSAndroid Build Coastguard Worker -l, --list List all test cases, or those only within the 156*053f45beSAndroid Build Coastguard Worker specified category 157*053f45beSAndroid Build Coastguard Worker -s, --show Display the selected test cases 158*053f45beSAndroid Build Coastguard Worker -i, --id Generate ID numbers for new test cases 159*053f45beSAndroid Build Coastguard Worker 160*053f45beSAndroid Build Coastguard Workernetns: 161*053f45beSAndroid Build Coastguard Worker options for nsPlugin (run commands in net namespace) 162*053f45beSAndroid Build Coastguard Worker 163*053f45beSAndroid Build Coastguard Worker -N, --no-namespace 164*053f45beSAndroid Build Coastguard Worker Do not run commands in a network namespace. 165*053f45beSAndroid Build Coastguard Worker 166*053f45beSAndroid Build Coastguard Workervalgrind: 167*053f45beSAndroid Build Coastguard Worker options for valgrindPlugin (run command under test under Valgrind) 168*053f45beSAndroid Build Coastguard Worker 169*053f45beSAndroid Build Coastguard Worker -V, --valgrind Run commands under valgrind 170*053f45beSAndroid Build Coastguard Worker 171*053f45beSAndroid Build Coastguard Worker 172*053f45beSAndroid Build Coastguard WorkerPLUGIN ARCHITECTURE 173*053f45beSAndroid Build Coastguard Worker------------------- 174*053f45beSAndroid Build Coastguard Worker 175*053f45beSAndroid Build Coastguard WorkerThere is now a plugin architecture, and some of the functionality that 176*053f45beSAndroid Build Coastguard Workerwas in the tdc.py script has been moved into the plugins. 177*053f45beSAndroid Build Coastguard Worker 178*053f45beSAndroid Build Coastguard WorkerThe plugins are in the directory plugin-lib. The are executed from 179*053f45beSAndroid Build Coastguard Workerdirectory plugins. Put symbolic links from plugins to plugin-lib, 180*053f45beSAndroid Build Coastguard Workerand name them according to the order you want them to run. This is not 181*053f45beSAndroid Build Coastguard Workernecessary if a test case being run requires a specific plugin to work. 182*053f45beSAndroid Build Coastguard Worker 183*053f45beSAndroid Build Coastguard WorkerExample: 184*053f45beSAndroid Build Coastguard Worker 185*053f45beSAndroid Build Coastguard Workerbjb@bee:~/work/tc-testing$ ls -l plugins 186*053f45beSAndroid Build Coastguard Workertotal 4 187*053f45beSAndroid Build Coastguard Workerlrwxrwxrwx 1 bjb bjb 27 Oct 4 16:12 10-rootPlugin.py -> ../plugin-lib/rootPlugin.py 188*053f45beSAndroid Build Coastguard Workerlrwxrwxrwx 1 bjb bjb 25 Oct 12 17:55 20-nsPlugin.py -> ../plugin-lib/nsPlugin.py 189*053f45beSAndroid Build Coastguard Worker-rwxr-xr-x 1 bjb bjb 0 Sep 29 15:56 __init__.py 190*053f45beSAndroid Build Coastguard Worker 191*053f45beSAndroid Build Coastguard WorkerThe plugins are a subclass of TdcPlugin, defined in TdcPlugin.py and 192*053f45beSAndroid Build Coastguard Workermust be called "SubPlugin" so tdc can find them. They are 193*053f45beSAndroid Build Coastguard Workerdistinguished from each other in the python program by their module 194*053f45beSAndroid Build Coastguard Workername. 195*053f45beSAndroid Build Coastguard Worker 196*053f45beSAndroid Build Coastguard WorkerThis base class supplies "hooks" to run extra functions. These hooks are as follows: 197*053f45beSAndroid Build Coastguard Worker 198*053f45beSAndroid Build Coastguard Workerpre- and post-suite 199*053f45beSAndroid Build Coastguard Workerpre- and post-case 200*053f45beSAndroid Build Coastguard Workerpre- and post-execute stage 201*053f45beSAndroid Build Coastguard Workeradjust-command (runs in all stages and receives the stage name) 202*053f45beSAndroid Build Coastguard Worker 203*053f45beSAndroid Build Coastguard WorkerThe pre-suite hook receives the number of tests and an array of test ids. 204*053f45beSAndroid Build Coastguard WorkerThis allows you to dump out the list of skipped tests in the event of a 205*053f45beSAndroid Build Coastguard Workerfailure during setup or teardown stage. 206*053f45beSAndroid Build Coastguard Worker 207*053f45beSAndroid Build Coastguard WorkerThe pre-case hook receives the ordinal number and test id of the current test. 208*053f45beSAndroid Build Coastguard Worker 209*053f45beSAndroid Build Coastguard WorkerThe adjust-command hook receives the stage id (see list below) and the 210*053f45beSAndroid Build Coastguard Workerfull command to be executed. This allows for last-minute adjustment 211*053f45beSAndroid Build Coastguard Workerof the command. 212*053f45beSAndroid Build Coastguard Worker 213*053f45beSAndroid Build Coastguard WorkerThe stages are identified by the following strings: 214*053f45beSAndroid Build Coastguard Worker 215*053f45beSAndroid Build Coastguard Worker - pre (pre-suite) 216*053f45beSAndroid Build Coastguard Worker - setup 217*053f45beSAndroid Build Coastguard Worker - command 218*053f45beSAndroid Build Coastguard Worker - verify 219*053f45beSAndroid Build Coastguard Worker - teardown 220*053f45beSAndroid Build Coastguard Worker - post (post-suite) 221*053f45beSAndroid Build Coastguard Worker 222*053f45beSAndroid Build Coastguard Worker 223*053f45beSAndroid Build Coastguard WorkerTo write a plugin, you need to inherit from TdcPlugin in 224*053f45beSAndroid Build Coastguard WorkerTdcPlugin.py. To use the plugin, you have to put the 225*053f45beSAndroid Build Coastguard Workerimplementation file in plugin-lib, and add a symbolic link to it from 226*053f45beSAndroid Build Coastguard Workerplugins. It will be detected at run time and invoked at the 227*053f45beSAndroid Build Coastguard Workerappropriate times. There are a few examples in the plugin-lib 228*053f45beSAndroid Build Coastguard Workerdirectory: 229*053f45beSAndroid Build Coastguard Worker 230*053f45beSAndroid Build Coastguard Worker - rootPlugin.py: 231*053f45beSAndroid Build Coastguard Worker implements the enforcement of running as root 232*053f45beSAndroid Build Coastguard Worker - nsPlugin.py: 233*053f45beSAndroid Build Coastguard Worker sets up a network namespace and runs all commands in that namespace, 234*053f45beSAndroid Build Coastguard Worker while also setting up dummy devices to be used in testing. 235*053f45beSAndroid Build Coastguard Worker - valgrindPlugin.py 236*053f45beSAndroid Build Coastguard Worker runs each command in the execute stage under valgrind, 237*053f45beSAndroid Build Coastguard Worker and checks for leaks. 238*053f45beSAndroid Build Coastguard Worker This plugin will output an extra test for each test in the test file, 239*053f45beSAndroid Build Coastguard Worker one is the existing output as to whether the test passed or failed, 240*053f45beSAndroid Build Coastguard Worker and the other is a test whether the command leaked memory or not. 241*053f45beSAndroid Build Coastguard Worker (This one is a preliminary version, it may not work quite right yet, 242*053f45beSAndroid Build Coastguard Worker but the overall template is there and it should only need tweaks.) 243*053f45beSAndroid Build Coastguard Worker - buildebpfPlugin.py: 244*053f45beSAndroid Build Coastguard Worker builds all programs in $EBPFDIR. 245*053f45beSAndroid Build Coastguard Worker 246*053f45beSAndroid Build Coastguard Worker 247*053f45beSAndroid Build Coastguard WorkerACKNOWLEDGEMENTS 248*053f45beSAndroid Build Coastguard Worker---------------- 249*053f45beSAndroid Build Coastguard Worker 250*053f45beSAndroid Build Coastguard WorkerThanks to: 251*053f45beSAndroid Build Coastguard Worker 252*053f45beSAndroid Build Coastguard WorkerJamal Hadi Salim, for providing valuable test cases 253*053f45beSAndroid Build Coastguard WorkerKeara Leibovitz, who wrote the CLI test driver that I used as a base for the 254*053f45beSAndroid Build Coastguard Worker first version of the tc testing suite. This work was presented at 255*053f45beSAndroid Build Coastguard Worker Netdev 1.2 Tokyo in October 2016. 256*053f45beSAndroid Build Coastguard WorkerSamir Hussain, for providing help while I dove into Python for the first time 257*053f45beSAndroid Build Coastguard Worker and being a second eye for this code. 258