ruby_yacht 0.1.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/.codeclimate.yml +27 -0
- data/.gitignore +4 -0
- data/.rdoc_options +29 -0
- data/.rspec +1 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +8 -0
- data/README.md +216 -0
- data/doc/CONTRIBUTING.md +12 -0
- data/doc/TODO.md +28 -0
- data/doc/configuration_sample.rb +87 -0
- data/lib/ruby_yacht/dsl/app.rb +59 -0
- data/lib/ruby_yacht/dsl/configuration.rb +55 -0
- data/lib/ruby_yacht/dsl/database.rb +57 -0
- data/lib/ruby_yacht/dsl/dns_server.rb +38 -0
- data/lib/ruby_yacht/dsl/dsl.rb +252 -0
- data/lib/ruby_yacht/dsl/project.rb +140 -0
- data/lib/ruby_yacht/dsl.rb +6 -0
- data/lib/ruby_yacht/images/app/Dockerfile.erb +32 -0
- data/lib/ruby_yacht/images/app/checkout.rb +7 -0
- data/lib/ruby_yacht/images/app/startup.rb +17 -0
- data/lib/ruby_yacht/images/app/update_database_config.rb +45 -0
- data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +23 -0
- data/lib/ruby_yacht/images/app-dependencies/install_gems.rb +12 -0
- data/lib/ruby_yacht/images/database/Dockerfile.erb +26 -0
- data/lib/ruby_yacht/images/database/load_seeds.rb +42 -0
- data/lib/ruby_yacht/images/database/setup.rb +19 -0
- data/lib/ruby_yacht/images/database/setup_database.sql.erb +12 -0
- data/lib/ruby_yacht/images/deploy/Dockerfile.erb +2 -0
- data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -0
- data/lib/ruby_yacht/images/web/add_app.rb +12 -0
- data/lib/ruby_yacht/images/web/add_project.rb +14 -0
- data/lib/ruby_yacht/images/web/app_config.erb +11 -0
- data/lib/ruby_yacht/images/web/index.html.erb +10 -0
- data/lib/ruby_yacht/images/web/index_config.erb +12 -0
- data/lib/ruby_yacht/images/web/setup.rb +22 -0
- data/lib/ruby_yacht/runner/build.rb +21 -0
- data/lib/ruby_yacht/runner/build_images.rb +82 -0
- data/lib/ruby_yacht/runner/checkout.rb +68 -0
- data/lib/ruby_yacht/runner/command.rb +161 -0
- data/lib/ruby_yacht/runner/help.rb +55 -0
- data/lib/ruby_yacht/runner/implode.rb +33 -0
- data/lib/ruby_yacht/runner/run_containers.rb +105 -0
- data/lib/ruby_yacht/runner/runner.rb +42 -0
- data/lib/ruby_yacht/runner/services.rb +79 -0
- data/lib/ruby_yacht/runner/shell.rb +66 -0
- data/lib/ruby_yacht/runner/update_hosts.rb +72 -0
- data/lib/ruby_yacht/runner.rb +18 -0
- data/lib/ruby_yacht.rb +6 -0
- data/ruby_yacht.gemspec +18 -0
- data/spec/docker/Dockerfile +5 -0
- data/spec/docker/build.bash +10 -0
- data/spec/dsl/app_spec.rb +47 -0
- data/spec/dsl/configuration_spec.rb +64 -0
- data/spec/dsl/database_spec.rb +75 -0
- data/spec/dsl/dns_server_spec.rb +25 -0
- data/spec/dsl/dsl_spec.rb +298 -0
- data/spec/dsl/project_spec.rb +266 -0
- data/spec/fixtures/app-dependencies-dockerfile +25 -0
- data/spec/fixtures/database-dockerfile +31 -0
- data/spec/fixtures/deploy-dockerfile +2 -0
- data/spec/fixtures/mars-dockerfile +32 -0
- data/spec/fixtures/multi-project-web-dockerfile +35 -0
- data/spec/fixtures/web-dockerfile +27 -0
- data/spec/runner/build_images_spec.rb +164 -0
- data/spec/runner/build_spec.rb +86 -0
- data/spec/runner/checkout_spec.rb +128 -0
- data/spec/runner/command_spec.rb +94 -0
- data/spec/runner/help_spec.rb +73 -0
- data/spec/runner/implode_spec.rb +62 -0
- data/spec/runner/run_containers_spec.rb +141 -0
- data/spec/runner/runner_spec.rb +117 -0
- data/spec/runner/services_spec.rb +135 -0
- data/spec/runner/shell_spec.rb +123 -0
- data/spec/runner/update_hosts_spec.rb +163 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/docker_stubbing.rb +93 -0
- data/spec/support/test_project.rb +56 -0
- metadata +193 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
FROM nginx
|
2
|
+
|
3
|
+
RUN apt-get update
|
4
|
+
RUN apt-get upgrade -y
|
5
|
+
RUN apt-get install -y ruby
|
6
|
+
|
7
|
+
RUN mkdir -p /var/docker
|
8
|
+
|
9
|
+
COPY add_project.rb /var/docker/add_project.rb
|
10
|
+
COPY add_app.rb /var/docker/add_app.rb
|
11
|
+
COPY index.html.erb /var/docker/index.html.erb
|
12
|
+
COPY index_config.erb /var/docker/index_config.erb
|
13
|
+
COPY app_config.erb /var/docker/app_config.erb
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
RUN ruby /var/docker/add_project.rb apollo apollo.test.com mars,saturn
|
18
|
+
|
19
|
+
RUN ruby /var/docker/add_app.rb apollo apollo.test.com mars 8080
|
20
|
+
|
21
|
+
RUN ruby /var/docker/add_app.rb apollo apollo.test.com saturn 8080
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
RUN rm -r /var/docker
|
26
|
+
RUN apt-get remove -y ruby
|
27
|
+
RUN apt-get autoremove -y
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::BuildImages do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'build_images' }
|
8
|
+
specify { expect(described_class.description).to eq 'Build images for your environment' }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "running" do
|
12
|
+
it "builds all the images for the project" do
|
13
|
+
docker.fail_unexpected_commands!
|
14
|
+
docker.expect "network create apollo 2> /dev/null"
|
15
|
+
docker.expect "build -t apollo-app-dependencies tmp"
|
16
|
+
docker.expect "build -t apollo-mars tmp"
|
17
|
+
docker.expect "build -t apollo-saturn tmp"
|
18
|
+
docker.expect "build -t apollo-web tmp"
|
19
|
+
subject.run
|
20
|
+
end
|
21
|
+
|
22
|
+
it "generates the dockerfile for the app dependencies" do
|
23
|
+
docker.expect("build -t apollo-app-dependencies tmp") do
|
24
|
+
files = Dir[File.join("tmp", "*")].sort
|
25
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/install_gems.rb']
|
26
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
27
|
+
expected = File.read(File.join('spec', 'fixtures', 'app-dependencies-dockerfile'))
|
28
|
+
expect(dockerfile).to eq expected
|
29
|
+
end
|
30
|
+
subject.run
|
31
|
+
end
|
32
|
+
|
33
|
+
it "generates the dockerfiles for the apps" do
|
34
|
+
docker.expect("build -t apollo-mars tmp") do
|
35
|
+
files = Dir[File.join("tmp", "*")].sort
|
36
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/checkout.rb', 'tmp/startup.rb', 'tmp/update_database_config.rb']
|
37
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
38
|
+
expected = File.read(File.join('spec', 'fixtures', 'mars-dockerfile'))
|
39
|
+
expect(dockerfile).to eq expected
|
40
|
+
end
|
41
|
+
subject.run
|
42
|
+
end
|
43
|
+
|
44
|
+
it "generates the dockerfiles for the web server" do
|
45
|
+
docker.expect "build -t apollo-web tmp" do
|
46
|
+
files = Dir[File.join("tmp", "*")].sort
|
47
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/add_app.rb', 'tmp/add_project.rb', 'tmp/app_config.erb', 'tmp/index.html.erb', 'tmp/index_config.erb', 'tmp/setup.rb']
|
48
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
49
|
+
expected = File.read(File.join('spec', 'fixtures', 'web-dockerfile'))
|
50
|
+
expect(dockerfile).to eq expected
|
51
|
+
end
|
52
|
+
subject.run
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns true" do
|
56
|
+
expect(subject.run).to be_truthy
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with a local database" do
|
60
|
+
before do
|
61
|
+
RubyYacht.configuration.projects[0].database.host = 'localhost'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "builds the database" do
|
65
|
+
docker.expect("build -t apollo-database tmp") do
|
66
|
+
files = Dir[File.join("tmp", "*")].sort
|
67
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/load_seeds.rb', 'tmp/setup.rb', 'tmp/setup_database.sql.erb']
|
68
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
69
|
+
expected = File.read(File.join('spec', 'fixtures', 'database-dockerfile'))
|
70
|
+
expect(dockerfile).to eq expected
|
71
|
+
end
|
72
|
+
subject.run
|
73
|
+
end
|
74
|
+
|
75
|
+
it "returns true" do
|
76
|
+
expect(subject.run).to be_truthy
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with an id_rsa key" do
|
81
|
+
let(:id_file_path) { File.join(ENV['HOME'], '.ssh', 'id_rsa') }
|
82
|
+
let(:missing_id_file) { !File.exist?(id_file_path) }
|
83
|
+
before do
|
84
|
+
if missing_id_file
|
85
|
+
FileUtils.mkdir_p(File.dirname(id_file_path))
|
86
|
+
File.open(id_file_path, 'w') do |file|
|
87
|
+
file.write('test')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it "copies the id_rsa key to the app-dependencies container" do
|
93
|
+
docker.expect "build -t apollo-app-dependencies tmp" do
|
94
|
+
files = Dir[File.join("tmp", "*")].sort
|
95
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/id_rsa', 'tmp/install_gems.rb']
|
96
|
+
expect(File.read('tmp/id_rsa')).to eq File.read(id_file_path)
|
97
|
+
end
|
98
|
+
|
99
|
+
subject.run
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns true" do
|
103
|
+
expect(subject.run).to be_truthy
|
104
|
+
end
|
105
|
+
|
106
|
+
after do
|
107
|
+
if missing_id_file
|
108
|
+
FileUtils.rm(id_file_path)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "with a deploy container" do
|
114
|
+
before do
|
115
|
+
RubyYacht.configuration.projects.first.create_deploy_container = true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "creates the deploy container" do
|
119
|
+
docker.expect("build -t apollo-deploy tmp") do
|
120
|
+
files = Dir[File.join("tmp", "*")].sort
|
121
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb']
|
122
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
123
|
+
expected = File.read(File.join('spec', 'fixtures', 'deploy-dockerfile'))
|
124
|
+
expect(dockerfile).to eq expected
|
125
|
+
end
|
126
|
+
subject.run
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "with multiple projects" do
|
131
|
+
before do
|
132
|
+
RubyYacht.configure_second_test_project
|
133
|
+
end
|
134
|
+
|
135
|
+
it "builds the containers for both projects" do
|
136
|
+
docker.fail_unexpected_commands!
|
137
|
+
docker.expect "network create apollo 2> /dev/null"
|
138
|
+
docker.expect "build -t apollo-app-dependencies tmp"
|
139
|
+
docker.expect "build -t apollo-mars tmp"
|
140
|
+
docker.expect "build -t apollo-saturn tmp"
|
141
|
+
docker.expect "build -t jupiter-app-dependencies tmp"
|
142
|
+
docker.expect "build -t jupiter-venus tmp"
|
143
|
+
docker.expect "build -t jupiter-saturn tmp"
|
144
|
+
docker.expect "build -t apollo-web tmp"
|
145
|
+
subject.run
|
146
|
+
end
|
147
|
+
|
148
|
+
it "generates one dockerfile for the web server with both projects" do
|
149
|
+
docker.expect "build -t apollo-web tmp" do
|
150
|
+
files = Dir[File.join("tmp", "*")].sort
|
151
|
+
expect(files).to eq ['tmp/Dockerfile', 'tmp/Dockerfile.erb', 'tmp/add_app.rb', 'tmp/add_project.rb', 'tmp/app_config.erb', 'tmp/index.html.erb', 'tmp/index_config.erb', 'tmp/setup.rb']
|
152
|
+
dockerfile = File.read(File.join('tmp', 'Dockerfile'))
|
153
|
+
expected = File.read(File.join('spec', 'fixtures', 'multi-project-web-dockerfile'))
|
154
|
+
expect(dockerfile).to eq expected
|
155
|
+
end
|
156
|
+
subject.run
|
157
|
+
end
|
158
|
+
|
159
|
+
it "returns true" do
|
160
|
+
expect(subject.run).to be_truthy
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Build do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'build' }
|
8
|
+
specify { expect(described_class.description).to eq 'Build images and run containers' }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "run behavior" do
|
12
|
+
let(:commands) { [double, double, double] }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(RubyYacht::Runner::BuildImages).to receive(:new).and_return commands[0]
|
16
|
+
allow(RubyYacht::Runner::RunContainers).to receive(:new).and_return commands[1]
|
17
|
+
allow(RubyYacht::Runner::UpdateHosts).to receive(:new).and_return commands[2]
|
18
|
+
|
19
|
+
commands.each { |command| allow(command).to receive(:run).and_return(true) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with successes from all commands" do
|
23
|
+
it "builds the images, runs the containers, and update the hosts" do
|
24
|
+
subject.run
|
25
|
+
expect(commands[0]).to have_received(:run)
|
26
|
+
expect(commands[1]).to have_received(:run)
|
27
|
+
expect(commands[2]).to have_received(:run)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true" do
|
31
|
+
expect(subject.run).to be_truthy
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with an error building the images" do
|
36
|
+
before do
|
37
|
+
allow(commands[0]).to receive(:run).and_return false
|
38
|
+
end
|
39
|
+
|
40
|
+
it "builds the images, but does not runs the containers or update the hosts" do
|
41
|
+
subject.run
|
42
|
+
expect(commands[0]).to have_received(:run)
|
43
|
+
expect(commands[1]).not_to have_received(:run)
|
44
|
+
expect(commands[2]).not_to have_received(:run)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns false" do
|
48
|
+
expect(subject.run).to be_falsey
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "an error running containers" do
|
53
|
+
before do
|
54
|
+
allow(commands[1]).to receive(:run).and_return false
|
55
|
+
end
|
56
|
+
|
57
|
+
it "builds the images and runs the containers, but does not update the hosts" do
|
58
|
+
subject.run
|
59
|
+
expect(commands[0]).to have_received(:run)
|
60
|
+
expect(commands[1]).to have_received(:run)
|
61
|
+
expect(commands[2]).not_to have_received(:run)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns false" do
|
65
|
+
expect(subject.run).to be_falsey
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with an error updating hosts" do
|
70
|
+
before do
|
71
|
+
allow(commands[2]).to receive(:run).and_return false
|
72
|
+
end
|
73
|
+
|
74
|
+
it "builds the images, runs the containers, and update the hosts" do
|
75
|
+
subject.run
|
76
|
+
expect(commands[0]).to have_received(:run)
|
77
|
+
expect(commands[1]).to have_received(:run)
|
78
|
+
expect(commands[2]).to have_received(:run)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns true" do
|
82
|
+
expect(subject.run).to be_falsey
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Checkout do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'checkout' }
|
8
|
+
specify { expect(described_class.description).to eq 'Check out a new branch for an app' }
|
9
|
+
|
10
|
+
describe "command-line parsing" do
|
11
|
+
let(:options) { subject.option_parser }
|
12
|
+
it "gives a summary in the banner" do
|
13
|
+
expect(options.banner).to eq "Usage: rspec checkout [options] [APP] [BRANCH]"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "explains the options in the summary" do
|
17
|
+
expect(options.summarize).to eq [
|
18
|
+
"Options:\n",
|
19
|
+
" -p, --project PROJECT The project with the app we are checking out the branch in. Default: apollo\n"
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "sets the project name from the command line" do
|
24
|
+
RubyYacht.configure_second_test_project
|
25
|
+
arguments = %w(-p jupiter venus issue1234)
|
26
|
+
subject.option_parser.parse!(arguments)
|
27
|
+
expect(subject.project_name).to eq :jupiter
|
28
|
+
expect(arguments).to eq %w(venus issue1234)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "takes the app and checkout from the command line" do
|
32
|
+
subject.parse_positional_arguments(['venus', 'issue1234'])
|
33
|
+
expect(subject.app).to eq 'venus'
|
34
|
+
expect(subject.branch).to eq 'issue1234'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "run behavior" do
|
40
|
+
before do
|
41
|
+
subject.app = 'saturn'
|
42
|
+
subject.branch = 'issue1234'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "runs the commands to check out the branch and update the app" do
|
46
|
+
docker.fail_unexpected_commands!
|
47
|
+
docker.expect "exec apollo-saturn bash -c 'cd /var/code; git fetch; git checkout .; git checkout issue1234; git pull'"
|
48
|
+
docker.expect "exec apollo-saturn bash -c '/var/docker/update_database_config.rb; rake db:migrate'"
|
49
|
+
docker.expect "restart apollo-saturn"
|
50
|
+
subject.run
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns true" do
|
54
|
+
expect(subject.run).to be_truthy
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with an explicit project" do
|
58
|
+
before do
|
59
|
+
RubyYacht.configure_second_test_project
|
60
|
+
subject.project_name = :jupiter
|
61
|
+
end
|
62
|
+
|
63
|
+
it "runs the command in that project" do
|
64
|
+
subject.app = 'venus'
|
65
|
+
docker.fail_unexpected_commands!
|
66
|
+
docker.expect "exec jupiter-venus bash -c 'cd /var/code; git fetch; git checkout .; git checkout issue1234; git pull'"
|
67
|
+
docker.expect "exec jupiter-venus bash -c '/var/docker/update_database_config.rb; rake db:migrate'"
|
68
|
+
docker.expect "restart jupiter-venus"
|
69
|
+
subject.run
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns true" do
|
73
|
+
expect(subject.run).to be_truthy
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "with an invalid project" do
|
78
|
+
before do
|
79
|
+
subject.project_name = :foo
|
80
|
+
end
|
81
|
+
|
82
|
+
it "logs an error" do
|
83
|
+
subject.run
|
84
|
+
expect(@log_entries).to eq ['There is no project named foo']
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns false" do
|
88
|
+
expect(subject.run).to be_falsey
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with no app" do
|
93
|
+
before do
|
94
|
+
subject.app = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "logs an error" do
|
98
|
+
subject.run
|
99
|
+
expect(@log_entries).to eq [
|
100
|
+
"You must provide an app name",
|
101
|
+
"Run rspec help checkout for more information"
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns false" do
|
106
|
+
expect(subject.run).to be_falsey
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "with no branch" do
|
111
|
+
before do
|
112
|
+
subject.branch = nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "logs an error" do
|
116
|
+
subject.run
|
117
|
+
expect(@log_entries).to eq [
|
118
|
+
"You must provide a branch",
|
119
|
+
"Run rspec help checkout for more information"
|
120
|
+
]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "returns false" do
|
124
|
+
expect(subject.run).to be_falsey
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Command do
|
4
|
+
class SampleCommand < RubyYacht::Runner::Command
|
5
|
+
def self.command; 'sample_command'; end
|
6
|
+
def self.description; 'Provides a sample command for testing'; end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "command information" do
|
10
|
+
specify { expect { described_class.command }.to raise_error "Command not defined for RubyYacht::Runner::Command" }
|
11
|
+
specify { expect { described_class.description }.to raise_error "Description not defined for RubyYacht::Runner::Command" }
|
12
|
+
|
13
|
+
describe "option_parser" do
|
14
|
+
it "takes the usage from the command information" do
|
15
|
+
expect(SampleCommand.new.option_parser.banner).to eq "Usage: rspec sample_command\n\nProvides a sample command for testing"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not have anything beyond the banner" do
|
19
|
+
parser = SampleCommand.new.option_parser
|
20
|
+
expect(parser.to_s).to eq parser.banner + "\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "parse_positional_arguments" do
|
25
|
+
it "does not modify the arguments" do
|
26
|
+
arguments = %w(foo bar)
|
27
|
+
subject.parse_positional_arguments(arguments)
|
28
|
+
expect(arguments).to eq %w(foo bar)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "run behavior" do
|
34
|
+
it "raises an error" do
|
35
|
+
expect { subject.run }.to raise_error "Run method not defined for #{subject}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "helpers" do
|
40
|
+
describe "short_script_name" do
|
41
|
+
it "is the name of the invoked command" do
|
42
|
+
expect(described_class.short_script_name).to eq "rspec"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "projects" do
|
47
|
+
it "provides the full list of projects" do
|
48
|
+
RubyYacht.configure_test_project
|
49
|
+
RubyYacht.configure_second_test_project
|
50
|
+
expect(subject.projects.collect(&:name)).to eq [:apollo, :jupiter]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "get_machine_info" do
|
55
|
+
it "gets the property from docker" do
|
56
|
+
allow(subject).to receive(:backtick).with("docker-machine inspect default -f {{System.Name}}").and_return("Jimmy\n")
|
57
|
+
expect(subject.get_machine_info('System.Name')).to eq 'Jimmy'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "logs" do
|
62
|
+
it "logs the message to stdout" do
|
63
|
+
allow($stdout).to receive(:puts)
|
64
|
+
subject.log('Test Message')
|
65
|
+
expect($stdout).to have_received(:puts).with('Test Message')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "docker" do
|
70
|
+
it "sends the command to docker" do
|
71
|
+
allow(subject).to receive(:system)
|
72
|
+
subject.docker "run hello-world"
|
73
|
+
expect(subject).to have_received(:system).with('docker run hello-world')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "system" do
|
78
|
+
it "executes the command" do
|
79
|
+
subject.system 'echo test > tmp/test'
|
80
|
+
expect(File.read('tmp/test')).to eq "test\n"
|
81
|
+
FileUtils.rm('tmp/test')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "backtick" do
|
86
|
+
it "returns the result of executing the command" do
|
87
|
+
File.open('tmp/test', 'w') { |f| f.write('test contents') }
|
88
|
+
value = subject.backtick('cat tmp/test')
|
89
|
+
expect(value).to eq 'test contents'
|
90
|
+
FileUtils.rm('tmp/test')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Help do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'help' }
|
8
|
+
specify { expect(described_class.description).to eq 'Get information on available commands' }
|
9
|
+
|
10
|
+
describe "option_parser" do
|
11
|
+
it "provides the usage information" do
|
12
|
+
options = subject.option_parser
|
13
|
+
expect(options.banner).to eq "Usage: rspec help [command]\n\nGet information on available commands"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "parse_positional_arguments" do
|
18
|
+
it "takes the command from the arguments" do
|
19
|
+
subject.parse_positional_arguments(%w(checkout foo))
|
20
|
+
expect(subject.command).to eq 'checkout'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "run behavior" do
|
26
|
+
context "with no command" do
|
27
|
+
it "prints the available commands" do
|
28
|
+
subject.run
|
29
|
+
expected = ["Available commands: \n\n"]
|
30
|
+
expected += RubyYacht::Runner.commands.map { |c| "#{c.name}: #{c.description}" }
|
31
|
+
expected << "\nRun rspec help [command] for more information on a command"
|
32
|
+
expect(@log_entries).to eq expected
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns true" do
|
36
|
+
expect(subject.run).to be_truthy
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with a command" do
|
41
|
+
before do
|
42
|
+
subject.command = 'checkout'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "prints the usage information for the command" do
|
46
|
+
subject.run
|
47
|
+
expect(@log_entries).to eq [RubyYacht::Runner::Checkout.new.option_parser.to_s]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns true" do
|
51
|
+
expect(subject.run).to be_truthy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with an invalid command" do
|
56
|
+
before do
|
57
|
+
subject.command = 'foo'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "prints an error" do
|
61
|
+
subject.run
|
62
|
+
expect(@log_entries).to eq [
|
63
|
+
"Command not available: foo",
|
64
|
+
"Run rspec help for more options"
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns false" do
|
69
|
+
expect(subject.run).to be_falsey
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Implode do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'implode' }
|
8
|
+
specify { expect(described_class.description).to eq 'Destroy your local environment' }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "run behavior" do
|
12
|
+
before do
|
13
|
+
allow(subject).to receive(:backtick).with('docker ps -a | grep apollo').and_return("123 up apollo-mars\n456 up apollo-saturn\n789 apollo-venus")
|
14
|
+
allow(subject).to receive(:backtick).with('docker images | grep apollo').and_return("apollo-app-dependencies 1GB\napollo-mars 1GB")
|
15
|
+
allow(subject).to receive(:backtick).with('docker ps -a | grep jupiter').and_return("abc up jupiter-saturn")
|
16
|
+
allow(subject).to receive(:backtick).with('docker images | grep jupiter').and_return("jupiter-app-dependencies 1GB\njupiter-mars 1GB")
|
17
|
+
|
18
|
+
allow(subject).to receive(:backtick).with('docker images -q --filter dangling=true').and_return("111\n222")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "removes all the containers and images" do
|
22
|
+
docker.fail_unexpected_commands!
|
23
|
+
docker.expect 'rm -f 123'
|
24
|
+
docker.expect 'rm -f 456'
|
25
|
+
docker.expect 'rm -f 789'
|
26
|
+
docker.expect 'rmi apollo-app-dependencies'
|
27
|
+
docker.expect 'rmi apollo-mars'
|
28
|
+
docker.expect 'rmi 111'
|
29
|
+
docker.expect 'rmi 222'
|
30
|
+
subject.run
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns true" do
|
34
|
+
expect(subject.run).to be_truthy
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with a second project" do
|
38
|
+
before do
|
39
|
+
RubyYacht.configure_second_test_project
|
40
|
+
end
|
41
|
+
|
42
|
+
it "removes containers and images for both projects" do
|
43
|
+
docker.fail_unexpected_commands!
|
44
|
+
docker.expect 'rm -f 123'
|
45
|
+
docker.expect 'rm -f 456'
|
46
|
+
docker.expect 'rm -f 789'
|
47
|
+
docker.expect 'rmi apollo-app-dependencies'
|
48
|
+
docker.expect 'rmi apollo-mars'
|
49
|
+
docker.expect 'rm -f abc'
|
50
|
+
docker.expect 'rmi jupiter-app-dependencies'
|
51
|
+
docker.expect 'rmi jupiter-mars'
|
52
|
+
docker.expect 'rmi 111'
|
53
|
+
docker.expect 'rmi 222'
|
54
|
+
subject.run
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns true" do
|
58
|
+
expect(subject.run).to be_truthy
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|