diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-05-27 03:24:52 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-05-27 03:24:52 +0000 |
commit | dbd239a7aafd2c19fad795b5c453c79eefa1ec87 (patch) | |
tree | 407df54ddd855b486fa3cb4c48dd14db4a5fbc2c /test | |
parent | 2e5d698538ea132a4dcd46d924c071227b5f4956 (diff) | |
download | ruby-dbd239a7aafd2c19fad795b5c453c79eefa1ec87.tar.gz |
* test/lib/minitest/unit.rb: Show leaked file descriptors.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r-- | test/lib/minitest/unit.rb | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/test/lib/minitest/unit.rb b/test/lib/minitest/unit.rb index 54f34d55f7..25160340db 100644 --- a/test/lib/minitest/unit.rb +++ b/test/lib/minitest/unit.rb @@ -932,6 +932,7 @@ module MiniTest } threads = find_threads + fds = find_fds tempfiles = find_tempfiles assertions = filtered_test_methods.map { |method| @@ -949,6 +950,8 @@ module MiniTest threads = check_thread_leak inst, threads, find_threads + fds = check_fd_leak inst, fds, find_fds + # find_tempfiles is too slow to run for each test method. #tempfiles = check_tempfile_leak inst, tempfiles, find_tempfiles @@ -984,6 +987,60 @@ module MiniTest live2 end + def find_fds + fd_dir = "/proc/#{$$}/fd" + if File.directory?(fd_dir) + Dir.entries(fd_dir).grep(/\A\d+\z/).map(&:to_i).sort + else + [] + end + end + + def check_fd_leak(inst, live1, live2) + name = "#{inst.class}\##{inst.__name__}" + fd_closed = live1 - live2 + if !fd_closed.empty? + fd_closed.each {|fd| + puts "Closed file descriptor: #{name}: #{fd}" + } + end + fd_leaked = live2 - live1 + if !fd_leaked.empty? + h = {} + ObjectSpace.each_object(IO) {|io| + begin + fd = io.fileno + rescue IOError # closed IO object + next + end + (h[fd] ||= []) << io + } + fd_leaked.each {|fd| + str = '' + if h[fd] + str << ' :' + h[fd].map {|io| + s = ' ' + io.inspect + s << "(not-autoclose)" if !io.autoclose? + s + }.each {|s| + str << s + } + end + puts "Leaked file descriptor: #{name}: #{fd}#{str}" + } + h.each {|fd, ios| + next if ios.length <= 1 + list = ios.map {|io| [io, io.autoclose?] } + if 1 < list.count {|io, autoclose| autoclose } + str = list.map {|io, autoclose| " #{io.inspect}" + (autoclose ? "(autoclose)" : "") }.sort.join + puts "Multiple autoclose IO object for a file descriptor:#{str}" + end + } + end + live2 + end + def find_tempfiles if defined? Tempfile ObjectSpace.each_object(Tempfile).find_all {|t| |