Commit 45c0e7b2 authored by David S. Miller's avatar David S. Miller

Merge branch 'Add-tests-for-unlocked-flower-classifier-implementation'

Vlad Buslov says:

====================
Add tests for unlocked flower classifier implementation

Implement tests for tdc testsuite to verify concurrent rules update with
rtnl-unlocked flower classifier implementation. The goal of these tests
is to verify general flower classifier correctness by updating filters
on same classifier instance in parallel and to verify its atomicity by
concurrently updating filters in same handle range. All three filter
update operations (add, replace, delete) are tested.

Existing script tdc_batch.py is re-used for batch file generation. It is
extended with several optional CLI arguments that are needed for
concurrency tests. Thin wrapper tdc_multibatch.py is implemented on top
of tdc_batch.py to simplify its usage when generating multiple batch
files for several test configurations.

Parallelism in tests is implemented by running multiple instances of tc
in batch mode with xargs tool. Xargs is chosen for its ease of use and
because it is available by default on most modern Linux distributions.
====================
Acked-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a0dce875 5ce46451
[
{
"id": "e41d",
"name": "Add 1M flower filters with 10 parallel tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 add"
],
"cmdUnderTest": "find $BATCH_DIR/add* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "1000000",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "6f52",
"name": "Delete 1M flower filters with 10 parallel tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 1000000 1 add",
"$TC -b $BATCH_DIR/add_0",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 del"
],
"cmdUnderTest": "find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "0",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "c9da",
"name": "Replace 1M flower filters with 10 parallel tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 1000000 1 add",
"$TC -b $BATCH_DIR/add_0",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 10 replace"
],
"cmdUnderTest": "find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "1000000",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "14be",
"name": "Concurrently replace same range of 100k flower filters from 10 tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 1 add",
"$TC -b $BATCH_DIR/add_0",
"./tdc_multibatch.py -d $DEV2 $BATCH_DIR 100000 10 replace"
],
"cmdUnderTest": "find $BATCH_DIR/replace* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "100000",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "0c44",
"name": "Concurrently delete same range of 100k flower filters from 10 tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py $DEV2 $BATCH_DIR 100000 1 add",
"$TC -b $BATCH_DIR/add_0",
"./tdc_multibatch.py -d $DEV2 $BATCH_DIR 100000 10 del"
],
"cmdUnderTest": "find $BATCH_DIR/del* -print | xargs -n 1 -P 10 $TC -f -b",
"expExitCode": "123",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "0",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "ab62",
"name": "Add and delete from same tp with 10 tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py -x init_ $DEV2 $BATCH_DIR 100000 5 add",
"find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b",
"./tdc_multibatch.py -x par_ -a 500001 -m 5 $DEV2 $BATCH_DIR 100000 5 add",
"./tdc_multibatch.py -x par_ $DEV2 $BATCH_DIR 100000 5 del"
],
"cmdUnderTest": "find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "500000",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
},
{
"id": "6e8f",
"name": "Replace and delete from same tp with 10 tc instances",
"category": [
"filter",
"flower",
"concurrency"
],
"setup": [
"/bin/mkdir $BATCH_DIR",
"$TC qdisc add dev $DEV2 ingress",
"./tdc_multibatch.py -x init_ $DEV2 $BATCH_DIR 100000 10 add",
"find $BATCH_DIR/init_* -print | xargs -n 1 -P 5 $TC -b",
"./tdc_multibatch.py -x par_ -a 500001 -m 5 $DEV2 $BATCH_DIR 100000 5 replace",
"./tdc_multibatch.py -x par_ $DEV2 $BATCH_DIR 100000 5 del"
],
"cmdUnderTest": "find $BATCH_DIR/par_* -print | xargs -n 1 -P 10 $TC -b",
"expExitCode": "0",
"verifyCmd": "$TC -s filter show dev $DEV2 ingress",
"matchPattern": "filter protocol ip pref 1 flower chain 0 handle",
"matchCount": "500000",
"teardown": [
"$TC qdisc del dev $DEV2 ingress",
"/bin/rm -rf $BATCH_DIR"
]
}
]
...@@ -13,6 +13,12 @@ parser.add_argument("device", help="device name") ...@@ -13,6 +13,12 @@ parser.add_argument("device", help="device name")
parser.add_argument("file", help="batch file name") parser.add_argument("file", help="batch file name")
parser.add_argument("-n", "--number", type=int, parser.add_argument("-n", "--number", type=int,
help="how many lines in batch file") help="how many lines in batch file")
parser.add_argument(
"-a",
"--handle_start",
type=int,
default=1,
help="start handle range from (default: 1)")
parser.add_argument("-o", "--skip_sw", parser.add_argument("-o", "--skip_sw",
help="skip_sw (offload), by default skip_hw", help="skip_sw (offload), by default skip_hw",
action="store_true") action="store_true")
...@@ -22,6 +28,21 @@ parser.add_argument("-s", "--share_action", ...@@ -22,6 +28,21 @@ parser.add_argument("-s", "--share_action",
parser.add_argument("-p", "--prio", parser.add_argument("-p", "--prio",
help="all filters have different prio", help="all filters have different prio",
action="store_true") action="store_true")
parser.add_argument(
"-e",
"--operation",
choices=['add', 'del', 'replace'],
default='add',
help="operation to perform on filters"
"(default: add filter)")
parser.add_argument(
"-m",
"--mac_prefix",
type=int,
default=0,
choices=range(0, 256),
help="third byte of source MAC address of flower filter"
"(default: 0)")
args = parser.parse_args() args = parser.parse_args()
device = args.device device = args.device
...@@ -31,6 +52,8 @@ number = 1 ...@@ -31,6 +52,8 @@ number = 1
if args.number: if args.number:
number = args.number number = args.number
handle_start = args.handle_start
skip = "skip_hw" skip = "skip_hw"
if args.skip_sw: if args.skip_sw:
skip = "skip_sw" skip = "skip_sw"
...@@ -45,16 +68,43 @@ if args.prio: ...@@ -45,16 +68,43 @@ if args.prio:
if number > 0x4000: if number > 0x4000:
number = 0x4000 number = 0x4000
mac_prefix = args.mac_prefix
def format_add_filter(device, prio, handle, skip, src_mac, dst_mac,
share_action):
return ("filter add dev {} {} protocol ip parent ffff: handle {} "
" flower {} src_mac {} dst_mac {} action drop {}".format(
device, prio, handle, skip, src_mac, dst_mac, share_action))
def format_rep_filter(device, prio, handle, skip, src_mac, dst_mac,
share_action):
return ("filter replace dev {} {} protocol ip parent ffff: handle {} "
" flower {} src_mac {} dst_mac {} action drop {}".format(
device, prio, handle, skip, src_mac, dst_mac, share_action))
def format_del_filter(device, prio, handle, skip, src_mac, dst_mac,
share_action):
return ("filter del dev {} {} protocol ip parent ffff: handle {} "
"flower".format(device, prio, handle))
formatter = format_add_filter
if args.operation == "del":
formatter = format_del_filter
elif args.operation == "replace":
formatter = format_rep_filter
index = 0 index = 0
for i in range(0x100): for i in range(0x100):
for j in range(0x100): for j in range(0x100):
for k in range(0x100): for k in range(0x100):
mac = ("{:02x}:{:02x}:{:02x}".format(i, j, k)) mac = ("{:02x}:{:02x}:{:02x}".format(i, j, k))
src_mac = "e4:11:00:" + mac src_mac = "e4:11:{:02x}:{}".format(mac_prefix, mac)
dst_mac = "e4:12:00:" + mac dst_mac = "e4:12:00:" + mac
cmd = ("filter add dev {} {} protocol ip parent ffff: flower {} " cmd = formatter(device, prio, handle_start + index, skip, src_mac,
"src_mac {} dst_mac {} action drop {}".format dst_mac, share_action)
(device, prio, skip, src_mac, dst_mac, share_action))
file.write("{}\n".format(cmd)) file.write("{}\n".format(cmd))
index += 1 index += 1
if index >= number: if index >= number:
......
...@@ -15,6 +15,7 @@ NAMES = { ...@@ -15,6 +15,7 @@ NAMES = {
'DEV1': 'v0p1', 'DEV1': 'v0p1',
'DEV2': '', 'DEV2': '',
'BATCH_FILE': './batch.txt', 'BATCH_FILE': './batch.txt',
'BATCH_DIR': 'tmp',
# Length of time in seconds to wait before terminating a command # Length of time in seconds to wait before terminating a command
'TIMEOUT': 12, 'TIMEOUT': 12,
# Name of the namespace to use # Name of the namespace to use
......
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0
"""
tdc_multibatch.py - a thin wrapper over tdc_batch.py to generate multiple batch
files
Copyright (C) 2019 Vlad Buslov <vladbu@mellanox.com>
"""
import argparse
import os
parser = argparse.ArgumentParser(
description='TC multiple batch file generator')
parser.add_argument("device", help="device name")
parser.add_argument("dir", help="where to put batch files")
parser.add_argument(
"num_filters", type=int, help="how many lines per batch file")
parser.add_argument("num_files", type=int, help="how many batch files")
parser.add_argument(
"operation",
choices=['add', 'del', 'replace'],
help="operation to perform on filters")
parser.add_argument(
"-x",
"--file_prefix",
default="",
help="prefix for generated batch file names")
parser.add_argument(
"-d",
"--duplicate_handles",
action="store_true",
help="duplicate filter handle range in all files")
parser.add_argument(
"-a",
"--handle_start",
type=int,
default=1,
help="start handle range from (default: 1)")
parser.add_argument(
"-m",
"--mac_prefix",
type=int,
default=0,
choices=range(0, 256),
help="add this value to third byte of source MAC address of flower filter"
"(default: 0)")
args = parser.parse_args()
device = args.device
dir = args.dir
file_prefix = args.file_prefix + args.operation + "_"
num_filters = args.num_filters
num_files = args.num_files
operation = args.operation
duplicate_handles = args.duplicate_handles
handle = args.handle_start
mac_prefix = args.mac_prefix
for i in range(num_files):
file = dir + '/' + file_prefix + str(i)
os.system("./tdc_batch.py -n {} -a {} -e {} -m {} {} {}".format(
num_filters, handle, operation, i + mac_prefix, device, file))
if not duplicate_handles:
handle += num_filters
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment