Skip to content

Commit

Permalink
Merge pull request #27 from fractaledmind/clearer-verification-msg
Browse files Browse the repository at this point in the history
Improve the verification task
  • Loading branch information
fractaledmind authored May 4, 2024
2 parents ae97364 + e845360 commit 45ae21b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 58 deletions.
66 changes: 48 additions & 18 deletions lib/tasks/litestream_tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,53 @@ namespace :litestream do
options.symbolize_keys!

result = Litestream::Commands.verify(database, async: true, **options)

puts <<~TXT if result
tables
original #{result["original"]["tables"]}
restored #{result["restored"]["tables"]}
delta #{result["original"]["tables"] - result["restored"]["tables"]}
indexes
original #{result["original"]["indexes"]}
restored #{result["restored"]["indexes"]}
delta #{result["original"]["indexes"] - result["restored"]["indexes"]}
rows
original #{result["original"]["rows"]}
restored #{result["restored"]["rows"]}
delta #{result["original"]["rows"] - result["restored"]["rows"]}
TXT
original_tables = result["original"]["tables"]
restored_tables = result["restored"]["tables"]
original_indexes = result["original"]["indexes"]
restored_indexes = result["restored"]["indexes"]
original_rows = result["original"]["rows"]
restored_rows = result["restored"]["rows"]

same_number_of_tables = original_tables == restored_tables
same_number_of_indexes = original_indexes == restored_indexes
same_number_of_rows = original_rows == restored_rows

if same_number_of_tables && same_number_of_indexes && same_number_of_rows
puts "Backup for `#{database}` verified as consistent!\n" + [
" tables #{original_tables}",
" indexes #{original_indexes}",
" rows #{original_rows}"
].compact.join("\n")
else
abort "Verification failed for #{database}:\n" + [
(unless same_number_of_tables
if original_tables > restored_tables
diff = original_tables - restored_tables
" Backup is missing #{diff} table#{"s" if diff > 1}"
else
diff = restored_tables - original_tables
" Backup has extra #{diff} table#{"s" if diff > 1}"
end
end),
(unless same_number_of_indexes
if original_indexes > restored_indexes
diff = original_indexes - restored_indexes
" Backup is missing #{diff} index#{"es" if diff > 1}"
else
diff = restored_indexes - original_indexes
" Backup has extra #{diff} index#{"es" if diff > 1}"
end
end),
(unless same_number_of_rows
if original_rows > restored_rows
diff = original_rows - restored_rows
" Backup is missing #{diff} row#{"s" if diff > 1}"
else
diff = restored_rows - original_rows
" Backup has extra #{diff} row#{"s" if diff > 1}"
end
end)
].compact.join("\n")
end
end
end
73 changes: 33 additions & 40 deletions test/tasks/test_litestream_tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,74 +219,67 @@ def test_snapshots_task_with_arguments_without_separator
end

class TestVerifyTask < TestLitestreamTasks
def test_verify_task_with_only_database_using_single_dash
def test_verify_task_with_only_database_using_single_dash_failing
ARGV.replace ["--", "-database=db/test.sqlite3"]
fake = Minitest::Mock.new
out = nil
fake.expect :call, {"original" => {"tables" => 2, "indexes" => 2, "rows" => 2}, "restored" => {"tables" => 1, "indexes" => 1, "rows" => 1}}, ["db/test.sqlite3"], async: true
fake.expect :call,
{"original" => {"tables" => 2, "indexes" => 4, "rows" => 6}, "restored" => {"tables" => 1, "indexes" => 2, "rows" => 3}},
["db/test.sqlite3"],
async: true

Litestream::Commands.stub :verify, fake do
out, _err = capture_io do
Rake.application.invoke_task "litestream:verify"
error = assert_raises SystemExit do
capture_io { Rake.application.invoke_task "litestream:verify" }
end
assert_match("Verification failed for db/test.sqlite3", error.message)
assert_match("Backup is missing 1 table", error.message)
assert_match("Backup is missing 2 indexes", error.message)
assert_match("Backup is missing 3 rows", error.message)
end

fake.verify
assert_match(/tables\s+original\s+2\s+restored\s+1/, out)
assert_match(/indexes\s+original\s+2\s+restored\s+1/, out)
assert_match(/rows\s+original\s+2\s+restored\s+1/, out)
end

def test_verify_task_with_only_database_using_double_dash
def test_verify_task_with_only_database_using_double_dash_failing
ARGV.replace ["--", "--database=db/test.sqlite3"]
fake = Minitest::Mock.new
out = nil
fake.expect :call, {"original" => {"tables" => 2, "indexes" => 2, "rows" => 2}, "restored" => {"tables" => 1, "indexes" => 1, "rows" => 1}}, ["db/test.sqlite3"], async: true
fake.expect :call,
{"original" => {"tables" => 1, "indexes" => 2, "rows" => 3}, "restored" => {"tables" => 2, "indexes" => 4, "rows" => 6}},
["db/test.sqlite3"],
async: true

Litestream::Commands.stub :verify, fake do
out, _err = capture_io do
Rake.application.invoke_task "litestream:verify"
error = assert_raises SystemExit do
capture_io { Rake.application.invoke_task "litestream:verify" }
end
assert_match("Verification failed for db/test.sqlite3", error.message)
assert_match("Backup has extra 1 table", error.message)
assert_match("Backup has extra 2 indexes", error.message)
assert_match("Backup has extra 3 rows", error.message)
end

fake.verify
assert_match(/tables\s+original\s+2\s+restored\s+1/, out)
assert_match(/indexes\s+original\s+2\s+restored\s+1/, out)
assert_match(/rows\s+original\s+2\s+restored\s+1/, out)
end

def test_verify_task_with_arguments
def test_verify_task_with_arguments_succeeding
ARGV.replace ["--", "-database=db/test.sqlite3", "--if-db-not-exists"]
fake = Minitest::Mock.new
out = nil
fake.expect :call, {"original" => {"tables" => 2, "indexes" => 2, "rows" => 2}, "restored" => {"tables" => 1, "indexes" => 1, "rows" => 1}}, ["db/test.sqlite3"], async: true, "--if-db-not-exists": nil

Litestream::Commands.stub :verify, fake do
out, _err = capture_io do
Rake.application.invoke_task "litestream:verify"
end
end

fake.verify
assert_match(/tables\s+original\s+2\s+restored\s+1/, out)
assert_match(/indexes\s+original\s+2\s+restored\s+1/, out)
assert_match(/rows\s+original\s+2\s+restored\s+1/, out)
end

def test_verify_task_with_arguments_without_separator
ARGV.replace ["-database=db/test.sqlite3"]
fake = Minitest::Mock.new
out = nil
fake.expect :call, nil, [nil], async: true
fake.expect :call,
{"original" => {"tables" => 2, "indexes" => 2, "rows" => 2}, "restored" => {"tables" => 2, "indexes" => 2, "rows" => 2}},
["db/test.sqlite3"],
async: true,
"--if-db-not-exists": nil

Litestream::Commands.stub :verify, fake do
out, _err = capture_io do
Rake.application.invoke_task "litestream:verify"
end
out, _err = capture_io { Rake.application.invoke_task "litestream:verify" }
assert_match("Backup for `db/test.sqlite3` verified as consistent!", out)
assert_match("tables 2", out)
assert_match("indexes 2", out)
assert_match("rows 2", out)
end

fake.verify
assert_equal "", out
end
end
end

0 comments on commit 45ae21b

Please sign in to comment.