summaryrefslogtreecommitdiff
path: root/test/socket
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2022-11-17 14:50:25 -0800
committerGitHub <noreply@github.com>2022-11-17 14:50:25 -0800
commitea8a7287e2b96b9c24e5e89fe863e5bfa60bfdda (patch)
tree1935b65502eb16b6913d6183fc11c6f1cf4db34d /test/socket
parent4e4b29b1a9e534554594b6f18fc0bdc462638934 (diff)
downloadruby-ea8a7287e2b96b9c24e5e89fe863e5bfa60bfdda.tar.gz
Add support for `sockaddr_un` on Windows. (#6513)
* Windows: Fix warning about undefined if_indextoname() * Windows: Fix UNIXSocket on MINGW and make .pair more reliable * Windows: Use nonblock=true for read tests with scheduler * Windows: Move socket detection from File.socket? to File.stat Add S_IFSOCK to Windows and interpret reparse points accordingly. Enable tests that work now. * Windows: Use wide-char functions to UNIXSocket This fixes behaviour with non-ASCII characters. It also fixes deletion of temporary UNIXSocket.pair files. * Windows: Add UNIXSocket tests for specifics of Windows impl. * Windows: fix VC build due to missing _snwprintf Avoid usage of _snwprintf, since it fails linking ruby.dll like so: linking shared-library x64-vcruntime140-ruby320.dll x64-vcruntime140-ruby320.def : error LNK2001: unresolved external symbol snwprintf x64-vcruntime140-ruby320.def : error LNK2001: unresolved external symbol vsnwprintf_l whereas linking miniruby.exe succeeds. This patch uses snprintf on the UTF-8 string instead. Also remove branch GetWindowsDirectoryW, since it doesn't work. * Windows: Fix dangling symlink test failures Co-authored-by: Lars Kanis <kanis@comcard.de>
Diffstat (limited to 'test/socket')
-rw-r--r--test/socket/test_nonblock.rb4
-rw-r--r--test/socket/test_unix.rb147
2 files changed, 108 insertions, 43 deletions
diff --git a/test/socket/test_nonblock.rb b/test/socket/test_nonblock.rb
index d9d1e186b2..5a4688bac3 100644
--- a/test/socket/test_nonblock.rb
+++ b/test/socket/test_nonblock.rb
@@ -307,11 +307,13 @@ class TestSocketNonblock < Test::Unit::TestCase
loop { s1.sendmsg_nonblock(buf) }
end
end
- rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT
+ rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT, Errno::EPROTOTYPE
omit "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
end
def test_sendmsg_nonblock_no_exception
+ omit "AF_UNIX + SEQPACKET is not supported on windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+
buf = '*' * 4096
UNIXSocket.pair(:SEQPACKET) do |s1, s2|
n = 0
diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb
index 8c74d0c939..b1dcc813e7 100644
--- a/test/socket/test_unix.rb
+++ b/test/socket/test_unix.rb
@@ -60,6 +60,8 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
assert_not_equal s1.fileno, r.fileno
r.close
end
+ rescue NotImplementedError => error
+ omit error.message
end
def test_fd_passing_n
@@ -334,62 +336,70 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
end
def test_noname_path
- s1, s2 = UNIXSocket.pair
- assert_equal("", s1.path)
- assert_equal("", s2.path)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal("", s1.path)
+ assert_equal("", s2.path)
+ end
end
def test_noname_addr
- s1, s2 = UNIXSocket.pair
- assert_equal(["AF_UNIX", ""], s1.addr)
- assert_equal(["AF_UNIX", ""], s2.addr)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal(["AF_UNIX", ""], s1.addr)
+ assert_equal(["AF_UNIX", ""], s2.addr)
+ end
end
def test_noname_peeraddr
- s1, s2 = UNIXSocket.pair
- assert_equal(["AF_UNIX", ""], s1.peeraddr)
- assert_equal(["AF_UNIX", ""], s2.peeraddr)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal(["AF_UNIX", ""], s1.peeraddr)
+ assert_equal(["AF_UNIX", ""], s2.peeraddr)
+ end
end
def test_noname_unpack_sockaddr_un
- s1, s2 = UNIXSocket.pair
- n = nil
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != ""
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ n = nil
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != ""
+ end
end
def test_noname_recvfrom
- s1, s2 = UNIXSocket.pair
- s2.write("a")
- assert_equal(["a", ["AF_UNIX", ""]], s1.recvfrom(10))
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ s2.write("a")
+ assert_equal(["a", ["AF_UNIX", ""]], s1.recvfrom(10))
+ end
end
def test_noname_recv_nonblock
- s1, s2 = UNIXSocket.pair
- s2.write("a")
- IO.select [s1]
- assert_equal("a", s1.recv_nonblock(10))
- ensure
- s1.close
- s2.close
+ UNIXSocket.pair do |s1, s2|
+ s2.write("a")
+ IO.select [s1]
+ assert_equal("a", s1.recv_nonblock(10))
+ end
end
def test_too_long_path
@@ -429,12 +439,18 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
rv = s1.recv(100, 0, buf)
assert_equal buf.object_id, rv.object_id
assert_equal "BBBBBB", rv
+ rescue Errno::EPROTOTYPE => error
+ omit error.message
ensure
s1.close if s1
s2.close if s2
end
def test_dgram_pair_sendrecvmsg_errno_set
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit("AF_UNIX + SOCK_DGRAM is not supported on windows")
+ end
+
s1, s2 = to_close = UNIXSocket.pair(Socket::SOCK_DGRAM)
pipe = IO.pipe
to_close.concat(pipe)
@@ -457,9 +473,17 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
end
def test_epipe # [ruby-dev:34619]
+ # This is a good example of why reporting the exact `errno` is a terrible
+ # idea for platform abstractions.
+ if RUBY_PLATFORM =~ /mswin|mingw/
+ error = Errno::ESHUTDOWN
+ else
+ error = Errno::EPIPE
+ end
+
UNIXSocket.pair {|s1, s2|
s1.shutdown(Socket::SHUT_WR)
- assert_raise(Errno::EPIPE) { s1.write "a" }
+ assert_raise(error) { s1.write "a" }
assert_equal(nil, s2.read(1))
s2.write "a"
assert_equal("a", s1.read(1))
@@ -493,6 +517,45 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
}
end
+ if /mingw|mswin/ =~ RUBY_PLATFORM
+
+ def test_unix_socket_with_encoding
+ Dir.mktmpdir do |tmpdir|
+ path = "#{tmpdir}/sockäöü".encode("cp850")
+ UNIXServer.open(path) do |serv|
+ assert File.socket?(path)
+ assert File.stat(path).socket?
+ assert File.lstat(path).socket?
+ assert_equal path.encode("utf-8"), serv.path
+ UNIXSocket.open(path) do |s1|
+ s2 = serv.accept
+ s2.close
+ end
+ end
+ end
+ end
+
+ def test_windows_unix_socket_pair_with_umlaut
+ otmp = ENV['TMP']
+ ENV['TMP'] = File.join(Dir.tmpdir, "äöü€")
+ FileUtils.mkdir_p ENV['TMP']
+
+ s1, s2 = UNIXSocket.pair
+ assert !s1.path.empty?
+ assert !File.exist?(s1.path)
+ ensure
+ FileUtils.rm_rf ENV['TMP']
+ ENV['TMP'] = otmp
+ end
+
+ def test_windows_unix_socket_pair_paths
+ s1, s2 = UNIXSocket.pair
+ assert !s1.path.empty?
+ assert s2.path.empty?
+ assert !File.exist?(s1.path)
+ end
+ end
+
def test_initialize
Dir.mktmpdir {|d|
Socket.open(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) {|s|