Device Emulation (contd.): Fix frames not being truncated (introduced by recent changes in StreamBase::frameValue()); add test case for the same and add checksum/error check to pktlentest(s)
This commit is contained in:
parent
754a9ac20e
commit
e3a3a0cf1f
@ -529,7 +529,7 @@ int StreamBase::frameCount() const
|
|||||||
// length i.e. bufMaxSize
|
// length i.e. bufMaxSize
|
||||||
int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const
|
int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const
|
||||||
{
|
{
|
||||||
int size, pktLen, len = 0;
|
int maxSize, size, pktLen, len = 0;
|
||||||
|
|
||||||
pktLen = frameLen(frameIndex);
|
pktLen = frameLen(frameIndex);
|
||||||
|
|
||||||
@ -539,6 +539,8 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const
|
|||||||
if (pktLen <= 0)
|
if (pktLen <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
maxSize = qMin(pktLen, bufMaxSize);
|
||||||
|
|
||||||
ProtocolListIterator *iter;
|
ProtocolListIterator *iter;
|
||||||
|
|
||||||
iter = createProtocolListIterator();
|
iter = createProtocolListIterator();
|
||||||
@ -550,18 +552,18 @@ int StreamBase::frameValue(uchar *buf, int bufMaxSize, int frameIndex) const
|
|||||||
proto = iter->next();
|
proto = iter->next();
|
||||||
ba = proto->protocolFrameValue(frameIndex);
|
ba = proto->protocolFrameValue(frameIndex);
|
||||||
|
|
||||||
size = qMin(ba.size(), bufMaxSize-len);
|
size = qMin(ba.size(), maxSize-len);
|
||||||
memcpy(buf+len, ba.constData(), size);
|
memcpy(buf+len, ba.constData(), size);
|
||||||
len += size;
|
len += size;
|
||||||
|
|
||||||
if (len == bufMaxSize)
|
if (len == maxSize)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete iter;
|
delete iter;
|
||||||
|
|
||||||
// Pad with zero, if required and if we have space
|
// Pad with zero, if required and if we have space
|
||||||
if ((len < pktLen) && (len < bufMaxSize)) {
|
if (len < maxSize) {
|
||||||
size = qMin(pktLen-len, bufMaxSize-len);
|
size = maxSize-len;
|
||||||
memset(buf+len, 0, size);
|
memset(buf+len, 0, size);
|
||||||
len += size;
|
len += size;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import sys
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from harness import extract_column
|
from harness import extract_column
|
||||||
|
from utils import get_tshark
|
||||||
|
|
||||||
sys.path.insert(1, '../binding')
|
sys.path.insert(1, '../binding')
|
||||||
from core import ost_pb, DroneProxy
|
from core import ost_pb, DroneProxy
|
||||||
@ -21,10 +22,7 @@ host_name = '127.0.0.1'
|
|||||||
tx_number = -1
|
tx_number = -1
|
||||||
rx_number = -1
|
rx_number = -1
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
tshark = get_tshark(minversion='1.2.0')
|
||||||
tshark = r'C:\Program Files\Wireshark\tshark.exe'
|
|
||||||
else:
|
|
||||||
tshark = 'tshark'
|
|
||||||
|
|
||||||
fmt = 'column.format:"Packet#","%m","Time","%t","Source","%uns","Destination","%und","Protocol","%p","Size","%L","Info","%i","Expert","%a"'
|
fmt = 'column.format:"Packet#","%m","Time","%t","Source","%uns","Destination","%und","Protocol","%p","Size","%L","Info","%i","Expert","%a"'
|
||||||
fmt_col = 7 # col# in fmt for Size/PktLength
|
fmt_col = 7 # col# in fmt for Size/PktLength
|
||||||
@ -32,8 +30,10 @@ fmt_col = 7 # col# in fmt for Size/PktLength
|
|||||||
# setup protocol number dictionary
|
# setup protocol number dictionary
|
||||||
proto_number = {}
|
proto_number = {}
|
||||||
proto_number['mac'] = ost_pb.Protocol.kMacFieldNumber
|
proto_number['mac'] = ost_pb.Protocol.kMacFieldNumber
|
||||||
|
proto_number['vlan'] = ost_pb.Protocol.kVlanFieldNumber
|
||||||
proto_number['eth2'] = ost_pb.Protocol.kEth2FieldNumber
|
proto_number['eth2'] = ost_pb.Protocol.kEth2FieldNumber
|
||||||
proto_number['ip4'] = ost_pb.Protocol.kIp4FieldNumber
|
proto_number['ip4'] = ost_pb.Protocol.kIp4FieldNumber
|
||||||
|
proto_number['ip6'] = ost_pb.Protocol.kIp6FieldNumber
|
||||||
proto_number['udp'] = ost_pb.Protocol.kUdpFieldNumber
|
proto_number['udp'] = ost_pb.Protocol.kUdpFieldNumber
|
||||||
proto_number['payload'] = ost_pb.Protocol.kPayloadFieldNumber
|
proto_number['payload'] = ost_pb.Protocol.kPayloadFieldNumber
|
||||||
|
|
||||||
@ -115,8 +115,7 @@ def ports(request, drone):
|
|||||||
|
|
||||||
return ports
|
return ports
|
||||||
|
|
||||||
protolist=['mac eth2 ip4 udp payload', 'mac eth2 ip4 udp']
|
@pytest.fixture(scope='module')
|
||||||
@pytest.fixture(scope='module', params=protolist)
|
|
||||||
def stream(request, drone, ports):
|
def stream(request, drone, ports):
|
||||||
global proto_number
|
global proto_number
|
||||||
|
|
||||||
@ -136,7 +135,39 @@ def stream(request, drone, ports):
|
|||||||
s.control.packets_per_sec = 100
|
s.control.packets_per_sec = 100
|
||||||
s.control.num_packets = 10
|
s.control.num_packets = 10
|
||||||
|
|
||||||
# setup stream protocols as mac:eth2:ip:udp:payload
|
# XXX: don't setup any stream protocols
|
||||||
|
|
||||||
|
def fin():
|
||||||
|
# delete streams
|
||||||
|
log.info('deleting tx_stream %d' % stream_id.stream_id[0].id)
|
||||||
|
drone.deleteStream(stream_id)
|
||||||
|
|
||||||
|
request.addfinalizer(fin)
|
||||||
|
|
||||||
|
return stream_cfg
|
||||||
|
|
||||||
|
protolist=['mac eth2 ip4 udp payload', 'mac eth2 ip4 udp']
|
||||||
|
@pytest.fixture(scope='module', params=protolist)
|
||||||
|
def stream_toggle_payload(request, drone, ports):
|
||||||
|
global proto_number
|
||||||
|
|
||||||
|
# add a stream
|
||||||
|
stream_id = ost_pb.StreamIdList()
|
||||||
|
stream_id.port_id.CopyFrom(ports.tx.port_id[0])
|
||||||
|
stream_id.stream_id.add().id = 1
|
||||||
|
log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
|
||||||
|
drone.addStream(stream_id)
|
||||||
|
|
||||||
|
# configure the stream
|
||||||
|
stream_cfg = ost_pb.StreamConfigList()
|
||||||
|
stream_cfg.port_id.CopyFrom(ports.tx.port_id[0])
|
||||||
|
s = stream_cfg.stream.add()
|
||||||
|
s.stream_id.id = stream_id.stream_id[0].id
|
||||||
|
s.core.is_enabled = True
|
||||||
|
s.control.packets_per_sec = 100
|
||||||
|
s.control.num_packets = 10
|
||||||
|
|
||||||
|
# setup stream protocols
|
||||||
s.ClearField("protocol")
|
s.ClearField("protocol")
|
||||||
protos = request.param.split()
|
protos = request.param.split()
|
||||||
for p in protos:
|
for p in protos:
|
||||||
@ -156,11 +187,12 @@ def stream(request, drone, ports):
|
|||||||
ost_pb.StreamCore.e_fl_dec,
|
ost_pb.StreamCore.e_fl_dec,
|
||||||
ost_pb.StreamCore.e_fl_random
|
ost_pb.StreamCore.e_fl_random
|
||||||
])
|
])
|
||||||
def test_packet_length(drone, ports, stream, mode):
|
def test_framelen_modes(drone, ports, stream_toggle_payload, mode):
|
||||||
""" Test random length packets """
|
""" Test various framelen modes """
|
||||||
|
|
||||||
min_pkt_len = 100
|
min_pkt_len = 100
|
||||||
max_pkt_len = 1000
|
max_pkt_len = 1000
|
||||||
|
stream = stream_toggle_payload
|
||||||
stream.stream[0].core.len_mode = mode
|
stream.stream[0].core.len_mode = mode
|
||||||
stream.stream[0].core.frame_len_min = min_pkt_len
|
stream.stream[0].core.frame_len_min = min_pkt_len
|
||||||
stream.stream[0].core.frame_len_max = max_pkt_len
|
stream.stream[0].core.frame_len_max = max_pkt_len
|
||||||
@ -168,6 +200,13 @@ def test_packet_length(drone, ports, stream, mode):
|
|||||||
log.info('configuring tx_stream %d' % stream.stream[0].stream_id.id)
|
log.info('configuring tx_stream %d' % stream.stream[0].stream_id.id)
|
||||||
drone.modifyStream(stream)
|
drone.modifyStream(stream)
|
||||||
|
|
||||||
|
if stream.stream[0].protocol[-1].protocol_id.id \
|
||||||
|
== ost_pb.Protocol.kPayloadFieldNumber:
|
||||||
|
filter = 'udp && !expert.severity'
|
||||||
|
else:
|
||||||
|
filter = 'udp && eth.fcs_bad==1' \
|
||||||
|
'&& ip.checksum_bad==0 && udp.checksum_bad==0'
|
||||||
|
|
||||||
# clear tx/rx stats
|
# clear tx/rx stats
|
||||||
log.info('clearing tx/rx stats')
|
log.info('clearing tx/rx stats')
|
||||||
drone.clearStats(ports.tx)
|
drone.clearStats(ports.tx)
|
||||||
@ -187,9 +226,11 @@ def test_packet_length(drone, ports, stream, mode):
|
|||||||
log.info('dumping Rx capture buffer')
|
log.info('dumping Rx capture buffer')
|
||||||
cap_pkts = subprocess.check_output([tshark, '-n', '-r', 'capture.pcap'])
|
cap_pkts = subprocess.check_output([tshark, '-n', '-r', 'capture.pcap'])
|
||||||
print(cap_pkts)
|
print(cap_pkts)
|
||||||
|
print(filter)
|
||||||
cap_pkts = subprocess.check_output([tshark, '-n', '-r', 'capture.pcap',
|
cap_pkts = subprocess.check_output([tshark, '-n', '-r', 'capture.pcap',
|
||||||
'-R', 'udp', '-o', fmt])
|
'-Y', filter, '-o', fmt])
|
||||||
print(cap_pkts)
|
print(cap_pkts)
|
||||||
|
assert cap_pkts.count('\n') == stream.stream[0].control.num_packets
|
||||||
result = extract_column(cap_pkts, fmt_col)
|
result = extract_column(cap_pkts, fmt_col)
|
||||||
print(result)
|
print(result)
|
||||||
diffSum = 0
|
diffSum = 0
|
||||||
@ -217,3 +258,51 @@ def test_packet_length(drone, ports, stream, mode):
|
|||||||
finally:
|
finally:
|
||||||
drone.stopTransmit(ports.tx)
|
drone.stopTransmit(ports.tx)
|
||||||
|
|
||||||
|
def test_frame_trunc(drone, ports, stream):
|
||||||
|
""" Test frame is truncated even if the protocol sizes exceed framelen """
|
||||||
|
|
||||||
|
#stream.stream[0].core.frame_len_min = min_pkt_len
|
||||||
|
|
||||||
|
# setup stream protocols as mac:vlan:eth2:ip6:udp:payload
|
||||||
|
stream.stream[0].ClearField("protocol")
|
||||||
|
protos = ['mac', 'vlan', 'eth2', 'ip6', 'udp', 'payload']
|
||||||
|
for p in protos:
|
||||||
|
stream.stream[0].protocol.add().protocol_id.id = proto_number[p]
|
||||||
|
|
||||||
|
# note: unless truncated minimum size of payload protocol is 1
|
||||||
|
exp_framelen = min(12+4+2+40+8+1, 60)
|
||||||
|
|
||||||
|
log.info('configuring tx_stream %d' % stream.stream[0].stream_id.id)
|
||||||
|
drone.modifyStream(stream)
|
||||||
|
|
||||||
|
# clear tx/rx stats
|
||||||
|
log.info('clearing tx/rx stats')
|
||||||
|
drone.clearStats(ports.tx)
|
||||||
|
drone.clearStats(ports.rx)
|
||||||
|
|
||||||
|
try:
|
||||||
|
drone.startCapture(ports.rx)
|
||||||
|
drone.startTransmit(ports.tx)
|
||||||
|
log.info('waiting for transmit to finish ...')
|
||||||
|
time.sleep(3)
|
||||||
|
drone.stopTransmit(ports.tx)
|
||||||
|
drone.stopCapture(ports.rx)
|
||||||
|
|
||||||
|
log.info('getting Rx capture buffer')
|
||||||
|
buff = drone.getCaptureBuffer(ports.rx.port_id[0])
|
||||||
|
drone.saveCaptureBuffer(buff, 'capture.pcap')
|
||||||
|
log.info('dumping Rx capture buffer')
|
||||||
|
cap_pkts = subprocess.check_output([tshark, '-n', '-r', 'capture.pcap',
|
||||||
|
'-Y', 'vlan', '-o', fmt])
|
||||||
|
print(cap_pkts)
|
||||||
|
assert cap_pkts.count('\n') == stream.stream[0].control.num_packets
|
||||||
|
result = extract_column(cap_pkts, fmt_col)
|
||||||
|
print(result)
|
||||||
|
for i in range(len(result)):
|
||||||
|
assert (int(result[i]) == exp_framelen)
|
||||||
|
|
||||||
|
os.remove('capture.pcap')
|
||||||
|
except RpcError as e:
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
drone.stopTransmit(ports.tx)
|
||||||
|
Loading…
Reference in New Issue
Block a user