1#!/usr/bin/env rspec 2 3require 'spec_helper' 4 5module MCollective 6 class Application 7 describe Puppet do 8 before do 9 application_file = File.join(File.dirname(__FILE__), '../../', 'application', 'puppet.rb') 10 @app = MCollective::Test::ApplicationTest.new('puppet', :application_file => application_file).plugin 11 12 client = mock 13 client.stubs(:stats).returns(RPC::Stats.new) 14 client.stubs(:progress=) 15 @app.stubs(:client).returns(client) 16 @app.stubs(:printrpc) 17 @app.stubs(:printrpcstats) 18 @app.stubs(:halt) 19 end 20 21 describe "#application_description" do 22 it "should have a descrption set" do 23 @app.should have_a_description 24 end 25 end 26 27 describe "#post_option_parser" do 28 it "should detect unsupported commands" do 29 ARGV << "rspec" 30 expect { @app.post_option_parser(@app.configuration) }.to raise_error(/Action must be/) 31 end 32 33 it "should get the concurrency for runall" do 34 ARGV << "runall" 35 ARGV << "1" 36 37 @app.post_option_parser(@app.configuration) 38 @app.configuration[:command].should == "runall" 39 @app.configuration[:concurrency].should == 1 40 end 41 42 it "should get the message for disable" do 43 ARGV << "disable" 44 ARGV << "rspec test" 45 46 @app.post_option_parser(@app.configuration) 47 @app.configuration[:message].should == "rspec test" 48 end 49 50 it "should detect when no command is given" do 51 ARGV.clear 52 53 @app.expects(:raise_message).with(2) 54 @app.post_option_parser(@app.configuration) 55 end 56 end 57 58 describe "#validate_configuration" do 59 it "should not allow the splay option when forcing" do 60 @app.configuration[:force] = true 61 @app.configuration[:splay] = true 62 63 @app.expects(:raise_message).with(3) 64 @app.validate_configuration(@app.configuration) 65 end 66 67 it "should not allow the splaylimit option when forcing" do 68 @app.configuration[:force] = true 69 @app.configuration[:splaylimit] = 60 70 71 @app.expects(:raise_message).with(4) 72 @app.validate_configuration(@app.configuration) 73 end 74 75 it "should ensure the runall command has a concurrency" do 76 @app.configuration[:command] = "runall" 77 78 @app.expects(:raise_message).with(5) 79 @app.validate_configuration(@app.configuration) 80 end 81 82 it "should make sure the concurrency is > 0" do 83 @app.configuration[:command] = "runall" 84 @app.configuration[:concurrency] = 0 85 86 @app.expects(:raise_message).with(7) 87 @app.validate_configuration(@app.configuration) 88 89 @app.configuration[:concurrency] = 1 90 @app.validate_configuration(@app.configuration) 91 end 92 end 93 94 describe "#shorten_number" do 95 it "should shorten numbers correctly" do 96 @app.shorten_number("9999999").should == "10.0m" 97 @app.shorten_number("8999999").should == "9.0m" 98 @app.shorten_number("9000").should == "9.0k" 99 @app.shorten_number("9").should == "9.0" 100 @app.shorten_number("wat").should == "NaN" 101 end 102 end 103 104 describe "#calculate_longest_hostname" do 105 it "should calculate the correct size" do 106 results = [{:sender => "a"}, {:sender => "abcdef"}, {:sender => "ab"}] 107 @app.calculate_longest_hostname(results).should == 6 108 end 109 end 110 111 describe "#display_results_single_field" do 112 it "should print succesful results correctly" do 113 result = [{:statuscode => 0, :sender => "rspec sender", :data => {:message => "rspec test"}}] 114 @app.expects(:puts).with(" rspec sender: rspec test") 115 @app.display_results_single_field(result, :message) 116 end 117 118 it "should print failed results correctly" do 119 result = [{:statuscode => 1, :sender => "rspec sender", :data => {:message => "rspec test"}, :statusmsg => "error"}] 120 Util.expects(:colorize).with(:red, "error").returns("error") 121 @app.expects(:puts).with(" rspec sender: error") 122 123 @app.display_results_single_field(result, :message) 124 end 125 126 it "should not fail for empty results" do 127 @app.display_results_single_field([], :message).should == false 128 end 129 end 130 131 describe "#sparkline_for_field" do 132 it "should correctly extract and draw the data" do 133 results = [] 134 135 (10...22).each do |c| 136 results << {:statuscode => 0, :data => {:rspec => c}} 137 end 138 139 @app.expects(:spark).with([2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0]).returns("rspec") 140 @app.sparkline_for_field(results, :rspec, 11).should == "rspec min: 10.0 avg: 15.5 max: 21.0 " 141 end 142 143 it "should return an empty string with bad data to extract from" do 144 results = [] 145 (10...22).each do |c| 146 results << {:statuscode => 1, :data => {:rspec => c}} 147 end 148 149 @app.sparkline_for_field(results, :rspec).should == '' 150 end 151 152 it "should return an empty string with no data to extract" do 153 results = [] 154 @app.sparkline_for_field(results, :rspec).should == '' 155 end 156 157 it "should correctly handle mixed agent versions where some fields might be missing from some results" do 158 results = [] 159 160 (10...22).each do |c| 161 results << {:statuscode => 0, :data => {:rspec => c}} 162 end 163 results << {:statuscode => 0, :data => {}} 164 165 @app.expects(:spark).with([2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0]).returns("rspec") 166 @app.sparkline_for_field(results, :rspec, 11).should == "rspec min: 10.0 avg: 15.5 max: 21.0 " 167 end 168 end 169 170 describe "#spark" do 171 it "should correctly draw all zeros" do 172 @app.spark([0,0,0,0,0], ["0", "1", "2", "3"]).should == "00000" 173 end 174 175 it "should draw non zero for small numbers" do 176 @app.spark([1,0,0,0,100], ["0", "1", "2", "3"]).should == "10003" 177 end 178 end 179 180 describe "#runonce_arguments" do 181 it "should set the correct arguments" do 182 @app.configuration[:force] = true 183 @app.configuration[:server] = "rspec:123" 184 @app.configuration[:noop] = true 185 @app.configuration[:environment] = "rspec" 186 @app.configuration[:splay] = true 187 @app.configuration[:splaylimit] = 60 188 @app.configuration[:tag] = ["one", "two"] 189 @app.configuration[:use_cached_catalog] = false 190 @app.configuration[:ignoreschedules] = true 191 192 @app.runonce_arguments.should == {:splaylimit=>60, :force=>true, :environment=>"rspec", :noop=>true, :server=>"rspec:123", :tags=>"one,two", :splay=>true, :use_cached_catalog=>false, :ignoreschedules=>true} 193 end 194 end 195 196 describe "runall_command" do 197 it "should use the Puppetrunner to schedule runs" do 198 runner = mock 199 runner.expects(:logger) 200 runner.expects(:runall) 201 202 @app.runall_command(runner) 203 end 204 end 205 206 describe "#summary_command" do 207 it "should gather the summaries and display it" do 208 @app.client.expects(:progress=).with(false) 209 @app.client.expects(:last_run_summary).returns([]) 210 @app.expects(:halt) 211 212 [:total_resources, :out_of_sync_resources, :failed_resources, :changed_resources, 213 :config_retrieval_time, :total_time, :since_lastrun, :corrected_resources]. each do |field| 214 @app.expects(:sparkline_for_field).with([], field) 215 end 216 217 @app.summary_command 218 end 219 end 220 221 describe "#status_command" do 222 it "should display the :message result and stats" do 223 @app.client.expects(:status).returns("rspec") 224 @app.expects(:display_results_single_field).with("rspec", :message) 225 @app.expects(:printrpcstats).with(:summarize => true) 226 @app.expects(:halt) 227 @app.status_command 228 end 229 end 230 231 describe "#enable_command" do 232 it "should enable the daemons and print results" do 233 @app.client.expects(:enable) 234 @app.expects(:printrpcstats).with(:summarize => true) 235 @app.expects(:halt) 236 @app.enable_command 237 end 238 end 239 240 describe "#disable_command" do 241 before do 242 @app.expects(:printrpcstats).with(:summarize => true) 243 @app.expects(:halt) 244 end 245 246 it "should support disabling with a message" do 247 @app.configuration[:message] = "rspec test" 248 @app.client.expects(:disable).with(:message => "rspec test").returns("rspec") 249 @app.disable_command 250 end 251 252 it "should support disabling without a message" do 253 @app.client.expects(:disable).with({}).returns("rspec") 254 @app.disable_command 255 end 256 end 257 258 describe "#runonce_command" do 259 it "should run the agent along with any custom arguments" do 260 @app.configuration[:force] = true 261 @app.configuration[:server] = "rspec:123" 262 @app.configuration[:noop] = true 263 @app.configuration[:environment] = "rspec" 264 @app.configuration[:splay] = true 265 @app.configuration[:splaylimit] = 60 266 @app.configuration[:tag] = ["one", "two"] 267 @app.configuration[:use_cached_catalog] = false 268 @app.configuration[:ignoreschedules] = true 269 270 @app.client.expects(:runonce).with(:force => true, 271 :server => "rspec:123", 272 :noop => true, 273 :environment => "rspec", 274 :splay => true, 275 :splaylimit => 60, 276 :use_cached_catalog => false, 277 :ignoreschedules => true, 278 :tags => "one,two").returns("result") 279 @app.expects(:halt) 280 @app.runonce_command 281 end 282 end 283 284 describe "#count_command" do 285 it "should display the totals" do 286 @app.client.expects(:status) 287 @app.client.stats.expects(:okcount).returns(3) 288 @app.client.stats.stubs(:failcount).returns(1) 289 Util.expects(:colorize).with(:red, "Failed to retrieve status of 1 node").returns("Failed to retrieve status of 1 node") 290 @app.expects(:extract_values_from_aggregates).returns(:enabled => {"enabled" => 3}, 291 :applying => {true => 1, false => 2}, 292 :daemon_present => {"running" => 2}, 293 :idling => {true => 1}) 294 295 296 @app.expects(:puts).with("Total Puppet nodes: 3") 297 @app.expects(:puts).with(" Nodes currently enabled: 3") 298 @app.expects(:puts).with(" Nodes currently disabled: 0") 299 @app.expects(:puts).with("Nodes currently doing puppet runs: 1") 300 @app.expects(:puts).with(" Nodes currently stopped: 2") 301 @app.expects(:puts).with(" Nodes with daemons started: 2") 302 @app.expects(:puts).with(" Nodes without daemons started: 0") 303 @app.expects(:puts).with(" Daemons started but idling: 1") 304 @app.expects(:puts).with("Failed to retrieve status of 1 node") 305 306 @app.count_command 307 end 308 end 309 310 describe "#main" do 311 it "should call the command if it exist" do 312 @app.expects(:count_command) 313 @app.configuration[:command] = "count" 314 @app.main 315 end 316 317 it "should fail gracefully when a command does not exist" do 318 @app.expects(:raise_message).with(6, "rspec") 319 @app.configuration[:command] = "rspec" 320 @app.main 321 end 322 end 323 end 324 end 325end 326