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 "

View File

Binary file not shown.

View File

Binary file not shown.

View File

View File

Binary file not shown.

View File

Binary file not shown.

View File

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")