Commit ea156ea4 authored by Joanne Hugé's avatar Joanne Hugé

Add A20 RTT measures

parent a286f717
...@@ -93,7 +93,7 @@ class MeasureSetHandler: ...@@ -93,7 +93,7 @@ class MeasureSetHandler:
with open(MeasureSetHandler.measure_sets_path, 'w') as measure_sets_file: with open(MeasureSetHandler.measure_sets_path, 'w') as measure_sets_file:
json.dump(self.measure_sets, measure_sets_file) json.dump(self.measure_sets, measure_sets_file)
def import_from_json(self, path, flat=False, cyclictest=False, user_input=False, file_input=None): def import_from_file(self, path, cyclictest=False, ping=False, user_input=False, file_input=None):
measure_sets = [] measure_sets = []
...@@ -101,6 +101,8 @@ class MeasureSetHandler: ...@@ -101,6 +101,8 @@ class MeasureSetHandler:
if cyclictest: if cyclictest:
data = MeasureSet.parse_cyclictest(infile) data = MeasureSet.parse_cyclictest(infile)
elif ping:
data = MeasureSet.parse_ping(infile)
else: else:
data = json.load(infile) data = json.load(infile)
...@@ -111,7 +113,7 @@ class MeasureSetHandler: ...@@ -111,7 +113,7 @@ class MeasureSetHandler:
for measure_set_data in data['measure_sets']: for measure_set_data in data['measure_sets']:
measure_set = MeasureSet(self.metadata_defvals) measure_set = MeasureSet(self.metadata_defvals)
measure_set.import_from_json_data(measure_set_data, flat=flat, user_input=user_input) measure_set.import_from_json_data(measure_set_data, user_input=user_input)
if file_input != None: if file_input != None:
measure_set.update_metadata(metadata, []); measure_set.update_metadata(metadata, []);
...@@ -123,7 +125,7 @@ class MeasureSetHandler: ...@@ -123,7 +125,7 @@ class MeasureSetHandler:
def get_measure_set(self, measure_name): def get_measure_set(self, measure_name):
measure_path = "{}/{}.json".format(self.measures_dir, measure_name) measure_path = "{}/{}.json".format(self.measures_dir, measure_name)
measure_set = self.import_from_json(measure_path, False)[0] measure_set = self.import_from_file(measure_path)[0]
return measure_set return measure_set
def add_measure_set(self, measure_set): def add_measure_set(self, measure_set):
...@@ -226,10 +228,13 @@ class MeasureSetHandler: ...@@ -226,10 +228,13 @@ class MeasureSetHandler:
mids = [] mids = []
for mid in self.measure_sets[mtype]['ids']: for mid in self.measure_sets[mtype]['ids']:
measure = self.get_measure_set("{}{}".format(mtype, mid)) measure = self.get_measure_set("{}{}".format(mtype, mid))
# Measures with lost packets are not relevant to graph # Measures with lost packets are not relevant to graph
if measure.metadata['lost_packets'] == "0": if measure.metadata['lost_packets'] == "0":
if measure.props_type != 'minmaxavg':
measures.append(measure) measures.append(measure)
mids.append(mid) mids.append(mid)
if len(measures) == 0: if len(measures) == 0:
continue continue
...@@ -515,6 +520,28 @@ class MeasureSet: ...@@ -515,6 +520,28 @@ class MeasureSet:
self.avg.append(avg) self.avg.append(avg)
self.dev.append(sqrt(var)) self.dev.append(sqrt(var))
def add_minmaxavg(self, props_names, props):
self.props = props
self.props_names = props_names
self.props_type = 'minmaxavg'
self.max = []
self.min = []
self.avg = []
self.dev = []
self.nb_measures = []
for prop in props:
min_v, max_v, avg_v, dev_v, nb_measures = prop
self.max.append(max_v)
self.min.append(min_v)
self.avg.append(avg_v)
self.dev.append(dev_v)
self.nb_measures.append(nb_measures)
def export_to_json(self, path): def export_to_json(self, path):
with open(path, 'w') as outfile: with open(path, 'w') as outfile:
...@@ -528,6 +555,41 @@ class MeasureSet: ...@@ -528,6 +555,41 @@ class MeasureSet:
'metadata': self.metadata} 'metadata': self.metadata}
]}, outfile) ]}, outfile)
def parse_ping(infile):
data = {}
data['measure_sets'] = []
lines = [line for line in infile]
s = lines[-2]
transmitted,s = s.split(" packets transmitted, ")
received,s = s.split(" received")
tmp,s = s.split("time ")
nb_minutes = int(s[:-3]) // (1000 * 60)
hours,minutes = nb_minutes // 60, nb_minutes % 60
s = lines[-1]
s = s.split(" = ")[1]
s = s.split(" ms")[0]
values = s.split("/")
values = [int(float(v) * 1000) for v in values]
min_rtt, avg_rtt, max_rtt, mdev_rtt = values
measure_set = {}
measure_set['props_type'] = 'minmaxavg'
measure_set['units'] = ['us']
measure_set['props'] = [(min_rtt, max_rtt, avg_rtt, mdev_rtt, transmitted)]
measure_set['metadata'] = {}
measure_set['metadata']['lost_packets'] = str(int(transmitted) - int(received))
measure_set['measure_type'] = 'ping_interval'
measure_set['props_names'] = ['ping RTT']
measure_set['metadata']['duration'] = "{}h{}".format(hours, minutes)
data['measure_sets'].append(measure_set)
return data
def parse_cyclictest(infile): def parse_cyclictest(infile):
data = {} data = {}
...@@ -610,13 +672,17 @@ class MeasureSet: ...@@ -610,13 +672,17 @@ class MeasureSet:
def compute_duration(self): def compute_duration(self):
print(self.props_type)
if self.props_type == 'minmaxavg':
nb_packets = int(self.props[0][4])
else:
nb_packets = sum(self.props[0]) nb_packets = sum(self.props[0])
nb_us = int(self.metadata['i'][:-2]) * nb_packets nb_us = int(self.metadata['i'][:-2]) * nb_packets
hours = int((nb_us / 10**6) / 3600) hours = int((nb_us / 10**6) / 3600)
minutes = int((nb_us / 10**6) / 60) % 60 minutes = int((nb_us / 10**6) / 60) % 60
self.metadata['duration'] = "{}h{}".format(hours, minutes) self.metadata['duration'] = "{}h{}".format(hours, minutes)
def import_from_json_data(self, data, flat=False, user_input=False): def import_from_json_data(self, data, user_input=False):
measure_type = data['measure_type'] measure_type = data['measure_type']
units = data['units'] units = data['units']
...@@ -629,25 +695,13 @@ class MeasureSet: ...@@ -629,25 +695,13 @@ class MeasureSet:
self.add_metadata(measure_type, units, middle, metadata, user_input) self.add_metadata(measure_type, units, middle, metadata, user_input)
props_names = data['props_names'] props_names = data['props_names']
props = data['props']
if data['props_type'] == 'histogram': if data['props_type'] == 'histogram':
props = data['props']
self.add_histogram(props_names, props) self.add_histogram(props_names, props)
elif data['props_type'] == 'minmaxavg':
self.add_minmaxavg(props_names, props)
else: else:
if flat:
values = data['values']
nb_props = len(props_names)
props = [[] for c in range(nb_props)]
for i,value in enumerate(values):
props[i % nb_props].append(value)
else:
props = data['props']
self.add_chronological(props_names, props) self.add_chronological(props_names, props)
def generate_histogram(self, i, name): def generate_histogram(self, i, name):
...@@ -739,7 +793,8 @@ def parse_args(): ...@@ -739,7 +793,8 @@ def parse_args():
parser = argparse parser = argparse
parser = argparse.ArgumentParser(description='Measure analysis') parser = argparse.ArgumentParser(description='Measure analysis')
parser.add_argument('-i', nargs=1, required=False, help='import json measures') parser.add_argument('-i', nargs=1, required=False, help='import json measures')
parser.add_argument('-c', action='store_true', required=False, help='parse cyclictest-like histogram (usable with client and server program\'s histograms)') parser.add_argument('-c', action='store_true', required=False, help='parse cyclictest-like output (usable with client and server program\'s output)')
parser.add_argument('-p', action='store_true', required=False, help='parse ping output')
parser.add_argument('-I', nargs=1, required=False, help='import metadata file') parser.add_argument('-I', nargs=1, required=False, help='import metadata file')
parser.add_argument('--remove', nargs=1, required=False, help='remove a measure') parser.add_argument('--remove', nargs=1, required=False, help='remove a measure')
parser.add_argument('--remove-type', nargs=1, required=False, help='remove all measures from a type') parser.add_argument('--remove-type', nargs=1, required=False, help='remove all measures from a type')
...@@ -784,10 +839,12 @@ def parse_args(): ...@@ -784,10 +839,12 @@ def parse_args():
file_input = None file_input = None
user_input = True user_input = True
if args.c: if not (args.p or args.c):
measure_sets = ms_handler.import_from_json(args.i[0], cyclictest=True, user_input=user_input, file_input=file_input) print("Select either -p or -c when importing")
else: parser.print_help()
measure_sets = ms_handler.import_from_json(args.i[0], flat=True, user_input=user_input, file_input=file_input) exit()
measure_sets = ms_handler.import_from_file(args.i[0], cyclictest=bool(args.c), ping=bool(args.p), user_input=user_input, file_input=file_input)
for measure_set in measure_sets: for measure_set in measure_sets:
ms_handler.add_measure_set(measure_set) ms_handler.add_measure_set(measure_set)
......
...@@ -41,7 +41,6 @@ A20, 5.6, 18h13 (328153384) | 8.0000us | 73.0000us | 9 ...@@ -41,7 +41,6 @@ A20, 5.6, 18h13 (328153384) | 8.0000us | 73.0000us | 9
Two shuttles connected end to end with an ethernet cable and synchronized with PTP emit signals, and a logic analyzer measures variation in those signals, similar to "Shuttle controlled A20 signal output jitter" measures Two shuttles connected end to end with an ethernet cable and synchronized with PTP emit signals, and a logic analyzer measures variation in those signals, similar to "Shuttle controlled A20 signal output jitter" measures
**Common test metadata:** Device: Shuttle, Linux kernel version: 4.19, Task priority: 98, Interval: 10000us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Test duration: 0h10, Speed (Mb/s): 1000, ETF offset: 500us, Packet route: E2E, qdisc: pfifo_fast, Client device: A20, XDP: no **Common test metadata:** Device: Shuttle, Linux kernel version: 4.19, Task priority: 98, Interval: 10000us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Test duration: 0h10, Speed (Mb/s): 1000, ETF offset: 500us, Packet route: E2E, qdisc: pfifo_fast, Client device: A20, XDP: no
Minimum | Maximum | Average | Standard deviation | Lost packets Minimum | Maximum | Average | Standard deviation | Lost packets
...@@ -81,4 +80,18 @@ Minimum | Maximum ...@@ -81,4 +80,18 @@ Minimum | Maximum
![alt text](measures/graphs/shuttle_a20_signal_jitterShuttle controlled A20 signal output jitter.png "shuttle_a20_signal_jitter Graph") ![alt text](measures/graphs/shuttle_a20_signal_jitterShuttle controlled A20 signal output jitter.png "shuttle_a20_signal_jitter Graph")
### ping_interval results
Ping RTT from A20 to shuttle, with fixed interval
**Common test metadata:** Device: A20, Linux kernel version: 5.6, Task priority: 98, Interval: 1000us, Boot Parameters: isolcpus,rcu_nocbs,irqaffinity, ETF qdisc delta: None, Device and processor load: None, Test duration: 0h37, Speed (Mb/s): 1000, Packet route: E2E, Client device: A20, XDP: no
Minimum | Maximum | Average | Standard deviation | Lost packets
------------ | ------------ | ------------ | ------------------ | ------------
**ping RTT** | **ping RTT** | **ping RTT** | **ping RTT** |
59.0000us | 460.0000us | 272.0000us | 74.0000us | 0
![alt text](measures/graphs/ping_intervalping RTT.png "ping_interval Graph")
{"cyclictest_wake-up_latency": {"ids": [3, 5], "next_id": 6}, "shuttle_signal_jitter": {"ids": [0], "next_id": 1}, "packet_jitter": {"ids": [0, 1, 2, 3, 4], "next_id": 5}, "shuttle_a20_signal_jitter": {"ids": [0], "next_id": 1}} {"cyclictest_wake-up_latency": {"ids": [3, 5], "next_id": 6}, "shuttle_signal_jitter": {"ids": [0], "next_id": 1}, "packet_jitter": {"ids": [0, 1, 2, 3, 4], "next_id": 5}, "shuttle_a20_signal_jitter": {"ids": [0], "next_id": 1}, "ping_interval": {"ids": [0], "next_id": 1}}
\ No newline at end of file \ No newline at end of file
{"measure_sets": [{"measure_type": "ping_interval", "props_names": ["ping RTT"], "units": ["us"], "middle": 0, "props": [[59, 460, 272, 74, "2271655"]], "props_type": "minmaxavg", "metadata": {"dev": "A20", "ker": "5.6", "prio": "98", "i": "1000us", "boot_p": "isolcpus,rcu_nocbs,irqaffinity", "delta": "None", "load": "None", "duration": "0h37", "speed": "1000", "etf_offset": "500us", "route": "E2E", "qdisc": "pfifo_fast", "client": "A20", "XDP": "no", "lost_packets": "0"}}]}
\ No newline at end of file
...@@ -122,3 +122,8 @@ Description: Two A20 boards are connected end to end with an ethernet cable to a ...@@ -122,3 +122,8 @@ Description: Two A20 boards are connected end to end with an ethernet cable to a
Ignored metadata: Ignored metadata:
Description: Two shuttles connected end to end with an ethernet cable and synchronized with PTP emit signals, and a logic analyzer measures variation in those signals, similar to "Shuttle controlled A20 signal output jitter" measures Description: Two shuttles connected end to end with an ethernet cable and synchronized with PTP emit signals, and a logic analyzer measures variation in those signals, similar to "Shuttle controlled A20 signal output jitter" measures
##ping_interval
Ignored metadata: delta,qdisc,etf_offset
Description: Ping RTT from A20 to shuttle, with fixed interval
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