1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
| | # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors
# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
$stdout.sync = $stderr.sync = Thread.abort_on_exception = true
$-w = true if RUBY_VERSION.to_f >= 2.0
require 'thread'
# Global Test Lock, to protect:
# Process.wait*, Dir.chdir, ENV, trap, require, etc...
GTL = Mutex.new
# fork-aware coverage data gatherer, see also test/covshow.rb
if ENV["COVERAGE"]
require "coverage"
COVMATCH = %r{/lib/yahns\b.*rb\z}
def __covmerge
res = Coverage.result
# 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
covtmp.rewind
covtmp.truncate(0)
covtmp.write(Marshal.dump(prev))
covtmp.flock(File::LOCK_UN)
end
end
Coverage.start
# we need to nest at_exit to fire after minitest runs
at_exit { at_exit { __covmerge } }
end
gem 'minitest'
begin # favor minitest 5
require 'minitest'
Testcase = Minitest::Test
mtobj = Minitest
rescue NameError, LoadError # but support minitest 4
require 'minitest/unit'
Testcase = Minitest::Unit::TestCase
mtobj = MiniTest::Unit.new
end
# Not using minitest/autorun because that doesn't guard against redundant
# extra runs with fork. We cannot use exit! in the tests either
# (since users/apps hosted on yahns _should_ expect exit, not exit!).
TSTART_PID = $$
at_exit do
# skipping @@after_run stuff in minitest since we don't need it
case $!
when nil, SystemExit
mtobj.run(ARGV) if $$ == TSTART_PID
end
end
require "tempfile"
require 'tmpdir'
class Dir
require 'fileutils'
def Dir.mktmpdir
begin
d = "#{Dir.tmpdir}/#$$.#{rand}"
Dir.mkdir(d)
rescue Errno::EEXIST
end while true
begin
yield d
ensure
FileUtils.remove_entry(d)
end
end
end unless Dir.respond_to?(:mktmpdir)
def tmpfile(*args)
tmp = Tempfile.new(*args)
tmp.sync = true
tmp.binmode
tmp
end
require 'io/wait'
# needed for Rubinius 2.0.0, we only use IO#nread in tests
class IO
# this ignores buffers
def nread
buf = "\0" * 8
ioctl(0x541B, buf)
buf.unpack("l_")[0]
end
end if ! IO.method_defined?(:nread) && RUBY_PLATFORM =~ /linux/
require 'yahns'
# needed for parallel (MT) tests)
require 'yahns/rack'
|