sidekiq-spy 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/CHANGELOG.md +27 -0
- data/README.md +17 -12
- data/lib/sidekiq-spy.rb +6 -0
- data/lib/sidekiq-spy/app.rb +49 -12
- data/lib/sidekiq-spy/display/panel.rb +10 -1
- data/lib/sidekiq-spy/display/panels/header.rb +25 -0
- data/lib/sidekiq-spy/display/panels/redis_stats.rb +37 -0
- data/lib/sidekiq-spy/display/panels/sidekiq_stats.rb +33 -0
- data/lib/sidekiq-spy/display/panels/workers.rb +50 -0
- data/lib/sidekiq-spy/display/screen.rb +12 -47
- data/lib/sidekiq-spy/display/subpanel.rb +15 -7
- data/lib/sidekiq-spy/spy/stats.rb +1 -1
- data/lib/sidekiq-spy/spy/workers.rb +35 -0
- data/lib/sidekiq-spy/translatable.rb +7 -4
- data/lib/sidekiq-spy/version.rb +1 -1
- data/sidekiq-spy.gemspec +1 -2
- data/test/helper.rb +1 -5
- data/test/sidekiq-spy/app_test.rb +149 -3
- data/test/sidekiq-spy/config_test.rb +0 -92
- data/test/sidekiq-spy/display/panel_test.rb +161 -0
- data/test/sidekiq-spy/display/screen_test.rb +98 -0
- data/test/sidekiq-spy/display/subpanel_test.rb +186 -0
- data/test/sidekiq-spy/spy/stats_test.rb +23 -36
- data/test/sidekiq-spy/spy/workers_test.rb +81 -0
- data/test/sidekiq-spy/translatable_test.rb +18 -0
- metadata +24 -8
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.expand_path('../../../helper', __FILE__)
|
2
|
+
|
3
|
+
require File.expand_path('../../../../lib/sidekiq-spy/display/screen', __FILE__)
|
4
|
+
|
5
|
+
|
6
|
+
module SidekiqSpy
|
7
|
+
module Display
|
8
|
+
module Panels
|
9
|
+
class Header; end
|
10
|
+
class RedisStats; end
|
11
|
+
class SidekiqStats; end
|
12
|
+
class Workers; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
describe SidekiqSpy::Display::Screen do
|
19
|
+
|
20
|
+
before do
|
21
|
+
Object.send(:remove_const, :Curses) if Object.constants.include?(:Curses)
|
22
|
+
|
23
|
+
Curses = stub(
|
24
|
+
:init_screen => nil,
|
25
|
+
:close_screen => nil,
|
26
|
+
:nl => nil,
|
27
|
+
:noecho => nil,
|
28
|
+
:curs_set => nil,
|
29
|
+
:timeout= => nil,
|
30
|
+
:lines => 24,
|
31
|
+
:cols => 80
|
32
|
+
)
|
33
|
+
|
34
|
+
@panel = stub(
|
35
|
+
:close => nil
|
36
|
+
)
|
37
|
+
|
38
|
+
SidekiqSpy::Display::Panels::Header.stubs(:new).returns(@panel)
|
39
|
+
SidekiqSpy::Display::Panels::RedisStats.stubs(:new).returns(@panel)
|
40
|
+
SidekiqSpy::Display::Panels::SidekiqStats.stubs(:new).returns(@panel)
|
41
|
+
SidekiqSpy::Display::Panels::Workers.stubs(:new).returns(@panel)
|
42
|
+
|
43
|
+
@screen = SidekiqSpy::Display::Screen.new
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#initialize" do
|
47
|
+
it "inits screen" do
|
48
|
+
Curses.expects(:init_screen)
|
49
|
+
|
50
|
+
SidekiqSpy::Display::Screen.new
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sets height" do
|
54
|
+
@screen.height.must_equal 24
|
55
|
+
end
|
56
|
+
|
57
|
+
it "sets width" do
|
58
|
+
@screen.width.must_equal 80
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#close" do
|
63
|
+
it "closes screen" do
|
64
|
+
Curses.expects(:close_screen)
|
65
|
+
|
66
|
+
@screen.close
|
67
|
+
end
|
68
|
+
|
69
|
+
it "closes panels" do
|
70
|
+
@panel2 = stub
|
71
|
+
@panel2.expects(:close)
|
72
|
+
|
73
|
+
@screen.instance_variable_set(:@panels, { :panel2 => @panel2 })
|
74
|
+
|
75
|
+
@screen.close
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#refresh" do
|
80
|
+
it "refreshes panels" do
|
81
|
+
@panel2 = stub
|
82
|
+
@panel2.expects(:refresh)
|
83
|
+
|
84
|
+
@screen.instance_variable_set(:@panels, { :panel2 => @panel2 })
|
85
|
+
|
86
|
+
@screen.refresh
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#next_key" do
|
91
|
+
it "gets next key" do
|
92
|
+
Curses.expects(:getch)
|
93
|
+
|
94
|
+
@screen.next_key
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require File.expand_path('../../../helper', __FILE__)
|
2
|
+
|
3
|
+
require File.expand_path('../../../../lib/sidekiq-spy/display/subpanel', __FILE__)
|
4
|
+
|
5
|
+
|
6
|
+
describe SidekiqSpy::Display::Subpanel do
|
7
|
+
|
8
|
+
describe "#initialize" do
|
9
|
+
describe "required" do
|
10
|
+
before do
|
11
|
+
@window = stub
|
12
|
+
|
13
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(@window, 24, 80, 1, 2)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sets window" do
|
17
|
+
@subpanel.instance_variable_get(:@window).must_equal @window
|
18
|
+
end
|
19
|
+
|
20
|
+
it "sets height" do
|
21
|
+
@subpanel.height.must_equal 24
|
22
|
+
end
|
23
|
+
|
24
|
+
it "sets width" do
|
25
|
+
@subpanel.width.must_equal 80
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets top" do
|
29
|
+
@subpanel.top.must_equal 1
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sets left" do
|
33
|
+
@subpanel.left.must_equal 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "defaults data" do
|
37
|
+
@subpanel.data.must_equal({
|
38
|
+
:left => '',
|
39
|
+
:right => '',
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "defaults dividers" do
|
44
|
+
@subpanel.dividers.must_equal({
|
45
|
+
:left => '',
|
46
|
+
:right => '',
|
47
|
+
})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "calculates content_width" do
|
51
|
+
@subpanel.content_width.must_equal 80
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "optional" do
|
56
|
+
before do
|
57
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(stub, 24, 80, 1, 2, {
|
58
|
+
:data_l => 'key:',
|
59
|
+
:data_r => 'value',
|
60
|
+
:divider_l => '<',
|
61
|
+
:divider_r => '/>',
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sets data" do
|
66
|
+
@subpanel.data.must_equal({
|
67
|
+
:left => 'key:',
|
68
|
+
:right => 'value',
|
69
|
+
})
|
70
|
+
end
|
71
|
+
|
72
|
+
it "sets dividers" do
|
73
|
+
@subpanel.dividers.must_equal({
|
74
|
+
:left => '<',
|
75
|
+
:right => '/>',
|
76
|
+
})
|
77
|
+
end
|
78
|
+
|
79
|
+
it "calculates content_width" do
|
80
|
+
@subpanel.content_width.must_equal 77
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#refresh" do
|
86
|
+
describe "strings and dividers" do
|
87
|
+
before do
|
88
|
+
@window = stub
|
89
|
+
|
90
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(@window, 24, 80, 1, 2, {
|
91
|
+
:data_l => 'key:',
|
92
|
+
:data_r => 'value',
|
93
|
+
:divider_l => '<-',
|
94
|
+
:divider_r => '|',
|
95
|
+
})
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "when changed" do
|
99
|
+
it "sets position" do
|
100
|
+
@window.stubs(:addstr)
|
101
|
+
|
102
|
+
@window.expects(:setpos).with(1, 2)
|
103
|
+
|
104
|
+
@subpanel.refresh
|
105
|
+
end
|
106
|
+
|
107
|
+
it "sets data" do
|
108
|
+
@window.stubs(:setpos)
|
109
|
+
|
110
|
+
@window.expects(:addstr).with("<-key: value|")
|
111
|
+
|
112
|
+
@subpanel.refresh
|
113
|
+
end
|
114
|
+
|
115
|
+
it "sets truncated data when too long" do
|
116
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(@window, 24, 10, 1, 2, {
|
117
|
+
:data_l => 'key:',
|
118
|
+
:data_r => 'value',
|
119
|
+
:divider_l => '<-',
|
120
|
+
:divider_r => '|',
|
121
|
+
})
|
122
|
+
|
123
|
+
@window.stubs(:setpos)
|
124
|
+
|
125
|
+
@window.expects(:addstr).with("<-key:val|")
|
126
|
+
|
127
|
+
@subpanel.refresh
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "when unchanged" do
|
132
|
+
before do
|
133
|
+
@window.stubs(:setpos)
|
134
|
+
@window.stubs(:addstr)
|
135
|
+
|
136
|
+
@subpanel.refresh
|
137
|
+
end
|
138
|
+
|
139
|
+
it "skips position" do
|
140
|
+
@window.expects(:setpos).never
|
141
|
+
|
142
|
+
@subpanel.refresh
|
143
|
+
end
|
144
|
+
|
145
|
+
it "skips data" do
|
146
|
+
@window.expects(:addstr).never
|
147
|
+
|
148
|
+
@subpanel.refresh
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "lambdas" do
|
154
|
+
before do
|
155
|
+
@window = stub
|
156
|
+
|
157
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(@window, 24, 80, 0, 0, {
|
158
|
+
:data_l => -> { "the answer:" },
|
159
|
+
:data_r => -> { 2 * 3 * 7 }
|
160
|
+
})
|
161
|
+
end
|
162
|
+
|
163
|
+
it "sets data when changed" do
|
164
|
+
@window.stubs(:setpos)
|
165
|
+
|
166
|
+
@window.expects(:addstr).with("the answer: 42")
|
167
|
+
|
168
|
+
@subpanel.refresh
|
169
|
+
end
|
170
|
+
|
171
|
+
it "sets empty data when nil" do
|
172
|
+
@subpanel = SidekiqSpy::Display::Subpanel.new(@window, 24, 10, 0, 0, {
|
173
|
+
:data_l => -> { nil },
|
174
|
+
:data_r => -> { nil }
|
175
|
+
})
|
176
|
+
|
177
|
+
@window.stubs(:setpos)
|
178
|
+
|
179
|
+
@window.expects(:addstr).with(" ")
|
180
|
+
|
181
|
+
@subpanel.refresh
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
@@ -11,40 +11,35 @@ describe SidekiqSpy::Spy::Stats do
|
|
11
11
|
before do
|
12
12
|
@redis = Redis::Namespace.new('resque', :redis => Redis.new)
|
13
13
|
|
14
|
+
@redis.stubs(:info).returns(JSON.parse(File.read(
|
15
|
+
File.expand_path('../../../fixtures/redis_info.json', __FILE__)
|
16
|
+
)))
|
17
|
+
|
18
|
+
@redis.client.stubs(:location).returns('da.example.com:237')
|
19
|
+
@redis.client.stubs(:db).returns(42)
|
20
|
+
|
14
21
|
Sidekiq.configure_client do |config|
|
15
22
|
config.redis = ConnectionPool.new(:size => 1, &proc { @redis })
|
16
23
|
end
|
17
24
|
|
18
|
-
|
19
|
-
:
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
Sidekiq::Stats.stubs(:new).returns(stub(
|
26
|
+
:enqueued => 16776977673,
|
27
|
+
:retry_size => 924984826746,
|
28
|
+
:scheduled_size => 317321542620,
|
29
|
+
:processed => 923531545885,
|
30
|
+
:failed => 779187529140
|
31
|
+
))
|
23
32
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@sidekiq_stats.expect(:scheduled_size, 317321542620)
|
28
|
-
@sidekiq_stats.expect(:processed, 923531545885)
|
29
|
-
@sidekiq_stats.expect(:failed, 779187529140)
|
33
|
+
Sidekiq::Workers.stubs(:new).returns(stub(
|
34
|
+
:size => 162165179294
|
35
|
+
))
|
30
36
|
|
31
|
-
@
|
32
|
-
@sidekiq_workers.expect(:size, 162165179294)
|
33
|
-
|
34
|
-
Sidekiq::Stats.stub(:new, @sidekiq_stats) do
|
35
|
-
Sidekiq::Workers.stub(:new, @sidekiq_workers) do
|
36
|
-
@stats = SidekiqSpy::Spy::Stats.new
|
37
|
-
end
|
38
|
-
end
|
37
|
+
@stats = SidekiqSpy::Spy::Stats.new
|
39
38
|
end
|
40
39
|
|
41
40
|
describe "#connection" do
|
42
41
|
it "returns stat connection" do
|
43
|
-
@
|
44
|
-
@redis.client.stub(:db, 42) do
|
45
|
-
@stats.connection.must_equal 'da.example.com:237/42'
|
46
|
-
end
|
47
|
-
end
|
42
|
+
@stats.connection.must_equal 'da.example.com:237/42'
|
48
43
|
end
|
49
44
|
end
|
50
45
|
|
@@ -56,33 +51,25 @@ describe SidekiqSpy::Spy::Stats do
|
|
56
51
|
|
57
52
|
describe "#uptime" do
|
58
53
|
it "returns stat uptime" do
|
59
|
-
@
|
60
|
-
@stats.uptime.must_equal '7'
|
61
|
-
end
|
54
|
+
@stats.uptime.must_equal '7'
|
62
55
|
end
|
63
56
|
end
|
64
57
|
|
65
58
|
describe "#connections" do
|
66
59
|
it "returns stat connections" do
|
67
|
-
@
|
68
|
-
@stats.connections.must_equal '8'
|
69
|
-
end
|
60
|
+
@stats.connections.must_equal '8'
|
70
61
|
end
|
71
62
|
end
|
72
63
|
|
73
64
|
describe "#memory" do
|
74
65
|
it "returns stat memory" do
|
75
|
-
@
|
76
|
-
@stats.memory.must_equal '5.16M'
|
77
|
-
end
|
66
|
+
@stats.memory.must_equal '5.16M'
|
78
67
|
end
|
79
68
|
end
|
80
69
|
|
81
70
|
describe "#memory_peak" do
|
82
71
|
it "returns stat memory_peak" do
|
83
|
-
@
|
84
|
-
@stats.memory_peak.must_equal '5.14M'
|
85
|
-
end
|
72
|
+
@stats.memory_peak.must_equal '5.14M'
|
86
73
|
end
|
87
74
|
end
|
88
75
|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
|
4
|
+
require File.expand_path('../../../helper', __FILE__)
|
5
|
+
|
6
|
+
require File.expand_path('../../../../lib/sidekiq-spy/spy/workers', __FILE__)
|
7
|
+
|
8
|
+
|
9
|
+
describe SidekiqSpy::Spy::Workers do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@sidekiq_workers_data = {
|
13
|
+
'worker1' => {
|
14
|
+
'queue' => 'Q',
|
15
|
+
'run_at' => 11202710605,
|
16
|
+
'payload' => {
|
17
|
+
'class' => 'Geometry',
|
18
|
+
'args' => ['Euclid', 360],
|
19
|
+
}
|
20
|
+
},
|
21
|
+
}
|
22
|
+
|
23
|
+
@spy_workers_data = {
|
24
|
+
'worker1' => {
|
25
|
+
:name => 'worker1',
|
26
|
+
:queue => 'Q',
|
27
|
+
:class => 'Geometry',
|
28
|
+
:args => ['Euclid', 360],
|
29
|
+
:started_at => Time.parse('2325-01-01 00:03:25 +0000')
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
@sidekiq_workers_data2 = {
|
34
|
+
'worker2' => {
|
35
|
+
'queue' => 'Queueueue',
|
36
|
+
'run_at' => -1316908800,
|
37
|
+
'payload' => {
|
38
|
+
'class' => 'Elements',
|
39
|
+
'args' => ['Lehrer', 102],
|
40
|
+
}
|
41
|
+
},
|
42
|
+
}
|
43
|
+
|
44
|
+
@spy_workers_data2 = {
|
45
|
+
'worker2' => {
|
46
|
+
:name => 'worker2',
|
47
|
+
:queue => 'Queueueue',
|
48
|
+
:class => 'Elements',
|
49
|
+
:args => ['Lehrer', 102],
|
50
|
+
:started_at => Time.parse('1928-04-09 00:00:00 +0000')
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
Sidekiq::Workers.stubs(:new).returns(@sidekiq_workers_data)
|
55
|
+
|
56
|
+
@workers = SidekiqSpy::Spy::Workers.new
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#initialize" do
|
60
|
+
it "sets data list of workers" do
|
61
|
+
@workers.data.must_equal(@spy_workers_data)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#refresh" do
|
66
|
+
it "doesn't refresh if not called" do
|
67
|
+
@sidekiq_workers_data.merge!(@sidekiq_workers_data2)
|
68
|
+
|
69
|
+
@workers.data.must_equal(@spy_workers_data)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "refreshes if called" do
|
73
|
+
@sidekiq_workers_data.merge!(@sidekiq_workers_data2)
|
74
|
+
|
75
|
+
@workers.refresh
|
76
|
+
|
77
|
+
@workers.data.must_equal(@spy_workers_data.merge(@spy_workers_data2))
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|