[前][次][番号順一覧][スレッド一覧]

ruby-changes:34075

From: akr <ko1@a...>
Date: Tue, 27 May 2014 12:24:59 +0900 (JST)
Subject: [ruby-changes:34075] akr:r46156 (trunk): * test/lib/minitest/unit.rb: Show leaked file descriptors.

akr	2014-05-27 12:24:52 +0900 (Tue, 27 May 2014)

  New Revision: 46156

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=46156

  Log:
    * test/lib/minitest/unit.rb: Show leaked file descriptors.

  Modified files:
    trunk/ChangeLog
    trunk/test/lib/minitest/unit.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46155)
+++ ChangeLog	(revision 46156)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue May 27 12:24:22 2014  Tanaka Akira  <akr@f...>
+
+	* test/lib/minitest/unit.rb: Show leaked file descriptors.
+
 Tue May 27 11:12:56 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* io.c (rb_io_fileno, rb_io_inspect): non-modification does not
Index: test/lib/minitest/unit.rb
===================================================================
--- test/lib/minitest/unit.rb	(revision 46155)
+++ test/lib/minitest/unit.rb	(revision 46156)
@@ -932,6 +932,7 @@ module MiniTest https://github.com/ruby/ruby/blob/trunk/test/lib/minitest/unit.rb#L932
       }
 
       threads = find_threads
+      fds = find_fds
       tempfiles = find_tempfiles
 
       assertions = filtered_test_methods.map { |method|
@@ -949,6 +950,8 @@ module MiniTest https://github.com/ruby/ruby/blob/trunk/test/lib/minitest/unit.rb#L950
 
         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
 
@@ -982,6 +985,60 @@ module MiniTest https://github.com/ruby/ruby/blob/trunk/test/lib/minitest/unit.rb#L985
         }
       end
       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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]