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