Description
This repository intended to test can BadgerDB read wrong (damaged or incomplete) data without user notice.
How to run
./all-versions.sh -count=100 -failfast
Possible issue
One case that looks dangerous, from data integrity point of view:
- We have directory with valid Badger data files: sst files, vlog file.
- We flip random bit of some value (spoil data) in vlog file.
- Badger starts with provided vlog file without any error and end user got database with spoiled value without any notice.
Why it's bad
Files in database directory could be broken for a plethora of reasons, and if it would be data in vlog file it leads to situation where badger just opens directory with wrong data without any error or notice to user.
So it's dangerous to start badger on any data files, what are not from verified backups. Simple start/stop is dangerous (at least with default options set). :(
How to run test and prove issue
./all-versions.sh -count=50 &> tests.log
grep 'test exit code:' tests.log
grep -B5 'Test:.*Test_FlipBits/values_check' tests.log
grep 'An error on spoiled DB is expected but got nil' tests.log
Test gory details
- make.go builds
datagen script for required badger version (supports 1.5, 1.6, 2.0)
- make.go run tests in
_spoiler_tests directory with build environment for provided Badger version
_spoiler_tests run datagen, which generates badger data. Test waits unit data generation ends, ok kill datagen process with signal provided in KILL_GEN_SIGNAL env variable (for this case datagen runs in 'slow' mode)
_spoiler_tests copy directory with data generated by datagen and open copied directory as badger database, reads all key value pairs in it and then removes directory. (just to avoid files changes what could happen when badger open files)
spoiler_tests copy directory with data again, spoil random bit in vlog files and tries open directory with spoiled files.
- if spoiled database opens without error, it just print
An error on spoiled DB is expected but got nil, because we also want to check keys in this case (see the next step)
- test read all key values from opened database and compares all keys and values in loop. If any check failed found it stops with error.