Update mcollective.init according to OSCI-855
[packages/precise/mcollective.git] / spec / unit / rpc / stats_spec.rb
1 #!/usr/bin/env rspec
2
3 require 'spec_helper'
4
5 module MCollective
6   module RPC
7     describe Stats do
8       before(:each) do
9         @expected = {:discoverytime => 0,
10                      :okcount => 0,
11                      :blocktime => 0,
12                      :failcount => 0,
13                      :noresponsefrom => [],
14                      :responses => 0,
15                      :totaltime => 0,
16                      :discovered => 0,
17                      :starttime => 1300031826.0,
18                      :requestid => nil,
19                      :aggregate_summary => [],
20                      :aggregate_failures => [],
21                      :discovered_nodes => []}
22
23         @stats = Stats.new
24       end
25
26       describe "#initialize" do
27         it "should reset stats on creation" do
28           Stats.any_instance.stubs(:reset).returns(true).once
29           s = Stats.new
30         end
31       end
32
33       describe "#reset" do
34         it "should initialize data correctly" do
35           Time.stubs(:now).returns(Time.at(1300031826))
36           s = Stats.new
37
38           @expected.keys.each do |k|
39             @expected[k].should == s.send(k)
40           end
41         end
42       end
43
44       describe "#to_hash" do
45         it "should return correct stats" do
46           Time.stubs(:now).returns(Time.at(1300031826))
47           s = Stats.new
48
49           s.to_hash.should == @expected
50         end
51       end
52
53       describe "#[]" do
54         it "should return stat values" do
55           Time.stubs(:now).returns(Time.at(1300031826))
56           s = Stats.new
57
58           @expected.keys.each do |k|
59             @expected[k].should == s[k]
60           end
61         end
62
63         it "should return nil for unknown values" do
64           @stats["foo"].should == nil
65         end
66       end
67
68       describe "#ok" do
69         it "should increment stats" do
70           @stats.ok
71           @stats[:okcount].should == 1
72         end
73       end
74
75       describe "#fail" do
76         it "should increment stats" do
77           @stats.fail
78           @stats.failcount.should == 1
79         end
80       end
81
82       describe "#time_discovery" do
83         it "should set start time correctly" do
84           Time.stubs(:now).returns(Time.at(1300031826))
85
86           @stats.time_discovery(:start)
87
88           @stats.instance_variable_get("@discovery_start").should == 1300031826.0
89         end
90
91         it "should record the difference correctly" do
92           Time.stubs(:now).returns(Time.at(1300031826))
93           @stats.time_discovery(:start)
94
95           Time.stubs(:now).returns(Time.at(1300031827))
96           @stats.time_discovery(:end)
97
98           @stats.discoverytime.should == 1.0
99         end
100
101         it "should handle unknown actions and set discovery time to 0" do
102           Time.stubs(:now).returns(Time.at(1300031826))
103           @stats.time_discovery(:start)
104
105           Time.stubs(:now).returns(Time.at(1300031827))
106           @stats.time_discovery(:stop)
107
108           @stats.discoverytime.should == 0
109         end
110
111       end
112
113       describe "#client_stats=" do
114         it "should store stats correctly" do
115           data = {}
116           keys = [:noresponsefrom, :responses, :starttime, :blocktime, :totaltime, :discoverytime]
117           keys.each {|k| data[k] = k}
118
119           @stats.client_stats = data
120
121           keys.each do |k|
122             @stats[k].should == data[k]
123           end
124         end
125
126         it "should not store discovery time if it was already stored" do
127           data = {}
128           keys = [:noresponsefrom, :responses, :starttime, :blocktime, :totaltime, :discoverytime]
129           keys.each {|k| data[k] = k}
130
131           Time.stubs(:now).returns(Time.at(1300031826))
132           @stats.time_discovery(:start)
133
134           Time.stubs(:now).returns(Time.at(1300031827))
135           @stats.time_discovery(:end)
136
137           dtime = @stats.discoverytime
138
139           @stats.client_stats = data
140
141           @stats.discoverytime.should == dtime
142         end
143       end
144
145       describe "#time_block_execution" do
146         it "should set start time correctly" do
147           Time.stubs(:now).returns(Time.at(1300031826))
148
149           @stats.time_block_execution(:start)
150
151           @stats.instance_variable_get("@block_start").should == 1300031826.0
152         end
153
154         it "should record the difference correctly" do
155           Time.stubs(:now).returns(Time.at(1300031826))
156           @stats.time_block_execution(:start)
157
158           Time.stubs(:now).returns(Time.at(1300031827))
159           @stats.time_block_execution(:end)
160
161           @stats.blocktime.should == 1
162         end
163
164         it "should handle unknown actions and set discovery time to 0" do
165           Time.stubs(:now).returns(Time.at(1300031826))
166           @stats.time_block_execution(:start)
167
168           Time.stubs(:now).returns(Time.at(1300031827))
169           @stats.time_block_execution(:stop)
170
171           @stats.blocktime.should == 0
172         end
173       end
174
175       describe "#discovered_agents" do
176         it "should set discovered_nodes" do
177           nodes = ["one", "two"]
178           @stats.discovered_agents(nodes)
179           @stats.discovered_nodes.should == nodes
180         end
181
182         it "should set discovered count" do
183           nodes = ["one", "two"]
184           @stats.discovered_agents(nodes)
185           @stats.discovered.should == 2
186         end
187       end
188
189       describe "#finish_request" do
190         it "should calculate totaltime correctly" do
191           Time.stubs(:now).returns(Time.at(1300031824))
192           @stats.time_discovery(:start)
193
194           Time.stubs(:now).returns(Time.at(1300031825))
195           @stats.time_discovery(:end)
196
197           Time.stubs(:now).returns(Time.at(1300031826))
198           @stats.time_block_execution(:start)
199
200           Time.stubs(:now).returns(Time.at(1300031827))
201           @stats.time_block_execution(:end)
202
203           @stats.discovered_agents(["one", "two", "three"])
204           @stats.node_responded("one")
205           @stats.node_responded("two")
206
207           @stats.finish_request
208
209           @stats.totaltime.should == 2
210         end
211
212         it "should calculate no responses correctly" do
213           Time.stubs(:now).returns(Time.at(1300031824))
214           @stats.time_discovery(:start)
215
216           Time.stubs(:now).returns(Time.at(1300031825))
217           @stats.time_discovery(:end)
218
219           Time.stubs(:now).returns(Time.at(1300031826))
220           @stats.time_block_execution(:start)
221
222           Time.stubs(:now).returns(Time.at(1300031827))
223           @stats.time_block_execution(:end)
224
225           @stats.discovered_agents(["one", "two", "three"])
226           @stats.node_responded("one")
227           @stats.node_responded("two")
228
229           @stats.finish_request
230
231           @stats.noresponsefrom.should == ["three"]
232         end
233
234         it "should recover from failure correctly" do
235           Time.stubs(:now).returns(Time.at(1300031824))
236           @stats.time_discovery(:start)
237
238           Time.stubs(:now).returns(Time.at(1300031825))
239           @stats.time_discovery(:end)
240
241           Time.stubs(:now).returns(Time.at(1300031826))
242           @stats.time_block_execution(:start)
243
244           Time.stubs(:now).returns(Time.at(1300031827))
245           @stats.time_block_execution(:end)
246
247           # cause the .each to raise an exception
248           @stats.instance_variable_set("@responsesfrom", nil)
249           @stats.finish_request
250
251           @stats.noresponsefrom.should == []
252           @stats.totaltime.should == 0
253         end
254       end
255
256       describe "#node_responded" do
257         it "should append to the list of nodes" do
258           @stats.node_responded "foo"
259           @stats.responsesfrom.should == ["foo"]
260         end
261
262         it "should create a new array if adding fails" do
263           # cause the << to fail
264           @stats.instance_variable_set("@responsesfrom", nil)
265
266           @stats.node_responded "foo"
267           @stats.responsesfrom.should == ["foo"]
268         end
269       end
270
271       describe "#no_response_report" do
272         it "should create an empty report if all nodes responded" do
273           @stats.discovered_agents ["foo"]
274           @stats.node_responded "foo"
275           @stats.finish_request
276
277           @stats.no_response_report.should == ""
278         end
279
280         it "should list all nodes that did not respond" do
281           @stats.discovered_agents ["foo", "bar"]
282           @stats.finish_request
283
284           @stats.no_response_report.should match(Regexp.new(/No response from.+bar\s+foo/m))
285         end
286       end
287
288       describe "#text_for_aggregates" do
289         let(:aggregate){mock()}
290
291         before :each do
292           aggregate.stubs(:result).returns({:output => "success"})
293           aggregate.stubs(:action).returns("action")
294         end
295
296         it "should create the correct output text for aggregate functions" do
297           @stats.aggregate_summary = [aggregate]
298           aggregate.stubs(:is_a?).returns(true)
299           @stats.text_for_aggregates.should =~ /Summary of.*/
300         end
301
302         it "should display an error message for a failed statup hook" do
303           @stats.aggregate_failures = [{:name => "rspec", :type => :startup}]
304           @stats.text_for_aggregates.should =~  /exception raised while processing startup hook/
305         end
306
307         it "should display an error message for an unspecified output" do
308           @stats.aggregate_failures = [{:name => "rspec", :type => :create}]
309           @stats.text_for_aggregates.should =~  /unspecified output 'rspec' for the action/
310         end
311
312         it "should display an error message for a failed process_result" do
313           @stats.aggregate_failures = [{:name => "rspec", :type => :process_result}]
314           @stats.text_for_aggregates.should =~  /exception raised while processing result data/
315         end
316
317         it "should display an error message for a failed summarize" do
318           @stats.aggregate_failures = [{:name => "rspec", :type => :summarize}]
319           @stats.text_for_aggregates.should =~  /exception raised while summarizing/
320         end
321       end
322     end
323   end
324 end