Repository navigation
Expand file tree
/
Copy pathRakefile
More file actions
94 lines (88 loc) · 3.18 KB
/
Copy pathRakefile
File metadata and controls
94 lines (88 loc) · 3.18 KB
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
# frozen_string_literal: true
require "rake/testtask"
Rake::TestTask.new do |task|
task.libs << "test"
task.pattern = "test/**/*_test.rb"
task.warning = true
end
desc "Soak test with memory/resource limits: rake soak[http] or soak[webrtc]"
task :soak, [:scenario] do |_task, arguments|
require_relative "test/support/soak_runner"
require "timeout"
scenario = arguments[:scenario] || "http"
abort "Scenario must be http or webrtc" unless %w[http webrtc].include?(scenario)
config = TransportSoak::Config.new
report = ENV.fetch("UTCP_SOAK_REPORT", "tmp/soak/#{scenario}.json")
FileUtils.mkdir_p(File.dirname(report))
File.write(report, JSON.pretty_generate("scenario" => scenario, "status" => "starting") + "\n")
environment = { "UTCP_SOAK_REPORT" => report }
command = [RbConfig.ruby, "-Itest"]
if scenario == "webrtc"
environment["UTCP_NATIVE_SOAK"] = "1"
command.concat(["test/integration/native_transports.rb", "--name", "/\\Atest_native_webrtc_soak\\z/"])
else
command << "test/integration/transport_soak.rb"
end
pid = Process.spawn(environment, *command, pgroup: true)
reaped = false
begin
_pid, status = Timeout.timeout(config.duration + 60) { Process.wait2(pid) }
reaped = true
data = JSON.parse(File.read(report))
unless status.success? && data["status"] == "passed"
data["status"] = "failed"
data["error"] ||= "Subprocess exited with #{status.exitstatus.inspect} or did not finish the scenario"
File.write(report, JSON.pretty_generate(data) + "\n")
abort "#{scenario} soak failed"
end
rescue Timeout::Error
data = File.file?(report) ? JSON.parse(File.read(report)) : { "scenario" => scenario }
data.merge!("status" => "failed", "error" => "Subprocess watchdog expired, including cleanup")
FileUtils.mkdir_p(File.dirname(report))
File.write(report, JSON.pretty_generate(data) + "\n")
abort "#{scenario} soak exceeded #{config.duration + 60} seconds (including cleanup)"
ensure
unless reaped
begin
Process.kill("KILL", -pid)
rescue Errno::ESRCH
nil
end
begin
Process.wait(pid)
rescue Errno::ECHILD
nil
end
end
end
end
task default: :test
desc "Run tests with line and branch coverage thresholds"
task :coverage do
sh({ "COVERAGE" => "1" }, RbConfig.ruby, "-Itest", "-e",
'Dir["test/**/*_test.rb"].sort.each { |file| require File.expand_path(file) }')
end
desc "Test real gRPC and WebRTC backends (requires optional native gems)"
task :native do
require "timeout"
require "shellwords"
# A native deadlock can hold Ruby's GVL, so the watchdog must live in the parent.
pid = Process.spawn(RbConfig.ruby, "-Itest", "test/integration/native_transports.rb",
*Shellwords.split(ENV.fetch("TESTOPTS", "")))
begin
_pid, status = Timeout.timeout(45) { Process.wait2(pid) }
abort "Native integration tests failed" unless status.success?
rescue Timeout::Error
begin
Process.kill("KILL", pid)
rescue Errno::ESRCH
nil
end
begin
Process.wait(pid)
rescue Errno::ECHILD
nil
end
abort "Native integration timed out after 45 seconds (including backend cleanup)"
end
end