tests: add enhanced packet counter verification
Add support for inline packet counter verification to send_and_* functions. Diff dictionary is a dictionary of dictionaries of interesting stats: diff_dictionary = { "err" : { '/error/counter1' : 4, }, sw_if_index1 : { '/stat/segment/counter1' : 5, '/stat/segment/counter2' : 6, }, sw_if_index2 : { '/stat/segment/counter1' : 7, }, } It describes a per sw-if-index diffset, where each key is stat segment path and value is the expected change for that counter for sw-if-index. Special case string "err" is used for error counters. This then allows more precise packet counter verification by first defining a "zero" dictionary, e.g. for ED NAT: cls.no_diff = StatsDiff({ pg.sw_if_index: { '/nat44-ed/in2out/fastpath/tcp': 0, '/nat44-ed/in2out/fastpath/udp': 0, '/nat44-ed/in2out/fastpath/icmp': 0, '/nat44-ed/in2out/fastpath/drops': 0, '/nat44-ed/in2out/slowpath/tcp': 0, '/nat44-ed/in2out/slowpath/udp': 0, '/nat44-ed/in2out/slowpath/icmp': 0, '/nat44-ed/in2out/slowpath/drops': 0, '/nat44-ed/in2out/fastpath/tcp': 0, '/nat44-ed/in2out/fastpath/udp': 0, '/nat44-ed/in2out/fastpath/icmp': 0, '/nat44-ed/in2out/fastpath/drops': 0, '/nat44-ed/in2out/slowpath/tcp': 0, '/nat44-ed/in2out/slowpath/udp': 0, '/nat44-ed/in2out/slowpath/icmp': 0, '/nat44-ed/in2out/slowpath/drops': 0, } for pg in cls.pg_interfaces }) and then to specify only changed counters directly when calling one of send_and_* functions: self.send_and_assert_no_replies( self.pg0, pkts, msg="i2o pkts", stats_diff=self.no_diff | { "err": { '/err/nat44-ed-in2out-slowpath/out of ports': len(pkts), }, self.pg0.sw_if_index: { '/nat44-ed/in2out/slowpath/drops': len(pkts), }, } ) operator | is overloaded by StatsDiff class to perform a deep merge operation, so in above case, dictionaries for "err" and self.pg0.sw_if_index do not overwrite whole sub-dictionaries, rather the contents are merged, assuring that all the remaining counters are verified to be zero. Type: improvement Signed-off-by: Klement Sekera <klement.sekera@gmail.com> Change-Id: I2b87f7bd58a7d4b34ee72344e2f871b2f372e2d9
This commit is contained in:

committed by
Neale Ranns

parent
107ad73e1b
commit
ad3187fe23
50
test/util.py
50
test/util.py
@ -1,12 +1,11 @@
|
||||
""" test framework utilities """
|
||||
|
||||
import abc
|
||||
import ipaddress
|
||||
import logging
|
||||
import socket
|
||||
from socket import AF_INET6
|
||||
import sys
|
||||
import os.path
|
||||
from copy import deepcopy
|
||||
|
||||
import scapy.compat
|
||||
from scapy.layers.l2 import Ether
|
||||
@ -452,3 +451,50 @@ def reassemble4_ether(listoffragments):
|
||||
|
||||
def reassemble4(listoffragments):
|
||||
return reassemble4_core(listoffragments, True)
|
||||
|
||||
|
||||
def recursive_dict_merge(dict_base, dict_update):
|
||||
"""Recursively merge base dict with update dict, return merged dict"""
|
||||
for key in dict_update:
|
||||
if key in dict_base:
|
||||
if type(dict_update[key]) is dict:
|
||||
dict_base[key] = recursive_dict_merge(dict_base[key],
|
||||
dict_update[key])
|
||||
else:
|
||||
dict_base[key] = dict_update[key]
|
||||
else:
|
||||
dict_base[key] = dict_update[key]
|
||||
return dict_base
|
||||
|
||||
|
||||
class StatsDiff:
|
||||
"""
|
||||
Diff dictionary is a dictionary of dictionaries of interesting stats:
|
||||
|
||||
diff_dictionary =
|
||||
{
|
||||
"err" : { '/error/counter1' : 4, },
|
||||
sw_if_index1 : { '/stat/segment/counter1' : 5,
|
||||
'/stat/segment/counter2' : 6,
|
||||
},
|
||||
sw_if_index2 : { '/stat/segment/counter1' : 7,
|
||||
},
|
||||
}
|
||||
|
||||
It describes a per sw-if-index diffset, where each key is stat segment
|
||||
path and value is the expected change for that counter for sw-if-index.
|
||||
Special case string "err" is used for error counters, which are not per
|
||||
sw-if-index.
|
||||
"""
|
||||
|
||||
def __init__(self, stats_diff={}):
|
||||
self.stats_diff = stats_diff
|
||||
|
||||
def update(self, sw_if_index, key, value):
|
||||
if sw_if_index in self.stats_diff:
|
||||
self.stats_diff[sw_if_index][key] = value
|
||||
else:
|
||||
self.stats_diff[sw_if_index] = {key: value}
|
||||
|
||||
def __or__(self, other):
|
||||
return recursive_dict_merge(deepcopy(self.stats_diff), other)
|
||||
|
Reference in New Issue
Block a user