hello_goodbye 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +308 -0
- data/Rakefile +10 -0
- data/VERSION +1 -0
- data/hello_goodbye.gemspec +24 -0
- data/hello_goodbye.rb +25 -0
- data/lib/hello_goodbye/console.rb +88 -0
- data/lib/hello_goodbye/consoles/foreman_console.rb +23 -0
- data/lib/hello_goodbye/consoles/manager_console.rb +35 -0
- data/lib/hello_goodbye/foreman.rb +117 -0
- data/lib/hello_goodbye/foremen_manager.rb +103 -0
- data/lib/hello_goodbye/json/request.rb +20 -0
- data/lib/hello_goodbye/json/response.rb +36 -0
- data/lib/hello_goodbye/version.rb +3 -0
- data/lib/hello_goodbye.rb +25 -0
- data/spec/hello_goodbye/console_spec.rb +67 -0
- data/spec/hello_goodbye/consoles/foreman_console_spec.rb +35 -0
- data/spec/hello_goodbye/consoles/manager_console_spec.rb +47 -0
- data/spec/hello_goodbye/foremen_manager_spec.rb +84 -0
- data/spec/hello_goodbye/foremen_spec.rb +64 -0
- data/spec/hello_goodbye/json/request_spec.rb +28 -0
- data/spec/hello_goodbye/json/response_spec.rb +35 -0
- data/spec/hello_goodbye_spec.rb +21 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +66 -0
- data/spec/test_console.rb +23 -0
- data/spec/test_foreman.rb +15 -0
- metadata +179 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
module HelloGoodbye
|
2
|
+
require File.expand_path('../../hello_goodbye/console',__FILE__)
|
3
|
+
require File.expand_path('../../hello_goodbye/foreman',__FILE__)
|
4
|
+
class ForemenManager < Foreman
|
5
|
+
|
6
|
+
DEFAULT_MANAGER_PORT = 8080
|
7
|
+
|
8
|
+
set_console_type :manager
|
9
|
+
|
10
|
+
def self.default_manager_port
|
11
|
+
DEFAULT_MANAGER_PORT
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
@next_foreman_id = -1
|
16
|
+
options.map do |key,value|
|
17
|
+
self.send("#{key}=",value) if self.respond_to?("#{key}=".to_sym)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def port
|
22
|
+
@port || DEFAULT_MANAGER_PORT
|
23
|
+
end
|
24
|
+
|
25
|
+
def foremen
|
26
|
+
@foremen ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def next_foreman_id
|
30
|
+
@next_foreman_id += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
# Registers a new forman
|
34
|
+
# Parameters:
|
35
|
+
# * foreman_hash
|
36
|
+
# :port => (int) Port number to listen on.
|
37
|
+
# :class => A reference to the foreman class
|
38
|
+
# that will handle the connection and spawn
|
39
|
+
# workers.
|
40
|
+
def register_foreman(foreman_hash)
|
41
|
+
self.foremen << foreman_hash.merge(:reference => nil, :id => next_foreman_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Starts the manager console and all the
|
45
|
+
# registered foremen.
|
46
|
+
def start!
|
47
|
+
super do
|
48
|
+
self.start_foremen
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def on_error(&block)
|
53
|
+
EM::error_handler do |e|
|
54
|
+
block.call
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Start the consoles for all foremen. This does not start
|
59
|
+
# employing workers.
|
60
|
+
def start_foremen
|
61
|
+
self.foremen.each do |foreman|
|
62
|
+
foreman[:reference] = foreman[:class].new(:server => self.server,
|
63
|
+
:port => foreman[:port])
|
64
|
+
foreman[:reference].start!
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Trigger all formen to either start or stop employing workers.
|
69
|
+
# Parameters:
|
70
|
+
# * mode => :start or :stop
|
71
|
+
# * id => The foreman's integer ID or name
|
72
|
+
def trigger_foreman(mode,id)
|
73
|
+
[].tap do |toggled_foremen|
|
74
|
+
self.foremen.each do |foreman|
|
75
|
+
if foreman[:reference].nil? || (id != "all" && foreman[:reference].my_name != id && foreman[:id] != id.to_i)
|
76
|
+
next
|
77
|
+
end
|
78
|
+
next if mode == :start && foreman[:reference].running?
|
79
|
+
next if mode == :stop && !foreman[:reference].running?
|
80
|
+
|
81
|
+
if mode == :start
|
82
|
+
foreman[:reference].employ
|
83
|
+
else
|
84
|
+
foreman[:reference].unemploy
|
85
|
+
end
|
86
|
+
toggled_foremen << foreman[:id]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def report
|
92
|
+
[].tap do |r|
|
93
|
+
self.foremen.each do |foreman|
|
94
|
+
r << {
|
95
|
+
:id => foreman[:id],
|
96
|
+
:name => foreman[:reference].my_name,
|
97
|
+
:status => foreman[:reference].status.to_s
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module HelloGoodbye
|
2
|
+
class Request
|
3
|
+
attr_accessor :request_hash
|
4
|
+
attr_reader :command
|
5
|
+
|
6
|
+
def initialize(str)
|
7
|
+
self.request_data=str
|
8
|
+
end
|
9
|
+
|
10
|
+
def request_data=(str)
|
11
|
+
@request_data = JSON.parse(str)
|
12
|
+
unless @request_data.include?("command")
|
13
|
+
raise ArgumentError,
|
14
|
+
"The JSON string you supplied is invalid. All requests must include a 'command' attribute."
|
15
|
+
end
|
16
|
+
@command = @request_data["command"]
|
17
|
+
@request_data
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module HelloGoodbye
|
2
|
+
class Response
|
3
|
+
attr_accessor :success, :results, :message
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
options.map do |key,value|
|
7
|
+
self.send("#{key}=".to_sym,value) if self.respond_to?("#{key}=".to_sym)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def success
|
12
|
+
(@success == true ? true : false )
|
13
|
+
end
|
14
|
+
|
15
|
+
def results=(r)
|
16
|
+
if r.nil?
|
17
|
+
@results = nil
|
18
|
+
else
|
19
|
+
@results = Array(r)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
h = {
|
25
|
+
"success" => self.success,
|
26
|
+
"message" => self.message.to_s
|
27
|
+
}
|
28
|
+
h["results"] = self.results if !self.results.nil?
|
29
|
+
h
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
self.to_hash.to_json
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require File.expand_path('../hello_goodbye/foremen_manager',__FILE__)
|
6
|
+
|
7
|
+
module HelloGoodbye
|
8
|
+
|
9
|
+
# Resets the current foremen manager, so that the next time
|
10
|
+
# self.manager is called, a new ForemenManager instance will be
|
11
|
+
# created.
|
12
|
+
def self.reset!
|
13
|
+
@manager = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a new manager or use the existing manager. If an existing manager exists,
|
17
|
+
# port and server will be ignored.
|
18
|
+
# Parameters:
|
19
|
+
# * port: The port the manager should connect to.
|
20
|
+
# * server: The server the service will run from.
|
21
|
+
def self.manager(port=ForemenManager.default_manager_port,server=Foreman.default_server)
|
22
|
+
@manager ||= ForemenManager.new(:port => port, :server => server)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
describe HelloGoodbye::Console do
|
2
|
+
|
3
|
+
let(:console) do
|
4
|
+
h = HelloGoodbye::Console.new 1
|
5
|
+
|
6
|
+
# Override EM method for this object
|
7
|
+
def h.send_data(data)
|
8
|
+
# Do nothing
|
9
|
+
end
|
10
|
+
|
11
|
+
def h.close_connection
|
12
|
+
# Do nothing
|
13
|
+
end
|
14
|
+
|
15
|
+
h
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:test_console) do
|
19
|
+
HelloGoodbye::TestConsole.new 1
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".get" do
|
23
|
+
it "should raise error when console not recognized" do
|
24
|
+
expect{
|
25
|
+
HelloGoodbye::Console.get(:nothing)
|
26
|
+
}.to raise_error
|
27
|
+
end
|
28
|
+
it "should return a manager console" do
|
29
|
+
HelloGoodbye::Console.get(:manager).should be(HelloGoodbye::ManagerConsole)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#receive_command" do
|
34
|
+
it "should return false on unknown actions" do
|
35
|
+
console.receive_command("custom_action").should be(false)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return true on known actions" do
|
39
|
+
console.receive_command("hello").should be(true)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "basic commands" do
|
44
|
+
it "should reply to hello" do
|
45
|
+
command_to_console(console,"hello")["message"].should eq("hello")
|
46
|
+
end
|
47
|
+
it "should reply to goodbye and close connection" do
|
48
|
+
command_to_console(console,"goodbye")["message"].should eq("goodbye")
|
49
|
+
console.connection_closed?().should be_true
|
50
|
+
end
|
51
|
+
it "should report unknown commands" do
|
52
|
+
c = command_to_console(console,"unknown_action")
|
53
|
+
c["message"].should eq("unknown command")
|
54
|
+
c["success"].should be_false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "custom consoles" do
|
59
|
+
it "should reply to default commands" do
|
60
|
+
command_to_console(test_console,"hello")["message"].should eq("hello")
|
61
|
+
end
|
62
|
+
it "should reply to custom commands" do
|
63
|
+
command_to_console(test_console,"custom")["message"].should eq("test command")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
describe HelloGoodbye::Console do
|
2
|
+
|
3
|
+
before(:all) do
|
4
|
+
@foreman = HelloGoodbye::TestForeman.new
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:foreman_console) do
|
8
|
+
f = HelloGoodbye::TestConsole.new(1)
|
9
|
+
f.foreman = @foreman
|
10
|
+
f
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:foreman) do
|
14
|
+
@foreman
|
15
|
+
end
|
16
|
+
|
17
|
+
context "starting and stopping the foreman" do
|
18
|
+
it "should start the foreman class from the console" do
|
19
|
+
r = command_to_console(foreman_console,"start")
|
20
|
+
r["message"].should eq("ok")
|
21
|
+
foreman.status.should be(:running)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should stop the foreman class from the console" do
|
25
|
+
r = command_to_console(foreman_console,"stop")
|
26
|
+
r["message"].should eq("ok")
|
27
|
+
foreman.status.should be(:stopped)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should stop report the status of the forman" do
|
31
|
+
r = command_to_console(foreman_console,"status")
|
32
|
+
r["message"].should eq("stopped")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
describe HelloGoodbye::ManagerConsole do
|
2
|
+
before(:all) do
|
3
|
+
@manager = HelloGoodbye::ForemenManager.new
|
4
|
+
@manager.register_foreman({
|
5
|
+
:port => 8081,
|
6
|
+
:class => HelloGoodbye::TestForeman
|
7
|
+
})
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:manager) do
|
11
|
+
@manager
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:manager_console) do
|
15
|
+
m = HelloGoodbye::ManagerConsole.new(1)
|
16
|
+
m.foreman = @manager
|
17
|
+
m
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when running with a manager" do
|
21
|
+
it "should report on active foreman" do
|
22
|
+
start_foremen_manager_and(manager) do |manager|
|
23
|
+
h = command_to_console(manager_console, "foremen")
|
24
|
+
h["results"].size.should be(1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should start foremen by name" do
|
29
|
+
start_foremen_manager_and(manager) do |manager|
|
30
|
+
h = command_to_console(manager_console, "start test")
|
31
|
+
h["results"].first.should be(0)
|
32
|
+
manager_console.foreman.foremen.first[:reference].running?().should be_true
|
33
|
+
|
34
|
+
h = command_to_console(manager_console, "stop 0")
|
35
|
+
h["results"].first.should be(0)
|
36
|
+
manager_console.foreman.foremen.first[:reference].running?().should be_false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should start all foremen with 'all'" do
|
41
|
+
h = command_to_console(manager_console, "start all")
|
42
|
+
h["results"].first.should be(0)
|
43
|
+
manager_console.foreman.foremen.first[:reference].running?().should be_true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
describe HelloGoodbye::ForemenManager do
|
2
|
+
|
3
|
+
before(:all) do
|
4
|
+
@manager = HelloGoodbye::ForemenManager.new
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:manager) do
|
8
|
+
@manager
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".console_type" do
|
12
|
+
it "should be :manager" do
|
13
|
+
HelloGoodbye::ForemenManager.console_type.should be(:manager)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when registering foremen" do
|
18
|
+
it "should allow foremen to be registered" do
|
19
|
+
manager.register_foreman({
|
20
|
+
:port => 8081,
|
21
|
+
:class => HelloGoodbye::TestForeman
|
22
|
+
})
|
23
|
+
manager.register_foreman({
|
24
|
+
:port => 8082,
|
25
|
+
:class => HelloGoodbye::TestForeman
|
26
|
+
})
|
27
|
+
manager.foremen.size.should be(2)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should give each forman unique ids" do
|
31
|
+
manager.foremen.first[:id].should_not eq(manager.foremen[1][:id])
|
32
|
+
end
|
33
|
+
it "should not have references to objects" do
|
34
|
+
manager.foremen.each do |f|
|
35
|
+
f[:reference].should be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when starting the manager" do
|
41
|
+
it "should spawn a responsive console" do
|
42
|
+
start_foremen_manager_and do |manager|
|
43
|
+
EM.run_block do
|
44
|
+
expect {
|
45
|
+
c = TCPSocket.open(default_server,default_port)
|
46
|
+
c.close
|
47
|
+
}.to_not raise_error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should start foremen" do
|
53
|
+
start_foremen_manager_and(manager) do |manager|
|
54
|
+
manager.foremen.each do |f|
|
55
|
+
f[:reference].should be_a(HelloGoodbye::TestForeman)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should spawn a responsive console for foremen" do
|
61
|
+
start_foremen_manager_and(manager) do |manager|
|
62
|
+
EM.run_block do
|
63
|
+
expect {
|
64
|
+
c = TCPSocket.open(default_server,manager.foremen.first[:reference].port)
|
65
|
+
c.close
|
66
|
+
}.to_not raise_error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should report active foreman" do
|
72
|
+
start_foremen_manager_and(manager) do |manager|
|
73
|
+
EM.run_block do
|
74
|
+
manager.report.first.should eq({:id => manager.foremen.first[:id],
|
75
|
+
:name => "test", :status => "stopped"})
|
76
|
+
manager.foremen.first[:reference].employ
|
77
|
+
manager.report.first.should eq({:id => manager.foremen.first[:id],
|
78
|
+
:name => "test", :status => "running"})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
describe HelloGoodbye::Foreman do
|
2
|
+
before(:all) do
|
3
|
+
@manager = HelloGoodbye::ForemenManager.new
|
4
|
+
@manager.register_foreman({
|
5
|
+
:port => 8081,
|
6
|
+
:class => HelloGoodbye::TestForeman
|
7
|
+
})
|
8
|
+
end
|
9
|
+
let(:manager) do
|
10
|
+
@manager
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:foreman) do
|
14
|
+
HelloGoodbye::Foreman
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:test_foreman) do
|
18
|
+
HelloGoodbye::TestForeman
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".console_type" do
|
22
|
+
it "should default to type :foreman" do
|
23
|
+
foreman.console_type.should be(:foreman)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be overridable by custom consoles :test_foreman" do
|
27
|
+
test_foreman.console_type.should be(:test)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "starting the foreman" do
|
32
|
+
it "should only be startable once" do
|
33
|
+
f = foreman.new
|
34
|
+
EM.run_block do
|
35
|
+
f.start!
|
36
|
+
expect {
|
37
|
+
f.start!
|
38
|
+
}.to raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "under the control of a manager" do
|
44
|
+
it "should be stopped initially" do
|
45
|
+
start_foremen_manager_and(manager) do |manager|
|
46
|
+
manager.foremen.first[:reference].status.should be(:stopped)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
it "should be employable" do
|
50
|
+
start_foremen_manager_and(manager) do |manager|
|
51
|
+
f = manager.foremen.first[:reference]
|
52
|
+
f.employ
|
53
|
+
f.status.should be(:running)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
it "should be unemployable" do
|
57
|
+
start_foremen_manager_and(manager) do |manager|
|
58
|
+
f = manager.foremen.first[:reference]
|
59
|
+
f.unemploy
|
60
|
+
f.status.should be(:stopped)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe HelloGoodbye::Request do
|
2
|
+
let(:request) do
|
3
|
+
HelloGoodbye::Request
|
4
|
+
end
|
5
|
+
describe "#request_data" do
|
6
|
+
it "should require valid json" do
|
7
|
+
expect {
|
8
|
+
request.new("So not JSON")
|
9
|
+
}.to raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should require a command attribute" do
|
13
|
+
expect {
|
14
|
+
request.new '{"success": true}'
|
15
|
+
}.to raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be successful with a command" do
|
19
|
+
expect {
|
20
|
+
request.new '{"command": "hello"}'
|
21
|
+
}.to_not raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set command attribute" do
|
25
|
+
request.new('{"command": "hello"}').command.should eq("hello")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
describe HelloGoodbye::Response do
|
2
|
+
let(:results_response) do
|
3
|
+
HelloGoodbye::Response.new :success => true,
|
4
|
+
:message => "Hi Mom!", :results => [{"color" => "blue"}]
|
5
|
+
end
|
6
|
+
let(:response) do
|
7
|
+
HelloGoodbye::Response.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should set fields from initialization" do
|
11
|
+
results_response.success.should be_true
|
12
|
+
results_response.message.should eq("Hi Mom!")
|
13
|
+
results_response.results.first.should eq({"color" => "blue"})
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should default to unsuccessful" do
|
17
|
+
response.success.should be_false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should exclude results from hash when there are none" do
|
21
|
+
response.to_hash["results"].should be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should build a hash based on values" do
|
25
|
+
results_response.to_hash["message"].should eq("Hi Mom!")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should build a hash based on values" do
|
29
|
+
results_response.to_hash["results"].size.should eq(1)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return a json string" do
|
33
|
+
response.to_json.should be_a(String)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe HelloGoodbye do
|
2
|
+
describe "Mother Module" do
|
3
|
+
it "should create a new manager" do
|
4
|
+
m = HelloGoodbye.manager
|
5
|
+
m.should be_a(HelloGoodbye::ForemenManager)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should return the same manager instance" do
|
9
|
+
m = HelloGoodbye.manager(2000,"joshcom.net")
|
10
|
+
m2 = HelloGoodbye.manager
|
11
|
+
m.should be(m2)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should create a new manager instance after reset!" do
|
15
|
+
m = HelloGoodbye.manager(2000,"joshcom.net")
|
16
|
+
HelloGoodbye.reset!
|
17
|
+
m2 = HelloGoodbye.manager
|
18
|
+
m.should_not be(m2)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.expand_path('../../lib/hello_goodbye',__FILE__)
|
2
|
+
require File.expand_path('../../spec/test_foreman',__FILE__)
|
3
|
+
require File.expand_path('../../spec/test_console',__FILE__)
|
4
|
+
require File.expand_path('../../lib/hello_goodbye/json/request',__FILE__)
|
5
|
+
require File.expand_path('../../lib/hello_goodbye/json/response',__FILE__)
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
|
9
|
+
# Possibly the most important helper method.
|
10
|
+
# This method, in the following order:
|
11
|
+
# 1. Starts an event loop
|
12
|
+
# 2. Executes #start! on either the parameter ForemenManager or
|
13
|
+
# creates a new ForemenManager and executes start! on that.
|
14
|
+
# 3. Yields to a given block, passing the ForemenManager to that block.
|
15
|
+
# 4. Stops the event loop.
|
16
|
+
def start_foremen_manager_and(f=spec_manager)
|
17
|
+
f.instance_variable_set("@foreman_started",false)
|
18
|
+
EM.run_block do
|
19
|
+
f.start!
|
20
|
+
yield(f)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def command_to_json_str(command)
|
25
|
+
{
|
26
|
+
:command => command
|
27
|
+
}.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
def command_to_console(console,command)
|
31
|
+
sent_data = nil
|
32
|
+
override_method(console,'send_data') do |data|
|
33
|
+
sent_data = data
|
34
|
+
end
|
35
|
+
override_method(console,'close_connection') do
|
36
|
+
@test_connection_closed = true
|
37
|
+
end
|
38
|
+
override_method(console,'connection_closed?') do
|
39
|
+
@test_connection_closed || false
|
40
|
+
end
|
41
|
+
console.receive_command(command)
|
42
|
+
build_response_hash(sent_data)
|
43
|
+
end
|
44
|
+
|
45
|
+
def override_method(console,method,&block)
|
46
|
+
(class << console; self; end).send(:define_method, method) do |*args|
|
47
|
+
block.call(*args)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_response_hash(data)
|
52
|
+
JSON.parse(data)
|
53
|
+
end
|
54
|
+
|
55
|
+
def default_server
|
56
|
+
"127.0.0.1"
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_port
|
60
|
+
8080
|
61
|
+
end
|
62
|
+
|
63
|
+
def spec_manager
|
64
|
+
HelloGoodbye::ForemenManager.new(:port => default_port,
|
65
|
+
:server => default_server)
|
66
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../../lib/hello_goodbye',__FILE__)
|
2
|
+
|
3
|
+
module HelloGoodbye
|
4
|
+
class TestConsole < ForemanConsole
|
5
|
+
def receive_command(command)
|
6
|
+
case command
|
7
|
+
when "custom"
|
8
|
+
send_response :success => true,
|
9
|
+
:message => "test command"
|
10
|
+
return true
|
11
|
+
when "error"
|
12
|
+
send_response :success => true,
|
13
|
+
:message => "oops"
|
14
|
+
raise RuntimeError, "Oh noooooes!"
|
15
|
+
when "kill"
|
16
|
+
send_response :success => true,
|
17
|
+
:message => "Why me?"
|
18
|
+
EM.stop
|
19
|
+
end
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|