From d16aebf36e976e20b6cc731c9c8ffe640accb325 Mon Sep 17 00:00:00 2001 From: Alex Young Date: Tue, 3 Jul 2012 15:25:39 +0100 Subject: [PATCH] Test that a disconnect after the write request but before the data is an error --- src/client.c | 2 +- tests/acceptance/environment.rb | 2 +- .../fakes/dest/close_after_hello.rb | 3 +- .../fakes/dest/close_after_write.rb | 3 +- tests/acceptance/fakes/dest/error_on_write.rb | 3 +- .../fakes/dest/hang_after_connect.rb | 3 +- .../acceptance/fakes/dest/hang_after_write.rb | 3 +- .../fakes/dest/hello_wrong_magic.rb | 3 +- .../acceptance/fakes/dest/hello_wrong_size.rb | 3 +- tests/acceptance/fakes/dest/reject_acl.rb | 3 +- .../fakes/source/close_after_write.rb | 29 +++++++++++++++++++ tests/acceptance/flexnbd/fake_source.rb | 2 +- tests/acceptance/test_dest_error_handling.rb | 4 +++ 13 files changed, 52 insertions(+), 11 deletions(-) create mode 100755 tests/acceptance/fakes/source/close_after_write.rb diff --git a/src/client.c b/src/client.c index a27b1ed..295fb53 100644 --- a/src/client.c +++ b/src/client.c @@ -101,7 +101,7 @@ void write_not_zeroes(struct client* client, uint64_t from, int len) fprintf(stderr, "\n"); } - #define DO_READ(dst, len) FATAL_IF_NEGATIVE( \ + #define DO_READ(dst, len) ERROR_IF_NEGATIVE( \ readloop( \ client->socket, \ (dst), \ diff --git a/tests/acceptance/environment.rb b/tests/acceptance/environment.rb index 131a439..98a2705 100644 --- a/tests/acceptance/environment.rb +++ b/tests/acceptance/environment.rb @@ -114,7 +114,7 @@ class Environment raise "no addr" unless addr raise "no port" unless port @fake_pid = fork do - exec fake + " " + addr.to_s + " " + port.to_s + exec fake + " " + addr.to_s + " " + port.to_s + " " + @nbd1.pid.to_s end sleep(0.5) end diff --git a/tests/acceptance/fakes/dest/close_after_hello.rb b/tests/acceptance/fakes/dest/close_after_hello.rb index 4c21851..1c903dd 100755 --- a/tests/acceptance/fakes/dest/close_after_hello.rb +++ b/tests/acceptance/fakes/dest/close_after_hello.rb @@ -9,7 +9,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client = server.accept( "Timed out waiting for a connection" ) client.write_hello client.close diff --git a/tests/acceptance/fakes/dest/close_after_write.rb b/tests/acceptance/fakes/dest/close_after_write.rb index b4ca0a4..7db5917 100755 --- a/tests/acceptance/fakes/dest/close_after_write.rb +++ b/tests/acceptance/fakes/dest/close_after_write.rb @@ -10,7 +10,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client = server.accept( "Timed out waiting for a connection" ) client.write_hello client.read_request diff --git a/tests/acceptance/fakes/dest/error_on_write.rb b/tests/acceptance/fakes/dest/error_on_write.rb index 6def7f6..8bab036 100755 --- a/tests/acceptance/fakes/dest/error_on_write.rb +++ b/tests/acceptance/fakes/dest/error_on_write.rb @@ -4,7 +4,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client = server.accept client.write_hello diff --git a/tests/acceptance/fakes/dest/hang_after_connect.rb b/tests/acceptance/fakes/dest/hang_after_connect.rb index 127d748..2c3c54f 100755 --- a/tests/acceptance/fakes/dest/hang_after_connect.rb +++ b/tests/acceptance/fakes/dest/hang_after_connect.rb @@ -10,7 +10,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client = server.accept( "Client didn't make a connection" ) # Sleep for one second past the timeout (a bit of slop in case ruby diff --git a/tests/acceptance/fakes/dest/hang_after_write.rb b/tests/acceptance/fakes/dest/hang_after_write.rb index dd4c11f..f5e796a 100755 --- a/tests/acceptance/fakes/dest/hang_after_write.rb +++ b/tests/acceptance/fakes/dest/hang_after_write.rb @@ -8,7 +8,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client1 = server.accept( server ) client1.write_hello client1.read_request diff --git a/tests/acceptance/fakes/dest/hello_wrong_magic.rb b/tests/acceptance/fakes/dest/hello_wrong_magic.rb index c52e157..04349b8 100755 --- a/tests/acceptance/fakes/dest/hello_wrong_magic.rb +++ b/tests/acceptance/fakes/dest/hello_wrong_magic.rb @@ -6,7 +6,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client1 = server.accept # Launch a second thread so that we can spot the reconnection attempt diff --git a/tests/acceptance/fakes/dest/hello_wrong_size.rb b/tests/acceptance/fakes/dest/hello_wrong_size.rb index 5d5007f..6b90d39 100755 --- a/tests/acceptance/fakes/dest/hello_wrong_size.rb +++ b/tests/acceptance/fakes/dest/hello_wrong_size.rb @@ -7,7 +7,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) client = server.accept t = Thread.new do diff --git a/tests/acceptance/fakes/dest/reject_acl.rb b/tests/acceptance/fakes/dest/reject_acl.rb index e1e9feb..ab7e81b 100755 --- a/tests/acceptance/fakes/dest/reject_acl.rb +++ b/tests/acceptance/fakes/dest/reject_acl.rb @@ -5,7 +5,8 @@ require 'flexnbd/fake_dest' include FlexNBD -server = FakeDest.new( *ARGV ) +addr, port = *ARGV +server = FakeDest.new( addr, port ) server.accept.close server.close diff --git a/tests/acceptance/fakes/source/close_after_write.rb b/tests/acceptance/fakes/source/close_after_write.rb new file mode 100755 index 0000000..0f48dc6 --- /dev/null +++ b/tests/acceptance/fakes/source/close_after_write.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# encoding: utf-8 + +# We connect, pause the server, issue a write request, disconnect, +# then cont the server. This ensures that our disconnect happens +# while the server is trying to read the write data. + +require 'flexnbd/fake_source' +include FlexNBD + +addr, port, srv_pid = *ARGV + +client = FakeSource.new( addr, port, "Timed out connecting" ) +client.read_hello +Process.kill( "STOP", srv_pid.to_i ) +client.write_write_request( 0, 8 ) +client.close +Process.kill( "CONT", srv_pid.to_i ) + +# This sleep ensures that we don't return control to the test runner +# too soon, giving the flexnbd process time to fall over if it's going +# to. +sleep(0.25) + +# ...and can we reconnect? +client2 = FakeSource.new( addr, port, "Timed out connecting" ) +client2.close + +exit(0) diff --git a/tests/acceptance/flexnbd/fake_source.rb b/tests/acceptance/flexnbd/fake_source.rb index 1815ad8..76df06e 100644 --- a/tests/acceptance/flexnbd/fake_source.rb +++ b/tests/acceptance/flexnbd/fake_source.rb @@ -29,7 +29,7 @@ module FlexNBD end - def write_write_request( from, len, handle ) + def write_write_request( from, len, handle="myhandle" ) fail "Bad handle" unless handle.length == 8 @sock.write( "\x25\x60\x95\x13" ) diff --git a/tests/acceptance/test_dest_error_handling.rb b/tests/acceptance/test_dest_error_handling.rb index 3312a3c..c534e54 100644 --- a/tests/acceptance/test_dest_error_handling.rb +++ b/tests/acceptance/test_dest_error_handling.rb @@ -50,6 +50,10 @@ class TestDestErrorHandling < Test::Unit::TestCase end + def test_disconnect_before_write_reply_causes_error + run_fake( "source/close_after_write" ) + end + private def run_fake( name ) @env.run_fake( name, @env.ip, @env.port1 )