foreman-systemd 0.78.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.
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,36 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/runit"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Runit, :fakefs do
7
+ let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile", 'bar=baz') }
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
+
12
+ before(:each) { load_export_templates_into_fakefs("runit") }
13
+ before(:each) { stub(runit).say }
14
+ before(:each) { stub(FakeFS::FileUtils).chmod }
15
+
16
+ it "exports to the filesystem" do
17
+ engine.env["BAR"] = "baz"
18
+ runit.export
19
+
20
+ expect(File.read("/tmp/init/app-alpha-1/run")).to eq(example_export_file('runit/app-alpha-1/run'))
21
+ expect(File.read("/tmp/init/app-alpha-1/log/run")).to eq(example_export_file('runit/app-alpha-1/log/run'))
22
+ expect(File.read("/tmp/init/app-alpha-1/env/PORT")).to eq("5000\n")
23
+ expect(File.read("/tmp/init/app-alpha-1/env/BAR")).to eq("baz\n")
24
+ expect(File.read("/tmp/init/app-alpha-2/run")).to eq(example_export_file('runit/app-alpha-2/run'))
25
+ expect(File.read("/tmp/init/app-alpha-2/log/run")).to eq(example_export_file('runit/app-alpha-2/log/run'))
26
+ expect(File.read("/tmp/init/app-alpha-2/env/PORT")).to eq("5001\n")
27
+ expect(File.read("/tmp/init/app-alpha-2/env/BAR")).to eq("baz\n")
28
+ expect(File.read("/tmp/init/app-bravo-1/run")).to eq(example_export_file('runit/app-bravo-1/run'))
29
+ expect(File.read("/tmp/init/app-bravo-1/log/run")).to eq(example_export_file('runit/app-bravo-1/log/run'))
30
+ expect(File.read("/tmp/init/app-bravo-1/env/PORT")).to eq("5100\n")
31
+ end
32
+
33
+ it "creates a full path to the export directory" do
34
+ expect { runit.export }.to_not raise_error
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
+ expect(File.read("/tmp/init/app.conf")).to eq(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
+ expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("supervisord/app-alpha-2.conf"))
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,91 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/systemd"
4
+ require "tmpdir"
5
+
6
+ describe Foreman::Export::Systemd, :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(:systemd) { Foreman::Export::Systemd.new("/tmp/init", engine, options) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("systemd") }
14
+ before(:each) { stub(systemd).say }
15
+
16
+ it "exports to the filesystem" do
17
+ systemd.export
18
+
19
+ expect(File.read("/tmp/init/app.target")).to eq(example_export_file("systemd/standard/app.target"))
20
+ expect(File.read("/tmp/init/app-alpha.target")).to eq(example_export_file("systemd/standard/app-alpha.target"))
21
+ expect(File.read("/tmp/init/app-alpha-1.service")).to eq(example_export_file("systemd/standard/app-alpha-1.service"))
22
+ expect(File.read("/tmp/init/app-bravo.target")).to eq(example_export_file("systemd/standard/app-bravo.target"))
23
+ expect(File.read("/tmp/init/app-bravo-1.service")).to eq(example_export_file("systemd/standard/app-bravo-1.service"))
24
+ end
25
+
26
+ it "cleans up if exporting into an existing dir" do
27
+ mock(FileUtils).rm("/tmp/init/app.target")
28
+ mock(FileUtils).rm("/tmp/init/app-alpha.target")
29
+ mock(FileUtils).rm("/tmp/init/app-alpha-1.service")
30
+ mock(FileUtils).rm("/tmp/init/app-bravo.target")
31
+ mock(FileUtils).rm("/tmp/init/app-bravo-1.service")
32
+ mock(FileUtils).rm("/tmp/init/app-foo-bar.target")
33
+ mock(FileUtils).rm("/tmp/init/app-foo-bar-1.service")
34
+ mock(FileUtils).rm("/tmp/init/app-foo_bar.target")
35
+ mock(FileUtils).rm("/tmp/init/app-foo_bar-1.service")
36
+
37
+ systemd.export
38
+ systemd.export
39
+ end
40
+
41
+ it "includes environment variables" do
42
+ engine.env['KEY'] = 'some "value"'
43
+ systemd.export
44
+ expect(File.read("/tmp/init/app-alpha-1.service")).to match(/KEY=some "value"$/)
45
+ end
46
+
47
+ context "with a formation" do
48
+ let(:formation) { "alpha=2" }
49
+
50
+ it "exports to the filesystem with concurrency" do
51
+ systemd.export
52
+
53
+ expect(File.read("/tmp/init/app.target")).to eq(example_export_file("systemd/concurrency/app.target"))
54
+ expect(File.read("/tmp/init/app-alpha.target")).to eq(example_export_file("systemd/concurrency/app-alpha.target"))
55
+ expect(File.read("/tmp/init/app-alpha-1.service")).to eq(example_export_file("systemd/concurrency/app-alpha-1.service"))
56
+ expect(File.read("/tmp/init/app-alpha-2.service")).to eq(example_export_file("systemd/concurrency/app-alpha-2.service"))
57
+ expect(File.exists?("/tmp/init/app-bravo-1.service")).to eq(false)
58
+ end
59
+ end
60
+
61
+ context "with alternate templates" do
62
+ let(:template) { "/tmp/alternate" }
63
+ let(:options) { { :app => "app", :template => template } }
64
+
65
+ before do
66
+ FileUtils.mkdir_p template
67
+ File.open("#{template}/master.target.erb", "w") { |f| f.puts "alternate_template" }
68
+ end
69
+
70
+ it "can export with alternate template files" do
71
+ systemd.export
72
+ expect(File.read("/tmp/init/app.target")).to eq("alternate_template\n")
73
+ end
74
+ end
75
+
76
+ context "with alternate templates from home dir" do
77
+
78
+ before do
79
+ FileUtils.mkdir_p File.expand_path("~/.foreman/templates/systemd")
80
+ File.open(File.expand_path("~/.foreman/templates/systemd/master.target.erb"), "w") do |file|
81
+ file.puts "default_alternate_template"
82
+ end
83
+ end
84
+
85
+ it "can export with alternate template files" do
86
+ systemd.export
87
+ expect(File.read("/tmp/init/app.target")).to eq("default_alternate_template\n")
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,118 @@
1
+ require "spec_helper"
2
+ require "foreman/engine"
3
+ require "foreman/export/upstart"
4
+ require "tmpdir"
5
+
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) }
12
+
13
+ before(:each) { load_export_templates_into_fakefs("upstart") }
14
+ before(:each) { stub(upstart).say }
15
+
16
+ it "exports to the filesystem" do
17
+ upstart.export
18
+
19
+ expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("upstart/app.conf"))
20
+ expect(File.read("/tmp/init/app-alpha.conf")).to eq(example_export_file("upstart/app-alpha.conf"))
21
+ expect(File.read("/tmp/init/app-alpha-1.conf")).to eq(example_export_file("upstart/app-alpha-1.conf"))
22
+ expect(File.read("/tmp/init/app-bravo.conf")).to eq(example_export_file("upstart/app-bravo.conf"))
23
+ expect(File.read("/tmp/init/app-bravo-1.conf")).to eq(example_export_file("upstart/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
+ upstart.export
38
+ upstart.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
+ upstart.export
51
+ end
52
+
53
+ it 'does not delete exported files for app which share name prefix' do
54
+ FileUtils.mkdir_p "/tmp/init"
55
+
56
+ ["app-worker", "app-worker-worker", "app-worker-worker-1"].each do |name|
57
+ path = "/tmp/init/#{name}.conf"
58
+ FileUtils.touch(path)
59
+ dont_allow(FileUtils).rm(path)
60
+ end
61
+
62
+ upstart.export
63
+ expect(File.exist?('/tmp/init/app.conf')).to be true
64
+ expect(File.exist?('/tmp/init/app-worker.conf')).to be true
65
+ end
66
+
67
+ it "quotes and escapes environment variables" do
68
+ engine.env['KEY'] = 'd"\|d'
69
+ upstart.export
70
+ expect("foobarfoo").to include "bar"
71
+ expect(File.read("/tmp/init/app-alpha-1.conf")).to match(/KEY='d"\\\|d'/)
72
+ end
73
+
74
+ context "with a formation" do
75
+ let(:formation) { "alpha=2" }
76
+
77
+ it "exports to the filesystem with concurrency" do
78
+ upstart.export
79
+
80
+ expect(File.read("/tmp/init/app.conf")).to eq(example_export_file("upstart/app.conf"))
81
+ expect(File.read("/tmp/init/app-alpha.conf")).to eq(example_export_file("upstart/app-alpha.conf"))
82
+ expect(File.read("/tmp/init/app-alpha-1.conf")).to eq(example_export_file("upstart/app-alpha-1.conf"))
83
+ expect(File.read("/tmp/init/app-alpha-2.conf")).to eq(example_export_file("upstart/app-alpha-2.conf"))
84
+ expect(File.exists?("/tmp/init/app-bravo-1.conf")).to eq(false)
85
+ end
86
+ end
87
+
88
+ context "with alternate templates" do
89
+ let(:template) { "/tmp/alternate" }
90
+ let(:options) { { :app => "app", :template => template } }
91
+
92
+ before do
93
+ FileUtils.mkdir_p template
94
+ File.open("#{template}/master.conf.erb", "w") { |f| f.puts "alternate_template" }
95
+ end
96
+
97
+ it "can export with alternate template files" do
98
+ upstart.export
99
+ expect(File.read("/tmp/init/app.conf")).to eq("alternate_template\n")
100
+ end
101
+ end
102
+
103
+ context "with alternate templates from home dir" do
104
+
105
+ before do
106
+ FileUtils.mkdir_p File.expand_path("~/.foreman/templates/upstart")
107
+ File.open(File.expand_path("~/.foreman/templates/upstart/master.conf.erb"), "w") do |file|
108
+ file.puts "default_alternate_template"
109
+ end
110
+ end
111
+
112
+ it "can export with alternate template files" do
113
+ upstart.export
114
+ expect(File.read("/tmp/init/app.conf")).to eq("default_alternate_template\n")
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
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
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+ require "foreman/helpers"
3
+
4
+ describe "Foreman::Helpers" do
5
+ before do
6
+ module Foo
7
+ class Bar; end
8
+ end
9
+ end
10
+
11
+ after do
12
+ Object.send(:remove_const, :Foo)
13
+ end
14
+
15
+ subject { o = Object.new; o.extend(Foreman::Helpers); o }
16
+
17
+ it "should classify words" do
18
+ expect(subject.classify("foo")).to eq("Foo")
19
+ expect(subject.classify("foo-bar")).to eq("FooBar")
20
+ end
21
+
22
+ it "should constantize words" do
23
+ expect(subject.constantize("Object")).to eq(Object)
24
+ expect(subject.constantize("Foo::Bar")).to eq(Foo::Bar)
25
+ end
26
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'foreman/process'
3
+ require 'ostruct'
4
+ require 'timeout'
5
+ require 'tmpdir'
6
+
7
+ describe Foreman::Process do
8
+
9
+ def run(process, options={})
10
+ rd, wr = IO.method(:pipe).arity.zero? ? IO.pipe : IO.pipe("BINARY")
11
+ process.run(options.merge(:output => wr))
12
+ rd.gets
13
+ end
14
+
15
+ describe "#run" do
16
+
17
+ it "runs the process" do
18
+ process = Foreman::Process.new(resource_path("bin/test"))
19
+ expect(run(process)).to eq("testing\n")
20
+ end
21
+
22
+ it "can set environment" do
23
+ process = Foreman::Process.new(resource_path("bin/env FOO"), :env => { "FOO" => "bar" })
24
+ expect(run(process)).to eq("bar\n")
25
+ end
26
+
27
+ it "can set per-run environment" do
28
+ process = Foreman::Process.new(resource_path("bin/env FOO"))
29
+ expect(run(process, :env => { "FOO" => "bar "})).to eq("bar\n")
30
+ end
31
+
32
+ it "can handle env vars in the command" do
33
+ process = Foreman::Process.new(resource_path("bin/echo $FOO"), :env => { "FOO" => "bar" })
34
+ expect(run(process)).to eq("bar\n")
35
+ end
36
+
37
+ it "can handle per-run env vars in the command" do
38
+ process = Foreman::Process.new(resource_path("bin/echo $FOO"))
39
+ expect(run(process, :env => { "FOO" => "bar" })).to eq("bar\n")
40
+ end
41
+
42
+ it "should output utf8 properly" do
43
+ process = Foreman::Process.new(resource_path("bin/utf8"))
44
+ expect(run(process)).to eq(Foreman.ruby_18? ? "\xFF\x03\n" : "\xFF\x03\n".force_encoding('binary'))
45
+ end
46
+
47
+ it "can expand env in the command" do
48
+ process = Foreman::Process.new("command $FOO $BAR", :env => { "FOO" => "bar" })
49
+ expect(process.expanded_command).to eq("command bar $BAR")
50
+ end
51
+
52
+ it "can expand extra env in the command" do
53
+ process = Foreman::Process.new("command $FOO $BAR", :env => { "FOO" => "bar" })
54
+ expect(process.expanded_command("BAR" => "qux")).to eq("command bar qux")
55
+ end
56
+
57
+ it "can execute" do
58
+ mock(Kernel).exec "bin/command"
59
+ process = Foreman::Process.new("bin/command")
60
+ process.exec
61
+ end
62
+
63
+ it "can execute with env" do
64
+ mock(Kernel).exec "bin/command bar"
65
+ process = Foreman::Process.new("bin/command $FOO")
66
+ process.exec(:env => { "FOO" => "bar" })
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'foreman/procfile'
3
+ require 'pathname'
4
+ require 'tmpdir'
5
+
6
+ describe Foreman::Procfile, :fakefs do
7
+ subject { Foreman::Procfile.new }
8
+
9
+ it "can load from a file" do
10
+ write_procfile
11
+ subject.load "Procfile"
12
+ expect(subject["alpha"]).to eq("./alpha")
13
+ expect(subject["bravo"]).to eq("./bravo")
14
+ end
15
+
16
+ it "loads a passed-in Procfile" do
17
+ write_procfile
18
+ procfile = Foreman::Procfile.new("Procfile")
19
+ expect(procfile["alpha"]).to eq("./alpha")
20
+ expect(procfile["bravo"]).to eq("./bravo")
21
+ expect(procfile["foo-bar"]).to eq("./foo-bar")
22
+ expect(procfile["foo_bar"]).to eq("./foo_bar")
23
+ end
24
+
25
+ it "can have a process appended to it" do
26
+ subject["charlie"] = "./charlie"
27
+ expect(subject["charlie"]).to eq("./charlie")
28
+ end
29
+
30
+ it "can write to a string" do
31
+ subject["foo"] = "./foo"
32
+ subject["bar"] = "./bar"
33
+ expect(subject.to_s).to eq("foo: ./foo\nbar: ./bar")
34
+ end
35
+
36
+ it "can write to a file" do
37
+ subject["foo"] = "./foo"
38
+ subject["bar"] = "./bar"
39
+ subject.save "/tmp/proc"
40
+ expect(File.read("/tmp/proc")).to eq("foo: ./foo\nbar: ./bar\n")
41
+ end
42
+
43
+ end