summaryrefslogtreecommitdiff
path: root/spec/ruby/core/thread/abort_on_exception_spec.rb
blob: e424b2fd2660d40ade216dc2650f5b43a488948c (plain)
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
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Thread#abort_on_exception" do
  before do
    ThreadSpecs.clear_state
    @thread = Thread.new { Thread.pass until ThreadSpecs.state == :exit }
  end

  after do
    ThreadSpecs.state = :exit
    @thread.join
  end

  it "is false by default" do
    @thread.abort_on_exception.should be_false
  end

  it "returns true when #abort_on_exception= is passed true" do
    @thread.abort_on_exception = true
    @thread.abort_on_exception.should be_true
  end
end

describe :thread_abort_on_exception, shared: true do
  before do
    @thread = Thread.new do
      Thread.pass until ThreadSpecs.state == :run
      raise RuntimeError, "Thread#abort_on_exception= specs"
    end
  end

  it "causes the main thread to raise the exception raised in the thread" do
    begin
      ScratchPad << :before

      @thread.abort_on_exception = true if @object
      lambda do
        ThreadSpecs.state = :run
        # Wait for the main thread to be interrupted
        sleep
      end.should raise_error(RuntimeError, "Thread#abort_on_exception= specs")

      ScratchPad << :after
    rescue Exception => e
      ScratchPad << [:rescue, e]
    end

    ScratchPad.recorded.should == [:before, :after]
  end
end

describe "Thread#abort_on_exception=" do
  describe "when enabled and the thread dies due to an exception" do
    before do
      ScratchPad.record []
      ThreadSpecs.clear_state
      @stderr, $stderr = $stderr, IOStub.new
    end

    after do
      $stderr = @stderr
    end

    it_behaves_like :thread_abort_on_exception, nil, true
  end
end

describe "Thread.abort_on_exception" do
  before do
    @abort_on_exception = Thread.abort_on_exception
  end

  after do
     Thread.abort_on_exception = @abort_on_exception
  end

  it "is false by default" do
    Thread.abort_on_exception.should == false
  end

  it "returns true when .abort_on_exception= is passed true" do
    Thread.abort_on_exception = true
    Thread.abort_on_exception.should be_true
  end
end

describe "Thread.abort_on_exception=" do
  describe "when enabled and a non-main thread dies due to an exception" do
    before :each do
      ScratchPad.record []
      ThreadSpecs.clear_state
      @stderr, $stderr = $stderr, IOStub.new

      @abort_on_exception = Thread.abort_on_exception
      Thread.abort_on_exception = true
    end

    after :each do
      Thread.abort_on_exception = @abort_on_exception
      $stderr = @stderr
    end

    it_behaves_like :thread_abort_on_exception, nil, false
  end
end