invoker 1.4.1 → 1.5.1
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 +4 -4
- data/.gitignore +0 -1
- data/.rubocop.yml +0 -1
- data/.travis.yml +4 -2
- data/Dockerfile +7 -0
- data/Gemfile +3 -0
- data/Rakefile +8 -0
- data/examples/hello_sinatra.rb +26 -0
- data/examples/sample.ini +3 -0
- data/invoker.gemspec +2 -1
- data/lib/invoker.rb +20 -3
- data/lib/invoker/cli.rb +32 -6
- data/lib/invoker/dns_cache.rb +2 -2
- data/lib/invoker/ipc/add_http_command.rb +1 -1
- data/lib/invoker/ipc/dns_check_command.rb +2 -1
- data/lib/invoker/ipc/message.rb +2 -2
- data/lib/invoker/parsers/config.rb +4 -1
- data/lib/invoker/power/balancer.rb +16 -4
- data/lib/invoker/power/config.rb +3 -2
- data/lib/invoker/power/dns.rb +1 -1
- data/lib/invoker/power/pf_migrate.rb +1 -1
- data/lib/invoker/power/setup.rb +43 -4
- data/lib/invoker/power/setup/distro/arch.rb +1 -4
- data/lib/invoker/power/setup/distro/base.rb +23 -21
- data/lib/invoker/power/setup/distro/debian.rb +1 -1
- data/lib/invoker/power/setup/distro/opensuse.rb +11 -0
- data/lib/invoker/power/setup/distro/redhat.rb +1 -7
- 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 +46 -29
- data/lib/invoker/power/setup/osx_setup.rb +16 -28
- data/lib/invoker/power/url_rewriter.rb +6 -3
- data/lib/invoker/process_manager.rb +13 -7
- data/lib/invoker/version.rb +1 -1
- data/readme.md +4 -4
- data/spec/invoker/commander_spec.rb +19 -8
- data/spec/invoker/config_spec.rb +22 -27
- data/spec/invoker/invoker_spec.rb +2 -1
- data/spec/invoker/ipc/client_handler_spec.rb +11 -1
- data/spec/invoker/power/config_spec.rb +2 -1
- data/spec/invoker/power/pf_migrate_spec.rb +7 -0
- data/spec/invoker/power/setup/linux_setup_spec.rb +57 -9
- data/spec/invoker/power/setup/osx_setup_spec.rb +22 -8
- data/spec/invoker/power/url_rewriter_spec.rb +33 -1
- data/spec/invoker/power/web_sockets_spec.rb +61 -0
- data/spec/invoker/process_manager_spec.rb +34 -2
- data/spec/spec_helper.rb +12 -16
- metadata +27 -35
- data/spec/support/mock_setup_file.rb +0 -64
data/spec/invoker/config_spec.rb
CHANGED
@@ -134,59 +134,53 @@ command = ls
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
describe "loading power config" do
|
137
|
+
describe "loading power config", fakefs: true do
|
138
138
|
before do
|
139
|
-
|
139
|
+
FileUtils.mkdir_p('/tmp')
|
140
|
+
FileUtils.mkdir_p(inv_conf_dir)
|
141
|
+
File.open("/tmp/foo.ini", "w") { |fl| fl.write("") }
|
140
142
|
end
|
141
143
|
|
142
144
|
it "does not load config if platform is darwin but there is no power config file" do
|
143
145
|
Invoker::Power::Config.expects(:load_config).never
|
144
|
-
Invoker::Parsers::Config.new(
|
146
|
+
Invoker::Parsers::Config.new("/tmp/foo.ini", 9000)
|
145
147
|
end
|
146
148
|
|
147
149
|
it "loads config if platform is darwin and power config file exists" do
|
148
150
|
File.open(Invoker::Power::Config.config_file, "w") { |fl| fl.puts "sample" }
|
149
151
|
Invoker::Power::Config.expects(:load_config).once
|
150
|
-
Invoker::Parsers::Config.new(
|
152
|
+
Invoker::Parsers::Config.new("/tmp/foo.ini", 9000)
|
151
153
|
end
|
152
154
|
end
|
153
155
|
|
154
156
|
describe "Procfile" do
|
155
157
|
it "should load Procfiles and create config object" do
|
156
|
-
|
157
|
-
|
158
|
-
fl.write <<-EOD
|
158
|
+
File.open("/tmp/Procfile", "w") {|fl|
|
159
|
+
fl.write <<-EOD
|
159
160
|
web: bundle exec rails s -p $PORT
|
160
161
|
EOD
|
161
|
-
|
162
|
-
|
163
|
-
|
162
|
+
}
|
163
|
+
config = Invoker::Parsers::Config.new("/tmp/Procfile", 9000)
|
164
|
+
command1 = config.processes.first
|
164
165
|
|
165
|
-
|
166
|
-
|
167
|
-
ensure
|
168
|
-
File.delete("/tmp/Procfile")
|
169
|
-
end
|
166
|
+
expect(command1.port).to eq(9000)
|
167
|
+
expect(command1.cmd).to match(/bundle exec rails/)
|
170
168
|
end
|
171
169
|
end
|
172
170
|
|
173
171
|
describe "Copy of DNS information" do
|
174
172
|
it "should allow copy of DNS information" do
|
175
|
-
|
176
|
-
|
177
|
-
fl.write <<-EOD
|
173
|
+
File.open("/tmp/Procfile", "w") {|fl|
|
174
|
+
fl.write <<-EOD
|
178
175
|
web: bundle exec rails s -p $PORT
|
179
176
|
EOD
|
180
|
-
|
181
|
-
|
182
|
-
|
177
|
+
}
|
178
|
+
Invoker.load_invoker_config("/tmp/Procfile", 9000)
|
179
|
+
dns_cache = Invoker::DNSCache.new(Invoker.config)
|
183
180
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
ensure
|
188
|
-
File.delete("/tmp/Procfile")
|
189
|
-
end
|
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
|
190
184
|
end
|
191
185
|
end
|
192
186
|
|
@@ -227,6 +221,7 @@ command = bundle exec rails s -p $PORT
|
|
227
221
|
describe "global config file" do
|
228
222
|
it "should use global config file if available" do
|
229
223
|
begin
|
224
|
+
FileUtils.mkdir_p(Invoker::Power::Config.config_dir)
|
230
225
|
filename = "#{Invoker::Power::Config.config_dir}/foo.ini"
|
231
226
|
file = File.open(filename, "w")
|
232
227
|
config_data =<<-EOD
|
@@ -13,7 +13,8 @@ describe "Invoker" do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
describe "#can_run_balancer?" do
|
16
|
+
describe "#can_run_balancer?", fakefs: true do
|
17
|
+
before { FileUtils.mkdir_p(Invoker::Power::Config.config_dir) }
|
17
18
|
it "should return false if setup command was not run" do
|
18
19
|
expect(Invoker.can_run_balancer?).to be_falsey
|
19
20
|
end
|
@@ -35,7 +35,17 @@ describe Invoker::IPC::ClientHandler do
|
|
35
35
|
describe "add_http command" do
|
36
36
|
let(:message_object) { MM::AddHttp.new(process_name: 'foo', port: 9000)}
|
37
37
|
it "adds the process name and port to dns cache" do
|
38
|
-
invoker_dns_cache.expects(:add).with('foo', 9000)
|
38
|
+
invoker_dns_cache.expects(:add).with('foo', 9000, nil)
|
39
|
+
client_socket.string = message_object.encoded_message
|
40
|
+
|
41
|
+
client.read_and_execute
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "add_http command with optional ip" do
|
46
|
+
let(:message_object) { MM::AddHttp.new(process_name: 'foo', port: 9000, ip: '192.168.0.1')}
|
47
|
+
it "adds the process name, port and host ip to dns cache" do
|
48
|
+
invoker_dns_cache.expects(:add).with('foo', 9000, '192.168.0.1')
|
39
49
|
client_socket.string = message_object.encoded_message
|
40
50
|
|
41
51
|
client.read_and_execute
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "Invoker Power configuration" do
|
3
|
+
describe "Invoker Power configuration", fakefs: true do
|
4
4
|
describe "#create" do
|
5
5
|
it "should create a config file given a hash" do
|
6
|
+
FileUtils.mkdir_p(inv_conf_dir)
|
6
7
|
config = Invoker::Power::Config.create(
|
7
8
|
dns_port: 1200, http_port: 1201, ipfw_rule_number: 010
|
8
9
|
)
|
@@ -2,6 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Invoker::Power::PfMigrate do
|
4
4
|
before do
|
5
|
+
FileUtils.mkdir_p("/tmp/.invoker")
|
5
6
|
@old_firewall_file = Invoker::Power::OsxSetup::FIREWALL_PLIST_FILE
|
6
7
|
Invoker::Power::OsxSetup.const_set(:FIREWALL_PLIST_FILE, "/tmp/.invoker/firewall")
|
7
8
|
end
|
@@ -54,12 +55,18 @@ describe Invoker::Power::PfMigrate do
|
|
54
55
|
|
55
56
|
describe "#migrate" do
|
56
57
|
before do
|
58
|
+
@original_invoker_config = Invoker.config
|
57
59
|
mock_config = mock()
|
58
60
|
mock_config.stubs(:http_port).returns(80)
|
59
61
|
mock_config.stubs(:https_port).returns(443)
|
62
|
+
mock_config.stubs(:tld).returns('dev')
|
60
63
|
Invoker.config = mock_config
|
61
64
|
end
|
62
65
|
|
66
|
+
after do
|
67
|
+
Invoker.config = @original_invoker_config
|
68
|
+
end
|
69
|
+
|
63
70
|
it "should migrate firewall to new system" do
|
64
71
|
pf_migrator.expects(:firewall_config_requires_migration?).returns(true)
|
65
72
|
pf_migrator.expects(:ask_user_for_migration).returns(true)
|
@@ -1,9 +1,31 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "invoker/power/setup/distro/ubuntu"
|
3
|
+
require "invoker/power/setup/distro/opensuse"
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def mock_socat_scripts
|
6
|
+
FakeFS.deactivate!
|
7
|
+
socat_content = File.read(invoker_setup.forwarder_script)
|
8
|
+
socat_systemd = File.read(invoker_setup.socat_unit)
|
9
|
+
FakeFS.activate!
|
10
|
+
FileUtils.mkdir_p(File.dirname(invoker_setup.forwarder_script))
|
11
|
+
FileUtils.mkdir_p(File.dirname(invoker_setup.socat_unit))
|
12
|
+
File.open(invoker_setup.socat_unit, "w") do |fl|
|
13
|
+
fl.write(socat_systemd)
|
14
|
+
end
|
15
|
+
File.open(invoker_setup.forwarder_script, "w") do |fl|
|
16
|
+
fl.write(socat_content)
|
17
|
+
end
|
18
|
+
FileUtils.mkdir_p("/usr/bin")
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Invoker::Power::LinuxSetup, fakefs: true do
|
22
|
+
before do
|
23
|
+
FileUtils.mkdir_p(inv_conf_dir)
|
24
|
+
FileUtils.mkdir_p(Invoker::Power::Distro::Base::RESOLVER_DIR)
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:invoker_setup) { Invoker::Power::LinuxSetup.new('dev') }
|
28
|
+
let(:distro_installer) { Invoker::Power::Distro::Ubuntu.new('dev') }
|
7
29
|
|
8
30
|
describe "should only proceed after user confirmation" do
|
9
31
|
before { invoker_setup.distro_installer = distro_installer }
|
@@ -27,8 +49,20 @@ describe Invoker::Power::LinuxSetup do
|
|
27
49
|
end
|
28
50
|
end
|
29
51
|
|
30
|
-
describe "configuring dnsmasq and
|
31
|
-
before
|
52
|
+
describe "configuring dnsmasq and socat" do
|
53
|
+
before(:all) do
|
54
|
+
@original_invoker_config = Invoker.config
|
55
|
+
Invoker.config = mock
|
56
|
+
end
|
57
|
+
|
58
|
+
after(:all) do
|
59
|
+
Invoker.config = @original_invoker_config
|
60
|
+
end
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
invoker_setup.distro_installer = distro_installer
|
64
|
+
mock_socat_scripts
|
65
|
+
end
|
32
66
|
|
33
67
|
it "should create proper config file" do
|
34
68
|
invoker_setup.expects(:initialize_distro_installer).returns(true)
|
@@ -46,10 +80,24 @@ describe Invoker::Power::LinuxSetup do
|
|
46
80
|
expect(dnsmasq_content.strip).to_not be_empty
|
47
81
|
expect(dnsmasq_content).to match(/dev/)
|
48
82
|
|
49
|
-
|
50
|
-
expect(
|
51
|
-
expect(
|
52
|
-
expect(
|
83
|
+
socat_content = File.read(Invoker::Power::Distro::Base::SOCAT_SHELLSCRIPT)
|
84
|
+
expect(socat_content.strip).to_not be_empty
|
85
|
+
expect(socat_content.strip).to match(/#{config.https_port}/)
|
86
|
+
expect(socat_content.strip).to match(/#{config.http_port}/)
|
87
|
+
|
88
|
+
service_file = File.read(Invoker::Power::Distro::Base::SOCAT_SYSTEMD)
|
89
|
+
expect(service_file.strip).to_not be_empty
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'resolver file' do
|
94
|
+
context 'user sets up a custom top level domain' do
|
95
|
+
it 'should create the correct resolver file' do
|
96
|
+
linux_setup = Invoker::Power::LinuxSetup.new('local')
|
97
|
+
suse_installer = Invoker::Power::Distro::Opensuse.new('local')
|
98
|
+
linux_setup.distro_installer = suse_installer
|
99
|
+
expect(linux_setup.resolver_file).to eq('/etc/dnsmasq.d/local-tld')
|
100
|
+
end
|
53
101
|
end
|
54
102
|
end
|
55
103
|
end
|
@@ -1,9 +1,14 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe Invoker::Power::OsxSetup do
|
4
|
-
|
3
|
+
describe Invoker::Power::OsxSetup, fakefs: true do
|
4
|
+
before do
|
5
|
+
FileUtils.mkdir_p(inv_conf_dir)
|
6
|
+
FileUtils.mkdir_p(Invoker::Power::OsxSetup::RESOLVER_DIR)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "when no setup exists" do
|
5
10
|
it "should create a config file with port etc" do
|
6
|
-
setup = Invoker::Power::OsxSetup.new
|
11
|
+
setup = Invoker::Power::OsxSetup.new('dev')
|
7
12
|
setup.expects(:install_resolver).returns(true)
|
8
13
|
setup.expects(:drop_to_normal_user).returns(true)
|
9
14
|
setup.expects(:install_firewall).once
|
@@ -23,16 +28,16 @@ describe Invoker::Power::OsxSetup do
|
|
23
28
|
fl.write("foo test")
|
24
29
|
}
|
25
30
|
Invoker::Power::Setup.any_instance.expects(:setup_invoker).never
|
26
|
-
Invoker::Power::Setup.install()
|
31
|
+
Invoker::Power::Setup.install('dev')
|
27
32
|
end
|
28
33
|
end
|
29
34
|
|
30
35
|
describe "when pow like setup exists" do
|
31
36
|
before {
|
32
|
-
File.open(Invoker::Power::OsxSetup::
|
37
|
+
File.open(File.join(Invoker::Power::OsxSetup::RESOLVER_DIR, "dev"), "w") { |fl|
|
33
38
|
fl.write("hello")
|
34
39
|
}
|
35
|
-
@setup = Invoker::Power::OsxSetup.new
|
40
|
+
@setup = Invoker::Power::OsxSetup.new('dev')
|
36
41
|
}
|
37
42
|
|
38
43
|
describe "when user selects to overwrite it" do
|
@@ -60,7 +65,7 @@ describe Invoker::Power::OsxSetup do
|
|
60
65
|
|
61
66
|
describe "uninstalling firewall rules" do
|
62
67
|
it "should uninstall firewall rules and remove all files created by setup" do
|
63
|
-
setup = Invoker::Power::OsxSetup.new
|
68
|
+
setup = Invoker::Power::OsxSetup.new('dev')
|
64
69
|
|
65
70
|
Invoker::CLI::Question.expects(:agree).returns(true)
|
66
71
|
setup.expects(:remove_resolver_file).once
|
@@ -74,7 +79,7 @@ describe Invoker::Power::OsxSetup do
|
|
74
79
|
describe "setup on fresh osx install" do
|
75
80
|
context "when resolver directory does not exist" do
|
76
81
|
before do
|
77
|
-
@setup = Invoker::Power::OsxSetup.new
|
82
|
+
@setup = Invoker::Power::OsxSetup.new('dev')
|
78
83
|
FileUtils.rm_rf(Invoker::Power::OsxSetup::RESOLVER_DIR)
|
79
84
|
end
|
80
85
|
|
@@ -88,4 +93,13 @@ describe Invoker::Power::OsxSetup do
|
|
88
93
|
end
|
89
94
|
end
|
90
95
|
end
|
96
|
+
|
97
|
+
describe '.resolver_file' do
|
98
|
+
context 'user sets up a custom top level domain' do
|
99
|
+
it 'should create the correct resolver file' do
|
100
|
+
setup = Invoker::Power::OsxSetup.new('local')
|
101
|
+
expect(setup.resolver_file).to eq('/etc/resolver/local')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
91
105
|
end
|
@@ -4,7 +4,18 @@ describe Invoker::Power::UrlRewriter do
|
|
4
4
|
let(:rewriter) { Invoker::Power::UrlRewriter.new }
|
5
5
|
|
6
6
|
context "matching domain part of incoming request" do
|
7
|
-
|
7
|
+
before(:all) do
|
8
|
+
@original_invoker_config = Invoker.config
|
9
|
+
|
10
|
+
Invoker.config = mock
|
11
|
+
Invoker.config.stubs(:tld).returns("dev")
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
Invoker.config = @original_invoker_config
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should match foo.dev" do
|
8
19
|
match = rewriter.extract_host_from_domain("foo.dev")
|
9
20
|
expect(match).to_not be_empty
|
10
21
|
|
@@ -34,5 +45,26 @@ describe Invoker::Power::UrlRewriter do
|
|
34
45
|
|
35
46
|
expect(match[0]).to eq("hello-world")
|
36
47
|
end
|
48
|
+
|
49
|
+
context 'user sets up a custom top level domain' do
|
50
|
+
before(:all) do
|
51
|
+
@original_invoker_config = Invoker.config
|
52
|
+
|
53
|
+
Invoker.config = mock
|
54
|
+
Invoker.config.stubs(:tld).returns("local")
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should match domain part of incoming request correctly' do
|
58
|
+
match = rewriter.extract_host_from_domain("foo.local")
|
59
|
+
expect(match).to_not be_empty
|
60
|
+
|
61
|
+
matching_string = match[0]
|
62
|
+
expect(matching_string).to eq("foo")
|
63
|
+
end
|
64
|
+
|
65
|
+
after(:all) do
|
66
|
+
Invoker.config = @original_invoker_config
|
67
|
+
end
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Full integration test. Start a server, and client. Let client interact with
|
4
|
+
# server do a ping-pong. Client checks whether ping pong is successful or not.
|
5
|
+
# Also, mock rewriter so that it returns valid port for request proxying.
|
6
|
+
# - Server will run on port 28080.
|
7
|
+
# - Balancer will run on port 28081 proxying to 28080
|
8
|
+
# - Client will connect to 28081 performing ping-pong
|
9
|
+
|
10
|
+
def websocket_server
|
11
|
+
require 'websocket-eventmachine-server'
|
12
|
+
|
13
|
+
EM.run do
|
14
|
+
WebSocket::EventMachine::Server.start(host: "0.0.0.0", port: 28080) do |ws|
|
15
|
+
ws.onerror { |e| p e }
|
16
|
+
ws.onmessage { ws.send "pong" }
|
17
|
+
end
|
18
|
+
|
19
|
+
EM.add_timer(2) { EM.stop }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def websocket_client
|
24
|
+
require 'websocket-eventmachine-client'
|
25
|
+
|
26
|
+
@message = ""
|
27
|
+
|
28
|
+
EM.run do
|
29
|
+
ws = WebSocket::EventMachine::Client.connect(uri: 'ws://0.0.0.0:28081')
|
30
|
+
ws.onerror { |e| p e }
|
31
|
+
ws.onopen { ws.send("ping") }
|
32
|
+
ws.onmessage { |m, _| @message = m }
|
33
|
+
|
34
|
+
EM.add_timer(2) do
|
35
|
+
expect(@message).to eq "pong"
|
36
|
+
EM.stop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
describe 'Web sockets support' do
|
43
|
+
it 'can ping pong via balancer' do
|
44
|
+
dns_response = Struct.new(:port, :ip).new(28080, "0.0.0.0")
|
45
|
+
Invoker::Power::UrlRewriter.any_instance
|
46
|
+
.stubs(:select_backend_config)
|
47
|
+
.returns(dns_response)
|
48
|
+
|
49
|
+
EM.run do
|
50
|
+
EM.start_server("0.0.0.0", 28081, EM::ProxyServer::Connection, {}) do |conn|
|
51
|
+
Invoker::Power::Balancer.new(conn, "http").install_callbacks
|
52
|
+
end
|
53
|
+
|
54
|
+
fork { websocket_server }
|
55
|
+
fork { websocket_client }
|
56
|
+
EM.add_timer(3) { EM.stop }
|
57
|
+
end
|
58
|
+
|
59
|
+
Process.waitall
|
60
|
+
end
|
61
|
+
end
|
@@ -2,13 +2,19 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Invoker::ProcessManager do
|
4
4
|
let(:process_manager) { Invoker::ProcessManager.new }
|
5
|
+
|
5
6
|
describe "#start_process_by_name" do
|
6
7
|
it "should find command by label and start it, if found" do
|
7
|
-
|
8
|
-
|
8
|
+
@original_invoker_config = Invoker.config
|
9
|
+
Invoker.config = mock
|
10
|
+
|
11
|
+
Invoker.config.stubs(:processes).returns([OpenStruct.new(:label => "resque", :cmd => "foo", :dir => "bar")])
|
12
|
+
Invoker.config.expects(:process).returns(OpenStruct.new(:label => "resque", :cmd => "foo", :dir => "bar"))
|
9
13
|
process_manager.expects(:start_process).returns(true)
|
10
14
|
|
11
15
|
process_manager.start_process_by_name("resque")
|
16
|
+
|
17
|
+
Invoker.config = @original_invoker_config
|
12
18
|
end
|
13
19
|
|
14
20
|
it "should not start already running process" do
|
@@ -94,5 +100,31 @@ BAR=foo
|
|
94
100
|
dir = "/tmp"
|
95
101
|
expect(process_manager.load_env(dir)).to eq({})
|
96
102
|
end
|
103
|
+
|
104
|
+
it "should load .local.env file if it exists" do
|
105
|
+
dir = "/tmp"
|
106
|
+
begin
|
107
|
+
env_file = File.new("#{dir}/.env", "w")
|
108
|
+
env_data =<<-EOD
|
109
|
+
FOO=foo
|
110
|
+
BAR=bar
|
111
|
+
EOD
|
112
|
+
env_file.write(env_data)
|
113
|
+
env_file.close
|
114
|
+
|
115
|
+
local_env_file = File.new("#{dir}/.env.local", "w")
|
116
|
+
local_env_data =<<-EOD
|
117
|
+
FOO=emacs
|
118
|
+
EOD
|
119
|
+
local_env_file.write(local_env_data)
|
120
|
+
local_env_file.close
|
121
|
+
|
122
|
+
env_options = process_manager.load_env(dir)
|
123
|
+
expect(env_options).to include("FOO" => "emacs", "BAR" => "bar")
|
124
|
+
ensure
|
125
|
+
File.delete(env_file.path)
|
126
|
+
File.delete(local_env_file.path)
|
127
|
+
end
|
128
|
+
end
|
97
129
|
end
|
98
130
|
end
|