Compare commits

...

2 Commits

Author SHA1 Message Date
b6bba16505 fsck: fix error in reporting row number for timestamp errors
Since we process in chunks, we need to add "start" to the row number;
however, we don't need to use this when accessing data['timestamp']
(aka ts)
2020-08-18 00:31:40 -04:00
d4003d0d34 tests: fill out coverage for new fsck features 2020-08-17 23:27:32 -04:00
9 changed files with 20 additions and 13 deletions

View File

@ -248,23 +248,22 @@ class Fsck(object):
# Check that we can open bulkdata # Check that we can open bulkdata
tab = nilmdb.server.bulkdata.Table(bulk) tab = nilmdb.server.bulkdata.Table(bulk)
except FsckFormatError: except FsckFormatError as e:
# If there are no files except _format, try deleting # If there are no files except _format, try deleting
# the entire stream; this may remove metadata, but # the entire stream; this may remove metadata, but
# it's probably unimportant. # it's probably unimportant.
files = list(os.listdir(bulk)) files = list(os.listdir(bulk))
if len(files) > 1: if len(files) > 1:
raise raise FsckFormatError(f"{path}: can't load _format, "
if len(files) == 1 and files[0] != b'_format': f"but data is also present")
raise
# Since the stream was empty, just remove it # Since the stream was empty, just remove it
self.fix_remove_stream(sid, path, bulk, self.fix_remove_stream(sid, path, bulk,
"empty, with corrupted format file") "empty, with corrupted format file")
except FsckError as e:
except FsckError: raise e
raise except Exception as e: # pragma: no cover
except Exception as e: # No coverage because this is an unknown/unexpected error
raise FsckError("%s: can't open bulkdata: %s", raise FsckError("%s: can't open bulkdata: %s",
path, str(e)) path, str(e))
tab.close() tab.close()
@ -278,6 +277,7 @@ class Fsck(object):
fmt = pickle.load(f) fmt = pickle.load(f)
except Exception as e: except Exception as e:
raise FsckFormatError(f"{path}: can't load _format file ({e})") raise FsckFormatError(f"{path}: can't load _format file ({e})")
if fmt["version"] != 3: if fmt["version"] != 3:
raise FsckFormatError("%s: bad or unsupported bulkdata version %d", raise FsckFormatError("%s: bad or unsupported bulkdata version %d",
path, fmt["version"]) path, fmt["version"])
@ -511,18 +511,20 @@ class Fsck(object):
# Verify that all timestamps are in range. # Verify that all timestamps are in range.
match = (ts < stime) | (ts >= etime) match = (ts < stime) | (ts >= etime)
if match.any(): if match.any():
row = start + numpy.argmax(match) row = numpy.argmax(match)
raise FsckError("%s: data timestamp %d at row %d " raise FsckError("%s: data timestamp %d at row %d "
"outside interval range [%d,%d)", "outside interval range [%d,%d)",
path, data['timestamp'][row], row, path, ts[row], row + start,
stime, etime) stime, etime)
# Verify that timestamps are monotonic # Verify that timestamps are monotonic
match = numpy.diff(ts) <= 0 match = numpy.diff(ts) <= 0
if match.any(): if match.any():
row = start + numpy.argmax(match) row = numpy.argmax(match)
raise FsckError("%s: non-monotonic timestamp (%d -> %d) " raise FsckError("%s: non-monotonic timestamp (%d -> %d)"
"at row %d", path, ts[row], ts[row+1], row) " at row %d", path, ts[row], ts[row+1],
row + start)
first_ts = ts[0] first_ts = ts[0]
if last_ts is not None and first_ts <= last_ts: if last_ts is not None and first_ts <= last_ts:
raise FsckError("%s: first interval timestamp %d is not " raise FsckError("%s: first interval timestamp %d is not "

Binary file not shown.

Binary file not shown.

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

View File

@ -163,3 +163,8 @@ class TestFsck(object):
raise Exception("hi") raise Exception("hi")
with assert_raises(Exception): with assert_raises(Exception):
foo() foo()
self.failmsg("test2v", "can't load _format, but data is also present")
self.failmsg("test2v1", "bad bulkdata table")
self.failmsg("test2v2", "empty, with corrupted format file", fix=False)
self.okmsg("test2v2", "empty, with corrupted format file")