mcollective-client 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mcollective-client might be problematic. Click here for more details.

Files changed (140) hide show
  1. data/lib/mcollective.rb +32 -23
  2. data/lib/mcollective/agent.rb +5 -0
  3. data/lib/mcollective/agents.rb +5 -16
  4. data/lib/mcollective/aggregate.rb +61 -0
  5. data/lib/mcollective/aggregate/base.rb +40 -0
  6. data/lib/mcollective/aggregate/result.rb +9 -0
  7. data/lib/mcollective/aggregate/result/base.rb +25 -0
  8. data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
  9. data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
  10. data/lib/mcollective/application.rb +7 -4
  11. data/lib/mcollective/applications.rb +3 -14
  12. data/lib/mcollective/cache.rb +145 -0
  13. data/lib/mcollective/client.rb +10 -87
  14. data/lib/mcollective/config.rb +22 -8
  15. data/lib/mcollective/data.rb +87 -0
  16. data/lib/mcollective/data/base.rb +67 -0
  17. data/lib/mcollective/data/result.rb +40 -0
  18. data/lib/mcollective/ddl.rb +113 -0
  19. data/lib/mcollective/ddl/agentddl.rb +185 -0
  20. data/lib/mcollective/ddl/base.rb +220 -0
  21. data/lib/mcollective/ddl/dataddl.rb +56 -0
  22. data/lib/mcollective/ddl/discoveryddl.rb +52 -0
  23. data/lib/mcollective/ddl/validatorddl.rb +6 -0
  24. data/lib/mcollective/discovery.rb +143 -0
  25. data/lib/mcollective/generators.rb +7 -0
  26. data/lib/mcollective/generators/agent_generator.rb +51 -0
  27. data/lib/mcollective/generators/base.rb +46 -0
  28. data/lib/mcollective/generators/data_generator.rb +51 -0
  29. data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
  30. data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
  31. data/lib/mcollective/generators/templates/ddl.erb +8 -0
  32. data/lib/mcollective/generators/templates/plugin.erb +7 -0
  33. data/lib/mcollective/logger/console_logger.rb +15 -15
  34. data/lib/mcollective/matcher.rb +167 -0
  35. data/lib/mcollective/matcher/parser.rb +60 -25
  36. data/lib/mcollective/matcher/scanner.rb +156 -78
  37. data/lib/mcollective/message.rb +47 -6
  38. data/lib/mcollective/monkey_patches.rb +17 -0
  39. data/lib/mcollective/optionparser.rb +18 -1
  40. data/lib/mcollective/pluginmanager.rb +3 -3
  41. data/lib/mcollective/pluginpackager.rb +10 -3
  42. data/lib/mcollective/pluginpackager/agent_definition.rb +28 -20
  43. data/lib/mcollective/pluginpackager/standard_definition.rb +11 -9
  44. data/lib/mcollective/registration/base.rb +3 -1
  45. data/lib/mcollective/rpc.rb +18 -24
  46. data/lib/mcollective/rpc/agent.rb +37 -113
  47. data/lib/mcollective/rpc/client.rb +186 -64
  48. data/lib/mcollective/rpc/helpers.rb +42 -80
  49. data/lib/mcollective/rpc/progress.rb +3 -3
  50. data/lib/mcollective/rpc/reply.rb +37 -13
  51. data/lib/mcollective/rpc/request.rb +17 -6
  52. data/lib/mcollective/rpc/result.rb +9 -5
  53. data/lib/mcollective/rpc/stats.rb +71 -24
  54. data/lib/mcollective/security/base.rb +41 -34
  55. data/lib/mcollective/shell.rb +1 -1
  56. data/lib/mcollective/ssl.rb +34 -0
  57. data/lib/mcollective/util.rb +194 -23
  58. data/lib/mcollective/validator.rb +80 -0
  59. data/spec/fixtures/util/1.in +10 -0
  60. data/spec/fixtures/util/1.out +10 -0
  61. data/spec/fixtures/util/2.in +1 -0
  62. data/spec/fixtures/util/2.out +1 -0
  63. data/spec/fixtures/util/3.in +1 -0
  64. data/spec/fixtures/util/3.out +2 -0
  65. data/spec/fixtures/util/4.in +5 -0
  66. data/spec/fixtures/util/4.out +9 -0
  67. data/spec/spec.opts +1 -1
  68. data/spec/spec_helper.rb +2 -0
  69. data/spec/unit/agents_spec.rb +34 -19
  70. data/spec/unit/aggregate/base_spec.rb +57 -0
  71. data/spec/unit/aggregate/result/base_spec.rb +28 -0
  72. data/spec/unit/aggregate/result/collection_result_spec.rb +18 -0
  73. data/spec/unit/aggregate/result/numeric_result_spec.rb +22 -0
  74. data/spec/unit/aggregate_spec.rb +110 -0
  75. data/spec/unit/application_spec.rb +8 -3
  76. data/spec/unit/applications_spec.rb +2 -2
  77. data/spec/unit/cache_spec.rb +115 -0
  78. data/spec/unit/client_spec.rb +78 -0
  79. data/spec/unit/config_spec.rb +32 -34
  80. data/spec/unit/data/base_spec.rb +90 -0
  81. data/spec/unit/data/result_spec.rb +64 -0
  82. data/spec/unit/data_spec.rb +158 -0
  83. data/spec/unit/ddl/agentddl_spec.rb +217 -0
  84. data/spec/unit/{rpc/ddl_spec.rb → ddl/base_spec.rb} +238 -224
  85. data/spec/unit/ddl/dataddl_spec.rb +65 -0
  86. data/spec/unit/ddl/discoveryddl_spec.rb +58 -0
  87. data/spec/unit/ddl_spec.rb +84 -0
  88. data/spec/unit/discovery_spec.rb +196 -0
  89. data/spec/unit/facts/base_spec.rb +1 -1
  90. data/spec/unit/generators/agent_generator_spec.rb +72 -0
  91. data/spec/unit/generators/base_spec.rb +83 -0
  92. data/spec/unit/generators/data_generator_spec.rb +37 -0
  93. data/spec/unit/generators/snippets/agent_ddl +19 -0
  94. data/spec/unit/generators/snippets/data_ddl +20 -0
  95. data/spec/unit/logger/console_logger_spec.rb +76 -0
  96. data/spec/unit/logger/syslog_logger_spec.rb +2 -2
  97. data/spec/unit/matcher/parser_spec.rb +27 -10
  98. data/spec/unit/matcher/scanner_spec.rb +108 -5
  99. data/spec/unit/matcher_spec.rb +260 -0
  100. data/spec/unit/message_spec.rb +35 -13
  101. data/spec/unit/optionparser_spec.rb +2 -2
  102. data/spec/unit/pluginpackager/agent_definition_spec.rb +59 -42
  103. data/spec/unit/pluginpackager/standard_definition_spec.rb +10 -8
  104. data/spec/unit/pluginpackager_spec.rb +131 -0
  105. data/spec/unit/plugins/mcollective/aggregate/average_spec.rb +45 -0
  106. data/spec/unit/plugins/mcollective/aggregate/sum_spec.rb +31 -0
  107. data/spec/unit/plugins/mcollective/aggregate/summary_spec.rb +45 -0
  108. data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +1 -1
  109. data/spec/unit/plugins/mcollective/connector/rabbitmq_spec.rb +478 -0
  110. data/spec/unit/plugins/mcollective/connector/stomp_spec.rb +2 -0
  111. data/spec/unit/plugins/mcollective/data/agent_data_spec.rb +43 -0
  112. data/spec/unit/plugins/mcollective/data/fstat_data_spec.rb +135 -0
  113. data/spec/unit/plugins/mcollective/discovery/flatfile_spec.rb +48 -0
  114. data/spec/unit/plugins/mcollective/discovery/mc_spec.rb +40 -0
  115. data/spec/unit/plugins/mcollective/packagers/debpackage_packager_spec.rb +41 -15
  116. data/spec/unit/plugins/mcollective/packagers/ospackage_spec.rb +1 -1
  117. data/spec/unit/plugins/mcollective/packagers/rpmpackage_packager_spec.rb +22 -38
  118. data/spec/unit/plugins/mcollective/validator/array_validator_spec.rb +19 -0
  119. data/spec/unit/plugins/mcollective/validator/ipv4address_validator_spec.rb +19 -0
  120. data/spec/unit/plugins/mcollective/validator/ipv6address_validator_spec.rb +19 -0
  121. data/spec/unit/plugins/mcollective/validator/length_validator_spec.rb +19 -0
  122. data/spec/unit/plugins/mcollective/validator/regex_validator_spec.rb +19 -0
  123. data/spec/unit/plugins/mcollective/validator/shellsafe_validator_spec.rb +21 -0
  124. data/spec/unit/plugins/mcollective/validator/typecheck_validator_spec.rb +23 -0
  125. data/spec/unit/registration/base_spec.rb +1 -1
  126. data/spec/unit/rpc/actionrunner_spec.rb +2 -2
  127. data/spec/unit/rpc/agent_spec.rb +41 -65
  128. data/spec/unit/rpc/client_spec.rb +430 -134
  129. data/spec/unit/rpc/reply_spec.rb +31 -1
  130. data/spec/unit/rpc/request_spec.rb +33 -12
  131. data/spec/unit/rpc/result_spec.rb +7 -0
  132. data/spec/unit/rpc/stats_spec.rb +14 -14
  133. data/spec/unit/rpc_spec.rb +16 -0
  134. data/spec/unit/security/base_spec.rb +8 -8
  135. data/spec/unit/ssl_spec.rb +20 -2
  136. data/spec/unit/string_spec.rb +15 -0
  137. data/spec/unit/util_spec.rb +141 -21
  138. data/spec/unit/validator_spec.rb +67 -0
  139. metadata +145 -7
  140. data/lib/mcollective/rpc/ddl.rb +0 -258
@@ -0,0 +1,10 @@
1
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
2
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
3
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
4
+
5
+ foo
6
+ bar
7
+
8
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
9
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
10
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
@@ -0,0 +1,10 @@
1
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
2
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
3
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
4
+
5
+ foo
6
+ bar
7
+
8
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
9
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
10
+ This is a string This is a string This is a string This is a string This is a string This is a string This is a string
@@ -0,0 +1 @@
1
+ foooooooooooooooooooooooooooooooooooooooooooooooooooo
@@ -0,0 +1 @@
1
+ foooooooooooooooooooooooooooooooooooooooooooooooooooo
@@ -0,0 +1 @@
1
+ Strings Strings Strings Strings Strings Strings
@@ -0,0 +1,2 @@
1
+ Strings Strings Strings
2
+ Strings Strings Strings
@@ -0,0 +1,5 @@
1
+ this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text
2
+
3
+ foo(bar)
4
+
5
+ this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text this is usage text
@@ -0,0 +1,9 @@
1
+ this is usage text this is usage text this is usage text this is usage text
2
+ this is usage text this is usage text this is usage text this is usage text
3
+ this is usage text this is usage text this is usage text this is usage text
4
+
5
+ foo(bar)
6
+
7
+ this is usage text this is usage text this is usage text this is usage text
8
+ this is usage text this is usage text this is usage text this is usage text
9
+ this is usage text this is usage text this is usage text this is usage text
data/spec/spec.opts CHANGED
@@ -1 +1 @@
1
- --format s --colour --backtrace
1
+ --colour --backtrace
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  dir = File.expand_path(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift("#{dir}/")
3
3
  $LOAD_PATH.unshift("#{dir}/../lib")
4
+ $LOAD_PATH.unshift("#{dir}/../plugins")
4
5
 
5
6
  require 'rubygems'
6
7
 
@@ -21,6 +22,7 @@ RSpec.configure do |config|
21
22
  config.mock_with :mocha
22
23
 
23
24
  config.before :each do
25
+ MCollective::Config.instance.set_config_defaults("")
24
26
  MCollective::PluginManager.clear
25
27
  end
26
28
  end
@@ -27,7 +27,7 @@ module MCollective
27
27
 
28
28
  describe "#initialize" do
29
29
  it "should fail if configuration has not been loaded" do
30
- Config.any_instance.expects(:configured).returns(false)
30
+ Config.instance.expects(:configured).returns(false)
31
31
 
32
32
  expect {
33
33
  Agents.new
@@ -35,7 +35,7 @@ module MCollective
35
35
  end
36
36
 
37
37
  it "should load agents" do
38
- Config.any_instance.expects(:configured).returns(true)
38
+ Config.instance.expects(:configured).returns(true)
39
39
  Agents.any_instance.expects(:loadagents).once
40
40
 
41
41
  Agents.new
@@ -44,8 +44,8 @@ module MCollective
44
44
 
45
45
  describe "#clear!" do
46
46
  it "should delete and unsubscribe all loaded agents" do
47
- Config.any_instance.expects(:configured).returns(true).at_least_once
48
- Config.any_instance.expects(:libdir).returns([@tmpdir])
47
+ Config.instance.expects(:configured).returns(true).at_least_once
48
+ Config.instance.expects(:libdir).returns([@tmpdir])
49
49
  PluginManager.expects(:delete).with("foo_agent").once
50
50
  Util.expects(:make_subscriptions).with("foo", :broadcast).returns("foo_target")
51
51
  Util.expects(:unsubscribe).with("foo_target")
@@ -56,8 +56,8 @@ module MCollective
56
56
 
57
57
  describe "#loadagents" do
58
58
  before do
59
- Config.any_instance.stubs(:configured).returns(true)
60
- Config.any_instance.stubs(:libdir).returns([@tmpdir])
59
+ Config.instance.stubs(:configured).returns(true)
60
+ Config.instance.stubs(:libdir).returns([@tmpdir])
61
61
  Agents.any_instance.stubs("clear!").returns(true)
62
62
  end
63
63
 
@@ -67,7 +67,7 @@ module MCollective
67
67
  end
68
68
 
69
69
  it "should attempt to load agents from all libdirs" do
70
- Config.any_instance.expects(:libdir).returns(["/nonexisting", "/nonexisting"])
70
+ Config.instance.expects(:libdir).returns(["/nonexisting", "/nonexisting"])
71
71
  File.expects("directory?").with("/nonexisting/mcollective/agent").twice
72
72
 
73
73
  a = Agents.new
@@ -94,10 +94,11 @@ module MCollective
94
94
  describe "#loadagent" do
95
95
  before do
96
96
  FileUtils.touch(File.join([@agentsdir, "test.rb"]))
97
- Config.any_instance.stubs(:configured).returns(true)
98
- Config.any_instance.stubs(:libdir).returns([@tmpdir])
97
+ Config.instance.stubs(:configured).returns(true)
98
+ Config.instance.stubs(:libdir).returns([@tmpdir])
99
99
  Agents.any_instance.stubs("clear!").returns(true)
100
100
  PluginManager.stubs(:loadclass).returns(true)
101
+ PluginManager.stubs("[]").with("test_agent").returns(true)
101
102
  Util.stubs(:make_subscriptions).with("test", :broadcast).returns([{:agent => "test", :type => :broadcast, :collective => "test"}])
102
103
  Util.stubs(:subscribe).with([{:agent => "test", :type => :broadcast, :collective => "test"}]).returns(true)
103
104
  Agents.stubs(:findagentfile).returns(File.join([@agentsdir, "test.rb"]))
@@ -153,12 +154,26 @@ module MCollective
153
154
  Util.stubs(:make_subscriptions).with("foo", :broadcast).returns([{:agent => "foo", :type => :broadcast, :collective => "test"}])
154
155
  Util.expects("subscribe").with([{:type => :broadcast, :agent => 'foo', :collective => 'test'}]).returns(true)
155
156
  Agents.any_instance.expects(:findagentfile).with("foo").returns(File.join([@agentsdir, "foo.rb"]))
156
-
157
157
  FileUtils.touch(File.join([@agentsdir, "foo.rb"]))
158
+ Agents.any_instance.expects("activate_agent?").with("foo").returns(true)
159
+ PluginManager.stubs("[]").with("foo_agent").returns(true)
158
160
 
159
161
  @a.loadagent("foo")
160
162
  end
161
163
 
164
+ it "should check if an agent is loadable and remove it from the list if not" do
165
+ PluginManager.expects("<<").with({:type => "foo_agent", :class => "MCollective::Agent::Foo", :single_instance => false})
166
+ Agents.any_instance.expects(:findagentfile).with("foo").returns(File.join([@agentsdir, "foo.rb"]))
167
+ FileUtils.touch(File.join([@agentsdir, "foo.rb"]))
168
+ Agents.any_instance.expects("activate_agent?").with("foo").returns(true)
169
+ PluginManager.stubs("[]").with("foo_agent").raises("rspec")
170
+
171
+ Log.expects(:error).once.with("Loading agent foo failed: rspec")
172
+
173
+ @a.loadagent("foo").should == false
174
+ Agents.agentlist.include?("foo").should == false
175
+ end
176
+
162
177
  it "should add the agent to the agent list" do
163
178
  Agents.agentlist.should == ["test"]
164
179
  end
@@ -183,7 +198,7 @@ module MCollective
183
198
 
184
199
  describe "#class_for_agent" do
185
200
  it "should return the correct class" do
186
- Config.any_instance.stubs(:configured).returns(true)
201
+ Config.instance.stubs(:configured).returns(true)
187
202
  Agents.any_instance.stubs(:loadagents).returns(true)
188
203
  Agents.new.class_for_agent("foo").should == "MCollective::Agent::Foo"
189
204
  end
@@ -191,7 +206,7 @@ module MCollective
191
206
 
192
207
  describe "#activate_agent?" do
193
208
  before do
194
- Config.any_instance.stubs(:configured).returns(true)
209
+ Config.instance.stubs(:configured).returns(true)
195
210
  Agents.any_instance.stubs(:loadagents).returns(true)
196
211
  @a = Agents.new
197
212
 
@@ -225,14 +240,14 @@ module MCollective
225
240
 
226
241
  describe "#findagentfile" do
227
242
  before do
228
- Config.any_instance.stubs(:configured).returns(true)
229
- Config.any_instance.stubs(:libdir).returns([@tmpdir])
243
+ Config.instance.stubs(:configured).returns(true)
244
+ Config.instance.stubs(:libdir).returns([@tmpdir])
230
245
  Agents.any_instance.stubs(:loadagents).returns(true)
231
246
  @a = Agents.new
232
247
  end
233
248
 
234
249
  it "should support multiple libdirs" do
235
- Config.any_instance.expects(:libdir).returns([@tmpdir, @tmpdir]).once
250
+ Config.instance.expects(:libdir).returns([@tmpdir, @tmpdir]).once
236
251
  File.expects("exist?").returns(false).twice
237
252
  @a.findagentfile("test")
238
253
  end
@@ -255,8 +270,8 @@ module MCollective
255
270
 
256
271
  describe "#include?" do
257
272
  it "should correctly report the plugin state" do
258
- Config.any_instance.stubs(:configured).returns(true)
259
- Config.any_instance.stubs(:libdir).returns([@tmpdir])
273
+ Config.instance.stubs(:configured).returns(true)
274
+ Config.instance.stubs(:libdir).returns([@tmpdir])
260
275
  Agents.any_instance.stubs(:loadagents).returns(true)
261
276
  PluginManager.expects("include?").with("test_agent").returns(true)
262
277
 
@@ -268,8 +283,8 @@ module MCollective
268
283
 
269
284
  describe "#agentlist" do
270
285
  it "should return the correct agent list" do
271
- Config.any_instance.stubs(:configured).returns(true)
272
- Config.any_instance.stubs(:libdir).returns([@tmpdir])
286
+ Config.instance.stubs(:configured).returns(true)
287
+ Config.instance.stubs(:libdir).returns([@tmpdir])
273
288
  Agents.any_instance.stubs(:loadagents).returns(true)
274
289
 
275
290
  @a = Agents.new("test" => true)
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ class Aggregate
7
+ describe Base do
8
+ describe "#initialize" do
9
+ it "should set the correct instance variables and call the startup hook" do
10
+ Base.any_instance.expects(:startup_hook).once
11
+ base = Base.new("value", [], "%s%s", "rspec")
12
+ base.name.should == "MCollective::Aggregate::Base"
13
+ base.output_name.should == "value"
14
+ base.aggregate_format.should == "%s%s"
15
+ base.action.should == "rspec"
16
+ end
17
+ end
18
+
19
+ describe "#startup_hook and #process_result" do
20
+ it "should raise an exception for an unimplemented startup_hook method " do
21
+ expect{
22
+ base = Base.new("value", [], "", "rspec")
23
+ }.to raise_error(RuntimeError, "'startup_hook' method of function class MCollective::Aggregate::Base has not yet been implemented")
24
+ end
25
+
26
+ it "should raise an exception for an unimplemented process_result method" do
27
+ Base.any_instance.stubs(:startup_hook)
28
+ base = Base.new("value", [], "", "rspec")
29
+ expect{
30
+ base.process_result
31
+ }.to raise_error(RuntimeError,"'process_result' method of function class MCollective::Aggregate::Base has not yet been implemented")
32
+ end
33
+ end
34
+
35
+ describe "summarize" do
36
+ it "should raise and exception if the result type has not been set" do
37
+ Base.any_instance.stubs(:startup_hook)
38
+ base = Base.new("value", [], "", "rspec")
39
+ expect{
40
+ base.summarize
41
+ }.to raise_error(RuntimeError, "Result type is not set while trying to summarize aggregate function results")
42
+ end
43
+
44
+ it "should return the correct result class if result type has been set" do
45
+ result_object = mock
46
+ result_object.stubs(:new)
47
+
48
+ Base.any_instance.stubs(:startup_hook)
49
+ base = Base.new("value", [], "", "rspec")
50
+ base.result[:type] = :result_type
51
+ base.expects(:result_class).with(:result_type).returns(result_object)
52
+ base.summarize
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ class Aggregate
7
+ module Result
8
+ describe Base do
9
+ describe "#initialize" do
10
+ it "should raise an exception if neither the ddl or the aggregate function defines a format" do
11
+ expect{
12
+ base = Base.new(:structure, nil, :action)
13
+ }.to raise_error(RuntimeError, "No aggregate_format defined in ddl or aggregate function")
14
+ end
15
+ end
16
+
17
+ describe "#to_s" do
18
+ it "should raise an exception if the to_s method isn't implemented" do
19
+ base = Base.new(:structure, :aggregate_format, :action)
20
+ expect{
21
+ base.to_s
22
+ }.to raise_error(RuntimeError, "'to_s' method not implemented for result class 'MCollective::Aggregate::Result::Base'")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ class Aggregate
7
+ module Result
8
+ describe CollectionResult do
9
+ describe "#to_s" do
10
+ it "should return the correctly formatted string" do
11
+ result = CollectionResult.new({:output => [:test], :value => {"foo" => 3, "bar" => 2}}, "%s:%s", :action).to_s
12
+ result.should == " foo:3\n bar:2"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ class Aggregate
7
+ module Result
8
+ describe NumericResult do
9
+ describe "#to_s" do
10
+ it "should return empty string when no results were computed" do
11
+ NumericResult.new({}, "test %d", :action).to_s.should == ""
12
+ end
13
+
14
+ it "should return the correctly formatted string" do
15
+ num = NumericResult.new({:value => 1}, "test %d", :action).to_s
16
+ num.should == "test 1"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ describe Aggregate do
7
+ let(:ddl) do
8
+ {
9
+ :aggregate => [{:function => :func, :args=>[:value], :format => "%s"}],
10
+ :action => "test_action",
11
+ :output => {:foo => nil, :bar => nil}
12
+ }
13
+ end
14
+
15
+ describe '#create_functions' do
16
+ before :each do
17
+ Aggregate.any_instance.stubs(:contains_output?)
18
+ end
19
+
20
+ it "should load all the functions with a format if defined" do
21
+ function = mock
22
+ function.expects(:new).with(:value, [], "%s", 'test_action')
23
+ Aggregate.any_instance.expects(:load_function).once.returns(function)
24
+ @aggregate = Aggregate.new(ddl)
25
+ end
26
+
27
+ it "should load all the functions without a format if it isn't defined" do
28
+ function = mock
29
+ function.expects(:new).with(:value, [], nil, 'test_action')
30
+ Aggregate.any_instance.expects(:load_function).once.returns(function)
31
+ ddl[:aggregate].first[:format] = nil
32
+ @aggregate = Aggregate.new(ddl)
33
+ end
34
+ end
35
+
36
+ describe '#contains_ouput?' do
37
+ before :all do
38
+ Aggregate.any_instance.stubs(:create_functions)
39
+ @aggregate = Aggregate.new(ddl)
40
+ end
41
+
42
+ it "should raise an exception if the ddl output does not include the function's input" do
43
+ expect{
44
+ @aggregate.contains_output?(:baz)
45
+ }.to raise_error("'test_action' action does not contain output 'baz'")
46
+ end
47
+
48
+ it "should not raise an exception if the ddl output includes the function's input" do
49
+ @aggregate.contains_output?(:foo)
50
+ end
51
+ end
52
+
53
+ describe '#call_functions' do
54
+ it "should call all of the functions" do
55
+ Aggregate.any_instance.stubs(:create_functions)
56
+ aggregate = Aggregate.new(ddl)
57
+
58
+ result = RPC::Result.new("rspec", "rspec", :sender => "rspec", :statuscode => 0, :statusmsg => "rspec", :data => {:test => :result})
59
+
60
+ function = mock
61
+ function.expects(:process_result).with(:result, result).once
62
+ function.expects(:output_name).returns(:test)
63
+
64
+ aggregate.functions = [function]
65
+
66
+ aggregate.call_functions(result)
67
+ end
68
+ end
69
+
70
+ describe '#summarize' do
71
+ it "should return the ordered function results" do
72
+ Aggregate.any_instance.stubs(:create_functions)
73
+ aggregate = Aggregate.new(ddl)
74
+
75
+ func1 = mock
76
+ func1.expects(:summarize).returns(func1)
77
+ func1.stubs(:result).returns(:output => 5)
78
+
79
+ func2 = mock
80
+ func2.expects(:summarize).returns(func2)
81
+ func2.stubs(:result).returns(:output => 2)
82
+
83
+ aggregate.functions = [func1, func2]
84
+
85
+ result = aggregate.summarize
86
+ result.should == [func2, func1]
87
+ end
88
+ end
89
+
90
+ describe '#load_function' do
91
+ before :all do
92
+ Aggregate.any_instance.stubs(:create_functions)
93
+ @aggregate = Aggregate.new(ddl)
94
+ end
95
+
96
+ it "should return a class object if it can be loaded" do
97
+ PluginManager.expects(:loadclass).with("MCollective::Aggregate::Test")
98
+ Aggregate.expects(:const_get).with("Test")
99
+ function = @aggregate.load_function("test")
100
+ end
101
+
102
+ it "should raise an exception if the class object cannot be loaded" do
103
+ PluginManager.expects(:loadclass).with("MCollective::Aggregate::Test")
104
+ expect {
105
+ function = @aggregate.load_function("test")
106
+ }.to raise_error("Aggregate function file 'test.rb' cannot be loaded")
107
+ end
108
+ end
109
+ end
110
+ end