Files
flexnbd-c/tests/nbd_scenarios
Alex Young 7d1c15b07a Fix two bugs in mirroring.
First, Leaving off the source address caused a segfault in the
command-sending process because there was no NULL check on the ARGV
entry.

Second, while the migration thread sent a signal to the server to close
on successful completion, it didn't wait until the close actually
happened before releasing the IO lock.  This meant that any client
thread waiting on that IO lock could have a read or a write queued up
which could succeed despite the server shutdown.  This would have meant
dataloss as the guest would see a successful write to the wrong instance
of the file.  This patch adds a noddy serve_wait_for_close() function
which the mirror_runner calls to ensure that any clients will reject
operations they're waiting to complete.

This patch also adds a simple scenario test for migration, and fixes
TempFileWriter#read_original.
2012-06-13 13:44:21 +01:00

119 lines
2.4 KiB
Ruby

#!/usr/bin/ruby
require 'test/unit'
require 'flexnbd'
require 'test_file_writer'
class NBDScenarios < Test::Unit::TestCase
def setup
@blocksize = 1024
@filename1 = ".flexnbd.test.#{$$}.#{Time.now.to_i}.1"
@filename2 = ".flexnbd.test.#{$$}.#{Time.now.to_i}.2"
@ip = "127.0.0.1"
@available_ports = [*40000..41000] - listening_ports
@port1 = @available_ports.shift
@port2 = @available_ports.shift
@nbd1 = FlexNBD.new("../build/flexnbd", @ip, @port1)
@nbd2 = FlexNBD.new("../build/flexnbd", @ip, @port2)
end
def teardown
[@filename1, @filename2].each do |f|
File.unlink(f) if File.exists?(f)
end
end
def test_read1
writefile1("f"*64)
serve1
[0, 12, 63].each do |num|
assert_equal(
@nbd1.read(num*@blocksize, @blocksize),
@file1.read(num*@blocksize, @blocksize)
)
end
[124, 1200, 10028, 25488].each do |num|
assert_equal(@nbd1.read(num, 4), @file1.read(num, 4))
end
end
# Check that we're not
#
def test_writeread1
writefile1("0"*64)
serve1
[0, 12, 63].each do |num|
data = "X"*@blocksize
@nbd1.write(num*@blocksize, data)
assert_equal(data, @file1.read(num*@blocksize, data.size))
assert_equal(data, @nbd1.read(num*@blocksize, data.size))
end
end
# Check that we're not overstepping or understepping where our writes end
# up.
#
def test_writeread2
writefile1("0"*1024)
serve1
d0 = "\0"*@blocksize
d1 = "X"*@blocksize
(0..63).each do |num|
@nbd1.write(num*@blocksize*2, d1)
end
(0..63).each do |num|
assert_equal(d0, @nbd1.read(((2*num)+1)*@blocksize, d0.size))
end
end
def test_mirror
writefile1( "f"*4 )
serve1
writefile2( "0"*4 )
serve2
@nbd1.can_die
mirror12
assert_equal(@file1.read_original( 0, @blocksize ),
@file2.read( 0, @blocksize ) )
end
protected
def serve1(*acl)
@nbd1.serve(@filename1, *acl)
end
def serve2(*acl)
@nbd2.serve(@filename2, *acl)
end
def mirror12
@nbd1.mirror( @nbd2.ip, @nbd2.port )
end
def writefile1(data)
@file1 = TestFileWriter.new(@filename1, @blocksize).write(data)
end
def writefile2(data)
@file2 = TestFileWriter.new(@filename2, @blocksize).write(data)
end
def listening_ports
`netstat -ltn`.
split("\n").
map { |x| x.split(/\s+/) }[2..-1].
map { |l| l[3].split(":")[-1].to_i }
end
end