File: test_god_system.rb

package info (click to toggle)
ruby-god 0.13.7-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 832 kB
  • sloc: ruby: 6,641; ansic: 237; makefile: 3
file content (201 lines) | stat: -rw-r--r-- 6,026 bytes parent folder | download | duplicates (2)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
require File.dirname(__FILE__) + '/helper'

class TestGodSystem < MiniTest::Test
  def assert_watch_running(watch_name)
    assert_equal true, God.watches[watch_name].alive?
  end

  def with_god_cleanup
    old_terminate = God.method(:terminate)
    # necessary cuz actual god terminate will do exit(0) will stops tests
    God.class_eval do
      def self.terminate
        FileUtils.rm_f(self.pid) if self.pid
        self.server.stop if self.server
      end
    end
    begin
      yield
    ensure
      God.stop_all
      God.terminate # use our monkeypatched terminate
      God.watches.each do |name, w|
        w.stop_signal = 'KILL'
        w.action(:stop)
      end
      God.inited = false
      God.terminate_timeout = ::God::TERMINATE_TIMEOUT_DEFAULT
      God.internal_init # reset config, set running to false, etc.
      # set termiante back to old method, for other tests
      God.define_singleton_method(:terminate, old_terminate)
    end
  end

  def test_start_running
    with_god_cleanup do
      God.start
      assert_equal(God.running, true)
    end
  end

  def test_add_watch
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'add_watch'
        w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
      end
      assert God.watches['add_watch'] != nil
    end
  end

  def test_start_watch
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'start_watch'
        w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
      end
      God.watches['start_watch'].action(:start)
      sleep 2
      assert_equal true, God.watches['start_watch'].alive?
    end
  end

  def test_start_watch
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'start_watch'
        w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
      end
      God.watches['start_watch'].action(:start)
      sleep 2
      assert_equal true, God.watches['start_watch'].alive?
    end
  end

  def test_stop_all_with_one
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'start_watch'
        w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
      end
      God.watches['start_watch'].action(:start)
      sleep 2
      assert_equal true, God.watches['start_watch'].alive?
      God.stop_all
      assert_equal false, God.watches.any? { |name, w| w.alive? }
    end
  end

  # default 10s timeout will expire before SIGKILL sent
  def test_stop_all_with_non_killing_signal_long_timeout
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'long_timeout'
        w.stop_signal = 'USR1'
        w.stop_timeout = ::God::STOP_TIMEOUT_DEFAULT + 1
        w.start = File.join(GOD_ROOT, *%w[test configs usr1_trapper.rb])
      end
      God.watches['long_timeout'].action(:start)
      sleep 2
      assert_equal true, God.watches['long_timeout'].alive?
      God.stop_all
      assert_watch_running('long_timeout')
    end
  end

  # use short timeout to send SIGKILL before 10s timeout
  def test_stop_all_with_non_killing_signal_short_timeout
    with_god_cleanup do
      God.start
      God.watch do |w|
        w.name = 'short_timeout'
        w.stop_signal = 'USR1'
        w.stop_timeout = ::God::STOP_TIMEOUT_DEFAULT - 1
        w.start = File.join(GOD_ROOT, *%w[test configs usr1_trapper.rb])
      end
      God.watches['short_timeout'].action(:start)
      sleep 2
      assert_equal true, God.watches['short_timeout'].alive?
      God.stop_all
      assert_equal false, God.watches.any? { |name, w| w.alive? }
    end
  end

  # should be able to stop many simple watches within default timeout
  def test_stop_all_with_many_watches
    with_god_cleanup do
      God.start
      20.times do |i|
        God.watch do |w|
          w.name = "many_watches_#{i}"
          w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
        end
        God.watches["many_watches_#{i}"].action(:start)
      end
      while true do
        all_running = God.watches.select{ |name, w| name =~ /many_watches_/ }.all?{ |name, w| w.alive? }
        size = God.watches.size
        break if all_running && size >= 20
        sleep 2
      end
      God.stop_all
      assert_equal false, God.watches.any? { |name, w| w.alive? }
    end
  end

  # should be able to stop many simple watches within short timeout
  def test_stop_all_with_many_watches_short_timeout
    with_god_cleanup do
      God.start
      God.terminate_timeout = 1
      100.times do |i|
        God.watch do |w|
          w.name = "tons_of_watches_#{i}"
          w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
          w.keepalive
        end
        God.watches["tons_of_watches_#{i}"].action(:start)
      end
      while true do
        all_running = God.watches.select{ |name, w| name =~ /tons_of_watches_/ }.all?{ |name, w| w.alive? }
        size = God.watches.size
        break if all_running && size >= 100
        sleep 2
      end
      God.stop_all
      assert_equal false, God.watches.any? { |name, w| w.alive? }
    end
  end

  def test_god_terminate_with_many_watches_short_timeout
    with_god_cleanup do
      God.start
      God.terminate_timeout = 1
      100.times do |i|
        God.watch do |w|
          w.name = "tons_of_watches_#{i}"
          w.start = File.join(GOD_ROOT, *%w[test configs complex simple_server.rb])
          w.keepalive
        end
        God.watches["tons_of_watches_#{i}"].action(:start)
      end
      while true do
        all_running = God.watches.select{ |name, w| name =~ /tons_of_watches_/ }.all?{ |name, w| w.alive? }
        size = God.watches.size
        break if all_running && size >= 100
        sleep 2
      end
      begin
        God::CLI::Command.new('terminate', {port: 17165}, [])
      rescue SystemExit
      ensure
        assert_equal false, God.watches.any? { |name, w| w.alive? }
      end
    end
  end
end