Skip to content

Commit eb82212

Browse files
committed
Update the latest CoreAssetion for assert_no_memory_leak
1 parent 41b1d8b commit eb82212

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

test/lib/core_assertions.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,51 @@ def syntax_check(code, fname, line)
113113
end
114114
end
115115

116+
def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0, rss: false, **opt)
117+
# TODO: consider choosing some appropriate limit for MJIT and stop skipping this once it does not randomly fail
118+
pend 'assert_no_memory_leak may consider MJIT memory usage as leak' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
119+
120+
require_relative '../../memory_status'
121+
raise MiniTest::Skip, "unsupported platform" unless defined?(Memory::Status)
122+
123+
token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m"
124+
token_dump = token.dump
125+
token_re = Regexp.quote(token)
126+
envs = args.shift if Array === args and Hash === args.first
127+
args = [
128+
"--disable=gems",
129+
"-r", File.expand_path("../../../memory_status", __FILE__),
130+
*args,
131+
"-v", "-",
132+
]
133+
if defined? Memory::NO_MEMORY_LEAK_ENVS then
134+
envs ||= {}
135+
newenvs = envs.merge(Memory::NO_MEMORY_LEAK_ENVS) { |_, _, _| break }
136+
envs = newenvs if newenvs
137+
end
138+
args.unshift(envs) if envs
139+
cmd = [
140+
'END {STDERR.puts '"#{token_dump}"'"FINAL=#{Memory::Status.new}"}',
141+
prepare,
142+
'STDERR.puts('"#{token_dump}"'"START=#{$initial_status = Memory::Status.new}")',
143+
'$initial_size = $initial_status.size',
144+
code,
145+
'GC.start',
146+
].join("\n")
147+
_, err, status = EnvUtil.invoke_ruby(args, cmd, true, true, **opt)
148+
before = err.sub!(/^#{token_re}START=(\{.*\})\n/, '') && Memory::Status.parse($1)
149+
after = err.sub!(/^#{token_re}FINAL=(\{.*\})\n/, '') && Memory::Status.parse($1)
150+
assert(status.success?, FailDesc[status, message, err])
151+
([:size, (rss && :rss)] & after.members).each do |n|
152+
b = before[n]
153+
a = after[n]
154+
next unless a > 0 and b > 0
155+
assert_operator(a.fdiv(b), :<, limit, message(message) {"#{n}: #{b} => #{a}"})
156+
end
157+
rescue LoadError
158+
pend
159+
end
160+
116161
# :call-seq:
117162
# assert_nothing_raised( *args, &block )
118163
#

0 commit comments

Comments
 (0)