Commit 5372eb7d authored by juga's avatar juga
Browse files

Add class to manage bw files

* Move logic in generate to class
* Add test
* Move 7500 to global constant
* Make read_started_at not fail when conf is None
parent f19c2ab0
from sbws.globals import (fail_hard, is_initted)
from sbws.lib.v3bwfile import V3BwHeader, V3BWLine
from sbws.lib.resultdump import ResultSuccess
from sbws.globals import (fail_hard, is_initted, SCALE_CONSTANT)
from sbws.lib.v3bwfile import V3BwFile
from sbws.lib.resultdump import load_recent_results_in_datadir
from argparse import ArgumentDefaultsHelpFormatter
import os
......@@ -22,7 +21,7 @@ def gen_parser(sub):
# time, torflow happened to generate output that averaged to 7500 bw units
# per relay. We wanted the ability to try to be like torflow. See
# https://lists.torproject.org/pipermail/tor-dev/2018-March/013049.html
p.add_argument('--scale-constant', default=7500, type=int,
p.add_argument('--scale-constant', default=SCALE_CONSTANT, type=int,
help='When scaling bw weights, scale them using this const '
'multiplied by the number of measured relays')
p.add_argument('--scale', action='store_true',
......@@ -32,13 +31,6 @@ def gen_parser(sub):
'out, and we do so proportionally')
def log_stats(data_lines):
assert len(data_lines) > 0
total_bw = sum([l.bw for l in data_lines])
bw_per_line = total_bw / len(data_lines)
log.info('Mean bandwidth per line: %f "KiB"', bw_per_line)
def main(args, conf):
if not is_initted(args.directory):
fail_hard('Sbws isn\'t initialized. Try sbws init')
......@@ -56,4 +48,5 @@ def main(args, conf):
log.warning('No recent results, so not generating anything. (Have you '
'ran sbws scanner recently?)')
return
bw_file = V3BwFile.from_arg_results(args, conf, results)
log.info('Mean bandwidth per line: %f "KiB"', bw_file.avg_bw)
......@@ -24,6 +24,8 @@ TORRC_STARTING_POINT = {
'UseEntryGuards': '0',
}
SCALE_CONSTANT = 7500
def is_initted(d):
if not os.path.isdir(d):
......
......@@ -70,7 +70,10 @@ def read_started_ts(conf):
:param ConfigParser conf: configuration
:returns: str, ISO formated timestamp
"""
try:
filepath = conf['paths']['started_filepath']
except TypeError as e:
return ''
try:
with FileLock(filepath):
with open(filepath, 'r') as fd:
......@@ -336,3 +339,56 @@ class V3BWLine(object):
assert fingerprint in data
return cls.from_results(data[fingerprint])
class V3BwFile(object):
def __init__(self, v3bwheader, v3bwlines):
"""
:param V3BWHeader v3bwheader:
:param list v3bwlines:
"""
self.header = v3bwheader
self.bw_lines = v3bwlines
def __str__(self):
return str(self.header) + ''.join([str(bw_line)
for bw_line in self.bw_lines])
@property
def total_bw(self):
return total_bw(self.bw_lines)
@property
def num_lines(self):
return len(self.bw_lines)
@property
def avg_bw(self):
return self.total_bw / self.num_lines
@classmethod
def from_results(cls, conf, output, results):
bw_lines = [V3BWLine.from_results(results[fp]) for fp in results]
bw_lines = sorted(bw_lines, key=lambda d: d.bw, reverse=True)
header = V3BwHeader.from_results(conf, results)
f = cls(header, bw_lines)
f.write(output)
return f
@classmethod
def from_arg_results(cls, args, conf, results):
bw_lines = [V3BWLine.from_results(results[fp]) for fp in results]
bw_lines = sorted(bw_lines, key=lambda d: d.bw, reverse=True)
if args.scale:
bw_lines = scale_lines(bw_lines, args.scale_constant)
header = V3BwHeader.from_results(conf, results)
f = cls(header, bw_lines)
output = args.output or conf['paths']['v3bw_fname']
f.write(output)
return f
def write(self, output):
log.info('Writing v3bw file to %s', output)
with open(output, 'wt') as fd:
fd.write(str(self.header))
for line in self.bw_lines:
fd.write(str(line))
1523974147
version=1.1.0
earliest_bandwidth=2018-04-16T14:09:07
file_created=2018-04-25T13:10:57
generator_started=2018-04-16T14:09:05
latest_bandwidth=2018-04-17T14:09:07
software=sbws
software_version=0.3.1-dev
====
bw=54 error_auth=0 error_circ=0 error_misc=0 error_stream=1 last_time=2018-04-17T14:09:07 nick=A node_id=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA success=1
# -*- coding: utf-8 -*-
"""Test generation of bandwidth measurements document (v3bw)"""
import json
import os.path
from sbws import __version__ as version
from sbws.globals import SPEC_VERSION
from sbws.lib.resultdump import Result, load_result_file
from sbws.lib.v3bwfile import (V3BwHeader, V3BWLine, TERMINATOR, LINE_SEP,
KEYVALUE_SEP_V110, num_results_of_type)
KEYVALUE_SEP_V110, num_results_of_type,
V3BwFile)
timestamp = 1523974147
timestamp_l = str(timestamp)
......@@ -152,4 +152,14 @@ def test_v3bwline_from_results_file(datadir):
def test_v3bwfile(datadir, tmpdir):
"""Test generate v3bw file (including relay_lines)."""
pass
v3bw = datadir.read('v3bw.txt')
results = load_result_file(str(datadir.join("results.txt")))
header = V3BwHeader(timestamp_l,
file_created=file_created,
generator_started=generator_started,
earliest_bandwidth=earliest_bandwidth)
bwls = [V3BWLine.from_results(results[fp]) for fp in results]
f = V3BwFile(header, bwls)
# f = V3BwFile.from_results(None, str(tmpdir.join("v3bw.txt")), results)
assert v3bw == str(f)
Supports Markdown
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