176b903eeSLucas Batestdc - Linux Traffic Control (tc) unit testing suite 276b903eeSLucas Bates 376b903eeSLucas BatesAuthor: Lucas Bates - [email protected] 476b903eeSLucas Bates 576b903eeSLucas Batestdc is a Python script to load tc unit tests from a separate JSON file and 676b903eeSLucas Batesexecute them inside a network namespace dedicated to the task. 776b903eeSLucas Bates 876b903eeSLucas Bates 976b903eeSLucas BatesREQUIREMENTS 1076b903eeSLucas Bates------------ 1176b903eeSLucas Bates 1276b903eeSLucas Bates* Minimum Python version of 3.4. Earlier 3.X versions may work but are not 1376b903eeSLucas Bates guaranteed. 1476b903eeSLucas Bates 1576b903eeSLucas Bates* The kernel must have network namespace support 1676b903eeSLucas Bates 1776b903eeSLucas Bates* The kernel must have veth support available, as a veth pair is created 1876b903eeSLucas Bates prior to running the tests. 1976b903eeSLucas Bates 20b70f1f3aSKeara Leibovitz* The kernel must have the appropriate infrastructure enabled to run all tdc 21b70f1f3aSKeara Leibovitz unit tests. See the config file in this directory for minimum required 22b70f1f3aSKeara Leibovitz features. As new tests will be added, config options list will be updated. 23b70f1f3aSKeara Leibovitz 2495ce14c3SBrenda J. Butler* All tc-related features being tested must be built in or available as 2595ce14c3SBrenda J. Butler modules. To check what is required in current setup run: 2676b903eeSLucas Bates ./tdc.py -c 2776b903eeSLucas Bates 2876b903eeSLucas Bates Note: 2976b903eeSLucas Bates In the current release, tdc run will abort due to a failure in setup or 3076b903eeSLucas Bates teardown commands - which includes not being able to run a test simply 3176b903eeSLucas Bates because the kernel did not support a specific feature. (This will be 3276b903eeSLucas Bates handled in a future version - the current workaround is to run the tests 3376b903eeSLucas Bates on specific test categories that your kernel supports) 3476b903eeSLucas Bates 3576b903eeSLucas Bates 3676b903eeSLucas BatesBEFORE YOU RUN 3776b903eeSLucas Bates-------------- 3876b903eeSLucas Bates 3976b903eeSLucas BatesThe path to the tc executable that will be most commonly tested can be defined 4076b903eeSLucas Batesin the tdc_config.py file. Find the 'TC' entry in the NAMES dictionary and 4176b903eeSLucas Batesdefine the path. 4276b903eeSLucas Bates 4376b903eeSLucas BatesIf you need to test a different tc executable on the fly, you can do so by 4476b903eeSLucas Batesusing the -p option when running tdc: 4576b903eeSLucas Bates ./tdc.py -p /path/to/tc 4676b903eeSLucas Bates 4776b903eeSLucas Bates 4876b903eeSLucas BatesRUNNING TDC 4976b903eeSLucas Bates----------- 5076b903eeSLucas Bates 5195ce14c3SBrenda J. ButlerTo use tdc, root privileges are required. This is because the 5295ce14c3SBrenda J. Butlercommands being tested must be run as root. The code that enforces 5395ce14c3SBrenda J. Butlerexecution by root uid has been moved into a plugin (see PLUGIN 5495ce14c3SBrenda J. ButlerARCHITECTURE, below). 5576b903eeSLucas Bates 5695ce14c3SBrenda J. ButlerIf nsPlugin is linked, all tests are executed inside a network 5795ce14c3SBrenda J. Butlernamespace to prevent conflicts within the host. 5876b903eeSLucas Bates 5976b903eeSLucas BatesRunning tdc without any arguments will run all tests. Refer to the section 6076b903eeSLucas Bateson command line arguments for more information, or run: 6176b903eeSLucas Bates ./tdc.py -h 6276b903eeSLucas Bates 6376b903eeSLucas Batestdc will list the test names as they are being run, and print a summary in 6476b903eeSLucas BatesTAP (Test Anything Protocol) format when they are done. If tests fail, 6576b903eeSLucas Batesoutput captured from the failing test will be printed immediately following 6676b903eeSLucas Batesthe failed test in the TAP output. 6776b903eeSLucas Bates 6876b903eeSLucas Bates 6995ce14c3SBrenda J. ButlerOVERVIEW OF TDC EXECUTION 7095ce14c3SBrenda J. Butler------------------------- 7195ce14c3SBrenda J. Butler 7295ce14c3SBrenda J. ButlerOne run of tests is considered a "test suite" (this will be refined in the 7395ce14c3SBrenda J. Butlerfuture). A test suite has one or more test cases in it. 7495ce14c3SBrenda J. Butler 7595ce14c3SBrenda J. ButlerA test case has four stages: 7695ce14c3SBrenda J. Butler 7795ce14c3SBrenda J. Butler - setup 7895ce14c3SBrenda J. Butler - execute 7995ce14c3SBrenda J. Butler - verify 8095ce14c3SBrenda J. Butler - teardown 8195ce14c3SBrenda J. Butler 8295ce14c3SBrenda J. ButlerThe setup and teardown stages can run zero or more commands. The setup 8395ce14c3SBrenda J. Butlerstage does some setup if the test needs it. The teardown stage undoes 8495ce14c3SBrenda J. Butlerthe setup and returns the system to a "neutral" state so any other test 8595ce14c3SBrenda J. Butlercan be run next. These two stages require any commands run to return 8695ce14c3SBrenda J. Butlersuccess, but do not otherwise verify the results. 8795ce14c3SBrenda J. Butler 8895ce14c3SBrenda J. ButlerThe execute and verify stages each run one command. The execute stage 8995ce14c3SBrenda J. Butlertests the return code against one or more acceptable values. The 9095ce14c3SBrenda J. Butlerverify stage checks the return code for success, and also compares 9195ce14c3SBrenda J. Butlerthe stdout with a regular expression. 9295ce14c3SBrenda J. Butler 9395ce14c3SBrenda J. ButlerEach of the commands in any stage will run in a shell instance. 9495ce14c3SBrenda J. Butler 9595ce14c3SBrenda J. Butler 9676b903eeSLucas BatesUSER-DEFINED CONSTANTS 9776b903eeSLucas Bates---------------------- 9876b903eeSLucas Bates 9976b903eeSLucas BatesThe tdc_config.py file contains multiple values that can be altered to suit 10076b903eeSLucas Batesyour needs. Any value in the NAMES dictionary can be altered without affecting 10176b903eeSLucas Batesthe tests to be run. These values are used in the tc commands that will be 10276b903eeSLucas Batesexecuted as part of the test. More will be added as test cases require. 10376b903eeSLucas Bates 10476b903eeSLucas BatesExample: 10576b903eeSLucas Bates $TC qdisc add dev $DEV1 ingress 10676b903eeSLucas Bates 10795ce14c3SBrenda J. ButlerThe NAMES values are used to substitute into the commands in the test cases. 10895ce14c3SBrenda J. Butler 10976b903eeSLucas Bates 11076b903eeSLucas BatesCOMMAND LINE ARGUMENTS 11176b903eeSLucas Bates---------------------- 11276b903eeSLucas Bates 11376b903eeSLucas BatesRun tdc.py -h to see the full list of available arguments. 11476b903eeSLucas Bates 11595ce14c3SBrenda J. Butlerusage: tdc.py [-h] [-p PATH] [-D DIR [DIR ...]] [-f FILE [FILE ...]] 116b70f1f3aSKeara Leibovitz [-c [CATG [CATG ...]]] [-e ID [ID ...]] [-l] [-s] [-i] [-v] [-N] 117b70f1f3aSKeara Leibovitz [-d DEVICE] [-P] [-n] [-V] 11895ce14c3SBrenda J. Butler 11995ce14c3SBrenda J. ButlerLinux TC unit tests 12095ce14c3SBrenda J. Butler 12195ce14c3SBrenda J. Butleroptional arguments: 12295ce14c3SBrenda J. Butler -h, --help show this help message and exit 12395ce14c3SBrenda J. Butler -p PATH, --path PATH The full path to the tc executable to use 12495ce14c3SBrenda J. Butler -v, --verbose Show the commands that are being run 125b70f1f3aSKeara Leibovitz -N, --notap Suppress tap results for command under test 12695ce14c3SBrenda J. Butler -d DEVICE, --device DEVICE 12795ce14c3SBrenda J. Butler Execute the test case in flower category 128b70f1f3aSKeara Leibovitz -P, --pause Pause execution just before post-suite stage 12995ce14c3SBrenda J. Butler 13095ce14c3SBrenda J. Butlerselection: 13195ce14c3SBrenda J. Butler select which test cases: files plus directories; filtered by categories 13295ce14c3SBrenda J. Butler plus testids 13395ce14c3SBrenda J. Butler 13495ce14c3SBrenda J. Butler -D DIR [DIR ...], --directory DIR [DIR ...] 13595ce14c3SBrenda J. Butler Collect tests from the specified directory(ies) 13695ce14c3SBrenda J. Butler (default [tc-tests]) 13795ce14c3SBrenda J. Butler -f FILE [FILE ...], --file FILE [FILE ...] 13895ce14c3SBrenda J. Butler Run tests from the specified file(s) 13995ce14c3SBrenda J. Butler -c [CATG [CATG ...]], --category [CATG [CATG ...]] 14095ce14c3SBrenda J. Butler Run tests only from the specified category/ies, or if 14195ce14c3SBrenda J. Butler no category/ies is/are specified, list known 14295ce14c3SBrenda J. Butler categories. 14395ce14c3SBrenda J. Butler -e ID [ID ...], --execute ID [ID ...] 14495ce14c3SBrenda J. Butler Execute the specified test cases with specified IDs 14595ce14c3SBrenda J. Butler 14695ce14c3SBrenda J. Butleraction: 14795ce14c3SBrenda J. Butler select action to perform on selected test cases 14895ce14c3SBrenda J. Butler 14995ce14c3SBrenda J. Butler -l, --list List all test cases, or those only within the 15095ce14c3SBrenda J. Butler specified category 15195ce14c3SBrenda J. Butler -s, --show Display the selected test cases 15295ce14c3SBrenda J. Butler -i, --id Generate ID numbers for new test cases 15395ce14c3SBrenda J. Butler 15495ce14c3SBrenda J. Butlernetns: 15595ce14c3SBrenda J. Butler options for nsPlugin (run commands in net namespace) 15695ce14c3SBrenda J. Butler 157b70f1f3aSKeara Leibovitz -n, --namespace 158b70f1f3aSKeara Leibovitz Run commands in namespace as specified in tdc_config.py 15995ce14c3SBrenda J. Butler 16095ce14c3SBrenda J. Butlervalgrind: 16195ce14c3SBrenda J. Butler options for valgrindPlugin (run command under test under Valgrind) 16295ce14c3SBrenda J. Butler 16395ce14c3SBrenda J. Butler -V, --valgrind Run commands under valgrind 16495ce14c3SBrenda J. Butler 16595ce14c3SBrenda J. Butler 16695ce14c3SBrenda J. ButlerPLUGIN ARCHITECTURE 16795ce14c3SBrenda J. Butler------------------- 16895ce14c3SBrenda J. Butler 16995ce14c3SBrenda J. ButlerThere is now a plugin architecture, and some of the functionality that 17095ce14c3SBrenda J. Butlerwas in the tdc.py script has been moved into the plugins. 17195ce14c3SBrenda J. Butler 17295ce14c3SBrenda J. ButlerThe plugins are in the directory plugin-lib. The are executed from 17395ce14c3SBrenda J. Butlerdirectory plugins. Put symbolic links from plugins to plugin-lib, 17495ce14c3SBrenda J. Butlerand name them according to the order you want them to run. 17595ce14c3SBrenda J. Butler 17695ce14c3SBrenda J. ButlerExample: 17795ce14c3SBrenda J. Butler 17895ce14c3SBrenda J. Butlerbjb@bee:~/work/tc-testing$ ls -l plugins 17995ce14c3SBrenda J. Butlertotal 4 18095ce14c3SBrenda J. Butlerlrwxrwxrwx 1 bjb bjb 27 Oct 4 16:12 10-rootPlugin.py -> ../plugin-lib/rootPlugin.py 18195ce14c3SBrenda J. Butlerlrwxrwxrwx 1 bjb bjb 25 Oct 12 17:55 20-nsPlugin.py -> ../plugin-lib/nsPlugin.py 18295ce14c3SBrenda J. Butler-rwxr-xr-x 1 bjb bjb 0 Sep 29 15:56 __init__.py 18395ce14c3SBrenda J. Butler 18495ce14c3SBrenda J. ButlerThe plugins are a subclass of TdcPlugin, defined in TdcPlugin.py and 18595ce14c3SBrenda J. Butlermust be called "SubPlugin" so tdc can find them. They are 18695ce14c3SBrenda J. Butlerdistinguished from each other in the python program by their module 18795ce14c3SBrenda J. Butlername. 18895ce14c3SBrenda J. Butler 18995ce14c3SBrenda J. ButlerThis base class supplies "hooks" to run extra functions. These hooks are as follows: 19095ce14c3SBrenda J. Butler 19195ce14c3SBrenda J. Butlerpre- and post-suite 19295ce14c3SBrenda J. Butlerpre- and post-case 19395ce14c3SBrenda J. Butlerpre- and post-execute stage 19495ce14c3SBrenda J. Butleradjust-command (runs in all stages and receives the stage name) 19595ce14c3SBrenda J. Butler 19695ce14c3SBrenda J. ButlerThe pre-suite hook receives the number of tests and an array of test ids. 19795ce14c3SBrenda J. ButlerThis allows you to dump out the list of skipped tests in the event of a 19895ce14c3SBrenda J. Butlerfailure during setup or teardown stage. 19995ce14c3SBrenda J. Butler 20095ce14c3SBrenda J. ButlerThe pre-case hook receives the ordinal number and test id of the current test. 20195ce14c3SBrenda J. Butler 20295ce14c3SBrenda J. ButlerThe adjust-command hook receives the stage id (see list below) and the 20395ce14c3SBrenda J. Butlerfull command to be executed. This allows for last-minute adjustment 20495ce14c3SBrenda J. Butlerof the command. 20595ce14c3SBrenda J. Butler 20695ce14c3SBrenda J. ButlerThe stages are identified by the following strings: 20795ce14c3SBrenda J. Butler 20895ce14c3SBrenda J. Butler - pre (pre-suite) 20995ce14c3SBrenda J. Butler - setup 21095ce14c3SBrenda J. Butler - command 21195ce14c3SBrenda J. Butler - verify 21295ce14c3SBrenda J. Butler - teardown 21395ce14c3SBrenda J. Butler - post (post-suite) 21495ce14c3SBrenda J. Butler 21595ce14c3SBrenda J. Butler 21695ce14c3SBrenda J. ButlerTo write a plugin, you need to inherit from TdcPlugin in 21795ce14c3SBrenda J. ButlerTdcPlugin.py. To use the plugin, you have to put the 21895ce14c3SBrenda J. Butlerimplementation file in plugin-lib, and add a symbolic link to it from 21995ce14c3SBrenda J. Butlerplugins. It will be detected at run time and invoked at the 22095ce14c3SBrenda J. Butlerappropriate times. There are a few examples in the plugin-lib 22195ce14c3SBrenda J. Butlerdirectory: 22295ce14c3SBrenda J. Butler 22395ce14c3SBrenda J. Butler - rootPlugin.py: 22495ce14c3SBrenda J. Butler implements the enforcement of running as root 22595ce14c3SBrenda J. Butler - nsPlugin.py: 22695ce14c3SBrenda J. Butler sets up a network namespace and runs all commands in that namespace 22795ce14c3SBrenda J. Butler - valgrindPlugin.py 22895ce14c3SBrenda J. Butler runs each command in the execute stage under valgrind, 22995ce14c3SBrenda J. Butler and checks for leaks. 23095ce14c3SBrenda J. Butler This plugin will output an extra test for each test in the test file, 23195ce14c3SBrenda J. Butler one is the existing output as to whether the test passed or failed, 23295ce14c3SBrenda J. Butler and the other is a test whether the command leaked memory or not. 23395ce14c3SBrenda J. Butler (This one is a preliminary version, it may not work quite right yet, 23495ce14c3SBrenda J. Butler but the overall template is there and it should only need tweaks.) 235*4c2d39bdSDavide Caratti - buildebpfPlugin.py: 236*4c2d39bdSDavide Caratti builds all programs in $EBPFDIR. 23776b903eeSLucas Bates 23876b903eeSLucas Bates 23976b903eeSLucas BatesACKNOWLEDGEMENTS 24076b903eeSLucas Bates---------------- 24176b903eeSLucas Bates 24276b903eeSLucas BatesThanks to: 24376b903eeSLucas Bates 24476b903eeSLucas BatesJamal Hadi Salim, for providing valuable test cases 24576b903eeSLucas BatesKeara Leibovitz, who wrote the CLI test driver that I used as a base for the 24676b903eeSLucas Bates first version of the tc testing suite. This work was presented at 24776b903eeSLucas Bates Netdev 1.2 Tokyo in October 2016. 24876b903eeSLucas BatesSamir Hussain, for providing help while I dove into Python for the first time 24976b903eeSLucas Bates and being a second eye for this code. 250