hello_goodbye 0.1.0
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.
- 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
|