foreman 0.31.0 → 0.50.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/README.md +46 -0
- data/bin/foreman-runner +32 -0
- data/bin/taskman +8 -0
- data/data/example/Procfile +4 -2
- data/data/example/spawnee +14 -0
- data/data/example/spawner +7 -0
- data/data/example/utf8 +11 -0
- data/data/export/bluepill/master.pill.erb +11 -10
- data/data/export/launchd/launchd.plist.erb +22 -0
- data/data/export/runit/log/run.erb +7 -0
- data/data/export/runit/run.erb +2 -2
- data/data/export/supervisord/app.conf.erb +27 -0
- data/data/export/upstart/master.conf.erb +2 -2
- data/data/export/upstart/process.conf.erb +3 -3
- data/lib/foreman/cli.rb +83 -34
- data/lib/foreman/engine/cli.rb +105 -0
- data/lib/foreman/engine.rb +232 -140
- data/lib/foreman/env.rb +27 -0
- data/lib/foreman/export/base.rb +108 -6
- data/lib/foreman/export/bluepill.rb +4 -20
- data/lib/foreman/export/inittab.rb +11 -16
- data/lib/foreman/export/launchd.rb +15 -0
- data/lib/foreman/export/runit.rb +15 -41
- data/lib/foreman/export/supervisord.rb +16 -0
- data/lib/foreman/export/upstart.rb +10 -28
- data/lib/foreman/export.rb +23 -0
- data/lib/foreman/helpers.rb +45 -0
- data/lib/foreman/process.rb +80 -46
- data/lib/foreman/procfile.rb +68 -14
- data/lib/foreman/version.rb +1 -1
- data/lib/foreman.rb +12 -7
- data/man/foreman.1 +29 -3
- data/spec/foreman/cli_spec.rb +54 -60
- data/spec/foreman/engine_spec.rb +64 -46
- data/spec/foreman/export/base_spec.rb +19 -0
- data/spec/foreman/export/bluepill_spec.rb +24 -6
- data/spec/foreman/export/inittab_spec.rb +40 -0
- data/spec/foreman/export/launchd_spec.rb +21 -0
- data/spec/foreman/export/runit_spec.rb +23 -22
- data/spec/foreman/export/supervisord_spec.rb +36 -0
- data/spec/foreman/export/upstart_spec.rb +49 -16
- data/spec/foreman/export_spec.rb +22 -0
- data/spec/foreman/helpers_spec.rb +26 -0
- data/spec/foreman/process_spec.rb +48 -2
- data/spec/foreman/procfile_spec.rb +41 -0
- data/spec/foreman_spec.rb +3 -20
- data/spec/helper_spec.rb +18 -0
- data/spec/resources/Procfile +4 -0
- data/spec/resources/bin/echo +2 -0
- data/spec/resources/bin/env +2 -0
- data/spec/resources/bin/test +2 -0
- data/spec/resources/bin/utf8 +2 -0
- data/spec/resources/export/bluepill/app-concurrency.pill +49 -0
- data/spec/resources/export/bluepill/app.pill +6 -25
- data/spec/resources/export/inittab/inittab.concurrency +4 -0
- data/spec/resources/export/inittab/inittab.default +4 -0
- data/spec/resources/export/launchd/launchd-a.default +22 -0
- data/spec/resources/export/launchd/launchd-b.default +22 -0
- data/spec/resources/export/supervisord/app-alpha-1.conf +24 -0
- data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
- data/spec/spec_helper.rb +93 -10
- metadata +72 -76
- data/README.markdown +0 -49
- data/bin/runner +0 -2
- data/data/export/runit/log_run.erb +0 -7
- data/lib/foreman/procfile_entry.rb +0 -22
- data/lib/foreman/utils.rb +0 -15
- /data/spec/resources/export/runit/{app-alpha-1-log-run → app-alpha-1/log/run} +0 -0
- /data/spec/resources/export/runit/{app-alpha-1-run → app-alpha-1/run} +0 -0
- /data/spec/resources/export/runit/{app-alpha-2-log-run → app-alpha-2/log/run} +0 -0
- /data/spec/resources/export/runit/{app-alpha-2-run → app-alpha-2/run} +0 -0
- /data/spec/resources/export/runit/{app-bravo-1-log-run → app-bravo-1/log/run} +0 -0
- /data/spec/resources/export/runit/{app-bravo-1-run → app-bravo-1/run} +0 -0
data/spec/foreman/cli_spec.rb
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "foreman/cli"
|
|
3
3
|
|
|
4
|
-
describe "Foreman::CLI" do
|
|
4
|
+
describe "Foreman::CLI", :fakefs do
|
|
5
5
|
subject { Foreman::CLI.new }
|
|
6
6
|
|
|
7
|
+
describe ".foreman" do
|
|
8
|
+
before { File.open(".foreman", "w") { |f| f.puts "formation: alpha=2" } }
|
|
9
|
+
|
|
10
|
+
it "provides default options" do
|
|
11
|
+
subject.send(:options)["formation"].should == "alpha=2"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "is overridden by options at the cli" do
|
|
15
|
+
subject = Foreman::CLI.new([], :formation => "alpha=3")
|
|
16
|
+
subject.send(:options)["formation"].should == "alpha=3"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
7
20
|
describe "start" do
|
|
8
|
-
describe "
|
|
9
|
-
it "
|
|
21
|
+
describe "when a Procfile doesnt exist", :fakefs do
|
|
22
|
+
it "displays an error" do
|
|
10
23
|
mock_error(subject, "Procfile does not exist.") do
|
|
11
24
|
dont_allow.instance_of(Foreman::Engine).start
|
|
12
25
|
subject.start
|
|
@@ -14,79 +27,60 @@ describe "Foreman::CLI" do
|
|
|
14
27
|
end
|
|
15
28
|
end
|
|
16
29
|
|
|
17
|
-
describe "with a Procfile" do
|
|
18
|
-
|
|
30
|
+
describe "with a valid Procfile" do
|
|
31
|
+
it "can run a single command" do
|
|
32
|
+
without_fakefs do
|
|
33
|
+
output = foreman("start env -f #{resource_path("Procfile")}")
|
|
34
|
+
output.should =~ /env.1/
|
|
35
|
+
output.should_not =~ /test.1/
|
|
36
|
+
end
|
|
37
|
+
end
|
|
19
38
|
|
|
20
|
-
it "
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
it "can run all commands" do
|
|
40
|
+
without_fakefs do
|
|
41
|
+
output = foreman("start -f #{resource_path("Procfile")} -e #{resource_path(".env")}")
|
|
42
|
+
output.should =~ /echo.1 \| echoing/
|
|
43
|
+
output.should =~ /env.1 \| bar/
|
|
44
|
+
output.should =~ /test.1 \| testing/
|
|
45
|
+
end
|
|
24
46
|
end
|
|
25
47
|
end
|
|
26
48
|
end
|
|
27
49
|
|
|
28
|
-
describe "
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
write_env("envfile")
|
|
33
|
-
mock.instance_of(Foreman::Export::Upstart).export("/upstart", { "env" => "envfile" })
|
|
34
|
-
foreman %{ export upstart /upstart --env envfile }
|
|
35
|
-
end
|
|
50
|
+
describe "check" do
|
|
51
|
+
it "with a valid Procfile displays the jobs" do
|
|
52
|
+
write_procfile
|
|
53
|
+
foreman("check").should == "valid procfile detected (alpha, bravo)\n"
|
|
36
54
|
end
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
dont_allow.instance_of(Foreman::Engine).export
|
|
42
|
-
subject.export("testapp")
|
|
43
|
-
end
|
|
44
|
-
end
|
|
56
|
+
it "with a blank Procfile displays an error" do
|
|
57
|
+
FileUtils.touch "Procfile"
|
|
58
|
+
foreman("check").should == "ERROR: no processes defined\n"
|
|
45
59
|
end
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
describe "with an invalid formatter" do
|
|
51
|
-
it "prints an error" do
|
|
52
|
-
mock_error(subject, "Unknown export format: invalidformatter.") do
|
|
53
|
-
subject.export("invalidformatter")
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
describe "with a valid config" do
|
|
59
|
-
before(:each) { write_foreman_config("testapp") }
|
|
60
|
-
|
|
61
|
-
it "runs successfully" do
|
|
62
|
-
dont_allow(subject).error
|
|
63
|
-
mock.instance_of(Foreman::Export::Upstart).export("/tmp/foo", {})
|
|
64
|
-
subject.export("upstart", "/tmp/foo")
|
|
65
|
-
end
|
|
66
|
-
end
|
|
61
|
+
it "without a Procfile displays an error" do
|
|
62
|
+
FileUtils.rm_f "Procfile"
|
|
63
|
+
foreman("check").should == "ERROR: Procfile does not exist.\n"
|
|
67
64
|
end
|
|
68
65
|
end
|
|
69
66
|
|
|
70
|
-
describe "
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
describe "run" do
|
|
68
|
+
it "can run a command" do
|
|
69
|
+
forked_foreman("run echo 1").should == "1\n"
|
|
70
|
+
end
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
subject.check
|
|
77
|
-
end
|
|
72
|
+
it "includes the environment" do
|
|
73
|
+
forked_foreman("run #{resource_path("bin/env FOO")} -e #{resource_path(".env")}").should == "bar\n"
|
|
78
74
|
end
|
|
75
|
+
end
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
describe "version" do
|
|
78
|
+
it "displays gem version" do
|
|
79
|
+
foreman("version").chomp.should == Foreman::VERSION
|
|
80
|
+
end
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
subject.check
|
|
88
|
-
end
|
|
89
|
-
end
|
|
82
|
+
it "displays gem version on shortcut command" do
|
|
83
|
+
foreman("-v").chomp.should == Foreman::VERSION
|
|
90
84
|
end
|
|
91
85
|
end
|
|
92
86
|
|
data/spec/foreman/engine_spec.rb
CHANGED
|
@@ -1,86 +1,104 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "foreman/engine"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
class Foreman::Engine::Tester < Foreman::Engine
|
|
5
|
+
attr_reader :buffer
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
def startup
|
|
8
|
+
@buffer = ""
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def output(name, data)
|
|
12
|
+
@buffer += "#{name}: #{data}"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def shutdown
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "Foreman::Engine", :fakefs do
|
|
20
|
+
subject do
|
|
21
|
+
write_procfile "Procfile"
|
|
22
|
+
Foreman::Engine::Tester.new.load_procfile("Procfile")
|
|
23
|
+
end
|
|
13
24
|
|
|
25
|
+
describe "initialize" do
|
|
14
26
|
describe "with a Procfile" do
|
|
15
27
|
before { write_procfile }
|
|
16
28
|
|
|
17
29
|
it "reads the processes" do
|
|
18
|
-
subject.
|
|
19
|
-
subject.
|
|
30
|
+
subject.process("alpha").command.should == "./alpha"
|
|
31
|
+
subject.process("bravo").command.should == "./bravo"
|
|
20
32
|
end
|
|
21
33
|
end
|
|
22
34
|
end
|
|
23
35
|
|
|
24
36
|
describe "start" do
|
|
25
37
|
it "forks the processes" do
|
|
26
|
-
|
|
27
|
-
mock
|
|
28
|
-
mock.instance_of(Foreman::Process).run_process("./bravo", is_a(IO))
|
|
38
|
+
mock(subject.process("alpha")).run(anything)
|
|
39
|
+
mock(subject.process("bravo")).run(anything)
|
|
29
40
|
mock(subject).watch_for_output
|
|
30
41
|
mock(subject).watch_for_termination
|
|
31
42
|
subject.start
|
|
32
43
|
end
|
|
33
44
|
|
|
34
45
|
it "handles concurrency" do
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
mock
|
|
38
|
-
mock
|
|
39
|
-
mock(
|
|
40
|
-
|
|
41
|
-
engine.start
|
|
46
|
+
subject.options[:formation] = "alpha=2"
|
|
47
|
+
mock(subject.process("alpha")).run(anything).twice
|
|
48
|
+
mock(subject.process("bravo")).run(anything).never
|
|
49
|
+
mock(subject).watch_for_output
|
|
50
|
+
mock(subject).watch_for_termination
|
|
51
|
+
subject.start
|
|
42
52
|
end
|
|
43
53
|
end
|
|
44
54
|
|
|
45
|
-
describe "
|
|
46
|
-
|
|
47
|
-
write_procfile
|
|
48
|
-
|
|
55
|
+
describe "directories" do
|
|
56
|
+
it "has the directory default relative to the Procfile" do
|
|
57
|
+
write_procfile "/some/app/Procfile"
|
|
58
|
+
engine = Foreman::Engine.new.load_procfile("/some/app/Procfile")
|
|
59
|
+
engine.root.should == "/some/app"
|
|
49
60
|
end
|
|
61
|
+
end
|
|
50
62
|
|
|
51
|
-
|
|
63
|
+
describe "environment" do
|
|
64
|
+
it "should read env files" do
|
|
52
65
|
File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
mock(engine).spawn_processes
|
|
56
|
-
mock(engine).watch_for_termination
|
|
57
|
-
engine.environment.should == {"FOO"=>"baz"}
|
|
58
|
-
engine.start
|
|
66
|
+
subject.load_env("/tmp/env")
|
|
67
|
+
subject.env["FOO"].should == "baz"
|
|
59
68
|
end
|
|
60
69
|
|
|
61
70
|
it "should read more than one if specified" do
|
|
62
71
|
File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
|
|
63
72
|
File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
subject.load_env "/tmp/env1"
|
|
74
|
+
subject.load_env "/tmp/env2"
|
|
75
|
+
subject.env["FOO"].should == "bar"
|
|
76
|
+
subject.env["BAZ"].should == "qux"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should handle quoted values" do
|
|
80
|
+
File.open("/tmp/env", "w") do |f|
|
|
81
|
+
f.puts 'FOO=bar'
|
|
82
|
+
f.puts 'BAZ="qux"'
|
|
83
|
+
f.puts "FRED='barney'"
|
|
84
|
+
f.puts 'OTHER="escaped\"quote"'
|
|
85
|
+
end
|
|
86
|
+
subject.load_env "/tmp/env"
|
|
87
|
+
subject.env["FOO"].should == "bar"
|
|
88
|
+
subject.env["BAZ"].should == "qux"
|
|
89
|
+
subject.env["FRED"].should == "barney"
|
|
90
|
+
subject.env["OTHER"].should == 'escaped"quote'
|
|
70
91
|
end
|
|
71
92
|
|
|
72
93
|
it "should fail if specified and doesnt exist" do
|
|
73
|
-
|
|
74
|
-
engine = Foreman::Engine.new("Procfile", :env => "/tmp/env")
|
|
94
|
+
lambda { subject.load_env "/tmp/env" }.should raise_error(Errno::ENOENT)
|
|
75
95
|
end
|
|
76
96
|
|
|
77
|
-
it "should
|
|
78
|
-
File.open("
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
mock(engine).watch_for_termination
|
|
82
|
-
engine.environment.should == {"FOO"=>"qoo"}
|
|
83
|
-
engine.start
|
|
97
|
+
it "should set port from .env if specified" do
|
|
98
|
+
File.open("/tmp/env", "w") { |f| f.puts("PORT=9000") }
|
|
99
|
+
subject.load_env "/tmp/env"
|
|
100
|
+
subject.send(:base_port).should == 9000
|
|
84
101
|
end
|
|
85
102
|
end
|
|
103
|
+
|
|
86
104
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/engine"
|
|
3
|
+
require "foreman/export"
|
|
4
|
+
|
|
5
|
+
describe "Foreman::Export::Base", :fakefs do
|
|
6
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
7
|
+
let(:location) { "/tmp/init" }
|
|
8
|
+
let(:engine) { Foreman::Engine.new().load_procfile(procfile) }
|
|
9
|
+
let(:subject) { Foreman::Export::Base.new(location, engine) }
|
|
10
|
+
|
|
11
|
+
it "has a say method for displaying info" do
|
|
12
|
+
mock(subject).puts("[foreman export] foo")
|
|
13
|
+
subject.send(:say, "foo")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "raises errors as a Foreman::Export::Exception" do
|
|
17
|
+
lambda { subject.send(:error, "foo") }.should raise_error(Foreman::Export::Exception, "foo")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -3,17 +3,35 @@ require "foreman/engine"
|
|
|
3
3
|
require "foreman/export/bluepill"
|
|
4
4
|
require "tmpdir"
|
|
5
5
|
|
|
6
|
-
describe Foreman::Export::Bluepill do
|
|
7
|
-
let(:procfile)
|
|
8
|
-
let(:
|
|
9
|
-
let(:
|
|
6
|
+
describe Foreman::Export::Bluepill, :fakefs do
|
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:formation) { nil }
|
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
|
10
|
+
let(:options) { Hash.new }
|
|
11
|
+
let(:bluepill) { Foreman::Export::Bluepill.new("/tmp/init", engine, options) }
|
|
10
12
|
|
|
11
13
|
before(:each) { load_export_templates_into_fakefs("bluepill") }
|
|
12
14
|
before(:each) { stub(bluepill).say }
|
|
13
15
|
|
|
14
16
|
it "exports to the filesystem" do
|
|
15
|
-
bluepill.export
|
|
16
|
-
File.read("/tmp/init/app.pill").should == example_export_file("bluepill/app.pill")
|
|
17
|
+
bluepill.export
|
|
18
|
+
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "cleans up if exporting into an existing dir" do
|
|
22
|
+
mock(FileUtils).rm("/tmp/init/app.pill")
|
|
23
|
+
|
|
24
|
+
bluepill.export
|
|
25
|
+
bluepill.export
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "with a process formation" do
|
|
29
|
+
let(:formation) { "alpha=2" }
|
|
30
|
+
|
|
31
|
+
it "exports to the filesystem with concurrency" do
|
|
32
|
+
bluepill.export
|
|
33
|
+
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app-concurrency.pill"))
|
|
34
|
+
end
|
|
17
35
|
end
|
|
18
36
|
|
|
19
37
|
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/engine"
|
|
3
|
+
require "foreman/export/inittab"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
describe Foreman::Export::Inittab, :fakefs do
|
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:location) { "/tmp/inittab" }
|
|
9
|
+
let(:formation) { nil }
|
|
10
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
|
11
|
+
let(:options) { Hash.new }
|
|
12
|
+
let(:inittab) { Foreman::Export::Inittab.new(location, engine, options) }
|
|
13
|
+
|
|
14
|
+
before(:each) { load_export_templates_into_fakefs("inittab") }
|
|
15
|
+
before(:each) { stub(inittab).say }
|
|
16
|
+
|
|
17
|
+
it "exports to the filesystem" do
|
|
18
|
+
inittab.export
|
|
19
|
+
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.default")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "to stdout" do
|
|
23
|
+
let(:location) { "-" }
|
|
24
|
+
|
|
25
|
+
it "exports to stdout" do
|
|
26
|
+
mock(inittab).puts example_export_file("inittab/inittab.default")
|
|
27
|
+
inittab.export
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "with concurrency" do
|
|
32
|
+
let(:formation) { "alpha=2" }
|
|
33
|
+
|
|
34
|
+
it "exports to the filesystem with concurrency" do
|
|
35
|
+
inittab.export
|
|
36
|
+
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.concurrency")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/engine"
|
|
3
|
+
require "foreman/export/launchd"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
describe Foreman::Export::Launchd, :fakefs do
|
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:options) { Hash.new }
|
|
9
|
+
let(:engine) { Foreman::Engine.new().load_procfile(procfile) }
|
|
10
|
+
let(:launchd) { Foreman::Export::Launchd.new("/tmp/init", engine, options) }
|
|
11
|
+
|
|
12
|
+
before(:each) { load_export_templates_into_fakefs("launchd") }
|
|
13
|
+
before(:each) { stub(launchd).say }
|
|
14
|
+
|
|
15
|
+
it "exports to the filesystem" do
|
|
16
|
+
launchd.export
|
|
17
|
+
File.read("/tmp/init/app-alpha-1.plist").should == example_export_file("launchd/launchd-a.default")
|
|
18
|
+
File.read("/tmp/init/app-bravo-1.plist").should == example_export_file("launchd/launchd-b.default")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -3,33 +3,34 @@ require "foreman/engine"
|
|
|
3
3
|
require "foreman/export/runit"
|
|
4
4
|
require "tmpdir"
|
|
5
5
|
|
|
6
|
-
describe Foreman::Export::Runit do
|
|
6
|
+
describe Foreman::Export::Runit, :fakefs do
|
|
7
7
|
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
|
|
8
|
-
let(:engine)
|
|
9
|
-
let(:
|
|
10
|
-
|
|
8
|
+
let(:engine) { Foreman::Engine.new(:formation => "alpha=2,bravo=1").load_procfile(procfile) }
|
|
9
|
+
let(:options) { Hash.new }
|
|
10
|
+
let(:runit) { Foreman::Export::Runit.new('/tmp/init', engine, options) }
|
|
11
|
+
|
|
11
12
|
before(:each) { load_export_templates_into_fakefs("runit") }
|
|
12
13
|
before(:each) { stub(runit).say }
|
|
13
|
-
|
|
14
|
+
before(:each) { stub(FakeFS::FileUtils).chmod }
|
|
15
|
+
|
|
14
16
|
it "exports to the filesystem" do
|
|
15
|
-
|
|
16
|
-
runit.export
|
|
17
|
-
|
|
18
|
-
File.read("/tmp/init/app-alpha-1/run").should
|
|
19
|
-
File.read("/tmp/init/app-alpha-1/log/run").should
|
|
20
|
-
example_export_file('runit/app-alpha-1-log-run')
|
|
17
|
+
engine.env["BAR"] = "baz"
|
|
18
|
+
runit.export
|
|
19
|
+
|
|
20
|
+
File.read("/tmp/init/app-alpha-1/run").should == example_export_file('runit/app-alpha-1/run')
|
|
21
|
+
File.read("/tmp/init/app-alpha-1/log/run").should == example_export_file('runit/app-alpha-1/log/run')
|
|
21
22
|
File.read("/tmp/init/app-alpha-1/env/PORT").should == "5000\n"
|
|
22
|
-
File.read("/tmp/init/app-alpha-1/env/BAR").should
|
|
23
|
-
|
|
24
|
-
File.read("/tmp/init/app-alpha-2/run").should
|
|
25
|
-
File.read("/tmp/init/app-alpha-2/log/run").should ==
|
|
26
|
-
example_export_file('runit/app-alpha-2-log-run')
|
|
23
|
+
File.read("/tmp/init/app-alpha-1/env/BAR").should == "baz\n"
|
|
24
|
+
File.read("/tmp/init/app-alpha-2/run").should == example_export_file('runit/app-alpha-2/run')
|
|
25
|
+
File.read("/tmp/init/app-alpha-2/log/run").should == example_export_file('runit/app-alpha-2/log/run')
|
|
27
26
|
File.read("/tmp/init/app-alpha-2/env/PORT").should == "5001\n"
|
|
28
|
-
File.read("/tmp/init/app-alpha-2/env/BAR").should
|
|
29
|
-
|
|
30
|
-
File.read("/tmp/init/app-bravo-1/run").should
|
|
31
|
-
File.read("/tmp/init/app-bravo-1/log/run").should ==
|
|
32
|
-
example_export_file('runit/app-bravo-1-log-run')
|
|
27
|
+
File.read("/tmp/init/app-alpha-2/env/BAR").should == "baz\n"
|
|
28
|
+
File.read("/tmp/init/app-bravo-1/run").should == example_export_file('runit/app-bravo-1/run')
|
|
29
|
+
File.read("/tmp/init/app-bravo-1/log/run").should == example_export_file('runit/app-bravo-1/log/run')
|
|
33
30
|
File.read("/tmp/init/app-bravo-1/env/PORT").should == "5100\n"
|
|
34
31
|
end
|
|
35
|
-
|
|
32
|
+
|
|
33
|
+
it "creates a full path to the export directory" do
|
|
34
|
+
expect { runit.export }.to_not raise_error(Errno::ENOENT)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "foreman/engine"
|
|
3
|
+
require "foreman/export/supervisord"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
describe Foreman::Export::Supervisord, :fakefs do
|
|
7
|
+
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:formation) { nil }
|
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
|
10
|
+
let(:options) { Hash.new }
|
|
11
|
+
let(:supervisord) { Foreman::Export::Supervisord.new("/tmp/init", engine, options) }
|
|
12
|
+
|
|
13
|
+
before(:each) { load_export_templates_into_fakefs("supervisord") }
|
|
14
|
+
before(:each) { stub(supervisord).say }
|
|
15
|
+
|
|
16
|
+
it "exports to the filesystem" do
|
|
17
|
+
supervisord.export
|
|
18
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-1.conf")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "cleans up if exporting into an existing dir" do
|
|
22
|
+
mock(FileUtils).rm("/tmp/init/app.conf")
|
|
23
|
+
supervisord.export
|
|
24
|
+
supervisord.export
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "with concurrency" do
|
|
28
|
+
let(:formation) { "alpha=2" }
|
|
29
|
+
|
|
30
|
+
it "exports to the filesystem with concurrency" do
|
|
31
|
+
supervisord.export
|
|
32
|
+
File.read("/tmp/init/app.conf").should == example_export_file("supervisord/app-alpha-2.conf")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
@@ -3,51 +3,84 @@ require "foreman/engine"
|
|
|
3
3
|
require "foreman/export/upstart"
|
|
4
4
|
require "tmpdir"
|
|
5
5
|
|
|
6
|
-
describe Foreman::Export::Upstart do
|
|
7
|
-
let(:procfile)
|
|
8
|
-
let(:
|
|
9
|
-
let(:
|
|
6
|
+
describe Foreman::Export::Upstart, :fakefs do
|
|
7
|
+
let(:procfile) { write_procfile("/tmp/app/Procfile") }
|
|
8
|
+
let(:formation) { nil }
|
|
9
|
+
let(:engine) { Foreman::Engine.new(:formation => formation).load_procfile(procfile) }
|
|
10
|
+
let(:options) { Hash.new }
|
|
11
|
+
let(:upstart) { Foreman::Export::Upstart.new("/tmp/init", engine, options) }
|
|
10
12
|
|
|
11
13
|
before(:each) { load_export_templates_into_fakefs("upstart") }
|
|
12
14
|
before(:each) { stub(upstart).say }
|
|
13
15
|
|
|
14
16
|
it "exports to the filesystem" do
|
|
15
|
-
upstart.export
|
|
17
|
+
upstart.export
|
|
16
18
|
|
|
17
19
|
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
|
18
20
|
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
|
19
21
|
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
|
20
|
-
File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
|
|
21
22
|
File.read("/tmp/init/app-bravo.conf").should == example_export_file("upstart/app-bravo.conf")
|
|
22
23
|
File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
it "cleans up if exporting into an existing dir" do
|
|
27
|
+
mock(FileUtils).rm("/tmp/init/app.conf")
|
|
28
|
+
mock(FileUtils).rm("/tmp/init/app-alpha.conf")
|
|
29
|
+
mock(FileUtils).rm("/tmp/init/app-alpha-1.conf")
|
|
30
|
+
mock(FileUtils).rm("/tmp/init/app-bravo.conf")
|
|
31
|
+
mock(FileUtils).rm("/tmp/init/app-bravo-1.conf")
|
|
32
|
+
|
|
33
|
+
upstart.export
|
|
34
|
+
upstart.export
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "quotes and escapes environment variables" do
|
|
38
|
+
engine.env['KEY'] = 'd"\|d'
|
|
39
|
+
upstart.export
|
|
40
|
+
"foobarfoo".should include "bar"
|
|
41
|
+
File.read("/tmp/init/app-alpha-1.conf").should =~ /KEY="d\\"\\\\\\\|d/
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "with a formation" do
|
|
45
|
+
let(:formation) { "alpha=2" }
|
|
46
|
+
|
|
47
|
+
it "exports to the filesystem with concurrency" do
|
|
48
|
+
upstart.export
|
|
49
|
+
|
|
50
|
+
File.read("/tmp/init/app.conf").should == example_export_file("upstart/app.conf")
|
|
51
|
+
File.read("/tmp/init/app-alpha.conf").should == example_export_file("upstart/app-alpha.conf")
|
|
52
|
+
File.read("/tmp/init/app-alpha-1.conf").should == example_export_file("upstart/app-alpha-1.conf")
|
|
53
|
+
File.read("/tmp/init/app-alpha-2.conf").should == example_export_file("upstart/app-alpha-2.conf")
|
|
54
|
+
File.exists?("/tmp/init/app-bravo-1.conf").should == false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
25
58
|
context "with alternate templates" do
|
|
26
|
-
let(:
|
|
59
|
+
let(:template) { "/tmp/alternate" }
|
|
60
|
+
let(:options) { { :app => "app", :template => template } }
|
|
27
61
|
|
|
28
62
|
before do
|
|
29
|
-
FileUtils.mkdir_p
|
|
30
|
-
File.open("#{
|
|
63
|
+
FileUtils.mkdir_p template
|
|
64
|
+
File.open("#{template}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
|
|
31
65
|
end
|
|
32
66
|
|
|
33
67
|
it "can export with alternate template files" do
|
|
34
|
-
upstart.export
|
|
35
|
-
|
|
68
|
+
upstart.export
|
|
36
69
|
File.read("/tmp/init/app.conf").should == "alternate_template\n"
|
|
37
70
|
end
|
|
38
71
|
end
|
|
39
72
|
|
|
40
73
|
context "with alternate templates from home dir" do
|
|
41
|
-
let(:default_template_root) {File.expand_path("~/.foreman/templates")}
|
|
42
74
|
|
|
43
75
|
before do
|
|
44
|
-
FileUtils.mkdir_p
|
|
45
|
-
File.open("
|
|
76
|
+
FileUtils.mkdir_p File.expand_path("~/.foreman/templates/upstart")
|
|
77
|
+
File.open(File.expand_path("~/.foreman/templates/upstart/master.conf.erb"), "w") do |file|
|
|
78
|
+
file.puts "default_alternate_template"
|
|
79
|
+
end
|
|
46
80
|
end
|
|
47
81
|
|
|
48
82
|
it "can export with alternate template files" do
|
|
49
|
-
upstart.export
|
|
50
|
-
|
|
83
|
+
upstart.export
|
|
51
84
|
File.read("/tmp/init/app.conf").should == "default_alternate_template\n"
|
|
52
85
|
end
|
|
53
86
|
end
|
data/spec/foreman/export_spec.rb
CHANGED
|
@@ -1,2 +1,24 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "foreman/export"
|
|
3
|
+
|
|
4
|
+
describe "Foreman::Export" do
|
|
5
|
+
subject { Foreman::Export }
|
|
6
|
+
|
|
7
|
+
describe "with a formatter that doesn't declare the appropriate class" do
|
|
8
|
+
it "prints an error" do
|
|
9
|
+
mock(subject).require("foreman/export/invalidformatter")
|
|
10
|
+
mock_export_error("Unknown export format: invalidformatter (no class Foreman::Export::Invalidformatter).") do
|
|
11
|
+
subject.formatter("invalidformatter")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "with an invalid formatter" do
|
|
17
|
+
|
|
18
|
+
it "prints an error" do
|
|
19
|
+
mock_export_error("Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
|
|
20
|
+
subject.formatter("invalidformatter")
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|