diff options
Diffstat (limited to 'tools/testing/selftests/tc-testing')
14 files changed, 968 insertions, 30 deletions
diff --git a/tools/testing/selftests/tc-testing/README b/tools/testing/selftests/tc-testing/README index f9281e8aa313..22e5da9008fd 100644 --- a/tools/testing/selftests/tc-testing/README +++ b/tools/testing/selftests/tc-testing/README @@ -12,10 +12,10 @@ REQUIREMENTS * Minimum Python version of 3.4. Earlier 3.X versions may work but are not guaranteed. -* The kernel must have network namespace support +* The kernel must have network namespace support if using nsPlugin * The kernel must have veth support available, as a veth pair is created - prior to running the tests. + prior to running the tests when using nsPlugin. * The kernel must have the appropriate infrastructure enabled to run all tdc unit tests. See the config file in this directory for minimum required @@ -53,8 +53,12 @@ commands being tested must be run as root. The code that enforces execution by root uid has been moved into a plugin (see PLUGIN ARCHITECTURE, below). -If nsPlugin is linked, all tests are executed inside a network -namespace to prevent conflicts within the host. +Tests that use a network device should have nsPlugin.py listed as a +requirement for that test. nsPlugin executes all commands within a +network namespace and creates a veth pair which may be used in those test +cases. To disable execution within the namespace, pass the -N option +to tdc when starting a test run; the veth pair will still be created +by the plugin. Running tdc without any arguments will run all tests. Refer to the section on command line arguments for more information, or run: @@ -154,8 +158,8 @@ action: netns: options for nsPlugin (run commands in net namespace) - -n, --namespace - Run commands in namespace as specified in tdc_config.py + -N, --no-namespace + Do not run commands in a network namespace. valgrind: options for valgrindPlugin (run command under test under Valgrind) @@ -171,7 +175,8 @@ was in the tdc.py script has been moved into the plugins. The plugins are in the directory plugin-lib. The are executed from directory plugins. Put symbolic links from plugins to plugin-lib, -and name them according to the order you want them to run. +and name them according to the order you want them to run. This is not +necessary if a test case being run requires a specific plugin to work. Example: @@ -223,7 +228,8 @@ directory: - rootPlugin.py: implements the enforcement of running as root - nsPlugin.py: - sets up a network namespace and runs all commands in that namespace + sets up a network namespace and runs all commands in that namespace, + while also setting up dummy devices to be used in testing. - valgrindPlugin.py runs each command in the execute stage under valgrind, and checks for leaks. diff --git a/tools/testing/selftests/tc-testing/config b/tools/testing/selftests/tc-testing/config index 203302065458..1adc4f9bb795 100644 --- a/tools/testing/selftests/tc-testing/config +++ b/tools/testing/selftests/tc-testing/config @@ -38,11 +38,11 @@ CONFIG_NET_ACT_CSUM=m CONFIG_NET_ACT_VLAN=m CONFIG_NET_ACT_BPF=m CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m CONFIG_NET_ACT_SKBMOD=m CONFIG_NET_ACT_IFE=m CONFIG_NET_ACT_TUNNEL_KEY=m CONFIG_NET_IFE_SKBMARK=m CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m -CONFIG_NET_CLS_IND=y CONFIG_NET_SCH_FIFO=y diff --git a/tools/testing/selftests/tc-testing/plugin-lib/buildebpfPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/buildebpfPlugin.py index 9f0ba10c44b4..e98c36750fae 100644 --- a/tools/testing/selftests/tc-testing/plugin-lib/buildebpfPlugin.py +++ b/tools/testing/selftests/tc-testing/plugin-lib/buildebpfPlugin.py @@ -34,8 +34,9 @@ class SubPlugin(TdcPlugin): 'buildebpf', 'options for buildebpfPlugin') self.argparser_group.add_argument( - '-B', '--buildebpf', action='store_true', - help='build eBPF programs') + '--nobuildebpf', action='store_false', default=True, + dest='buildebpf', + help='Don\'t build eBPF programs') return self.argparser diff --git a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py index a194b1af2b30..affa7f2d9670 100644 --- a/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py +++ b/tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py @@ -18,6 +18,8 @@ class SubPlugin(TdcPlugin): if self.args.namespace: self._ns_create() + else: + self._ports_create() def post_suite(self, index): '''run commands after test_runner goes into a test loop''' @@ -27,6 +29,8 @@ class SubPlugin(TdcPlugin): if self.args.namespace: self._ns_destroy() + else: + self._ports_destroy() def add_args(self, parser): super().add_args(parser) @@ -34,8 +38,8 @@ class SubPlugin(TdcPlugin): 'netns', 'options for nsPlugin(run commands in net namespace)') self.argparser_group.add_argument( - '-n', '--namespace', action='store_true', - help='Run commands in namespace') + '-N', '--no-namespace', action='store_false', default=True, + dest='namespace', help='Don\'t run commands in namespace') return self.argparser def adjust_command(self, stage, command): @@ -73,20 +77,30 @@ class SubPlugin(TdcPlugin): print('adjust_command: return command [{}]'.format(command)) return command + def _ports_create(self): + cmd = 'ip link add $DEV0 type veth peer name $DEV1' + self._exec_cmd('pre', cmd) + cmd = 'ip link set $DEV0 up' + self._exec_cmd('pre', cmd) + if not self.args.namespace: + cmd = 'ip link set $DEV1 up' + self._exec_cmd('pre', cmd) + + def _ports_destroy(self): + cmd = 'ip link del $DEV0' + self._exec_cmd('post', cmd) + def _ns_create(self): ''' Create the network namespace in which the tests will be run and set up the required network devices for it. ''' + self._ports_create() if self.args.namespace: cmd = 'ip netns add {}'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) - cmd = 'ip link add $DEV0 type veth peer name $DEV1' - self._exec_cmd('pre', cmd) cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) - cmd = 'ip link set $DEV0 up' - self._exec_cmd('pre', cmd) cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS']) self._exec_cmd('pre', cmd) if self.args.device: diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json index b074ea9b6fe8..47a3082b6661 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json @@ -54,6 +54,9 @@ "actions", "bpf" ], + "plugins": { + "requires": "buildebpfPlugin" + }, "setup": [ [ "$TC action flush action bpf", @@ -78,6 +81,9 @@ "actions", "bpf" ], + "plugins": { + "requires": "buildebpfPlugin" + }, "setup": [ [ "$TC action flush action bpf", diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json index 6e5fb3d25681..2232b21e2510 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json @@ -459,5 +459,99 @@ "teardown": [ "$TC actions flush action mirred" ] + }, + { + "id": "4749", + "name": "Add batch of 32 mirred redirect egress actions with cookie", + "category": [ + "actions", + "mirred" + ], + "setup": [ + [ + "$TC actions flush action mirred", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred egress redirect dev lo index \\$i cookie aabbccddeeff112233445566778800a1 \\\"; args=\"\\$args\\$cmd\"; done && $TC actions add \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action mirred", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "32", + "teardown": [ + "$TC actions flush action mirred" + ] + }, + { + "id": "5c69", + "name": "Delete batch of 32 mirred redirect egress actions", + "category": [ + "actions", + "mirred" + ], + "setup": [ + [ + "$TC actions flush action mirred", + 0, + 1, + 255 + ], + "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred egress redirect dev lo index \\$i \\\"; args=\\\"\\$args\\$cmd\\\"; done && $TC actions add \\$args\"" + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred index \\$i \\\"; args=\"\\$args\\$cmd\"; done && $TC actions del \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action mirred", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "0", + "teardown": [] + }, + { + "id": "d3c0", + "name": "Add batch of 32 mirred mirror ingress actions with cookie", + "category": [ + "actions", + "mirred" + ], + "setup": [ + [ + "$TC actions flush action mirred", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred ingress mirror dev lo index \\$i cookie aabbccddeeff112233445566778800a1 \\\"; args=\"\\$args\\$cmd\"; done && $TC actions add \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action mirred", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "32", + "teardown": [ + "$TC actions flush action mirred" + ] + }, + { + "id": "e684", + "name": "Delete batch of 32 mirred mirror ingress actions", + "category": [ + "actions", + "mirred" + ], + "setup": [ + [ + "$TC actions flush action mirred", + 0, + 1, + 255 + ], + "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred ingress mirror dev lo index \\$i \\\"; args=\\\"\\$args\\$cmd\\\"; done && $TC actions add \\$args\"" + ], + "cmdUnderTest": "bash -c \"for i in \\`seq 1 32\\`; do cmd=\\\"action mirred index \\$i \\\"; args=\"\\$args\\$cmd\"; done && $TC actions del \\$args\"", + "expExitCode": "0", + "verifyCmd": "$TC actions list action mirred", + "matchPattern": "^[ \t]+index [0-9]+ ref", + "matchCount": "0", + "teardown": [] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json index ecd96eda7f6a..45e7e89928a5 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json @@ -24,8 +24,32 @@ ] }, { + "id": "c8cf", + "name": "Add skbedit action with 32-bit maximum mark", + "category": [ + "actions", + "skbedit" + ], + "setup": [ + [ + "$TC actions flush action skbedit", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "$TC actions add action skbedit mark 4294967295 pipe index 1", + "expExitCode": "0", + "verifyCmd": "$TC actions get action skbedit index 1", + "matchPattern": "action order [0-9]*: skbedit mark 4294967295.*pipe.*index 1", + "matchCount": "1", + "teardown": [ + "$TC actions flush action skbedit" + ] + }, + { "id": "407b", - "name": "Add skbedit action with invalid mark", + "name": "Add skbedit action with mark exceeding 32-bit maximum", "category": [ "actions", "skbedit" @@ -43,9 +67,7 @@ "verifyCmd": "$TC actions list action skbedit", "matchPattern": "action order [0-9]*: skbedit mark", "matchCount": "0", - "teardown": [ - "$TC actions flush action skbedit" - ] + "teardown": [] }, { "id": "081d", @@ -121,7 +143,7 @@ }, { "id": "985c", - "name": "Add skbedit action with invalid queue_mapping", + "name": "Add skbedit action with queue_mapping exceeding 16-bit maximum", "category": [ "actions", "skbedit" @@ -413,7 +435,7 @@ }, { "id": "a6d6", - "name": "Add skbedit action with index", + "name": "Add skbedit action with index at 32-bit maximum", "category": [ "actions", "skbedit" @@ -426,16 +448,38 @@ 255 ] ], - "cmdUnderTest": "$TC actions add action skbedit mark 808 index 4040404040", + "cmdUnderTest": "$TC actions add action skbedit mark 808 index 4294967295", "expExitCode": "0", - "verifyCmd": "$TC actions list action skbedit", - "matchPattern": "index 4040404040", + "verifyCmd": "$TC actions get action skbedit index 4294967295", + "matchPattern": "action order [0-9]*: skbedit mark 808.*index 4294967295", "matchCount": "1", "teardown": [ "$TC actions flush action skbedit" ] }, { + "id": "f0f4", + "name": "Add skbedit action with index exceeding 32-bit maximum", + "category": [ + "actions", + "skbedit" + ], + "setup": [ + [ + "$TC actions flush action skbedit", + 0, + 1, + 255 + ] + ], + "cmdUnderTest": "$TC actions add action skbedit mark 808 pass index 4294967297", + "expExitCode": "255", + "verifyCmd": "$TC actions get action skbedit index 4294967297", + "matchPattern": "action order [0-9]*:.*skbedit.*mark 808.*pass.*index 4294967297", + "matchCount": "0", + "teardown": [] + }, + { "id": "38f3", "name": "Delete skbedit action", "category": [ diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json index 3b97cfd7e0f8..5272049566d6 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/fw.json @@ -6,6 +6,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -25,6 +28,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -44,6 +50,114 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -57,6 +171,30 @@ ] }, { + "id": "c591", + "name": "Add fw filter with action ok by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet. Remove this when the behaviour is fixed.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact ok index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action pass.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "affe", "name": "Add fw filter with action continue", "category": [ @@ -76,6 +214,30 @@ ] }, { + "id": "38b3", + "name": "Add fw filter with action continue by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet. Remove this when the behaviour is fixed.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact continue index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action continue.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "28bc", "name": "Add fw filter with action pipe", "category": [ @@ -95,6 +257,30 @@ ] }, { + "id": "6753", + "name": "Add fw filter with action pipe by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact pipe index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action pipe.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "8da2", "name": "Add fw filter with action drop", "category": [ @@ -114,6 +300,30 @@ ] }, { + "id": "6dc6", + "name": "Add fw filter with action drop by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact drop index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action drop.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "9436", "name": "Add fw filter with action reclassify", "category": [ @@ -133,6 +343,30 @@ ] }, { + "id": "3bc2", + "name": "Add fw filter with action reclassify by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact reclassify index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action reclassify.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "95bb", "name": "Add fw filter with action jump 10", "category": [ @@ -152,6 +386,30 @@ ] }, { + "id": "36f7", + "name": "Add fw filter with action jump 10 by reference", + "__comment": "We add sleep here because action might have not been deleted by workqueue just yet.", + "category": [ + "filter", + "fw" + ], + "setup": [ + "$TC qdisc add dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions add action gact jump 10 index 1" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent ffff: handle 1 prio 1 fw action gact index 1", + "expExitCode": "0", + "verifyCmd": "$TC filter get dev $DEV1 parent ffff: handle 1 prio 1 protocol all fw", + "matchPattern": "handle 0x1.*gact action jump 10.*index 1 ref 2 bind 1", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "/bin/sleep 1", + "$TC actions del action gact index 1" + ] + }, + { "id": "3d74", "name": "Add fw filter with action goto chain 5", "category": [ @@ -728,6 +986,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: protocol 802_3 prio 3 handle 7 fw action ok" @@ -748,6 +1009,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: prio 6 handle 2 fw action continue index 5" @@ -768,6 +1032,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -787,6 +1054,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -806,6 +1076,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", @@ -828,6 +1101,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", @@ -850,6 +1126,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 5 prio 7 fw action pass", @@ -871,6 +1150,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 1 prio 4 fw action ok", @@ -892,6 +1174,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 chain 13 fw action pipe", @@ -913,6 +1198,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 2 prio 4 fw action drop" @@ -933,6 +1221,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 3 prio 4 fw action continue" @@ -953,6 +1244,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 protocol arp fw action pipe" @@ -973,6 +1267,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 4 prio 2 fw action pipe flowid 45" @@ -993,6 +1290,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok" @@ -1013,6 +1313,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok" @@ -1033,6 +1336,9 @@ "filter", "fw" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress", "$TC filter add dev $DEV1 parent ffff: handle 1 prio 2 fw action ok index 3" diff --git a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json index 16559c436f21..0f89cd50a94b 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json +++ b/tools/testing/selftests/tc-testing/tc-tests/filters/tests.json @@ -6,6 +6,9 @@ "filter", "u32" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 ingress" ], @@ -25,6 +28,9 @@ "filter", "matchall" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV1 clsact", "$TC filter add dev $DEV1 protocol all pref 1 ingress handle 0x1234 matchall action ok" @@ -64,6 +70,9 @@ "filter", "flower" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV2 ingress", "./tdc_batch.py $DEV2 $BATCH_FILE --share_action -n 1000000" @@ -85,6 +94,9 @@ "filter", "flower" ], + "plugins": { + "requires": "nsPlugin" + }, "setup": [ "$TC qdisc add dev $DEV2 ingress", "$TC filter add dev $DEV2 protocol ip prio 1 parent ffff: flower dst_mac e4:11:22:11:4a:51 src_mac e4:11:22:11:4a:50 ip_proto tcp src_ip 1.1.1.1 dst_ip 2.2.2.2 action drop" diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json new file mode 100644 index 000000000000..f518c55f468b --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/ingress.json @@ -0,0 +1,102 @@ +[ + { + "id": "9872", + "name": "Add ingress qdisc", + "category": [ + "qdisc", + "ingress" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "5c5e", + "name": "Add ingress qdisc with unsupported argument", + "category": [ + "qdisc", + "ingress" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress foorbar", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "74f6", + "name": "Add duplicate ingress qdisc", + "category": [ + "qdisc", + "ingress" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 ingress", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 ingress", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "f769", + "name": "Delete nonexistent ingress qdisc", + "category": [ + "qdisc", + "ingress" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 ingress", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "3b88", + "name": "Delete ingress qdisc twice", + "category": [ + "qdisc", + "ingress" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 ingress", + "$TC qdisc del dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 ingress", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + } +] diff --git a/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json new file mode 100644 index 000000000000..9c792fa8ca23 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/qdiscs/prio.json @@ -0,0 +1,276 @@ +[ + { + "id": "ddd9", + "name": "Add prio qdisc on egress", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "aa71", + "name": "Add prio qdisc on egress with handle of maximum value", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle ffff: prio", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio ffff: root", + "matchCount": "1", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "db37", + "name": "Add prio qdisc on egress with invalid handle exceeding maximum value", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 10000: prio", + "expExitCode": "255", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 10000: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "39d8", + "name": "Add prio qdisc on egress with unsupported argument", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio foorbar", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "5769", + "name": "Add prio qdisc on egress with 4 bands and new priomap", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "fe0f", + "name": "Add prio qdisc on egress with 4 bands and priomap exceeding TC_PRIO_MAX entries", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0 1 1", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 3 3 0 0 1 2 3 0 0 0 0 0 1 1", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "1f91", + "name": "Add prio qdisc on egress with 4 bands and priomap's values exceeding bands number", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 4 priomap 1 1 2 2 7 5 0 0 1 2 3 0 0 0 0 0", + "expExitCode": "1", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 4 priomap.*1 1 2 2 7 5 0 0 1 2 3 0 0 0 0 0", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "d248", + "name": "Add prio qdisc on egress with invalid bands value (< 2)", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 1 priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 1 priomap.*0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "1d0e", + "name": "Add prio qdisc on egress with invalid bands value exceeding TCQ_PRIO_BANDS", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio bands 1024 priomap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 1024 priomap.*1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "1971", + "name": "Replace default prio qdisc on egress with 8 bands and new priomap", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 handle 1: root prio" + ], + "cmdUnderTest": "$TC qdisc replace dev $DEV1 handle 1: root prio bands 8 priomap 1 1 2 2 3 3 4 4 5 5 6 6 7 7 0 0", + "expExitCode": "0", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root.*bands 8 priomap.*1 1 2 2 3 3 4 4 5 5 6 6 7 7 0 0", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "d88a", + "name": "Add duplicate prio qdisc on egress", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 handle 1: root prio" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 handle 1: root prio", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root", + "matchCount": "1", + "teardown": [ + "$TC qdisc del dev $DEV1 handle 1: root prio", + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "5948", + "name": "Delete nonexistent prio qdisc", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 root handle 1: prio", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 1: root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "6c0a", + "name": "Add prio qdisc on egress with invalid format for handles", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true" + ], + "cmdUnderTest": "$TC qdisc add dev $DEV1 root handle 123^ prio", + "expExitCode": "255", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc prio 123 root", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + }, + { + "id": "0175", + "name": "Delete prio qdisc twice", + "category": [ + "qdisc", + "prio" + ], + "setup": [ + "$IP link add dev $DEV1 type dummy || /bin/true", + "$TC qdisc add dev $DEV1 root handle 1: prio", + "$TC qdisc del dev $DEV1 root handle 1: prio" + ], + "cmdUnderTest": "$TC qdisc del dev $DEV1 handle 1: root prio", + "expExitCode": "2", + "verifyCmd": "$TC qdisc show dev $DEV1", + "matchPattern": "qdisc ingress ffff:", + "matchCount": "0", + "teardown": [ + "$IP link del dev $DEV1 type dummy" + ] + } +] diff --git a/tools/testing/selftests/tc-testing/tdc.py b/tools/testing/selftests/tc-testing/tdc.py index 5cee15659e5f..678182a2676d 100755 --- a/tools/testing/selftests/tc-testing/tdc.py +++ b/tools/testing/selftests/tc-testing/tdc.py @@ -25,6 +25,9 @@ from tdc_helper import * import TdcPlugin from TdcResults import * +class PluginDependencyException(Exception): + def __init__(self, missing_pg): + self.missing_pg = missing_pg class PluginMgrTestFail(Exception): def __init__(self, stage, output, message): @@ -37,7 +40,7 @@ class PluginMgr: super().__init__() self.plugins = {} self.plugin_instances = [] - self.args = [] + self.failed_plugins = {} self.argparser = argparser # TODO, put plugins in order @@ -53,6 +56,64 @@ class PluginMgr: self.plugins[mn] = foo self.plugin_instances.append(foo.SubPlugin()) + def load_plugin(self, pgdir, pgname): + pgname = pgname[0:-3] + foo = importlib.import_module('{}.{}'.format(pgdir, pgname)) + self.plugins[pgname] = foo + self.plugin_instances.append(foo.SubPlugin()) + self.plugin_instances[-1].check_args(self.args, None) + + def get_required_plugins(self, testlist): + ''' + Get all required plugins from the list of test cases and return + all unique items. + ''' + reqs = [] + for t in testlist: + try: + if 'requires' in t['plugins']: + if isinstance(t['plugins']['requires'], list): + reqs.extend(t['plugins']['requires']) + else: + reqs.append(t['plugins']['requires']) + except KeyError: + continue + reqs = get_unique_item(reqs) + return reqs + + def load_required_plugins(self, reqs, parser, args, remaining): + ''' + Get all required plugins from the list of test cases and load any plugin + that is not already enabled. + ''' + pgd = ['plugin-lib', 'plugin-lib-custom'] + pnf = [] + + for r in reqs: + if r not in self.plugins: + fname = '{}.py'.format(r) + source_path = [] + for d in pgd: + pgpath = '{}/{}'.format(d, fname) + if os.path.isfile(pgpath): + source_path.append(pgpath) + if len(source_path) == 0: + print('ERROR: unable to find required plugin {}'.format(r)) + pnf.append(fname) + continue + elif len(source_path) > 1: + print('WARNING: multiple copies of plugin {} found, using version found') + print('at {}'.format(source_path[0])) + pgdir = source_path[0] + pgdir = pgdir.split('/')[0] + self.load_plugin(pgdir, fname) + if len(pnf) > 0: + raise PluginDependencyException(pnf) + + parser = self.call_add_args(parser) + (args, remaining) = parser.parse_known_args(args=remaining, namespace=args) + return args + def call_pre_suite(self, testcount, testidlist): for pgn_inst in self.plugin_instances: pgn_inst.pre_suite(testcount, testidlist) @@ -98,6 +159,9 @@ class PluginMgr: command = pgn_inst.adjust_command(stage, command) return command + def set_args(self, args): + self.args = args + @staticmethod def _make_argparser(args): self.argparser = argparse.ArgumentParser( @@ -550,6 +614,7 @@ def filter_tests_by_category(args, testlist): return answer + def get_test_cases(args): """ If a test case file is specified, retrieve tests from that file. @@ -611,7 +676,7 @@ def get_test_cases(args): return allcatlist, allidlist, testcases_by_cats, alltestcases -def set_operation_mode(pm, args): +def set_operation_mode(pm, parser, args, remaining): """ Load the test case data and process remaining arguments to determine what the script should do for this run, and call the appropriate @@ -649,6 +714,12 @@ def set_operation_mode(pm, args): exit(0) if len(alltests): + req_plugins = pm.get_required_plugins(alltests) + try: + args = pm.load_required_plugins(req_plugins, parser, args, remaining) + except PluginDependencyException as pde: + print('The following plugins were not found:') + print('{}'.format(pde.missing_pg)) catresults = test_runner(pm, args, alltests) if args.format == 'none': print('Test results output suppression requested\n') @@ -686,11 +757,12 @@ def main(): parser = pm.call_add_args(parser) (args, remaining) = parser.parse_known_args() args.NAMES = NAMES + pm.set_args(args) check_default_settings(args, remaining, pm) if args.verbose > 2: print('args is {}'.format(args)) - set_operation_mode(pm, args) + set_operation_mode(pm, parser, args, remaining) exit(0) diff --git a/tools/testing/selftests/tc-testing/tdc_config.py b/tools/testing/selftests/tc-testing/tdc_config.py index 942c70c041be..b771d4c89621 100644 --- a/tools/testing/selftests/tc-testing/tdc_config.py +++ b/tools/testing/selftests/tc-testing/tdc_config.py @@ -10,6 +10,8 @@ Copyright (C) 2017 Lucas Bates <lucasb@mojatatu.com> NAMES = { # Substitute your own tc path here 'TC': '/sbin/tc', + # Substitute your own ip path here + 'IP': '/sbin/ip', # Name of veth devices to be created for the namespace 'DEV0': 'v0p0', 'DEV1': 'v0p1', diff --git a/tools/testing/selftests/tc-testing/tdc_helper.py b/tools/testing/selftests/tc-testing/tdc_helper.py index 9f35c96c88a0..0440d252c4c5 100644 --- a/tools/testing/selftests/tc-testing/tdc_helper.py +++ b/tools/testing/selftests/tc-testing/tdc_helper.py @@ -17,7 +17,10 @@ def get_categorized_testlist(alltests, ucat): def get_unique_item(lst): """ For a list, return a list of the unique items in the list. """ - return list(set(lst)) + if len(lst) > 1: + return list(set(lst)) + else: + return lst def get_test_categories(alltests): |