itrg-invoker 1.6.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.
- checksums.yaml +7 -0
- data/bin/invoker +7 -0
- data/lib/invoker/cli/pinger.rb +23 -0
- data/lib/invoker/cli/question.rb +15 -0
- data/lib/invoker/cli/tail.rb +34 -0
- data/lib/invoker/cli/tail_watcher.rb +34 -0
- data/lib/invoker/cli.rb +197 -0
- data/lib/invoker/command_worker.rb +64 -0
- data/lib/invoker/commander.rb +101 -0
- data/lib/invoker/daemon.rb +126 -0
- data/lib/invoker/dns_cache.rb +23 -0
- data/lib/invoker/errors.rb +17 -0
- data/lib/invoker/event/manager.rb +79 -0
- data/lib/invoker/ipc/add_command.rb +12 -0
- data/lib/invoker/ipc/add_http_command.rb +10 -0
- data/lib/invoker/ipc/base_command.rb +24 -0
- data/lib/invoker/ipc/client_handler.rb +26 -0
- data/lib/invoker/ipc/dns_check_command.rb +17 -0
- data/lib/invoker/ipc/list_command.rb +11 -0
- data/lib/invoker/ipc/message/list_response.rb +35 -0
- data/lib/invoker/ipc/message/tail_response.rb +10 -0
- data/lib/invoker/ipc/message.rb +170 -0
- data/lib/invoker/ipc/ping_command.rb +10 -0
- data/lib/invoker/ipc/reload_command.rb +12 -0
- data/lib/invoker/ipc/remove_command.rb +12 -0
- data/lib/invoker/ipc/server.rb +26 -0
- data/lib/invoker/ipc/tail_command.rb +11 -0
- data/lib/invoker/ipc/unix_client.rb +60 -0
- data/lib/invoker/ipc.rb +45 -0
- data/lib/invoker/logger.rb +13 -0
- data/lib/invoker/parsers/config.rb +184 -0
- data/lib/invoker/parsers/procfile.rb +86 -0
- data/lib/invoker/power/balancer.rb +133 -0
- data/lib/invoker/power/config.rb +77 -0
- data/lib/invoker/power/dns.rb +38 -0
- data/lib/invoker/power/http_parser.rb +68 -0
- data/lib/invoker/power/http_response.rb +81 -0
- data/lib/invoker/power/port_finder.rb +49 -0
- data/lib/invoker/power/power.rb +3 -0
- data/lib/invoker/power/powerup.rb +29 -0
- data/lib/invoker/power/setup/distro/arch.rb +15 -0
- data/lib/invoker/power/setup/distro/base.rb +80 -0
- data/lib/invoker/power/setup/distro/debian.rb +11 -0
- data/lib/invoker/power/setup/distro/opensuse.rb +11 -0
- data/lib/invoker/power/setup/distro/redhat.rb +11 -0
- data/lib/invoker/power/setup/distro/ubuntu.rb +46 -0
- data/lib/invoker/power/setup/files/invoker_forwarder.sh.erb +17 -0
- data/lib/invoker/power/setup/files/socat_invoker.service +12 -0
- data/lib/invoker/power/setup/linux_setup.rb +97 -0
- data/lib/invoker/power/setup/osx_setup.rb +137 -0
- data/lib/invoker/power/setup.rb +93 -0
- data/lib/invoker/power/templates/400.html +40 -0
- data/lib/invoker/power/templates/404.html +40 -0
- data/lib/invoker/power/templates/503.html +40 -0
- data/lib/invoker/power/url_rewriter.rb +40 -0
- data/lib/invoker/process_manager.rb +201 -0
- data/lib/invoker/process_printer.rb +59 -0
- data/lib/invoker/reactor/reader.rb +65 -0
- data/lib/invoker/reactor.rb +37 -0
- data/lib/invoker/version.rb +47 -0
- data/lib/invoker.rb +151 -0
- data/spec/invoker/cli/pinger_spec.rb +22 -0
- data/spec/invoker/cli/tail_watcher_spec.rb +39 -0
- data/spec/invoker/cli_spec.rb +27 -0
- data/spec/invoker/command_worker_spec.rb +45 -0
- data/spec/invoker/commander_spec.rb +152 -0
- data/spec/invoker/config_spec.rb +361 -0
- data/spec/invoker/daemon_spec.rb +34 -0
- data/spec/invoker/event/manager_spec.rb +67 -0
- data/spec/invoker/invoker_spec.rb +71 -0
- data/spec/invoker/ipc/client_handler_spec.rb +54 -0
- data/spec/invoker/ipc/dns_check_command_spec.rb +32 -0
- data/spec/invoker/ipc/message/list_response_spec.rb +24 -0
- data/spec/invoker/ipc/message_spec.rb +49 -0
- data/spec/invoker/ipc/unix_client_spec.rb +29 -0
- data/spec/invoker/power/balancer_spec.rb +53 -0
- data/spec/invoker/power/config_spec.rb +18 -0
- data/spec/invoker/power/http_parser_spec.rb +32 -0
- data/spec/invoker/power/http_response_spec.rb +34 -0
- data/spec/invoker/power/port_finder_spec.rb +16 -0
- data/spec/invoker/power/setup/linux_setup_spec.rb +166 -0
- data/spec/invoker/power/setup/osx_setup_spec.rb +105 -0
- data/spec/invoker/power/setup_spec.rb +4 -0
- data/spec/invoker/power/url_rewriter_spec.rb +69 -0
- data/spec/invoker/power/web_sockets_spec.rb +61 -0
- data/spec/invoker/process_manager_spec.rb +130 -0
- data/spec/invoker/reactor_spec.rb +6 -0
- data/spec/spec_helper.rb +43 -0
- metadata +376 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Invoker::CLI::TailWatcher do
|
4
|
+
let(:tail_watcher) { Invoker::CLI::TailWatcher.new }
|
5
|
+
|
6
|
+
describe "Adding processes to watch list" do
|
7
|
+
it "should allow add" do
|
8
|
+
tail_watcher.add(["rails"], "socket")
|
9
|
+
expect(tail_watcher.tail_watchers).to_not be_empty
|
10
|
+
expect(tail_watcher["rails"]).to eql ["socket"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "removing processes from watch list" do
|
15
|
+
context "when process has only one watcher" do
|
16
|
+
before do
|
17
|
+
tail_watcher.add(["rails"], "socket")
|
18
|
+
end
|
19
|
+
it "should remove and purge process watch list" do
|
20
|
+
expect(tail_watcher.tail_watchers).to_not be_empty
|
21
|
+
tail_watcher.remove("rails", "socket")
|
22
|
+
expect(tail_watcher.tail_watchers).to be_empty
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context "when process multiple watchers" do
|
26
|
+
before do
|
27
|
+
tail_watcher.add(["rails"], "socket")
|
28
|
+
tail_watcher.add(["rails"], "socket2")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should remove only related socket" do
|
32
|
+
expect(tail_watcher.tail_watchers).to_not be_empty
|
33
|
+
tail_watcher.remove("rails", "socket")
|
34
|
+
expect(tail_watcher.tail_watchers).to_not be_empty
|
35
|
+
expect(tail_watcher["rails"]).to eql ["socket2"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Invoker::CLI do
|
4
|
+
describe "default start command" do
|
5
|
+
it "should use default if no other command specified" do
|
6
|
+
Invoker::CLI.any_instance.expects(:start).with("dummy")
|
7
|
+
Invoker::CLI.start(["dummy"])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use proper command if it exists" do
|
11
|
+
Invoker::CLI.any_instance.expects(:list)
|
12
|
+
Invoker::CLI.start(["list"])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should list version" do
|
16
|
+
Invoker::CLI.any_instance.expects(:version)
|
17
|
+
Invoker::CLI.start(["-v"])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "stop command" do
|
22
|
+
it "should stop the daemon" do
|
23
|
+
Invoker.daemon.expects(:stop).once
|
24
|
+
Invoker::CLI.start(["stop"])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Command Worker" do
|
4
|
+
let(:pipe_end) { StringIO.new }
|
5
|
+
let(:command_worker) { Invoker::CommandWorker.new('rails', pipe_end, 100, :red) }
|
6
|
+
|
7
|
+
describe "converting workers hash to json" do
|
8
|
+
before do
|
9
|
+
@workers = {}
|
10
|
+
@workers["foo"] = Invoker::CommandWorker.new("foo", 89, 1023, "red")
|
11
|
+
@workers["bar"] = Invoker::CommandWorker.new("bar", 99, 1024, "blue")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should print json" do
|
15
|
+
expect(@workers.values.map {|worker| worker.to_h }.to_json).not_to be_empty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "sending json responses" do
|
20
|
+
before do
|
21
|
+
@socket = StringIO.new
|
22
|
+
Invoker.tail_watchers = Invoker::CLI::TailWatcher.new
|
23
|
+
Invoker.tail_watchers.add(['rails'], @socket)
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
Invoker.tail_watchers = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when there is a error encoding the message" do
|
31
|
+
it "should send nothing to the socket" do
|
32
|
+
MM::TailResponse.any_instance.expects(:encoded_message).raises(StandardError, "encoding error")
|
33
|
+
command_worker.receive_line('hello_world')
|
34
|
+
expect(@socket.string).to be_empty
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when there is successful delivery" do
|
39
|
+
it "should return json data to client if tail watchers" do
|
40
|
+
command_worker.receive_line('hello_world')
|
41
|
+
expect(@socket.string).to match(/hello_world/)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Invoker::Commander" do
|
4
|
+
before(:each) do
|
5
|
+
@original_invoker_config = Invoker.config
|
6
|
+
Invoker.config = mock
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
Invoker.config = @original_invoker_config
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "With no processes configured" do
|
14
|
+
before(:each) do
|
15
|
+
@commander = Invoker::Commander.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should throw error" do
|
19
|
+
Invoker.config.stubs(:processes).returns([])
|
20
|
+
|
21
|
+
expect {
|
22
|
+
@commander.start_manager
|
23
|
+
}.to raise_error(Invoker::Errors::InvalidConfig)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#start_process" do
|
28
|
+
describe "when not daemonized" do
|
29
|
+
before do
|
30
|
+
processes = [OpenStruct.new(:label => "foobar", :cmd => "foobar_command", :dir => ENV['HOME'], :sleep_duration => 2)]
|
31
|
+
Invoker.config.stubs(:processes).returns(processes)
|
32
|
+
Invoker.config.stubs(:autorunnable_processes).returns(processes)
|
33
|
+
Invoker.stubs(:can_run_balancer?).returns(false)
|
34
|
+
@commander = Invoker::Commander.new
|
35
|
+
Invoker.commander = @commander
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
Invoker.commander = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should populate workers and open_pipes" do
|
43
|
+
@commander.expects(:start_event_loop)
|
44
|
+
@commander.process_manager.expects(:load_env).returns({})
|
45
|
+
@commander.process_manager.expects(:spawn).returns(100)
|
46
|
+
@commander.process_manager.expects(:wait_on_pid)
|
47
|
+
@commander.expects(:at_exit)
|
48
|
+
@commander.start_manager
|
49
|
+
expect(@commander.process_manager.open_pipes).not_to be_empty
|
50
|
+
expect(@commander.process_manager.workers).not_to be_empty
|
51
|
+
|
52
|
+
worker = @commander.process_manager.workers['foobar']
|
53
|
+
|
54
|
+
expect(worker).not_to be_nil
|
55
|
+
expect(worker.command_label).to eq('foobar')
|
56
|
+
|
57
|
+
pipe_end_worker = @commander.process_manager.open_pipes[worker.pipe_end.fileno]
|
58
|
+
expect(pipe_end_worker).not_to be_nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "when daemonized" do
|
63
|
+
before do
|
64
|
+
processes = [OpenStruct.new(:label => "foobar", :cmd => "foobar_command", :dir => ENV['HOME'], :sleep_duration => 2)]
|
65
|
+
Invoker.config.stubs(:processes).returns(processes)
|
66
|
+
Invoker.config.stubs(:autorunnable_processes).returns(processes)
|
67
|
+
Invoker.stubs(:can_run_balancer?).returns(false)
|
68
|
+
@commander = Invoker::Commander.new
|
69
|
+
Invoker.commander = @commander
|
70
|
+
Invoker.daemonize = true
|
71
|
+
end
|
72
|
+
|
73
|
+
after do
|
74
|
+
Invoker.commander = nil
|
75
|
+
Invoker.daemonize = false
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should daemonize the process and populate workers and open_pipes" do
|
79
|
+
@commander.expects(:start_event_loop)
|
80
|
+
@commander.process_manager.expects(:load_env).returns({})
|
81
|
+
Invoker.daemon.expects(:start).once
|
82
|
+
@commander.process_manager.expects(:spawn).returns(100)
|
83
|
+
@commander.process_manager.expects(:wait_on_pid)
|
84
|
+
@commander.expects(:at_exit)
|
85
|
+
@commander.start_manager
|
86
|
+
|
87
|
+
expect(@commander.process_manager.open_pipes).not_to be_empty
|
88
|
+
expect(@commander.process_manager.workers).not_to be_empty
|
89
|
+
|
90
|
+
worker = @commander.process_manager.workers['foobar']
|
91
|
+
|
92
|
+
expect(worker).not_to be_nil
|
93
|
+
expect(worker.command_label).to eq('foobar')
|
94
|
+
|
95
|
+
pipe_end_worker = @commander.process_manager.open_pipes[worker.pipe_end.fileno]
|
96
|
+
expect(pipe_end_worker).not_to be_nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'disable_autorun option' do
|
102
|
+
context 'autorun is disabled for a process' do
|
103
|
+
before do
|
104
|
+
@processes = [
|
105
|
+
OpenStruct.new(:label => "foobar", :cmd => "foobar_command", :dir => ENV['HOME'], :sleep_duration => 2),
|
106
|
+
OpenStruct.new(:label => "panda", :cmd => "panda_command", :dir => ENV['HOME'], :disable_autorun => true, :sleep_duration => 2)
|
107
|
+
]
|
108
|
+
Invoker.config.stubs(:processes).returns(@processes)
|
109
|
+
Invoker.config.stubs(:autorunnable_processes).returns([@processes.first])
|
110
|
+
|
111
|
+
@commander = Invoker::Commander.new
|
112
|
+
end
|
113
|
+
|
114
|
+
it "doesn't run process" do
|
115
|
+
@commander.expects(:install_interrupt_handler)
|
116
|
+
@commander.process_manager.expects(:run_power_server)
|
117
|
+
@commander.expects(:at_exit)
|
118
|
+
@commander.expects(:start_event_loop)
|
119
|
+
|
120
|
+
@commander.process_manager.expects(:start_process).with(@processes[0])
|
121
|
+
@commander.process_manager.expects(:start_process).with(@processes[1]).never
|
122
|
+
@commander.start_manager
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#runnables" do
|
128
|
+
before do
|
129
|
+
@commander = Invoker::Commander.new
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should run runnables in reactor tick with one argument" do
|
133
|
+
@commander.on_next_tick("foo") { |cmd| start_process_by_name(cmd) }
|
134
|
+
@commander.expects(:start_process_by_name).returns(true)
|
135
|
+
@commander.run_runnables()
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should run runnables with multiple args" do
|
139
|
+
@commander.on_next_tick("foo", "bar", "baz") { |t1,*rest|
|
140
|
+
stop_process(t1, rest)
|
141
|
+
}
|
142
|
+
@commander.expects(:stop_process).with("foo", ["bar", "baz"]).returns(true)
|
143
|
+
@commander.run_runnables()
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should run runnable with no args" do
|
147
|
+
@commander.on_next_tick() { hello() }
|
148
|
+
@commander.expects(:hello).returns(true)
|
149
|
+
@commander.run_runnables()
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,361 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "tempfile"
|
4
|
+
|
5
|
+
describe "Invoker::Config" do
|
6
|
+
describe "with invalid directory" do
|
7
|
+
it "should raise error during startup" do
|
8
|
+
begin
|
9
|
+
file = Tempfile.new(["invalid_config", ".ini"])
|
10
|
+
|
11
|
+
config_data =<<-EOD
|
12
|
+
[try_sleep]
|
13
|
+
directory = /Users/gnufied/foo
|
14
|
+
command = ruby try_sleep.rb
|
15
|
+
EOD
|
16
|
+
file.write(config_data)
|
17
|
+
file.close
|
18
|
+
expect {
|
19
|
+
Invoker::Parsers::Config.new(file.path, 9000)
|
20
|
+
}.to raise_error(Invoker::Errors::InvalidConfig)
|
21
|
+
ensure
|
22
|
+
file.unlink()
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "with relative directory path" do
|
28
|
+
it "should expand path in commands" do
|
29
|
+
begin
|
30
|
+
file = Tempfile.new(["config", ".ini"])
|
31
|
+
|
32
|
+
config_data =<<-EOD
|
33
|
+
[pwd_home]
|
34
|
+
directory = ~
|
35
|
+
command = pwd
|
36
|
+
|
37
|
+
[pwd_parent]
|
38
|
+
directory = ../
|
39
|
+
command = pwd
|
40
|
+
EOD
|
41
|
+
file.write(config_data)
|
42
|
+
file.close
|
43
|
+
|
44
|
+
config = Invoker::Parsers::Config.new(file.path, 9000)
|
45
|
+
command1 = config.processes.first
|
46
|
+
|
47
|
+
expect(command1.dir).to match(File.expand_path('~'))
|
48
|
+
|
49
|
+
command2 = config.processes[1]
|
50
|
+
|
51
|
+
expect(command2.dir).to match(File.expand_path('..'))
|
52
|
+
ensure
|
53
|
+
file.unlink()
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "for ports" do
|
59
|
+
it "should replace port in commands" do
|
60
|
+
begin
|
61
|
+
file = Tempfile.new(["invalid_config", ".ini"])
|
62
|
+
|
63
|
+
config_data =<<-EOD
|
64
|
+
[try_sleep]
|
65
|
+
directory = /tmp
|
66
|
+
command = ruby try_sleep.rb -p $PORT
|
67
|
+
|
68
|
+
[ls]
|
69
|
+
directory = /tmp
|
70
|
+
command = ls -p $PORT
|
71
|
+
|
72
|
+
[noport]
|
73
|
+
directory = /tmp
|
74
|
+
command = ls
|
75
|
+
EOD
|
76
|
+
file.write(config_data)
|
77
|
+
file.close
|
78
|
+
|
79
|
+
config = Invoker::Parsers::Config.new(file.path, 9000)
|
80
|
+
command1 = config.processes.first
|
81
|
+
|
82
|
+
expect(command1.port).to eq(9000)
|
83
|
+
expect(command1.cmd).to match(/9000/)
|
84
|
+
|
85
|
+
command2 = config.processes[1]
|
86
|
+
|
87
|
+
expect(command2.port).to eq(9001)
|
88
|
+
expect(command2.cmd).to match(/9001/)
|
89
|
+
|
90
|
+
command2 = config.processes[2]
|
91
|
+
|
92
|
+
expect(command2.port).to be_nil
|
93
|
+
ensure
|
94
|
+
file.unlink()
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should use port from separate option" do
|
99
|
+
begin
|
100
|
+
file = Tempfile.new(["invalid_config", ".ini"])
|
101
|
+
config_data =<<-EOD
|
102
|
+
[try_sleep]
|
103
|
+
directory = /tmp
|
104
|
+
command = ruby try_sleep.rb -p $PORT
|
105
|
+
|
106
|
+
[ls]
|
107
|
+
directory = /tmp
|
108
|
+
port = 3000
|
109
|
+
command = pwd
|
110
|
+
|
111
|
+
[noport]
|
112
|
+
directory = /tmp
|
113
|
+
command = ls
|
114
|
+
EOD
|
115
|
+
file.write(config_data)
|
116
|
+
file.close
|
117
|
+
|
118
|
+
config = Invoker::Parsers::Config.new(file.path, 9000)
|
119
|
+
command1 = config.processes.first
|
120
|
+
|
121
|
+
expect(command1.port).to eq(9000)
|
122
|
+
expect(command1.cmd).to match(/9000/)
|
123
|
+
|
124
|
+
command2 = config.processes[1]
|
125
|
+
|
126
|
+
expect(command2.port).to eq(3000)
|
127
|
+
|
128
|
+
command2 = config.processes[2]
|
129
|
+
|
130
|
+
expect(command2.port).to be_nil
|
131
|
+
ensure
|
132
|
+
file.unlink()
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "loading power config", fakefs: true do
|
138
|
+
before do
|
139
|
+
FileUtils.mkdir_p('/tmp')
|
140
|
+
FileUtils.mkdir_p(inv_conf_dir)
|
141
|
+
File.open("/tmp/foo.ini", "w") { |fl| fl.write("") }
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does not load config if platform is darwin but there is no power config file" do
|
145
|
+
Invoker::Power::Config.expects(:load_config).never
|
146
|
+
Invoker::Parsers::Config.new("/tmp/foo.ini", 9000)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "loads config if platform is darwin and power config file exists" do
|
150
|
+
File.open(Invoker::Power::Config.config_file, "w") { |fl| fl.puts "sample" }
|
151
|
+
Invoker::Power::Config.expects(:load_config).once
|
152
|
+
Invoker::Parsers::Config.new("/tmp/foo.ini", 9000)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "Procfile" do
|
157
|
+
it "should load Procfiles and create config object" do
|
158
|
+
File.open("/tmp/Procfile", "w") {|fl|
|
159
|
+
fl.write <<-EOD
|
160
|
+
web: bundle exec rails s -p $PORT
|
161
|
+
EOD
|
162
|
+
}
|
163
|
+
config = Invoker::Parsers::Config.new("/tmp/Procfile", 9000)
|
164
|
+
command1 = config.processes.first
|
165
|
+
|
166
|
+
expect(command1.port).to eq(9000)
|
167
|
+
expect(command1.cmd).to match(/bundle exec rails/)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "Copy of DNS information" do
|
172
|
+
it "should allow copy of DNS information" do
|
173
|
+
File.open("/tmp/Procfile", "w") {|fl|
|
174
|
+
fl.write <<-EOD
|
175
|
+
web: bundle exec rails s -p $PORT
|
176
|
+
EOD
|
177
|
+
}
|
178
|
+
Invoker.load_invoker_config("/tmp/Procfile", 9000)
|
179
|
+
dns_cache = Invoker::DNSCache.new(Invoker.config)
|
180
|
+
|
181
|
+
expect(dns_cache.dns_data).to_not be_empty
|
182
|
+
expect(dns_cache.dns_data['web']).to_not be_empty
|
183
|
+
expect(dns_cache.dns_data['web']['port']).to eql 9000
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#autorunnable_processes" do
|
188
|
+
it "returns a list of processes that can be autorun" do
|
189
|
+
begin
|
190
|
+
file = Tempfile.new(["config", ".ini"])
|
191
|
+
config_data =<<-EOD
|
192
|
+
[postgres]
|
193
|
+
command = postgres -D /usr/local/var/postgres
|
194
|
+
|
195
|
+
[redis]
|
196
|
+
command = redis-server /usr/local/etc/redis.conf
|
197
|
+
disable_autorun = true
|
198
|
+
|
199
|
+
[memcached]
|
200
|
+
command = /usr/local/opt/memcached/bin/memcached
|
201
|
+
disable_autorun = false
|
202
|
+
|
203
|
+
[panda-api]
|
204
|
+
command = bundle exec rails s
|
205
|
+
disable_autorun = true
|
206
|
+
|
207
|
+
[panda-auth]
|
208
|
+
command = bundle exec rails s -p $PORT
|
209
|
+
EOD
|
210
|
+
file.write(config_data)
|
211
|
+
file.close
|
212
|
+
|
213
|
+
config = Invoker::Parsers::Config.new(file.path, 9000)
|
214
|
+
expect(config.autorunnable_processes.map(&:label)).to eq(['postgres', 'memcached', 'panda-auth'])
|
215
|
+
ensure
|
216
|
+
file.unlink()
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
it "returns a list of processes that can by index" do
|
221
|
+
begin
|
222
|
+
file = Tempfile.new(["config", ".ini"])
|
223
|
+
config_data =<<-EOD
|
224
|
+
[postgres]
|
225
|
+
command = postgres -D /usr/local/var/postgres
|
226
|
+
index = 2
|
227
|
+
sleep = 5
|
228
|
+
|
229
|
+
[redis]
|
230
|
+
command = redis-server /usr/local/etc/redis.conf
|
231
|
+
disable_autorun = true
|
232
|
+
index = 3
|
233
|
+
|
234
|
+
[memcached]
|
235
|
+
command = /usr/local/opt/memcached/bin/memcached
|
236
|
+
disable_autorun = false
|
237
|
+
index = 5
|
238
|
+
|
239
|
+
[panda-api]
|
240
|
+
command = bundle exec rails s
|
241
|
+
disable_autorun = true
|
242
|
+
index = 4
|
243
|
+
|
244
|
+
[panda-auth]
|
245
|
+
command = bundle exec rails s -p $PORT
|
246
|
+
index = 1
|
247
|
+
EOD
|
248
|
+
file.write(config_data)
|
249
|
+
file.close
|
250
|
+
|
251
|
+
config = Invoker::Parsers::Config.new(file.path, 9000)
|
252
|
+
processes = config.autorunnable_processes
|
253
|
+
expect(processes.map(&:label)).to eq(['panda-auth', 'postgres', 'memcached'])
|
254
|
+
expect(processes[0].sleep_duration).to eq(0)
|
255
|
+
expect(processes[1].sleep_duration).to eq(5)
|
256
|
+
ensure
|
257
|
+
file.unlink()
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "global config file" do
|
263
|
+
it "should use global config file if available" do
|
264
|
+
begin
|
265
|
+
FileUtils.mkdir_p(Invoker::Power::Config.config_dir)
|
266
|
+
filename = "#{Invoker::Power::Config.config_dir}/foo.ini"
|
267
|
+
file = File.open(filename, "w")
|
268
|
+
config_data =<<-EOD
|
269
|
+
[try_sleep]
|
270
|
+
directory = /tmp
|
271
|
+
command = ruby try_sleep.rb
|
272
|
+
EOD
|
273
|
+
file.write(config_data)
|
274
|
+
file.close
|
275
|
+
config = Invoker::Parsers::Config.new("foo", 9000)
|
276
|
+
expect(config.filename).to eql(filename)
|
277
|
+
ensure
|
278
|
+
File.unlink(filename)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "config file autodetection" do
|
284
|
+
context "no config file given" do
|
285
|
+
|
286
|
+
def create_invoker_ini
|
287
|
+
file = File.open("invoker.ini", "w")
|
288
|
+
config_data =<<-EOD
|
289
|
+
[some_process]
|
290
|
+
command = some_command
|
291
|
+
EOD
|
292
|
+
file.write(config_data)
|
293
|
+
file.close
|
294
|
+
|
295
|
+
file
|
296
|
+
end
|
297
|
+
|
298
|
+
def create_procfile
|
299
|
+
file = File.open("Procfile", "w")
|
300
|
+
config_data =<<-EOD
|
301
|
+
some_other_process: some_other_command
|
302
|
+
EOD
|
303
|
+
file.write(config_data)
|
304
|
+
file.close
|
305
|
+
|
306
|
+
file
|
307
|
+
end
|
308
|
+
|
309
|
+
context "directory has invoker.ini" do
|
310
|
+
it "autodetects invoker.ini" do
|
311
|
+
begin
|
312
|
+
file = create_invoker_ini
|
313
|
+
|
314
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
315
|
+
expect(config.process("some_process").cmd).to eq("some_command")
|
316
|
+
ensure
|
317
|
+
File.delete(file)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
context "directory has Procfile" do
|
323
|
+
it "autodetects Procfile" do
|
324
|
+
begin
|
325
|
+
file = create_procfile
|
326
|
+
|
327
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
328
|
+
expect(config.process("some_other_process").cmd).to eq("some_other_command")
|
329
|
+
ensure
|
330
|
+
File.delete(file)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "directory has both invoker.ini and Procfile" do
|
336
|
+
it "prioritizes invoker.ini" do
|
337
|
+
begin
|
338
|
+
invoker_ini = create_invoker_ini
|
339
|
+
procfile = create_procfile
|
340
|
+
|
341
|
+
config = Invoker::Parsers::Config.new(nil, 9000)
|
342
|
+
expect(config.process("some_process").cmd).to eq("some_command")
|
343
|
+
processes = config.autorunnable_processes
|
344
|
+
process_1 = processes[0]
|
345
|
+
expect(process_1.sleep_duration).to eq(0)
|
346
|
+
expect(process_1.index).to eq(0)
|
347
|
+
ensure
|
348
|
+
File.delete(invoker_ini)
|
349
|
+
File.delete(procfile)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "directory doesn't have invoker.ini or Procfile" do
|
355
|
+
it "aborts" do
|
356
|
+
expect { Invoker::Parsers::Config.new(nil, 9000) }.to raise_error(SystemExit)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Invoker::Daemon do
|
4
|
+
let(:daemon) { Invoker::Daemon.new}
|
5
|
+
|
6
|
+
describe "#start" do
|
7
|
+
context "when daemon is aleady running" do
|
8
|
+
it "exits without any error" do
|
9
|
+
daemon.expects(:running?).returns(true)
|
10
|
+
begin
|
11
|
+
daemon.start
|
12
|
+
rescue SystemExit => e
|
13
|
+
expect(e.status).to be(0)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when daemon is not running" do
|
19
|
+
it "starts the daemon" do
|
20
|
+
daemon.expects(:dead?).returns(false)
|
21
|
+
daemon.expects(:running?).returns(false)
|
22
|
+
daemon.expects(:daemonize)
|
23
|
+
daemon.start
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#stop" do
|
29
|
+
it "stops the daemon" do
|
30
|
+
daemon.expects(:kill_process)
|
31
|
+
daemon.stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|