foreman-systemd 0.78.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +64 -0
  3. data/bin/foreman +7 -0
  4. data/bin/foreman-runner +41 -0
  5. data/data/example/Procfile +4 -0
  6. data/data/example/Procfile.without_colon +2 -0
  7. data/data/example/error +7 -0
  8. data/data/example/log/neverdie.log +4 -0
  9. data/data/example/spawnee +14 -0
  10. data/data/example/spawner +7 -0
  11. data/data/example/ticker +14 -0
  12. data/data/example/utf8 +11 -0
  13. data/data/export/bluepill/master.pill.erb +28 -0
  14. data/data/export/daemon/master.conf.erb +14 -0
  15. data/data/export/daemon/process.conf.erb +8 -0
  16. data/data/export/daemon/process_master.conf.erb +2 -0
  17. data/data/export/launchd/launchd.plist.erb +33 -0
  18. data/data/export/runit/log/run.erb +7 -0
  19. data/data/export/runit/run.erb +4 -0
  20. data/data/export/supervisord/app.conf.erb +28 -0
  21. data/data/export/systemd/master.target.erb +6 -0
  22. data/data/export/systemd/process.service.erb +16 -0
  23. data/data/export/systemd/process_master.target.erb +4 -0
  24. data/data/export/upstart/master.conf.erb +2 -0
  25. data/data/export/upstart/process.conf.erb +14 -0
  26. data/data/export/upstart/process_master.conf.erb +2 -0
  27. data/lib/foreman.rb +17 -0
  28. data/lib/foreman/cli.rb +161 -0
  29. data/lib/foreman/distribution.rb +9 -0
  30. data/lib/foreman/engine.rb +441 -0
  31. data/lib/foreman/engine/cli.rb +104 -0
  32. data/lib/foreman/env.rb +29 -0
  33. data/lib/foreman/export.rb +36 -0
  34. data/lib/foreman/export/base.rb +156 -0
  35. data/lib/foreman/export/bluepill.rb +12 -0
  36. data/lib/foreman/export/daemon.rb +28 -0
  37. data/lib/foreman/export/inittab.rb +42 -0
  38. data/lib/foreman/export/launchd.rb +22 -0
  39. data/lib/foreman/export/runit.rb +34 -0
  40. data/lib/foreman/export/supervisord.rb +16 -0
  41. data/lib/foreman/export/systemd.rb +32 -0
  42. data/lib/foreman/export/upstart.rb +43 -0
  43. data/lib/foreman/helpers.rb +45 -0
  44. data/lib/foreman/process.rb +80 -0
  45. data/lib/foreman/procfile.rb +92 -0
  46. data/lib/foreman/version.rb +5 -0
  47. data/man/foreman.1 +278 -0
  48. data/spec/foreman/cli_spec.rb +107 -0
  49. data/spec/foreman/engine_spec.rb +112 -0
  50. data/spec/foreman/export/base_spec.rb +19 -0
  51. data/spec/foreman/export/bluepill_spec.rb +37 -0
  52. data/spec/foreman/export/daemon_spec.rb +97 -0
  53. data/spec/foreman/export/inittab_spec.rb +40 -0
  54. data/spec/foreman/export/launchd_spec.rb +31 -0
  55. data/spec/foreman/export/runit_spec.rb +36 -0
  56. data/spec/foreman/export/supervisord_spec.rb +36 -0
  57. data/spec/foreman/export/systemd_spec.rb +91 -0
  58. data/spec/foreman/export/upstart_spec.rb +118 -0
  59. data/spec/foreman/export_spec.rb +24 -0
  60. data/spec/foreman/helpers_spec.rb +26 -0
  61. data/spec/foreman/process_spec.rb +71 -0
  62. data/spec/foreman/procfile_spec.rb +43 -0
  63. data/spec/foreman_spec.rb +16 -0
  64. data/spec/helper_spec.rb +19 -0
  65. data/spec/resources/Procfile +5 -0
  66. data/spec/resources/bin/echo +2 -0
  67. data/spec/resources/bin/env +2 -0
  68. data/spec/resources/bin/test +2 -0
  69. data/spec/resources/bin/utf8 +2 -0
  70. data/spec/resources/export/bluepill/app-concurrency.pill +49 -0
  71. data/spec/resources/export/bluepill/app.pill +81 -0
  72. data/spec/resources/export/daemon/app-alpha-1.conf +7 -0
  73. data/spec/resources/export/daemon/app-alpha-2.conf +7 -0
  74. data/spec/resources/export/daemon/app-alpha.conf +2 -0
  75. data/spec/resources/export/daemon/app-bravo-1.conf +7 -0
  76. data/spec/resources/export/daemon/app-bravo.conf +2 -0
  77. data/spec/resources/export/daemon/app.conf +14 -0
  78. data/spec/resources/export/inittab/inittab.concurrency +4 -0
  79. data/spec/resources/export/inittab/inittab.default +6 -0
  80. data/spec/resources/export/launchd/launchd-a.default +29 -0
  81. data/spec/resources/export/launchd/launchd-b.default +29 -0
  82. data/spec/resources/export/launchd/launchd-c.default +30 -0
  83. data/spec/resources/export/runit/app-alpha-1/log/run +7 -0
  84. data/spec/resources/export/runit/app-alpha-1/run +4 -0
  85. data/spec/resources/export/runit/app-alpha-2/log/run +7 -0
  86. data/spec/resources/export/runit/app-alpha-2/run +4 -0
  87. data/spec/resources/export/runit/app-bravo-1/log/run +7 -0
  88. data/spec/resources/export/runit/app-bravo-1/run +4 -0
  89. data/spec/resources/export/supervisord/app-alpha-1.conf +46 -0
  90. data/spec/resources/export/supervisord/app-alpha-2.conf +24 -0
  91. data/spec/resources/export/systemd/concurrency/app-alpha-1.service +14 -0
  92. data/spec/resources/export/systemd/concurrency/app-alpha-2.service +14 -0
  93. data/spec/resources/export/systemd/concurrency/app-alpha.target +3 -0
  94. data/spec/resources/export/systemd/concurrency/app.target +6 -0
  95. data/spec/resources/export/systemd/standard/app-alpha-1.service +14 -0
  96. data/spec/resources/export/systemd/standard/app-alpha.target +3 -0
  97. data/spec/resources/export/systemd/standard/app-bravo-1.service +14 -0
  98. data/spec/resources/export/systemd/standard/app-bravo.target +3 -0
  99. data/spec/resources/export/systemd/standard/app.target +6 -0
  100. data/spec/resources/export/upstart/app-alpha-1.conf +11 -0
  101. data/spec/resources/export/upstart/app-alpha-2.conf +11 -0
  102. data/spec/resources/export/upstart/app-alpha.conf +2 -0
  103. data/spec/resources/export/upstart/app-bravo-1.conf +11 -0
  104. data/spec/resources/export/upstart/app-bravo.conf +2 -0
  105. data/spec/resources/export/upstart/app.conf +2 -0
  106. data/spec/spec_helper.rb +166 -0
  107. metadata +164 -0
@@ -0,0 +1,107 @@
1
+ require "spec_helper"
2
+ require "foreman/cli"
3
+
4
+ describe "Foreman::CLI", :fakefs do
5
+ subject { Foreman::CLI.new }
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
+ expect(subject.send(:options)["formation"]).to eq("alpha=2")
12
+ end
13
+
14
+ it "is overridden by options at the cli" do
15
+ subject = Foreman::CLI.new([], :formation => "alpha=3")
16
+ expect(subject.send(:options)["formation"]).to eq("alpha=3")
17
+ end
18
+ end
19
+
20
+ describe "start" do
21
+ describe "when a Procfile doesnt exist", :fakefs do
22
+ it "displays an error" do
23
+ mock_error(subject, "Procfile does not exist.") do
24
+ dont_allow.instance_of(Foreman::Engine).start
25
+ subject.start
26
+ end
27
+ end
28
+ end
29
+
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
+ expect(output).to match(/env.1/)
35
+ expect(output).not_to match(/test.1/)
36
+ end
37
+ end
38
+
39
+ it "can run all commands" do
40
+ without_fakefs do
41
+ output = foreman("start -f #{resource_path("Procfile")} -e #{resource_path(".env")}")
42
+ expect(output).to match(/echo.1 \| echoing/)
43
+ expect(output).to match(/env.1 \| bar/)
44
+ expect(output).to match(/test.1 \| testing/)
45
+ end
46
+ end
47
+
48
+ it "sets PS variable with the process name" do
49
+ without_fakefs do
50
+ output = foreman("start -f #{resource_path("Procfile")}")
51
+ expect(output).to match(/ps.1 \| PS env var is ps.1/)
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ describe "check" do
58
+ it "with a valid Procfile displays the jobs" do
59
+ write_procfile
60
+ expect(foreman("check")).to eq("valid procfile detected (alpha, bravo, foo_bar, foo-bar)\n")
61
+ end
62
+
63
+ it "with a blank Procfile displays an error" do
64
+ FileUtils.touch "Procfile"
65
+ expect(foreman("check")).to eq("ERROR: no processes defined\n")
66
+ end
67
+
68
+ it "without a Procfile displays an error" do
69
+ FileUtils.rm_f "Procfile"
70
+ expect(foreman("check")).to eq("ERROR: Procfile does not exist.\n")
71
+ end
72
+ end
73
+
74
+ describe "run" do
75
+ it "can run a command" do
76
+ expect(forked_foreman("run echo 1")).to eq("1\n")
77
+ end
78
+
79
+ it "doesn't parse options for the command" do
80
+ expect(forked_foreman("run grep -e FOO #{resource_path(".env")}")).to eq("FOO=bar\n")
81
+ end
82
+
83
+ it "includes the environment" do
84
+ expect(forked_foreman("run -e #{resource_path(".env")} #{resource_path("bin/env FOO")}")).to eq("bar\n")
85
+ end
86
+
87
+ it "can run a command from the Procfile" do
88
+ expect(forked_foreman("run -f #{resource_path("Procfile")} test")).to eq("testing\n")
89
+ end
90
+
91
+ it "exits with the same exit code as the command" do
92
+ expect(fork_and_get_exitstatus("run echo 1")).to eq(0)
93
+ expect(fork_and_get_exitstatus("run date 'invalid_date'")).to eq(1)
94
+ end
95
+ end
96
+
97
+ describe "version" do
98
+ it "displays gem version" do
99
+ expect(foreman("version").chomp).to eq(Foreman::VERSION)
100
+ end
101
+
102
+ it "displays gem version on shortcut command" do
103
+ expect(foreman("-v").chomp).to eq(Foreman::VERSION)
104
+ end
105
+ end
106
+
107
+ end
@@ -0,0 +1,112 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+
4
+ class Foreman::Engine::Tester < Foreman::Engine
5
+ attr_reader :buffer
6
+
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
24
+
25
+ describe "initialize" do
26
+ describe "with a Procfile" do
27
+ before { write_procfile }
28
+
29
+ it "reads the processes" do
30
+ expect(subject.process("alpha").command).to eq("./alpha")
31
+ expect(subject.process("bravo").command).to eq("./bravo")
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "start" do
37
+ it "forks the processes" do
38
+ mock(subject.process("alpha")).run(anything)
39
+ mock(subject.process("bravo")).run(anything)
40
+ mock(subject).watch_for_output
41
+ mock(subject).watch_for_termination
42
+ subject.start
43
+ end
44
+
45
+ it "handles concurrency" do
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
52
+ end
53
+ end
54
+
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
+ expect(engine.root).to eq("/some/app")
60
+ end
61
+ end
62
+
63
+ describe "environment" do
64
+ it "should read env files" do
65
+ File.open("/tmp/env", "w") { |f| f.puts("FOO=baz") }
66
+ subject.load_env("/tmp/env")
67
+ expect(subject.env["FOO"]).to eq("baz")
68
+ end
69
+
70
+ it "should read more than one if specified" do
71
+ File.open("/tmp/env1", "w") { |f| f.puts("FOO=bar") }
72
+ File.open("/tmp/env2", "w") { |f| f.puts("BAZ=qux") }
73
+ subject.load_env "/tmp/env1"
74
+ subject.load_env "/tmp/env2"
75
+ expect(subject.env["FOO"]).to eq("bar")
76
+ expect(subject.env["BAZ"]).to eq("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
+ expect(subject.env["FOO"]).to eq("bar")
88
+ expect(subject.env["BAZ"]).to eq("qux")
89
+ expect(subject.env["FRED"]).to eq("barney")
90
+ expect(subject.env["OTHER"]).to eq('escaped"quote')
91
+ end
92
+
93
+ it "should handle multiline strings" do
94
+ File.open("/tmp/env", "w") do |f|
95
+ f.puts 'FOO="bar\nbaz"'
96
+ end
97
+ subject.load_env "/tmp/env"
98
+ expect(subject.env["FOO"]).to eq("bar\nbaz")
99
+ end
100
+
101
+ it "should fail if specified and doesnt exist" do
102
+ expect { subject.load_env "/tmp/env" }.to raise_error(Errno::ENOENT)
103
+ end
104
+
105
+ it "should set port from .env if specified" do
106
+ File.open("/tmp/env", "w") { |f| f.puts("PORT=9000") }
107
+ subject.load_env "/tmp/env"
108
+ expect(subject.send(:base_port)).to eq(9000)
109
+ end
110
+ end
111
+
112
+ 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
+ expect { subject.send(:error, "foo") }.to raise_error(Foreman::Export::Exception, "foo")
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/bluepill"
4
+ require "tmpdir"
5
+
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) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("bluepill") }
14
+ before(:each) { stub(bluepill).say }
15
+
16
+ it "exports to the filesystem" do
17
+ bluepill.export
18
+ expect(normalize_space(File.read("/tmp/init/app.pill"))).to eq(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
+ expect(normalize_space(File.read("/tmp/init/app.pill"))).to eq(normalize_space(example_export_file("bluepill/app-concurrency.pill")))
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,97 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/daemon"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Daemon, :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(:daemon) { Foreman::Export::Daemon.new("/tmp/init", engine, options) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("daemon") }
14
+ before(:each) { stub(daemon).say }
15
+
16
+ it "exports to the filesystem" do
17
+ daemon.export
18
+
19
+ expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("daemon/app.conf"))
20
+ expect(File.read("/tmp/init/app-alpha.conf")).to eq(example_export_file("daemon/app-alpha.conf"))
21
+ expect(File.read("/tmp/init/app-alpha-1.conf")).to eq(example_export_file("daemon/app-alpha-1.conf"))
22
+ expect(File.read("/tmp/init/app-bravo.conf")).to eq(example_export_file("daemon/app-bravo.conf"))
23
+ expect(File.read("/tmp/init/app-bravo-1.conf")).to eq(example_export_file("daemon/app-bravo-1.conf"))
24
+ end
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
+ mock(FileUtils).rm("/tmp/init/app-foo-bar.conf")
33
+ mock(FileUtils).rm("/tmp/init/app-foo-bar-1.conf")
34
+ mock(FileUtils).rm("/tmp/init/app-foo_bar.conf")
35
+ mock(FileUtils).rm("/tmp/init/app-foo_bar-1.conf")
36
+
37
+ daemon.export
38
+ daemon.export
39
+ end
40
+
41
+ it "does not delete exported files for similarly named applications" do
42
+ FileUtils.mkdir_p "/tmp/init"
43
+
44
+ ["app2", "app2-alpha", "app2-alpha-1"].each do |name|
45
+ path = "/tmp/init/#{name}.conf"
46
+ FileUtils.touch(path)
47
+ dont_allow(FileUtils).rm(path)
48
+ end
49
+
50
+ daemon.export
51
+ end
52
+
53
+ context "with a formation" do
54
+ let(:formation) { "alpha=2" }
55
+
56
+ it "exports to the filesystem with concurrency" do
57
+ daemon.export
58
+
59
+ expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("daemon/app.conf"))
60
+ expect(File.read("/tmp/init/app-alpha.conf")).to eq(example_export_file("daemon/app-alpha.conf"))
61
+ expect(File.read("/tmp/init/app-alpha-1.conf")).to eq(example_export_file("daemon/app-alpha-1.conf"))
62
+ expect(File.read("/tmp/init/app-alpha-2.conf")).to eq(example_export_file("daemon/app-alpha-2.conf"))
63
+ expect(File.exists?("/tmp/init/app-bravo-1.conf")).to eq(false)
64
+ end
65
+ end
66
+
67
+ context "with alternate templates" do
68
+ let(:template) { "/tmp/alternate" }
69
+ let(:options) { { :app => "app", :template => template } }
70
+
71
+ before do
72
+ FileUtils.mkdir_p template
73
+ File.open("#{template}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
74
+ end
75
+
76
+ it "can export with alternate template files" do
77
+ daemon.export
78
+ expect(File.read("/tmp/init/app.conf")).to eq("alternate_template\n")
79
+ end
80
+ end
81
+
82
+ context "with alternate templates from home dir" do
83
+
84
+ before do
85
+ FileUtils.mkdir_p File.expand_path("~/.foreman/templates/daemon")
86
+ File.open(File.expand_path("~/.foreman/templates/daemon/master.conf.erb"), "w") do |file|
87
+ file.puts "default_alternate_template"
88
+ end
89
+ end
90
+
91
+ it "can export with alternate template files" do
92
+ daemon.export
93
+ expect(File.read("/tmp/init/app.conf")).to eq("default_alternate_template\n")
94
+ end
95
+ end
96
+
97
+ 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
+ expect(File.read("/tmp/inittab")).to eq(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
+ expect(File.read("/tmp/inittab")).to eq(example_export_file("inittab/inittab.concurrency"))
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,31 @@
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
+ expect(File.read("/tmp/init/app-alpha-1.plist")).to eq(example_export_file("launchd/launchd-a.default"))
18
+ expect(File.read("/tmp/init/app-bravo-1.plist")).to eq(example_export_file("launchd/launchd-b.default"))
19
+ end
20
+
21
+ context "with multiple command arguments" do
22
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", "charlie") }
23
+
24
+ it "splits each command argument" do
25
+ launchd.export
26
+ expect(File.read("/tmp/init/app-alpha-1.plist")).to eq(example_export_file("launchd/launchd-c.default"))
27
+ end
28
+
29
+ end
30
+
31
+ end