ghazel-SystemTimer 1.2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ unit_tests do
4
+
5
+ test "trigger_time returns the time given in the constructor" do
6
+ timer = SystemTimer::ThreadTimer.new(:a_tigger_time, nil)
7
+ assert_equal :a_tigger_time, timer.trigger_time
8
+ end
9
+
10
+ test "thread returns the thread given in the constructor" do
11
+ timer = SystemTimer::ThreadTimer.new(nil, :a_thread)
12
+ assert_equal :a_thread, timer.thread
13
+ end
14
+
15
+ test "to_s retruns a human friendly description of the timer" do
16
+ assert_match /<ThreadTimer :time => 24, :thread => #<Thread(.*)>, :exception_class => Timeout::Error>/,
17
+ SystemTimer::ThreadTimer.new(24, Thread.current).to_s
18
+ end
19
+
20
+ end
@@ -0,0 +1,282 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ functional_tests do
4
+
5
+ DEFAULT_ERROR_MARGIN = 2
6
+
7
+ test "original_ruby_sigalrm_handler is nil after reset" do
8
+ SystemTimer.send(:install_ruby_sigalrm_handler)
9
+ SystemTimer.send(:reset_original_ruby_sigalrm_handler)
10
+ assert_nil SystemTimer.send(:original_ruby_sigalrm_handler)
11
+ end
12
+
13
+ test "original_ruby_sigalrm_handler is set to existing handler after " +
14
+ "install_ruby_sigalrm_handler when save_previous_handler is true" do
15
+ SystemTimer.expects(:trap).with('SIGALRM').returns(:an_existing_handler)
16
+ SystemTimer.send(:install_ruby_sigalrm_handler)
17
+ assert_equal :an_existing_handler, SystemTimer.send(:original_ruby_sigalrm_handler)
18
+ end
19
+
20
+ test "restore_original_ruby_sigalrm_handler traps sigalrm using original_ruby_sigalrm_handler" do
21
+ SystemTimer.stubs(:original_ruby_sigalrm_handler).returns(:the_original_handler)
22
+ SystemTimer.expects(:trap).with('SIGALRM', :the_original_handler)
23
+ SystemTimer.send :restore_original_ruby_sigalrm_handler
24
+ end
25
+
26
+ test "restore_original_ruby_sigalrm_handler resets original_ruby_sigalrm_handler" do
27
+ SystemTimer.stubs(:trap)
28
+ SystemTimer.expects(:reset_original_ruby_sigalrm_handler)
29
+ SystemTimer.send :restore_original_ruby_sigalrm_handler
30
+ end
31
+
32
+ test "restore_original_ruby_sigalrm_handler reset SIGALRM handler to default when original_ruby_sigalrm_handler is nil" do
33
+ SystemTimer.stubs(:original_ruby_sigalrm_handler)
34
+ SystemTimer.expects(:trap).with('SIGALRM', 'DEFAULT')
35
+ SystemTimer.stubs(:reset_original_ruby_sigalrm_handler)
36
+ SystemTimer.send :restore_original_ruby_sigalrm_handler
37
+ end
38
+
39
+ test "restore_original_ruby_sigalrm_handler resets original_ruby_sigalrm_handler when trap raises" do
40
+ SystemTimer.stubs(:trap).returns(:the_original_handler)
41
+ SystemTimer.send(:install_ruby_sigalrm_handler)
42
+ SystemTimer.expects(:trap).raises("next time maybe...")
43
+ SystemTimer.expects(:reset_original_ruby_sigalrm_handler)
44
+
45
+ SystemTimer.send(:restore_original_ruby_sigalrm_handler) rescue nil
46
+ end
47
+
48
+ test "timeout_after raises TimeoutError if block takes too long" do
49
+ assert_raises(Timeout::Error) do
50
+ SystemTimer.timeout_after(1) {sleep 5}
51
+ end
52
+ end
53
+
54
+ test "timeout_after timeout can be a fraction of a second" do
55
+ assert_raises(Timeout::Error) do
56
+ SystemTimer.timeout_after(0.2) {sleep 3}
57
+ end
58
+ end
59
+
60
+
61
+ test "timeout_after raises a custom timeout when block takes too long and a custom exception class is provided" do
62
+ ACustomException = Class.new(Exception)
63
+ assert_raises(ACustomException) do
64
+ SystemTimer.timeout_after(1, ACustomException) {sleep 5}
65
+ end
66
+ end
67
+
68
+ test "timeout_after does not raises Timeout Error if block completes in time" do
69
+ SystemTimer.timeout_after(5) {sleep 1}
70
+ end
71
+
72
+ test "timeout_after returns the value returned by the black" do
73
+ assert_equal :block_value, SystemTimer.timeout_after(1) {:block_value}
74
+ end
75
+
76
+ test "timeout_after raises TimeoutError in thread that called timeout_after" do
77
+ raised_thread = nil
78
+ other_thread = Thread.new do
79
+ begin
80
+ SystemTimer.timeout_after(1) {sleep 5}
81
+ flunk "Should have timed out"
82
+ rescue Timeout::Error
83
+ raised_thread = Thread.current
84
+ end
85
+ end
86
+
87
+ other_thread.join
88
+ assert_equal other_thread, raised_thread
89
+ end
90
+
91
+ test "cancelling a timer that was installed restores previous ruby handler for SIG_ALRM" do
92
+ begin
93
+ fake_original_ruby_handler = proc {}
94
+ initial_ruby_handler = trap "SIGALRM", fake_original_ruby_handler
95
+ SystemTimer.install_first_timer_and_save_original_configuration 3
96
+ SystemTimer.restore_original_configuration
97
+ assert_equal fake_original_ruby_handler, trap("SIGALRM", "IGNORE")
98
+ ensure # avoid interfering with test infrastructure
99
+ trap("SIGALRM", initial_ruby_handler) if initial_ruby_handler
100
+ end
101
+ end
102
+
103
+ test "debug_enabled returns true after enabling debug" do
104
+ begin
105
+ SystemTimer.disable_debug
106
+ SystemTimer.enable_debug
107
+ assert_equal true, SystemTimer.debug_enabled?
108
+ ensure
109
+ SystemTimer.disable_debug
110
+ end
111
+ end
112
+
113
+ test "debug_enabled returns false after disable debug" do
114
+ begin
115
+ SystemTimer.enable_debug
116
+ SystemTimer.disable_debug
117
+ assert_equal false, SystemTimer.debug_enabled?
118
+ ensure
119
+ SystemTimer.disable_debug
120
+ end
121
+ end
122
+
123
+ test "timeout offers an API fully compatible with timeout.rb" do
124
+ assert_raises(Timeout::Error) do
125
+ SystemTimer.timeout(1) {sleep 5}
126
+ end
127
+ end
128
+
129
+ # Disable this test as it is failing on Ubuntu. The problem is that
130
+ # for some reason M.R.I 1.8 is trapping the Ruby signals at the
131
+ # time the system SIGALRM is delivered, hence we do not timeout as
132
+ # quickly as we should. Needs further investigation. At least the
133
+ # SIGALRM ensures that the system will schedule M.R.I. native thread.
134
+ #
135
+ #
136
+ # test "while exact timeouts cannot be guaranted the timeout should not exceed the provided timeout by 2 seconds" do
137
+ # start = Time.now
138
+ # begin
139
+ # SystemTimer.timeout_after(2) do
140
+ # open "http://www.invalid.domain.comz"
141
+ # end
142
+ # raise "should never get there"
143
+ # rescue SocketError => e
144
+ # rescue Timeout::Error => e
145
+ # end
146
+ # elapsed = Time.now - start
147
+ # assert elapsed < 4, "Got #{elapsed} s, expected 2, at most 4"
148
+ # end
149
+
150
+
151
+ test "timeout are enforced on system calls" do
152
+ assert_timeout_within(3) do
153
+ SystemTimer.timeout(3) do
154
+ sleep 30
155
+ end
156
+ end
157
+ end
158
+
159
+ test "timeout work when spawning a different thread" do
160
+ assert_timeout_within(3) do
161
+ thread = Thread.new do
162
+ SystemTimer.timeout(3) do
163
+ sleep 60
164
+ end
165
+ end
166
+ thread.join
167
+ end
168
+ end
169
+
170
+ test "can set multiple serial timers" do
171
+ 10.times do |i|
172
+ print(i) & STDOUT.flush
173
+ assert_timeout_within(1) do
174
+ SystemTimer.timeout(1) do
175
+ sleep 60
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ test "can set multiple serial timers with fractional timeout" do
182
+ 10.times do |i|
183
+ print(i) & STDOUT.flush
184
+ assert_timeout_within(0.5) do
185
+ SystemTimer.timeout(0.5) do
186
+ sleep 60
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ test "timeout work when setting concurrent timers, the first one expiring before the second one" do
193
+ first_thread = Thread.new do
194
+ assert_timeout_within(3) do
195
+ SystemTimer.timeout(3) do
196
+ sleep 60
197
+ end
198
+ end
199
+ end
200
+ second_thread = Thread.new do
201
+ assert_timeout_within(5) do
202
+ SystemTimer.timeout(5) do
203
+ sleep 60
204
+ end
205
+ end
206
+ end
207
+ first_thread.join
208
+ second_thread.join
209
+ end
210
+
211
+ test "timeout work when setting concurrent timers, the second one expiring before the first one" do
212
+
213
+ first_thread = Thread.new do
214
+ assert_timeout_within(10) do
215
+ SystemTimer.timeout(10) do
216
+ sleep 60
217
+ end
218
+ end
219
+ end
220
+ second_thread = Thread.new do
221
+ assert_timeout_within(3) do
222
+ SystemTimer.timeout(3) do
223
+ sleep 60
224
+ end
225
+ end
226
+ end
227
+ first_thread.join
228
+ second_thread.join
229
+ end
230
+
231
+ test "timeout work when setting concurrent timers with the exact same timeout" do
232
+
233
+ first_thread = Thread.new do
234
+ assert_timeout_within(2) do
235
+ SystemTimer.timeout(2) do
236
+ sleep 60
237
+ end
238
+ end
239
+ end
240
+ second_thread = Thread.new do
241
+ assert_timeout_within(2) do
242
+ SystemTimer.timeout(2) do
243
+ sleep 60
244
+ end
245
+ end
246
+ end
247
+ first_thread.join
248
+ second_thread.join
249
+ end
250
+
251
+ test "timeout works with random concurrent timers dynamics" do
252
+ all_threads = []
253
+
254
+ 10.times do
255
+ a_timeout = [1, (rand(10)).to_f].max
256
+ all_threads << Thread.new do
257
+ assert_timeout_within(a_timeout, 10) do
258
+ SystemTimer.timeout(a_timeout) do
259
+ sleep 180
260
+ end
261
+ end
262
+ end
263
+ end
264
+
265
+ all_threads.each {|t| t.join}
266
+ end
267
+
268
+ def assert_timeout_within(expected_timeout_in_seconds,
269
+ error_margin = DEFAULT_ERROR_MARGIN,
270
+ &block)
271
+ start = Time.now
272
+ yield
273
+ flunk "Did not timeout as expected!"
274
+ rescue Timeout::Error
275
+ elapsed = Time.now - start
276
+ assert elapsed >= expected_timeout_in_seconds,
277
+ "Timed out too early, expected #{expected_timeout_in_seconds}, got #{elapsed} s"
278
+ assert elapsed < (expected_timeout_in_seconds + error_margin),
279
+ "Timed out after #{elapsed} seconds, expected #{expected_timeout_in_seconds}"
280
+ end
281
+
282
+ end
@@ -0,0 +1,110 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ unit_tests do
4
+
5
+ test "timeout_after registers a new timer in the timer pool" do
6
+ pool = stub_everything
7
+ Thread.stubs(:current).returns(:the_current_thread)
8
+ SystemTimer.stubs(:timer_pool).returns(pool)
9
+ SystemTimer.stubs(:install_next_timer)
10
+ SystemTimer.stubs(:restore_original_configuration)
11
+
12
+ pool.expects(:add_timer).with(5, nil).returns(stub_everything)
13
+ SystemTimer.timeout_after(5) {}
14
+ end
15
+
16
+ test "timeout_after registers a new timer with a custom timeout exception in the timer pool" do
17
+ MyCustomException = Class.new(Exception)
18
+ pool = stub_everything
19
+ Thread.stubs(:current).returns(:the_current_thread)
20
+ SystemTimer.stubs(:timer_pool).returns(pool)
21
+ SystemTimer.stubs(:install_next_timer)
22
+ SystemTimer.stubs(:restore_original_configuration)
23
+
24
+ pool.expects(:add_timer).with(5, MyCustomException).returns(stub_everything)
25
+ SystemTimer.timeout_after(5, MyCustomException) {}
26
+ end
27
+
28
+ test "timeout_after installs a system timer saving the previous " +
29
+ "configuration when there is only one timer" do
30
+
31
+ now = Time.now
32
+ Time.stubs(:now).returns(now)
33
+ SystemTimer.stubs(:restore_original_configuration)
34
+ SystemTimer.expects(:install_first_timer_and_save_original_configuration) \
35
+ .with {|value| value.between?(23.99, 24.01) }
36
+ SystemTimer.timeout_after(24) {}
37
+ end
38
+
39
+ test "timeout_after installs a system timer without saving the previous " +
40
+ "configuration when there is more than one timer" do
41
+
42
+ now = Time.now
43
+ Time.stubs(:now).returns(now)
44
+ SystemTimer.timer_pool.register_timer now.to_f + 100, :a_thread
45
+ SystemTimer.stubs(:restore_original_configuration)
46
+ SystemTimer.stubs(:install_next_timer)
47
+
48
+ SystemTimer.expects(:install_next_timer) \
49
+ .with {|value| value.between?(23.99, 24.01) }
50
+ SystemTimer.timeout_after(24) {}
51
+ end
52
+
53
+ test "timeout_after installs a system timer with the interval before " +
54
+ "the next timer to expire" do
55
+
56
+ now = Time.now
57
+ Time.stubs(:now).returns(now)
58
+ SystemTimer.timer_pool.register_timer now.to_f + 24, :a_thread
59
+ SystemTimer.stubs(:restore_original_configuration)
60
+ SystemTimer.stubs(:install_next_timer)
61
+
62
+ SystemTimer.expects(:install_next_timer) \
63
+ .with {|value| value.between?(23.99, 24.01) }
64
+ SystemTimer.timeout_after(100) {}
65
+ end
66
+
67
+ test "timeout_after cancels the timer when the block completes without " +
68
+ "timeout" do
69
+
70
+ now = Time.now
71
+ the_timer = stub_everything
72
+ Time.stubs(:now).returns(now)
73
+ SystemTimer.stubs(:restore_original_configuration)
74
+ SystemTimer.stubs(:install_first_timer_and_save_original_configuration)
75
+ SystemTimer.timer_pool.stubs(:add_timer).returns(the_timer)
76
+ SystemTimer.timer_pool.stubs(:first_timer?).returns(true)
77
+
78
+ SystemTimer.timer_pool.expects(:cancel).with(the_timer)
79
+ SystemTimer.timeout_after(24) {}
80
+ end
81
+
82
+ test "debug does not output to stdout when debug is disabled" do
83
+ SystemTimer.stubs(:debug_enabled?).returns(false)
84
+ original_stdout = $stdout
85
+ begin
86
+ stdout = StringIO.new
87
+ $stdout = stdout
88
+
89
+ SystemTimer.send :debug, "a log message"
90
+ assert stdout.string.empty?
91
+ ensure
92
+ $stdout = original_stdout
93
+ end
94
+ end
95
+
96
+ test "debug logs messaget to stdout when debug is enabled" do
97
+ SystemTimer.stubs(:debug_enabled?).returns(true)
98
+ original_stdout = $stdout
99
+ begin
100
+ stdout = StringIO.new
101
+ $stdout = stdout
102
+
103
+ SystemTimer.send :debug, "a log message"
104
+ assert_match /a log message/, stdout.string
105
+ ensure
106
+ $stdout = original_stdout
107
+ end
108
+ end
109
+
110
+ end
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__) + '/../lib'
2
+ $:.unshift File.dirname(__FILE__) + '/../ext/system_timer'
3
+ $: << File.dirname(__FILE__) + "/../vendor/gems/dust-0.1.6/lib"
4
+ $: << File.dirname(__FILE__) + "/../vendor/gems/mocha-0.9.1/lib"
5
+ require 'test/unit'
6
+ require 'dust'
7
+ require 'mocha'
8
+ require 'stringio'
9
+ require "open-uri"
10
+ require 'system_timer'
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ghazel-SystemTimer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Philippe Hanrigou
8
+ - David Vollbracht
9
+ autorequire: system_timer
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-12-10 00:00:00 +00:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description:
18
+ email:
19
+ executables: []
20
+
21
+ extensions:
22
+ - ext/system_timer/extconf.rb
23
+ extra_rdoc_files:
24
+ - README
25
+ files:
26
+ - COPYING
27
+ - LICENSE
28
+ - ChangeLog
29
+ - ext/system_timer/system_timer_native.c
30
+ - ext/system_timer/extconf.rb
31
+ - lib/system_timer_stub.rb
32
+ - lib/system_timer/concurrent_timer_pool.rb
33
+ - lib/system_timer/thread_timer.rb
34
+ - lib/system_timer.rb
35
+ - test/all_tests.rb
36
+ - test/system_timer_unit_test.rb
37
+ - test/system_timer_functional_test.rb
38
+ - test/system_timer/concurrent_timer_pool_unit_test.rb
39
+ - test/system_timer/thread_timer_test.rb
40
+ - test/test_helper.rb
41
+ - README
42
+ has_rdoc: true
43
+ homepage:
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --title
49
+ - SystemTimer
50
+ - --main
51
+ - README
52
+ - --line-numbers
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: systemtimer
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Set a Timeout based on signals, which are more reliable than Timeout. Timeout is based on green threads.
74
+ test_files:
75
+ - test/all_tests.rb