about summary refs log tree commit homepage
path: root/test
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2013-10-19 01:30:53 +0000
committerEric Wong <e@80x24.org>2013-10-19 01:38:06 +0000
commitf89ee896e14bfa97179f3773d303dd0a1bdcf971 (patch)
treeaee7898b68b952470d933da253b72eb4231dee9a /test
parent8405eb8c49196b626dfdc747be4a3b91d530074a (diff)
downloadyahns-f89ee896e14bfa97179f3773d303dd0a1bdcf971.tar.gz
flock works on file handles (which are shared across processes).
So our use of flock on a global constant was not fork safe as the
same file handle would share locks between the client/parent
process.  Since we have to create/truncate the coverage.dump file in
the Makefile before any tests run anyways, we can just lazily open
the file handle when we need to use it, and never before.
Diffstat (limited to 'test')
-rw-r--r--test/helper.rb49
1 files changed, 26 insertions, 23 deletions
diff --git a/test/helper.rb b/test/helper.rb
index ab9a04f..896377f 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -11,38 +11,41 @@ GTL = Mutex.new
 if ENV["COVERAGE"]
   require "coverage"
   COVMATCH = %r{/lib/yahns\b.*rb\z}
-  COVTMP = File.open("coverage.dump", IO::CREAT|IO::RDWR)
-  COVTMP.binmode
-  COVTMP.sync = true
 
   def __covmerge
     res = Coverage.result
 
-    # we own this file (at least until somebody tries to use NFS :x)
-    COVTMP.flock(File::LOCK_EX)
-
-    COVTMP.rewind
-    prev = COVTMP.read
-    prev = prev.empty? ? {} : Marshal.load(prev)
-    res.each do |filename, counts|
-      # filter out stuff that's not in our project
-      COVMATCH =~ filename or next
-
-      merge = prev[filename] || []
-      merge = merge
-      counts.each_with_index do |count, i|
-        count or next
-        merge[i] = (merge[i] || 0) + count
+    # do not create the file, Makefile does htis before any tests run
+    File.open("coverage.dump", IO::RDWR) do |covtmp|
+      covtmp.binmode
+      covtmp.sync = true
+
+      # we own this file (at least until somebody tries to use NFS :x)
+      covtmp.flock(File::LOCK_EX)
+
+      prev = covtmp.read
+      prev = prev.empty? ? {} : Marshal.load(prev)
+      res.each do |filename, counts|
+        # filter out stuff that's not in our project
+        COVMATCH =~ filename or next
+
+        merge = prev[filename] || []
+        merge = merge
+        counts.each_with_index do |count, i|
+          count or next
+          merge[i] = (merge[i] || 0) + count
+        end
+        prev[filename] = merge
       end
-      prev[filename] = merge
+      covtmp.rewind
+      covtmp.truncate(0)
+      covtmp.write(Marshal.dump(prev))
+      covtmp.flock(File::LOCK_UN)
     end
-    COVTMP.rewind
-    COVTMP.truncate(0)
-    COVTMP.write(Marshal.dump(prev))
-    COVTMP.flock(File::LOCK_UN)
   end
 
   Coverage.start
+  # we need to nest at_exit to fire after minitest runs
   at_exit { at_exit { __covmerge } }
 end