From 7e89d926930aedc6a572784c7138771658571f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Sat, 15 Jun 2024 12:50:25 +0200 Subject: [PATCH] Enable specs for `close_on_exec` on Windows --- spec/std/io/file_descriptor_spec.cr | 60 ++++++++++++++++------------- spec/std/socket/socket_spec.cr | 14 +++---- spec/std/socket/spec_helper.cr | 2 + spec/std/socket/tcp_server_spec.cr | 14 +++---- spec/std/socket/unix_server_spec.cr | 16 ++++---- 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/spec/std/io/file_descriptor_spec.cr b/spec/std/io/file_descriptor_spec.cr index f64d5fd2d8b9..e20028bfda15 100644 --- a/spec/std/io/file_descriptor_spec.cr +++ b/spec/std/io/file_descriptor_spec.cr @@ -5,6 +5,8 @@ class IO::FileDescriptor include FinalizeCounter end +private CLOSE_ON_EXEC_AVAILABLE = {{ !flag?(:win32) }} + private def shell_command(command) {% if flag?(:win32) %} "cmd.exe /c #{Process.quote(command)}" @@ -103,45 +105,51 @@ describe IO::FileDescriptor do end end - {% unless flag?(:win32) %} - describe "close_on_exec" do - it "sets close on exec on the reopened standard descriptors" do - unless STDIN.fd == Crystal::System::FileDescriptor::STDIN_HANDLE - STDIN.close_on_exec?.should be_true - end + describe "close_on_exec" do + it "sets close on exec on the reopened standard descriptors" do + unless STDIN.fd == Crystal::System::FileDescriptor::STDIN_HANDLE + STDIN.close_on_exec?.should be_true + end - unless STDOUT.fd == Crystal::System::FileDescriptor::STDOUT_HANDLE - STDOUT.close_on_exec?.should be_true - end + unless STDOUT.fd == Crystal::System::FileDescriptor::STDOUT_HANDLE + STDOUT.close_on_exec?.should be_true + end - unless STDERR.fd == Crystal::System::FileDescriptor::STDERR_HANDLE - STDERR.close_on_exec?.should be_true - end + unless STDERR.fd == Crystal::System::FileDescriptor::STDERR_HANDLE + STDERR.close_on_exec?.should be_true end + end - it "is enabled by default (open)" do - File.open(datapath("test_file.txt")) do |file| - file.close_on_exec?.should be_true - end + it "is enabled by default (open)" do + File.open(datapath("test_file.txt")) do |file| + file.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE end + end - it "is enabled by default (pipe)" do - IO::FileDescriptor.pipe.each do |fd| - fd.close_on_exec?.should be_true - fd.close_on_exec?.should be_true - end + it "is enabled by default (pipe)" do + IO::FileDescriptor.pipe.each do |fd| + fd.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE + fd.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE end + end - it "can be disabled and reenabled" do - File.open(datapath("test_file.txt")) do |file| - file.close_on_exec = false - file.close_on_exec?.should be_false + it "can be disabled and reenabled" do + File.open(datapath("test_file.txt")) do |file| + file.close_on_exec = false + file.close_on_exec?.should be_false + if CLOSE_ON_EXEC_AVAILABLE file.close_on_exec = true file.close_on_exec?.should be_true + else + expect_raises(NotImplementedError) do + file.close_on_exec = true + end end end + end + if CLOSE_ON_EXEC_AVAILABLE it "is copied on reopen" do File.open(datapath("test_file.txt")) do |file1| file1.close_on_exec = true @@ -160,7 +168,7 @@ describe IO::FileDescriptor do end end end - {% end %} + end typeof(STDIN.noecho { }) typeof(STDIN.noecho!) diff --git a/spec/std/socket/socket_spec.cr b/spec/std/socket/socket_spec.cr index d4e7051d12bd..ef90ea8a30f4 100644 --- a/spec/std/socket/socket_spec.cr +++ b/spec/std/socket/socket_spec.cr @@ -57,9 +57,7 @@ describe Socket, tags: "network" do client.family.should eq(Socket::Family::INET) client.type.should eq(Socket::Type::STREAM) client.protocol.should eq(Socket::Protocol::TCP) - {% unless flag?(:win32) %} - client.close_on_exec?.should be_true - {% end %} + client.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE ensure client.close end @@ -163,10 +161,8 @@ describe Socket, tags: "network" do end end - {% unless flag?(:win32) %} - it "closes on exec by default" do - socket = Socket.new(Socket::Family::INET, Socket::Type::STREAM, Socket::Protocol::TCP) - socket.close_on_exec?.should be_true - end - {% end %} + it "closes on exec by default" do + socket = Socket.new(Socket::Family::INET, Socket::Type::STREAM, Socket::Protocol::TCP) + socket.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE + end end diff --git a/spec/std/socket/spec_helper.cr b/spec/std/socket/spec_helper.cr index 486e4a142ee7..31f203d20bac 100644 --- a/spec/std/socket/spec_helper.cr +++ b/spec/std/socket/spec_helper.cr @@ -1,6 +1,8 @@ require "spec" require "socket" +CLOSE_ON_EXEC_AVAILABLE = {{ !flag?(:win32) }} + module SocketSpecHelper class_getter?(supports_ipv6 : Bool) do TCPServer.open("::1", 0) { return true } diff --git a/spec/std/socket/tcp_server_spec.cr b/spec/std/socket/tcp_server_spec.cr index 0c6113a4a7ff..9ca86a5d71cc 100644 --- a/spec/std/socket/tcp_server_spec.cr +++ b/spec/std/socket/tcp_server_spec.cr @@ -138,16 +138,14 @@ describe TCPServer, tags: "network" do {% end %} describe "accept" do - {% unless flag?(:win32) %} - it "sets close on exec flag" do - TCPServer.open("localhost", 0) do |server| - TCPSocket.open("localhost", server.local_address.port) do |client| - server.accept? do |sock| - sock.close_on_exec?.should be_true - end + it "sets close on exec flag" do + TCPServer.open("localhost", 0) do |server| + TCPSocket.open("localhost", server.local_address.port) do |client| + server.accept? do |sock| + sock.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE end end end - {% end %} + end end end diff --git a/spec/std/socket/unix_server_spec.cr b/spec/std/socket/unix_server_spec.cr index ca364f08667c..45c29fc3d8e4 100644 --- a/spec/std/socket/unix_server_spec.cr +++ b/spec/std/socket/unix_server_spec.cr @@ -148,19 +148,17 @@ describe UNIXServer do end end - {% unless flag?(:win32) %} - it "sets close on exec flag" do - with_tempfile("unix_socket-accept.sock") do |path| - UNIXServer.open(path) do |server| - UNIXSocket.open(path) do |client| - server.accept? do |sock| - sock.close_on_exec?.should be_true - end + it "sets close on exec flag" do + with_tempfile("unix_socket-accept.sock") do |path| + UNIXServer.open(path) do |server| + UNIXSocket.open(path) do |client| + server.accept? do |sock| + sock.close_on_exec?.should eq CLOSE_ON_EXEC_AVAILABLE end end end end - {% end %} + end end # Datagram socket type is not supported on Windows yet: