I saw a case of non-deterministic failure in CI that's almost certainly caused by multiple threads being present when the thread printer runs. In particular, a thread with `puma` in the stack was present. Although the test suite is single-threaded, nothing synchronizes the joining of all threads between tests. While perhaps chasing such non-determinism could be fruitful, doing so via the ThreadPrinter test doesn't make sense; it'd have to be in a before/after/around arrangement, e.g. in dispatcher_spec.rb: describe "#start_cohort" do after do Thread.list.each { _1.join if _1 != Thread.current } end
34 lines
1.2 KiB
Ruby
34 lines
1.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe ThreadPrinter do
|
|
describe "#print" do
|
|
it "can dump threads" do
|
|
output = []
|
|
expect(described_class).to receive(:puts) do |str|
|
|
output << str
|
|
end.at_least(:once)
|
|
|
|
described_class.run
|
|
|
|
expect(output[0]).to match(/--BEGIN THREAD DUMP, .*/)
|
|
expect(output[1]).to match(/Thread: #<Thread:.*>/)
|
|
expect(output[2]).to match(/backtrace/)
|
|
expect(output[-1]).to match(/--END THREAD DUMP, .*/)
|
|
end
|
|
|
|
it "can handle threads with a nil backtrace and/or a created_at" do
|
|
# The documentation calls out that the backtrace is an array or
|
|
# nil.
|
|
expect(described_class).to receive(:puts).with(/--BEGIN THREAD DUMP, .*/)
|
|
expect(described_class).to receive(:puts).with(/Thread: #<InstanceDouble.*>/)
|
|
expect(described_class).to receive(:puts).with(/Created at: .*/)
|
|
expect(described_class).to receive(:puts).with(nil)
|
|
expect(described_class).to receive(:puts).with(/--END THREAD DUMP, .*/)
|
|
th = instance_double(Thread, backtrace: nil)
|
|
expect(th).to receive(:[]).with(:created_at).and_return(Time.now - 30)
|
|
expect(Thread).to receive(:list).and_return([th])
|
|
described_class.run
|
|
end
|
|
end
|
|
end
|