Actions
Bug #10915
closedError in FTPTest#test_abort and test_status on Solaris
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.0dev (2015-02-26) [sparc64-solaris2.10]
Description
Solaris 10 にて、make test-all で以下のエラーが出ます。
(r49732にて確認)
1) Error:
FTPTest#test_abort:
Net::ReadTimeout: Net::ReadTimeout
/XXXXXXXXXX/lib/net/protocol.rb:158:in `rescue in rbuf_fill'
/XXXXXXXXXX/lib/net/protocol.rb:152:in `rbuf_fill'
/XXXXXXXXXX/lib/net/protocol.rb:134:in `readuntil'
/XXXXXXXXXX/lib/net/ftp.rb:1108:in `gets'
/XXXXXXXXXX/lib/net/ftp.rb:1113:in `readline'
/XXXXXXXXXX/lib/net/ftp.rb:290:in `getline'
/XXXXXXXXXX/lib/net/ftp.rb:301:in `getmultiline'
/XXXXXXXXXX/lib/net/ftp.rb:886:in `abort'
/XXXXXXXXXX/test/net/ftp/test_ftp.rb:726:in `test_abort'
2) Error:
FTPTest#test_status:
Net::ReadTimeout: Net::ReadTimeout
/XXXXXXXXXX/lib/net/protocol.rb:158:in `rescue in rbuf_fill'
/XXXXXXXXXX/lib/net/protocol.rb:152:in `rbuf_fill'
/XXXXXXXXXX/lib/net/protocol.rb:134:in `readuntil'
/XXXXXXXXXX/lib/net/ftp.rb:1108:in `gets'
/XXXXXXXXXX/lib/net/ftp.rb:1113:in `readline'
/XXXXXXXXXX/lib/net/ftp.rb:290:in `getline'
/XXXXXXXXXX/lib/net/ftp.rb:301:in `getmultiline'
/XXXXXXXXXX/lib/net/ftp.rb:319:in `getresp'
/XXXXXXXXXX/lib/net/ftp.rb:900:in `status'
/XXXXXXXXXX/test/net/ftp/test_ftp.rb:759:in `test_status'
net/ftp の abort と status は、以下のように MSG_OOB オプションを付けて、
帯域外データとして送信しています。
@sock.send(line, Socket::MSG_OOB)
これを test_ftp.rb 内の sock.recv(1024) にて受けています。
Linux などでは、これで受信できているようですが、
Solaris では、ioctl() SIOCATMARK 要求をする必要があるような感じです。
しかし、この ioctl は Rubyレベルでは、少なくともポータブルには、出す方法がありません。
かわりに、OOBデータも通常データとみなして受信するソケット・オプション
SO_OOBINLINE を受信側のソケット・オプションに指定すると、
タイムアウトすることはなくなりましたが、以下のFailureが出ました。
2) Failure:
FTPTest#test_abort [/user3/gen-info/ngoto/testruby/daily/src/sparc64-cc12-trunk-49756/test/net/ftp/test_ftp.rb:727]:
<"ABOR\r"> expected but was
<"ABOR\r\n">.
3) Failure:
FTPTest#test_status [/user3/gen-info/ngoto/testruby/daily/src/sparc64-cc12-trunk-49756/test/net/ftp/test_ftp.rb:760]:
<"STAT\r"> expected but was
<"STAT\r\n">.
これは、受信側で BasicSocket#recv システムコールをそのまま使っているが、
バッファリングはOSや環境に依存するのが原因と思われます。
Linuxでは最後の"\n"だけ別の塊として受信しますが、Solarisでは全部を同時に受信するようです。
SO_OOBINLINE を指定したのだから、recv システムコールを直接使わなくても、gets を使えば十分と考えられます。
まとめると、以下のパッチにより、ErrorおよびFailureは出なくなりました。
Index: test/net/ftp/test_ftp.rb
===================================================================
--- test/net/ftp/test_ftp.rb (revision 49774)
+++ test/net/ftp/test_ftp.rb (working copy)
@@ -711,7 +711,7 @@
sock.print("230 Login successful.\r\n")
commands.push(sock.gets)
sock.print("200 Switching to Binary mode.\r\n")
- commands.push(sock.recv(1024))
+ commands.push(sock.gets)
sock.print("225 No transfer to ABOR.\r\n")
}
begin
@@ -724,7 +724,7 @@
assert_match(/\APASS /, commands.shift)
assert_equal("TYPE I\r\n", commands.shift)
ftp.abort
- assert_equal("ABOR\r", commands.shift)
+ assert_equal("ABOR\r\n", commands.shift)
assert_equal(nil, commands.shift)
ensure
ftp.close if ftp
@@ -744,7 +744,7 @@
sock.print("230 Login successful.\r\n")
commands.push(sock.gets)
sock.print("200 Switching to Binary mode.\r\n")
- commands.push(sock.recv(1024))
+ commands.push(sock.gets)
sock.print("211 End of status\r\n")
}
begin
@@ -757,7 +757,7 @@
assert_match(/\APASS /, commands.shift)
assert_equal("TYPE I\r\n", commands.shift)
ftp.status
- assert_equal("STAT\r", commands.shift)
+ assert_equal("STAT\r\n", commands.shift)
assert_equal(nil, commands.shift)
ensure
ftp.close if ftp
@@ -856,6 +856,7 @@
end
sock = server.accept
begin
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE, 1)
yield(sock)
sock.shutdown(Socket::SHUT_WR)
sock.read unless sock.eof?
Solaris, Linux にて動作を確認しました。
Windowsなどその他のOSでは未確認です。
Files
Actions
Like0
Like0Like0