Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 260 lines (226 sloc) 7.104 kb
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
1 require 'spec_helper'
2
4ab18ac @qrush rename data to summaries
qrush authored
3 describe Daikon::Monitor, ".pop without summaries" do
4 it "clears out current summaries" do
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
5 Daikon::Monitor.pop do |summary|
6 summary["commands"].size.should be_zero
7 summary["totals"].size.should be_zero
8 summary["keys"].size.should be_zero
9 end
10 end
11 end
12
4ab18ac @qrush rename data to summaries
qrush authored
13 describe Daikon::Monitor, ".pop with summaries" do
cfa5b38 @qrush Move to new api format
qrush authored
14 before do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
15 parse("INCR foo")
16 parse("DECR foo")
17 parse("DECR baz")
18 parse("HGETALL faz")
19 parse("PING")
cfa5b38 @qrush Move to new api format
qrush authored
20 end
21
9b548f3 @qrush Send only the top 100 key listings
qrush authored
22 it "only saves the top 100 key listings" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
23 150.times { |n| parse("INCR foo#{n}") }
24 150.times { |n| parse("DECR foo#{n}") }
25 100.times { |n| parse("DEL foo#{n}") }
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
26
27 Daikon::Monitor.pop do |summary|
28 summary["keys"].size.should == 100
29 summary["keys"].values.all? { |n| n == 3 }.should be_true
30 end
9b548f3 @qrush Send only the top 100 key listings
qrush authored
31 end
32
a0a3183 @qrush Sanitize key names since BSON sucks
qrush authored
33 it "santizes key names" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
34 parse("INCR $foo.zomg")
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
35
36 Daikon::Monitor.pop do |summary|
37 summary["keys"]["$foo.zomg"].should be_nil
38 summary["keys"]["{DOLLAR}foo{PERIOD}zomg"].should == 1
39 end
a0a3183 @qrush Sanitize key names since BSON sucks
qrush authored
40 end
41
cfa5b38 @qrush Move to new api format
qrush authored
42 it "increments each command type" do
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
43 Daikon::Monitor.pop do |summary|
44 summary["commands"]["INCR"].should == 1
45 summary["commands"]["DECR"].should == 2
46 end
cfa5b38 @qrush Move to new api format
qrush authored
47 end
48
49 it "keeps track of key accesses" do
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
50 Daikon::Monitor.pop do |summary|
51 summary["keys"]["foo"].should == 2
52 summary["keys"]["baz"].should == 1
53 end
cfa5b38 @qrush Move to new api format
qrush authored
54 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
55
cfa5b38 @qrush Move to new api format
qrush authored
56 it "tallies up totals of commands" do
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
57 Daikon::Monitor.pop do |summary|
58 summary["totals"]["all"].should == 5
59 summary["totals"]["read"].should == 1
60 summary["totals"]["write"].should == 3
61 summary["totals"]["other"].should == 1
62 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
63 end
64 end
65
66 describe Daikon::Monitor, "#parse with new format" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
67 before do
68 parse('1291699658.994073 "decrby" "fooz" "2000"')
69 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
70
71 it "parses the log into json" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
72 Daikon::Monitor.pop do |summary|
73 summary["commands"]["DECRBY"].should == 1
74 summary["keys"]["fooz"].should == 1
75 summary["totals"]["all"].should == 1
76 summary["totals"]["write"].should == 1
77 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
78 end
79 end
80
82b1ce5 @qrush Cover reply byte in new format
qrush authored
81 describe Daikon::Monitor, "#parse with new format that has reply byte" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
82 before do
83 parse('+1291699658.994073 "decrby" "fooz" "2000"')
84 end
82b1ce5 @qrush Cover reply byte in new format
qrush authored
85
86 it "parses the log into json" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
87 Daikon::Monitor.pop do |summary|
88 summary["commands"]["DECRBY"].should == 1
89 summary["keys"]["fooz"].should == 1
90 summary["totals"]["all"].should == 1
91 summary["totals"]["write"].should == 1
92 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
93 end
94 end
95
96 describe Daikon::Monitor, "#parse with old multi line input" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
97 before do
98 parse("incr foo")
99 parse("sismember project-13897-global-error-classes 17")
100 parse("incrApiParameterError")
101 parse("decr foo")
102 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
103
cfa5b38 @qrush Move to new api format
qrush authored
104 it "parses logs" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
105 Daikon::Monitor.pop do |summary|
d0b3135 @qrush base Monitor#summaries off the current time as buckets
qrush authored
106 summary["commands"]["DECR"].should == 1
107 summary["commands"]["INCR"].should == 1
108 summary["commands"]["SISMEMBER"].should == 1
109 summary["keys"]["foo"].should == 2
110 summary["keys"]["project-13897-global-error-classes"].should == 1
111 summary["totals"]["all"].should == 3
112 summary["totals"]["write"].should == 2
113 summary["totals"]["read"].should == 1
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
114 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
115 end
116 end
117
cfa5b38 @qrush Move to new api format
qrush authored
118 describe Daikon::Monitor, "#parse with old input" do
119 shared_examples_for "a valid parser" do
120 it "parses the given commands properly" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
121 Daikon::Monitor.pop do |summary|
d0b3135 @qrush base Monitor#summaries off the current time as buckets
qrush authored
122 summary["commands"]["DECR"].should == 1
123 summary["commands"]["INCR"].should == 1
124 summary["commands"]["SET"].should == 1
125 summary["keys"]["foo"].should == 2
126 summary["keys"]["g:2470920:mrn"].should == 1
127 summary["totals"]["all"].should == 3
128 summary["totals"]["write"].should == 3
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
129 end
cfa5b38 @qrush Move to new api format
qrush authored
130 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
131 end
132
cfa5b38 @qrush Move to new api format
qrush authored
133 context "with a bulk input that is a number" do
134 before do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
135 parse("incr foo")
136 parse("set g:2470920:mrn 9")
137 parse("554079885")
138 parse("decr foo")
cfa5b38 @qrush Move to new api format
qrush authored
139 end
140 it_should_behave_like "a valid parser"
141 end
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
142
cfa5b38 @qrush Move to new api format
qrush authored
143 context "with a bulk input that is a number" do
144 before do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
145 parse("incr foo")
146 parse("set g:2470920:mrn 9")
147 parse("46fdcf77c1bb2108e6191602c2f5f9ae")
148 parse("decr foo")
cfa5b38 @qrush Move to new api format
qrush authored
149 end
150 it_should_behave_like "a valid parser"
3d29ed5 @qrush Move to json monitor api, split out monitor to its own class and do pars...
qrush authored
151 end
152 end
4e69f22 @qrush Commands must be in the set of all commands to be submitted
qrush authored
153
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
154 describe Daikon::Monitor, "#parse with a bad command name" do
155 it "does not save command" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
156 parse("gmail foo")
157 Daikon::Monitor.pop do |summary|
158 summary["commands"].size.should be_zero
159 end
4e69f22 @qrush Commands must be in the set of all commands to be submitted
qrush authored
160 end
161 end
d9e923d @qrush Start collecting namespaces
qrush authored
162
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
163 describe Daikon::Monitor, "#parse with namespaces" do
d9e923d @qrush Start collecting namespaces
qrush authored
164 before do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
165 parse("set g:2470920:mrn 9")
166 parse("get g:2470914:mrn")
167 parse("incr s3-queue-key")
168 parse("info")
169 parse("decr somehorriblynamespacedkey")
170 parse("flushdb")
d9e923d @qrush Start collecting namespaces
qrush authored
171 end
172
173 it "keeps track of namespace accesses" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
174 Daikon::Monitor.pop do |summary|
175 summary["namespaces"]["g"].should == 2
176 summary["namespaces"]["global"].should == 3
177 summary["namespaces"]["s3"].should == 1
178 end
d9e923d @qrush Start collecting namespaces
qrush authored
179 end
180 end
f559eb9 @qrush make sure the command is valid before incrementing anything
qrush authored
181
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
182 describe Daikon::Monitor, "#parse with values that have spaces" do
f559eb9 @qrush make sure the command is valid before incrementing anything
qrush authored
183 before do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
184 parse("set g:2470920:mrn 11")
185 parse("Email Error")
f559eb9 @qrush make sure the command is valid before incrementing anything
qrush authored
186 end
187
68d88f9 @qrush extract rotating out to Monitor#pop
qrush authored
188 it "counts them properly" do
4d9be85 @qrush refactor Monitor#parse to happen at an instance level
qrush authored
189 Daikon::Monitor.pop do |summary|
190 summary["commands"].should == {"SET" => 1}
191 summary["keys"].should == {"g:2470920:mrn" => 1}
192 summary["namespaces"].should == {"g" => 1}
193 end
f559eb9 @qrush make sure the command is valid before incrementing anything
qrush authored
194 end
195 end
d0b3135 @qrush base Monitor#summaries off the current time as buckets
qrush authored
196
197 describe Daikon::Monitor, "#parse over several minutes keeps several minutes of data" do
198 before do
199 Timecop.freeze(Time.at(Time.now - 179)) do
200 parse("INCR foo")
201 end
202
203 Timecop.freeze(Time.at(Time.now - 119)) do
204 parse("DECR foo")
205 end
206
207 Timecop.freeze(Time.at(Time.now - 60)) do
208 parse("INCR foo")
209 end
210 end
211
212 it "separates each into a separate minute" do
213 Daikon::Monitor.pop do |summary|
214 summary["commands"].should == {"INCR" => 1}
215 summary["keys"].should == {"foo" => 1}
216 end
217
218 Daikon::Monitor.pop do |summary|
219 summary["commands"].should == {"DECR" => 1}
220 summary["keys"].should == {"foo" => 1}
221 end
222
223 Daikon::Monitor.pop do |summary|
224 summary["commands"].should == {"INCR" => 1}
225 summary["keys"].should == {"foo" => 1}
226 end
227 end
228 end
b4143e0 @halogenandtoast Now with channels!
halogenandtoast authored
229
59883f0 @sikachu Fix `Daikon::Monitor` to handle log from multiple databases correctly
sikachu authored
230 describe Daikon::Monitor, "#parse multiple database log" do
231 it "parses the data correctly" do
232 parse('1304626114.869421 (db 2) "rpop" "shoppinshoppinshoppinshoppinshoppingggggshopping"')
233
234 Daikon::Monitor.pop do |summary|
235 summary["commands"].should == {"RPOP" => 1}
236 summary["keys"].should == {"shoppinshoppinshoppinshoppinshoppingggggshopping" => 1}
237 end
238 end
239 end
240
b4143e0 @halogenandtoast Now with channels!
halogenandtoast authored
241 describe Daikon::Monitor, ".start" do
242 let(:redis) { stub('redis', :monitor => true) }
243 before do
244 redis.stubs(:on).with(:monitor).yields("INCR foo")
245 end
246 it "should subscribe to monitor" do
247 Daikon::Monitor.start(redis)
248 redis.should have_received(:monitor)
249 redis.should have_received(:on).with(:monitor)
250 end
251
252 it "should parse subscription data" do
253 Daikon::Monitor.start(redis)
254 Daikon::Monitor.pop do |summary|
255 summary["commands"].should == {"INCR" => 1}
256 summary["keys"].should == {"foo" => 1 }
257 end
258 end
259 end
Something went wrong with that request. Please try again.