Commit 4dedec83 authored by Petr Špaček's avatar Petr Špaček

evalzone: generate text & CSV output at the same time

parent 6b27e075
Pipeline #40746 passed with stage
in 57 seconds
......@@ -102,11 +102,10 @@ def main():
ednscomp2pickle.save(nsstats_permissive, 'permissive')
summary, results_strict, results_permissive = evalzone.evaluate(nsstats_strict, nsstats_permissive, domain_nsset, nsname_ipsets, domain_ipset)
evalzone.save(results_strict, 'strict')
evalzone.save(results_permissive, 'permissive')
with open('summary', 'w') as summary_file:
summary_file.write(summary)
print(summary)
evalzone.save_pickle(results_strict, 'strict')
evalzone.save_pickle(results_permissive, 'permissive')
evalzone.save_summary(summary)
print(summary.text)
if __name__ == "__main__":
testedns.check_env()
......
......@@ -4,9 +4,10 @@
produce EDNS stats summary from pickled statistical data
"""
from enum import IntEnum
import collections
import logging
import pickle
from typing import Counter, Dict, Iterable, Iterator, NamedTuple, Set
from typing import Counter, Dict, List, Iterable, Iterator, NamedTuple, Set, Union
import dns.name
......@@ -30,6 +31,8 @@ NSIPResult = NamedTuple('NSIPResult', [('ip', str),
DomainResult = NamedTuple('DomainResult', [('state', EDNSResult),
('reason', str)])
ComparisonRow = NamedTuple('ComparisonRow', [('permissive', int),
('strict', int)])
def zone_stream(zone2ns_fn: str, threshold: int) -> Iterator[ZoneNSStats]:
"""
......@@ -114,14 +117,6 @@ def eval_edns_mode(
results[domain_res.state][domain] = domain_res.reason
return results
def stat_line(mode, modename, total, res_perm, res_strict):
perm_pass = len(res_perm[mode])
strict_pass = len(res_strict[mode])
return '{:13s}| {:>11n} {:>7.2f} %\t| {:>11n} {:>7.2f} %'.format(
modename,
perm_pass, perm_pass/total*100,
strict_pass, strict_pass/total*100)
def load():
logging.info('loading EDNS statistics for strict mode (2019+)')
with open('ednsstats_strict.pickle', 'rb') as ednsstats_bin:
......@@ -140,6 +135,44 @@ def load():
domain2ipset = pickle.load(domain2ipset_bin)
return ednsstats_strict, ednsstats_permissive, domain2nsset, nsname2ipset, domain2ipset
class ResultTable():
header = ['Mode', 'Permissive (<= 2018)', 'Strict (2019+)']
names = collections.OrderedDict([
(EDNSResult.ok, 'Ok'),
(EDNSResult.compatible, 'Compatible'),
(EDNSResult.high_latency, 'High latency'),
(EDNSResult.dead, 'Dead')
])
def __init__(self, total, results_permissive, results_strict):
self.results = {}
self.total = total
for category in self.names:
self.results[category] = \
ComparisonRow(len(results_permissive[category]),
len(results_strict[category]))
@property
def csv(self) -> str:
lines = [';'.join(self.header)]
for mode, name in self.names.items():
lines.append('{};{};{}'.format(name,
self.results[mode].permissive, self.results[mode].strict))
return '\n'.join(lines)
@property
def text(self) -> str:
output = '{:13s}| {:.20s} | {:.20s}\n'.format(*self.header)
output += '{:.13s}+-{:.20s}--+--{:.20s}\n'.format(*['-'*30]*3)
for mode, modename in self.names.items():
perm_pass = self.results[mode].permissive
strict_pass = self.results[mode].strict
output += '{:13s}| {:>11n} {:>7.2f} % | {:>11n} {:>7.2f} %\n'.format(
modename,
perm_pass, perm_pass/self.total*100,
strict_pass, strict_pass/self.total*100)
return output
def evaluate(ednsstats_strict, ednsstats_permissive, domain2nsset, nsname2ipset, domain2ipset):
logging.info('starting strict mode evaluation')
results_strict = eval_edns_mode(ednsstats_strict, domain2nsset, nsname2ipset, domain2ipset)
......@@ -150,28 +183,25 @@ def evaluate(ednsstats_strict, ednsstats_permissive, domain2nsset, nsname2ipset,
logging.debug('%s', {case: len(results_permissive[case]) for case in EDNSResult})
total = len(domain2nsset)
output = []
output.append('Mode | Permissive (<= 2018)\t| Strict (2019+)')
output.append('---------------------------------------------------------------')
output.append(stat_line(EDNSResult.ok, 'Ok', total, results_permissive, results_strict))
output.append(stat_line(EDNSResult.compatible, 'Compatible', total, results_permissive, results_strict))
output.append(stat_line(EDNSResult.high_latency, 'High latency', total, results_permissive, results_strict))
output.append(stat_line(EDNSResult.dead, 'Dead', total, results_permissive, results_strict))
summary = '\n'.join(output)
summary = ResultTable(total, results_permissive, results_strict)
return summary, results_strict, results_permissive
def save(results, mode: str) -> None:
def save_pickle(results, mode: str) -> None:
logging.info('pickling results for EDNS {} mode'.format(mode))
with open('results_{}.pickle'.format(mode), 'wb') as results_bin:
pickle.dump(results, results_bin)
def save_summary(summary) -> None:
with open('summary.txt', 'w') as summary_file:
summary_file.write(summary.text)
with open('summary.csv', 'w') as summary_file:
summary_file.write(summary.csv)
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s')
summary, results_strict, results_permissive = evaluate(*load())
save(results_strict, 'strict')
save(results_permissive, 'permissive')
print(summary)
with open('summary', 'w') as summary_file:
summary_file.write(summary)
\ No newline at end of file
save_pickle(results_strict, 'strict')
save_pickle(results_permissive, 'permissive')
save_summary(summary)
print(summary.text)
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