def _read(fname: str) -> List[MeasLine]: ''' Read all per-second results from the given filename. :param fname: the filename to read :returns: List of :class:`MeasLine`, sorted by timestamp The file must exist. The file is partially assumed to be well-formed: it might have invalid lines or comments, which will be skipped over just fine, but this function does not actually care that BEGIN lines come before data lines, which themselves come before END lines. :func:`sorted` is stable, so good order in == good order out. If the file name ends in ``.gz``, it is assumed to be gzip compressed. ''' log.debug('Reading per-second results from %s', fname) out = [] if fname.endswith('.gz'): fd = gzip.open(fname, 'rt') else: fd = open(fname, 'rt') for line in fd: meas_line = MeasLine.parse(line) if not meas_line: continue out.append(meas_line) fd.close() return sorted(out, key=lambda item: item.ts)
def test_begin(self): s = '%d %d BEGIN %s' % (MEAS_ID, TS, FP) out = MeasLine.parse(s) assert isinstance(out, MeasLineBegin) assert out.relay_fp == FP assert out.meas_id == MEAS_ID assert out.ts == TS
def test_data_measr(self): given = 42069 s = '%d %d MEASR %d' % (MEAS_ID, TS, given) out = MeasLine.parse(s) assert isinstance(out, MeasLineData) assert out.meas_id == MEAS_ID assert out.ts == TS assert out.given_bw == given assert out.trusted_bw is None
def test_data_bg(self): given = 420 trusted = 69 s = '%d %d BG %d %d' % (MEAS_ID, TS, given, trusted) out = MeasLine.parse(s) assert isinstance(out, MeasLineData) assert out.meas_id == MEAS_ID assert out.ts == TS assert out.given_bw == given assert out.trusted_bw == trusted
def test_comment_otherwise_valid(self): prefixes = ['#', '# ', ' #', ' # '] for prefix in prefixes: s = prefix + '%s %d %d BEGIN' % (FP, MEAS_ID, TS) assert MeasLine.parse(s) is None
def test_comment_nonsense(self): s = ' # foo ' assert MeasLine.parse(s) is None
def test_end(self): s = '%d %d END' % (MEAS_ID, TS) out = MeasLine.parse(s) assert isinstance(out, MeasLineEnd) assert out.meas_id == MEAS_ID assert out.ts == TS
def test_too_few_bg(self): s = '%d %d BG %d' % (MEAS_ID, TS, 420) assert MeasLine.parse(s) is None
def test_too_many_measr(self): s = '%d %d MEASR %d %d' % (MEAS_ID, TS, 420, 69) assert MeasLine.parse(s) is None
def test_bad_ts(self): s = '%d bad_ts BEGIN %s' % (MEAS_ID, FP) assert MeasLine.parse(s) is None
def test_bad_third_word(self): s = '%d %d NOT_A_REAL_WORD %s' % (MEAS_ID, TS, FP) assert MeasLine.parse(s) is None
def test_bad_meas_id(self): s = 'bad_meas_id 1 BEGIN %s' % (FP, ) assert MeasLine.parse(s) is None
def test_too_many_words(self): s = ' '.join(['a'] * 7) assert MeasLine.parse(s) is None
def test_too_few_words(self): s = ' '.join(['a'] * 3) assert MeasLine.parse(s) is None
def test_empty_whitespace(self): assert MeasLine.parse(' ') is None
def test_empty(self): assert MeasLine.parse('') is None