Skip to content

Commit 2a2748f

Browse files
committed
improve informer test
1 parent 3891b99 commit 2a2748f

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

lib/kubeclient/informer.rb

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def initialize(client, resource_name, reconcile_timeout: 15 * 60, logger: nil)
88
@logger = logger
99
@cache = nil
1010
@started = nil
11+
@stopped = false
1112
@watching = []
1213
end
1314

@@ -21,22 +22,37 @@ def watch(&block)
2122

2223
# not implicit so users know they have to `stop`
2324
def start_worker
25+
@stopped = false
2426
@worker = Thread.new do
2527
loop do
26-
fill_cache
27-
watch_to_update_cache
28-
rescue StandardError => e
29-
# need to keep retrying since we work in the background
30-
@logger&.error("ignoring error during background work #{e}")
31-
ensure
32-
sleep(1) # do not overwhelm the api-server if we are somehow broken
28+
puts('LOOP')
29+
begin
30+
fill_cache
31+
watch_to_update_cache
32+
rescue StandardError => e
33+
# need to keep retrying since we work in the background
34+
@logger&.error("ignoring error during background work #{e}")
35+
ensure
36+
puts('SLEEP')
37+
sleep(1) # do not overwhelm the api-server if we are somehow broken
38+
end
39+
break if @stopped
3340
end
3441
end
35-
sleep(0.01) until @cache
42+
sleep(0.01) until @cache || @stopped
3643
end
3744

3845
def stop_worker
39-
@worker&.kill # TODO: be nicer ?
46+
puts('STOP')
47+
@stopped = true
48+
[@waiter, @worker].compact.each do |thread|
49+
begin
50+
thread.run # cancel sleep so either the loop sleep or the timeout sleep are interrupted
51+
rescue ThreadError
52+
# thread was already dead
53+
end
54+
thread.join
55+
end
4056
end
4157

4258
private
@@ -69,9 +85,11 @@ def watch_to_update_cache
6985
stop_reason = 'disconnect'
7086

7187
# stop watcher without using timeout
72-
Thread.new do
88+
@waiter = Thread.new do
89+
puts('HEY I started')
7390
sleep(@reconcile_timeout)
7491
stop_reason = 'reconcile'
92+
puts('HEY I FINISHED')
7593
@watcher.finish
7694
end
7795

@@ -87,7 +105,18 @@ def watch_to_update_cache
87105
end
88106
@watching.each { |q| q << notice }
89107
end
108+
puts('HEY I watched')
90109
@logger&.info("watch restarted: #{stop_reason}")
110+
111+
# wake the waiter unless it's dead so it does not hang around
112+
begin
113+
@waiter.run
114+
rescue ThreadError # rubocop:disable Lint/SuppressedException
115+
end
116+
@waiter.join
117+
rescue Exception # rubocop:disable Lint/RescueException
118+
puts("KABOOM--#{$!}") # rubocop:disable Style/SpecialGlobalVars
119+
raise
91120
end
92121
end
93122
end

test/test_informer.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
require 'stringio'
55
require 'logger'
66

7-
# tests with_retries in kubeclient.rb
8-
class RetryTest < MiniTest::Test
7+
class TestInformer < MiniTest::Test
98
def setup
109
super
1110
skip if RUBY_ENGINE == 'truffleruby' # TODO: race condition in truffle-ruby fails random tests
@@ -87,14 +86,14 @@ def test_restarts_on_error
8786
status: 200
8887
)
8988
slept = []
90-
informer.stubs(:sleep).with { |x| slept << x; sleep(0.01) }
89+
informer.stubs(:sleep).with { |x| slept << x; sleep(0.02) }
9190

9291
with_worker do
9392
assert_equal(['a'], informer.list.map { |p| p.metadata.name })
94-
sleep(0.05)
93+
sleep(0.16) # should give us 4+ restarts (each timeout is 1 sleep and 1 sleep before restart)
9594
end
9695

97-
assert slept.size >= 2, slept
96+
assert slept.size >= 4, slept
9897
assert_requested(list, at_least_times: 2)
9998
assert_requested(watch, at_least_times: 2)
10099
end
@@ -131,10 +130,14 @@ def test_can_watch_watches
131130
def test_timeout
132131
timeout = 0.1
133132
informer.instance_variable_set(:@reconcile_timeout, timeout)
134-
stub_list
133+
list = stub_list
135134
Kubeclient::Common::WatchStream.any_instance.expects(:finish)
136-
stub_request(:get, %r{/v1/watch/pods})
135+
watch = stub_request(:get, %r{/v1/watch/pods})
136+
137137
with_worker { sleep(timeout * 1.9) }
138+
139+
assert_requested(list)
140+
assert_requested(watch)
138141
end
139142

140143
private

0 commit comments

Comments
 (0)