103 lines
2.8 KiB
Ruby
103 lines
2.8 KiB
Ruby
#!/usr/bin/ruby
|
|
|
|
$:.push "acceptance"
|
|
|
|
require 'flexnbd'
|
|
|
|
binary = ARGV.shift
|
|
test_size = ARGV.shift.to_i
|
|
repetitions = ARGV.shift.to_i
|
|
repetitions = 50 if repetitions == 0
|
|
seed = ARGV.shift.to_i
|
|
|
|
max_length = test_size > 10000000 ? 10000000 : test_size
|
|
CHEAT_AND_ROUND_DOWN = false # set to 'false' to expose bugs
|
|
|
|
srand(seed)
|
|
|
|
if test_size < 32768 || repetitions < 1 || !File.executable?(binary)
|
|
STDERR.print "Syntax: #{$0} <flexnbd bin> <test size> [repetitions] [seed]\n"
|
|
STDERR.print "test_size must be >= 32768 and repeitions must be >= 1"
|
|
exit 1
|
|
end
|
|
|
|
testname_local = "#{$0}.test.#{$$}.local"
|
|
testname_serve = "#{$0}.test.#{$$}.serve"
|
|
[testname_local, testname_serve].each do |name|
|
|
File.open(name, "w+") { |fh| fh.seek(test_size-1, IO::SEEK_SET); fh.write("\0") }
|
|
end
|
|
|
|
@local = File.open(testname_local, "r+")
|
|
|
|
@serve = FlexNBD::FlexNBD.new(binary, "127.0.0.1", 41234)
|
|
@serve.serve(testname_serve)
|
|
|
|
$record = []
|
|
def print_record
|
|
$record.each do |offset, length, byte|
|
|
STDERR.print " wrote #{byte} to #{offset}+#{length}\n"
|
|
end
|
|
end
|
|
|
|
repetitions.times do |n|
|
|
|
|
begin
|
|
|
|
if File.size(testname_local) != File.size(testname_serve)
|
|
STDERR.print "Before pass #{n}: File sizes are different: local=#{File.size(testname_local)} serve=#{File.size(testname_serve)}\n"
|
|
exit 1;
|
|
end
|
|
|
|
md5_local = `md5sum < #{testname_local}`.split(" ").first
|
|
md5_serve = `md5sum < #{testname_serve}`.split(" ").first
|
|
|
|
if md5_local != md5_serve
|
|
STDERR.print "Before pass #{n}: MD5 error: local=#{md5_local} serve=#{md5_serve}\n"
|
|
print_record
|
|
STDERR.print "**** Local contents:\n"
|
|
system("hexdump #{testname_local}")
|
|
STDERR.print "**** Serve contents:\n"
|
|
system("hexdump #{testname_serve}")
|
|
exit 1
|
|
end
|
|
|
|
length = rand(max_length/8)
|
|
length &= 0xfffff000 if CHEAT_AND_ROUND_DOWN
|
|
offset = rand(test_size - length)
|
|
offset &= 0xfffff000 if CHEAT_AND_ROUND_DOWN
|
|
|
|
content = (n%2 == 0) ? ("\0" * length) : ( (n&255).chr * length)
|
|
|
|
$record << [offset, length, content[0]]
|
|
|
|
@local.seek(offset, IO::SEEK_SET)
|
|
@local.write(content)
|
|
@local.fsync
|
|
|
|
@serve.write(offset, content)
|
|
|
|
check_read = @serve.read(offset, length)
|
|
if check_read != content
|
|
STDERR.print "After pass #{n}: Didn't read back what we wrote!\n"
|
|
print_record
|
|
STDERR.print "*** We wrote these #{content.length} bytes...\n"
|
|
IO.popen("hexdump", "w") { |io| io.print(content) }
|
|
STDERR.print "*** But we got back these #{check_read.length} bytes...\n"
|
|
IO.popen("hexdump", "w") { |io| io.print(check_read) }
|
|
exit 1
|
|
end
|
|
|
|
rescue StandardError => ex
|
|
STDERR.print "During pass #{n}: Exception: #{ex}"
|
|
print_record
|
|
STDERR.print ex.backtrace.join("\n") + "\n"
|
|
exit 2
|
|
end
|
|
|
|
end
|
|
|
|
File.unlink(testname_local)
|
|
File.unlink(testname_serve)
|
|
|
|
@serve.can_die(0)
|