build_status_server 0.8 → 0.9

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.
@@ -1,9 +1,6 @@
1
- # TODO
2
- # move all configuration stuff to Config
3
- # and just call config[:blaj] instead of if blah
4
1
  module BuildStatusServer
5
2
  class Server
6
- attr_reader :config, :store
3
+ attr_reader :config, :store, :udp_server
7
4
 
8
5
  def initialize(options = {})
9
6
  @config = Config.new
@@ -11,30 +8,11 @@ module BuildStatusServer
11
8
  end
12
9
 
13
10
  def listen
14
- sock = UDPSocket.new
15
- udp_server = config.udp_server
16
-
17
- begin
18
- sock.bind(udp_server["address"], udp_server["port"])
19
- rescue Errno::EADDRINUSE
20
- STDERR.puts <<-EOT
21
- There appears that another instance is running, or another process
22
- is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
23
-
24
- EOT
25
- exit
26
- end
27
-
28
- puts "Listening on UDP #{udp_server["address"]}:#{udp_server["port"]}" if config.verbose
11
+ setup_udp_server
29
12
 
30
13
  begin
31
14
  while true
32
- data, addr = sock.recvfrom(2048)
33
-
34
- if process_job(data)
35
- status = process_all_statuses
36
- notify(status)
37
- end
15
+ process_loop
38
16
  end
39
17
  rescue Interrupt
40
18
  puts "Good bye."
@@ -45,6 +23,39 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
45
23
 
46
24
  private
47
25
 
26
+ def process_loop
27
+ data, addr = udp_server.recvfrom(2048)
28
+
29
+ if process_job(data)
30
+ status = process_all_statuses
31
+ notify(status)
32
+ end
33
+ end
34
+
35
+ def setup_udp_server
36
+ address, port = config.udp_server["address"], config.udp_server["port"]
37
+ @udp_server = UDPSocket.new
38
+
39
+ begin
40
+ udp_server.bind(address, port)
41
+ rescue Errno::EADDRINUSE
42
+ STDERR.puts <<-EOT
43
+ There appears that another instance is running, or another process
44
+ is listening on the same port (#{address}:#{port})
45
+
46
+ EOT
47
+ exit
48
+ rescue Errno::EADDRNOTAVAIL
49
+ STDERR.puts <<-EOT
50
+ The address configured is not available (#{address})
51
+
52
+ EOT
53
+ exit
54
+ end
55
+
56
+ STDOUT.puts "Listening on UDP #{address}:#{port}" if config.verbose
57
+ end
58
+
48
59
  def load_store
49
60
  @store = begin
50
61
  YAML.load_file(config.store_file)
@@ -75,7 +86,8 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
75
86
  status = job["build"]["status"]
76
87
 
77
88
  if phase == "FINISHED"
78
- STDOUT.puts "Got #{status} for #{build_name} on #{Time.now} [#{job.inspect}]" if config.verbose
89
+ # Got SUCCESS for topic_action_master on Tue May 01 12:02:31 -0400 2012 []
90
+ STDOUT.puts "Got #{status} for #{build_name} on #{Time.now} [#{job_internals(job)}]" if config.verbose
79
91
  case status
80
92
  when "SUCCESS", "FAILURE"
81
93
  load_store
@@ -84,12 +96,18 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
84
96
  return true
85
97
  end
86
98
  else
87
- STDOUT.puts "Started for #{build_name} on #{Time.now} [#{job.inspect}]" if config.verbose
99
+ # Started for topic_action_master on Tue May 01 12:00:30 -0400 2012 [{"name"=>"topic_action_master", "url"=>"job/topic_action_master/", "build"=>{"number"=>98, "url"=>"job/topic_action_master/98/", "phase"= >"STARTED", "full_url"=>"http://ci.berman.challengepost.com/job/topic_action_master/98/"}}]
100
+ # Started for topic_action_master on Tue May 01 12:02:31 -0400 2012 [{"name"=>"topic_action_master", "url"=>"job/topic_action_master/", "build"=>{"number"=>98, "url"=>"job/topic_action_master/98/", "status" =>"SUCCESS", "phase"=>"COMPLETED", "full_url"=>"http://ci.berman.challengepost.com/job/topic_action_master/98/"}}]
101
+ STDOUT.puts "Started for #{build_name} on #{Time.now} [#{job_internals(job)}]" if config.verbose
88
102
  end
89
103
 
90
104
  return false
91
105
  end
92
106
 
107
+ def job_internals(job)
108
+ "build=>#{job["build"]["number"]}, status=>#{job["build"]["status"]}"
109
+ end
110
+
93
111
  def should_process_build(build_name)
94
112
  # If mask exists, then ...
95
113
  ! (
@@ -103,7 +121,7 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
103
121
  def process_all_statuses
104
122
  pass = true
105
123
 
106
- @store.values.each do |val|
124
+ store.values.each do |val|
107
125
  pass &&= (val == "pass" || val == "SUCCESS")
108
126
  end
109
127
 
@@ -112,10 +130,12 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
112
130
 
113
131
  def notify(status)
114
132
  tcp_client = config.tcp_client
133
+ tcp_client["attempts"] ||= 2
115
134
 
116
135
  attempts = 0
117
136
  light = status ? tcp_client["pass"] : tcp_client["fail"]
118
137
 
138
+ client = nil
119
139
  begin
120
140
  timeout(5) do
121
141
  attempts += 1
@@ -123,39 +143,18 @@ is listening at the same port (#{udp_server["address"]}:#{udp_server["port"]}
123
143
  client.print "GET #{light} HTTP/1.0\n\n"
124
144
  answer = client.gets(nil)
125
145
  STDOUT.puts answer if config.verbose
126
- client.close
127
146
  end
128
147
  rescue Timeout::Error => ex
129
148
  STDERR.puts "Error: #{ex} while trying to send #{light}"
130
- retry unless attempts > 2
149
+ retry unless attempts > tcp_client["attempts"]
131
150
  rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH => ex
132
151
  STDERR.puts "Error: #{ex} while trying to send #{light}"
133
152
  STDERR.puts "Will wait for 2 seconds and try again..."
134
153
  sleep 2
135
- retry unless attempts > 2
154
+ retry unless attempts > tcp_client["attempts"]
155
+ ensure
156
+ client.close if client
136
157
  end
137
158
  end
138
159
  end
139
160
  end
140
-
141
- __END__
142
-
143
- Example payload:
144
- {
145
- "name":"test",
146
- "url":"job/test/",
147
- "build":{
148
- "full_url":"http://cronus.local:3001/job/test/20/",
149
- "number":20,
150
- "phase":"FINISHED",
151
- "status":"SUCCESS",
152
- "url":"job/test/20/"
153
- }
154
- }
155
-
156
- We're getting this error once in a while:
157
- /usr/local/lib/ruby/1.8/timeout.rb:64:in `notify': execution expired (Timeout::Error)
158
- from /home/jcmuller/build_notifier/lib/server.rb:102:in `notify'
159
- from /home/jcmuller/build_notifier/lib/server.rb:33:in `listen'
160
- from bin/server:5
161
-
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
5
+ <title>version.rb</title>
6
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
7
+ </head>
8
+ <body>
9
+ <div id='container'>
10
+ <div id="background"></div>
11
+ <div id="jump_to">
12
+ Jump To &hellip;
13
+ <div id="jump_wrapper">
14
+ <div id="jump_page">
15
+ <a class="source" href="../build_status_server.html">build_status_server.rb</a>
16
+ <a class="source" href="config.html">config.rb</a>
17
+ <a class="source" href="server.html">server.rb</a>
18
+ <a class="source" href="version.html">version.rb</a>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ <table cellspacing=0 cellpadding=0>
23
+ <thead>
24
+ <tr>
25
+ <th class=docs><h1>version.rb</h1></th>
26
+ <th class=code></th>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ </table>
31
+ </div>
32
+ </body>
@@ -1,3 +1,3 @@
1
1
  module BuildStatusServer
2
- VERSION = "0.8"
2
+ VERSION = "0.9"
3
3
  end
@@ -1,6 +1,6 @@
1
- require 'spec_helper'
2
- require 'build_status_server'
3
- require 'tempfile'
1
+ require "spec_helper"
2
+ require "build_status_server"
3
+ require "tempfile"
4
4
 
5
5
  describe BuildStatusServer::Config do
6
6
  let(:config) { BuildStatusServer::Config.new }
@@ -15,7 +15,7 @@ describe BuildStatusServer::Config do
15
15
  it "should set the config values from yaml file" do
16
16
  config.should_receive(:load_config_file).and_return(YAML.load(config.send(:get_example_config)))
17
17
  config.load
18
- config.udp_server.should == {'address' => '127.0.0.1', 'port' => 1234}
18
+ config.udp_server.should == {"address" => "127.0.0.1", "port" => 1234}
19
19
  config.verbose.should == false
20
20
  end
21
21
  end
@@ -24,7 +24,7 @@ describe BuildStatusServer::Config do
24
24
  it "should load the yaml file passed in as a file argument" do
25
25
  file_name = nil
26
26
 
27
- Tempfile.open('config') do |f|
27
+ Tempfile.open(["config", ".yml"]) do |f|
28
28
  f.puts "---"
29
29
  f.puts "key: value"
30
30
  f.puts "key2: value2"
@@ -39,7 +39,7 @@ describe BuildStatusServer::Config do
39
39
 
40
40
  it "should try to load paths from the locations to try" do
41
41
  file_name = nil
42
- Tempfile.open("config") do |f|
42
+ Tempfile.open(["config", ".yml"]) do |f|
43
43
  f.puts "---"
44
44
  f.puts "key: value"
45
45
  f.puts "key2: value2"
@@ -60,7 +60,7 @@ describe BuildStatusServer::Config do
60
60
 
61
61
  it "should throw an exception if the config file isn't a hash" do
62
62
  file_name = nil
63
- Tempfile.open(file_name) do |f|
63
+ Tempfile.open(["base", ".yml"]) do |f|
64
64
  f.puts "YADDA YADDA"
65
65
  file_name = f.path
66
66
  end
@@ -5,12 +5,101 @@ describe BuildStatusServer::Server do
5
5
  let(:server) { BuildStatusServer::Server.new }
6
6
 
7
7
  before do
8
- STDERR.should_receive :puts
8
+ STDERR.should_receive(:puts)
9
9
  end
10
10
 
11
11
  describe "#listen"
12
12
 
13
13
  context "private methods" do
14
+
15
+ describe "#setup_udp_server" do
16
+ it "reads the udp_server options from configuration file" do
17
+ server.config.stub!(:udp_server).and_return({"address" => "address", "port" => "port"})
18
+ socket = mock(:udp_socket)
19
+ socket.should_receive(:bind).with("address", "port")
20
+ UDPSocket.should_receive(:new).and_return(socket)
21
+
22
+ server.send(:setup_udp_server)
23
+ end
24
+
25
+ it "instantiates a UDPSocket object and binds it to address and port" do
26
+ server.config.stub!(:udp_server).and_return({"address" => "127.0.0.1", "port" => "9999"})
27
+
28
+ server.send(:setup_udp_server)
29
+
30
+ client = UDPSocket.new
31
+ client.connect("127.0.0.1", 9999)
32
+ client.send "hello, world!", 0
33
+ msg = server.udp_server.recvfrom(13)
34
+
35
+ msg[0].should == "hello, world!"
36
+ ["AF_INET", "127.0.0.1"].each do |e|
37
+ msg[1].should include e
38
+ end
39
+ end
40
+
41
+ it "should show message and exit when connecting to address not available" do
42
+ server.config.stub!(:udp_server).and_return({"address" => "192.192.192.192", "port" => "9999"})
43
+
44
+ STDERR.should_receive(:puts).with("The address configured is not available (192.192.192.192)\n\n")
45
+ server.should_receive(:exit)
46
+
47
+ server.send(:setup_udp_server)
48
+ end
49
+
50
+ it "it recovers from an address in use exception" do
51
+ server.config.stub!(:udp_server).and_return({"address" => "127.0.0.1", "port" => "9999"})
52
+
53
+ socket = mock(:udp_socket)
54
+ socket.should_receive(:bind).and_raise(Errno::EADDRINUSE)
55
+ UDPSocket.should_receive(:new).and_return(socket)
56
+
57
+ STDERR.should_receive(:puts).with("There appears that another instance is running, or another process\nis listening on the same port (127.0.0.1:9999)\n\n")
58
+ server.should_receive(:exit)
59
+ server.send(:setup_udp_server)
60
+ end
61
+
62
+ it "if verbose is enabled, show message" do
63
+ server.config.stub!(:udp_server).and_return({"address" => "address", "port" => "port"})
64
+ socket = mock(:udp_socket)
65
+ socket.should_receive(:bind).with("address", "port")
66
+ UDPSocket.should_receive(:new).and_return(socket)
67
+
68
+ server.config.stub!(:verbose).and_return(true)
69
+ STDOUT.should_receive(:puts).with("Listening on UDP address:port")
70
+
71
+ server.send(:setup_udp_server)
72
+ end
73
+ end
74
+
75
+ describe "#process_loop" do
76
+ it "should process all statuses and notify when process job returns true" do
77
+ socket = mock(:udp_socket)
78
+ socket.stub!(:recvfrom).and_return("data", "addr")
79
+
80
+ server.should_receive(:udp_server).and_return(socket)
81
+ server.should_receive(:process_job).with("data").and_return(true)
82
+
83
+ server.should_receive(:process_all_statuses).and_return("status")
84
+ server.should_receive(:notify).with("status")
85
+
86
+ server.send(:process_loop)
87
+ end
88
+
89
+ it "should not process all statuses or notify when process job returns false" do
90
+ socket = mock(:udp_socket)
91
+ socket.stub!(:recvfrom).and_return("data", "addr")
92
+
93
+ server.should_receive(:udp_server).and_return(socket)
94
+ server.should_receive(:process_job).with("data").and_return(false)
95
+
96
+ server.should_not_receive(:process_all_statuses)
97
+ server.should_not_receive(:notify)
98
+
99
+ server.send(:process_loop)
100
+ end
101
+ end
102
+
14
103
  describe "#load_store" do
15
104
  before do
16
105
  server.config.stub!(:store_file).and_return("/tmp/build")
@@ -38,19 +127,12 @@ describe BuildStatusServer::Server do
38
127
  end
39
128
  end
40
129
 
41
- describe "#notify"
42
- describe "#process_all_statuses"
43
- describe "#process_job"
44
-
45
130
  describe "#should_process_build" do
46
131
  context "when mask exists" do
47
- before do
48
- server.stub!(:mask).and_return(%r{.*(?:master).*})
49
- end
50
132
 
51
133
  context "when policy is include" do
52
134
  before do
53
- server.stub!(:mask_policy).and_return("include")
135
+ server.config.stub!(:mask).and_return({"policy" => "include", "regex" => %r{.*(?:master).*}})
54
136
  end
55
137
 
56
138
  it "ignores builds if mask doesn't match build name" do
@@ -64,7 +146,7 @@ describe BuildStatusServer::Server do
64
146
 
65
147
  context "when policy is exclude" do
66
148
  before do
67
- server.config.stub!(:mask).and_return({"policy" => "exclude", "regex" => /.*(?:master).*/})
149
+ server.config.stub!(:mask).and_return({"policy" => "exclude", "regex" => %r{.*(?:master).*}})
68
150
  end
69
151
 
70
152
  it "ignores builds if mask matches build name" do
@@ -105,7 +187,7 @@ describe BuildStatusServer::Server do
105
187
  end
106
188
  end
107
189
 
108
- context "when mask doesn't" do
190
+ context "when mask regex doesn't" do
109
191
  before do
110
192
  server.config.stub!(:mask).and_return({"policy" => "include", "regex" => nil})
111
193
  end
@@ -115,6 +197,201 @@ describe BuildStatusServer::Server do
115
197
  end
116
198
  end
117
199
  end
200
+
201
+ describe "#process_job" do
202
+ it "returns false if should_process_build returns false" do
203
+ server.should_receive(:should_process_build).and_return(false)
204
+ server.send(:process_job).should be_false
205
+ end
206
+
207
+ it "returns false and says so on stderr if payload doesn't have a hash for build" do
208
+ server.should_receive(:should_process_build).and_return(true)
209
+ JSON.should_receive(:parse).and_return({"build" => "Not a hash!"})
210
+ STDERR.should_receive(:puts).with("Pinged with an invalid payload")
211
+ server.send(:process_job).should be_false
212
+ end
213
+
214
+ it "returns false and says that the we got the job started when phase is FINISHED but status isn't success nor failure" do
215
+ server.config.should_receive(:verbose).and_return(true)
216
+ server.should_receive(:should_process_build).and_return(true)
217
+ JSON.should_receive(:parse).with("{}").and_return({
218
+ "name" => "name",
219
+ "build" => { "phase" => "FINISHED", "status" => "some status", "number" => "number" }
220
+ })
221
+ Time.should_receive(:now).and_return("this is the time")
222
+ STDOUT.should_receive(:puts).with('Got some status for name on this is the time [build=>number, status=>some status]')
223
+ server.send(:process_job).should be_false
224
+ end
225
+
226
+ it "returns false and says that the job started when the phase isn't finished" do
227
+ server.config.should_receive(:verbose).and_return(true)
228
+ server.should_receive(:should_process_build).and_return(true)
229
+ JSON.should_receive(:parse).with("{}").and_return({
230
+ "name" => "name",
231
+ "build" => { "phase" => "STARTED", "status" => "some status", "number" => "number" }
232
+ })
233
+ Time.should_receive(:now).and_return("this is the time")
234
+ STDOUT.should_receive(:puts).with("Started for name on this is the time [build=>number, status=>some status]")
235
+ server.send(:process_job).should be_false
236
+ end
237
+
238
+ context "phase is FINISHED and status is either SUCCESS or FAILURE" do
239
+ before do
240
+ server.config.should_receive(:verbose).and_return(true)
241
+ server.should_receive(:should_process_build).and_return(true)
242
+ Time.should_receive(:now).and_return("this is the time")
243
+ YAML.should_receive(:load_file).and_return({})
244
+ File.should_receive(:open)
245
+ end
246
+
247
+ it "should return true and write yaml file when phase is FINISHED and status is SUCCESS" do
248
+ JSON.should_receive(:parse).with("{}").and_return({
249
+ "name" => "name",
250
+ "build" => { "phase" => "FINISHED", "status" => "SUCCESS", "number" => "number" }
251
+ })
252
+ STDOUT.should_receive(:puts).with("Got SUCCESS for name on this is the time [build=>number, status=>SUCCESS]")
253
+
254
+ server.send(:process_job).should be_true
255
+ end
256
+
257
+ it "should return true and write yaml file when phase is FINISHED and status is FAILURE" do
258
+ JSON.should_receive(:parse).with("{}").and_return({
259
+ "name" => "name",
260
+ "build" => { "phase" => "FINISHED", "status" => "FAILURE", "number" => "number" }
261
+ })
262
+ STDOUT.should_receive(:puts).with("Got FAILURE for name on this is the time [build=>number, status=>FAILURE]")
263
+
264
+ server.send(:process_job).should be_true
265
+ end
266
+ end
267
+ end
268
+
269
+ describe "#notify" do
270
+ let(:client) { mock(:client) }
271
+
272
+ context "no exceptions" do
273
+ before do
274
+ options = {
275
+ "pass" => "pass",
276
+ "fail" => "fail",
277
+ "host" => "host",
278
+ "port" => "port"
279
+ }
280
+ config = mock(:config)
281
+ config.should_receive(:tcp_client).and_return(options)
282
+ config.should_receive(:verbose).and_return(true)
283
+
284
+ server.should_receive(:config).twice.and_return(config)
285
+
286
+ STDOUT.should_receive(:puts).with("answer")
287
+
288
+ client.should_receive(:gets).and_return("answer")
289
+ client.should_receive(:close)
290
+
291
+ TCPSocket.should_receive(:new).with("host", "port").and_return(client)
292
+ end
293
+
294
+ it "should send passing packet to tcp socket when status is true" do
295
+ client.should_receive(:print).with("GET pass HTTP/1.0\n\n")
296
+ server.send(:notify, true)
297
+ end
298
+
299
+ it "should send failing packet to tcp socket when status is false" do
300
+ client.should_receive(:print).with("GET fail HTTP/1.0\n\n")
301
+ server.send(:notify, false)
302
+ end
303
+ end
304
+
305
+ context "exceptions" do
306
+ before do
307
+ options = {
308
+ "fail" => "fail",
309
+ "host" => "host",
310
+ "port" => "port",
311
+ "attempts" => 2
312
+ }
313
+ config = mock(:config)
314
+ config.should_receive(:tcp_client).and_return(options)
315
+ config.should_receive(:verbose).and_return(false)
316
+
317
+ server.should_receive(:config).twice.and_return(config)
318
+ client.should_receive(:close)
319
+
320
+ client.should_receive(:gets).and_return("answer")
321
+ end
322
+
323
+ it "should time out and retry 2 times" do
324
+ TCPSocket.should_receive(:new).exactly(3).with("host", "port").and_return(client)
325
+ STDERR.should_receive(:puts).exactly(2).with("Error: Timeout::Error while trying to send fail")
326
+ client.should_receive(:print).exactly(2).with("GET fail HTTP/1.0\n\n").and_raise(Timeout::Error)
327
+ client.should_receive(:print).with("GET fail HTTP/1.0\n\n")
328
+
329
+ server.send(:notify, false)
330
+ end
331
+
332
+ it "should not connect and retry 2 times" do
333
+ STDERR.should_receive(:puts).with("Error: Connection refused while trying to send fail")
334
+ STDERR.should_receive(:puts).with("Error: No route to host while trying to send fail")
335
+ STDERR.should_receive(:puts).exactly(2).with("Will wait for 2 seconds and try again...")
336
+
337
+ TCPSocket.should_receive(:new).with("host", "port").and_raise(Errno::ECONNREFUSED)
338
+ TCPSocket.should_receive(:new).with("host", "port").and_raise(Errno::EHOSTUNREACH)
339
+ TCPSocket.should_receive(:new).with("host", "port").and_return(client)
340
+
341
+ server.should_receive(:sleep).twice.with(2)
342
+
343
+ client.should_receive(:print).with("GET fail HTTP/1.0\n\n")
344
+
345
+ server.send(:notify, false)
346
+ end
347
+ end
348
+
349
+ it "should gracefully recover if config doesn't have attempts configured" do
350
+ options = {
351
+ "fail" => "fail",
352
+ "host" => "host",
353
+ "port" => "port"
354
+ }
355
+
356
+ config = mock(:config)
357
+ config.should_receive(:tcp_client).and_return(options)
358
+ config.should_receive(:verbose).and_return(false)
359
+
360
+ server.should_receive(:config).twice.and_return(config)
361
+ client.should_receive(:close)
362
+
363
+ client.should_receive(:gets).and_return("answer")
364
+ TCPSocket.should_receive(:new).exactly(3).with("host", "port").and_return(client)
365
+ STDERR.should_receive(:puts).exactly(2).with("Error: Timeout::Error while trying to send fail")
366
+ client.should_receive(:print).exactly(2).with("GET fail HTTP/1.0\n\n").and_raise(Timeout::Error)
367
+ client.should_receive(:print).with("GET fail HTTP/1.0\n\n")
368
+
369
+ server.send(:notify, false)
370
+ end
371
+ end
372
+
373
+ describe "#process_all_statuses" do
374
+ it "should return true if all values are SUCCESS" do
375
+ server.should_receive(:store).and_return(mock(:blah, :values => %w(SUCCESS SUCCESS SUCCESS)))
376
+ server.send(:process_all_statuses).should be_true
377
+ end
378
+
379
+ it "should return true if all values are pass" do
380
+ server.should_receive(:store).and_return(mock(:blah, :values => %w(pass pass pass)))
381
+ server.send(:process_all_statuses).should be_true
382
+ end
383
+
384
+ it "should return true if some values are pass and some are SUCCESS" do
385
+ server.should_receive(:store).and_return(mock(:blah, :values => %w(SUCCESS pass SUCCESS)))
386
+ server.send(:process_all_statuses).should be_true
387
+ end
388
+
389
+ it "should return false if at least one value isn't pass or SUCCESS" do
390
+ server.should_receive(:store).and_return(mock(:blah, :values => %w(SUCCESS blah SUCCESS)))
391
+ server.send(:process_all_statuses).should be_false
392
+ end
393
+ end
394
+
118
395
  end
119
396
  end
120
397