Permalink
Browse files

FIX: Ensure Rack::Test::UploadedFile closes its tempfile file descrip…

…tor on GC (#180)
  • Loading branch information...
bsodmike authored and junaruga committed Jun 5, 2017
1 parent a5aa1e5 commit b3b20dd45a7074a4324f270719f96bdad89a6212
Showing with 43 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +11 −0 lib/rack/test/uploaded_file.rb
  3. +31 −0 spec/rack/test/uploaded_file_spec.rb
@@ -6,3 +6,4 @@ VERSION
*.rbc
*.swp
/.bundle
/.idea
@@ -30,6 +30,8 @@ def initialize(path, content_type = "text/plain", binary = false)
@tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
@tempfile.binmode if binary
ObjectSpace.define_finalizer(self, self.class.finalize(@tempfile))
FileUtils.copy_file(path, @tempfile.path)
end
@@ -47,6 +49,15 @@ def respond_to?(method_name, include_private = false) #:nodoc:
@tempfile.respond_to?(method_name, include_private) || super
end
def self.finalize(file)
proc { actually_finalize file }
end
def self.actually_finalize(file)
file.close
file.unlink
end
end
end
@@ -5,6 +5,12 @@ def test_file_path
File.dirname(__FILE__) + "/../../fixtures/foo.txt"
end
it "returns an instance of `Rack::Test::UploadedFile`" do
uploaded_file = Rack::Test::UploadedFile.new(test_file_path)
expect(uploaded_file).to be_a(Rack::Test::UploadedFile)
end
it "responds to things that Tempfile responds to" do
uploaded_file = Rack::Test::UploadedFile.new(test_file_path)
@@ -26,4 +32,29 @@ def test_file_path
expect(File.extname(uploaded_file.path)).to eq(".txt")
end
context "it should call its destructor" do
it "calls the destructor" do
expect(Rack::Test::UploadedFile).to receive(:actually_finalize).at_least(:once)
if RUBY_PLATFORM == 'java'
require 'java'
java_import 'java.lang.System'
20.times do |i|
uploaded_file = Rack::Test::UploadedFile.new(test_file_path)
uploaded_file = nil
System.gc()
end
else
uploaded_file = Rack::Test::UploadedFile.new(test_file_path)
uploaded_file = nil
GC.start
end
end
end
end

0 comments on commit b3b20dd

Please sign in to comment.