boxci 0.0.30
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/.gitignore +19 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +146 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +118 -0
- data/Rakefile +13 -0
- data/bin/boxci +6 -0
- data/boxci.gemspec +28 -0
- data/lib/boxci/builder.rb +29 -0
- data/lib/boxci/cli.rb +70 -0
- data/lib/boxci/config_permutation.rb +15 -0
- data/lib/boxci/config_permutation_component.rb +11 -0
- data/lib/boxci/config_permutation_component_factory.rb +7 -0
- data/lib/boxci/config_permutation_components/rbenv.rb +13 -0
- data/lib/boxci/dependency_checker.rb +55 -0
- data/lib/boxci/global_config.rb +26 -0
- data/lib/boxci/initializer.rb +41 -0
- data/lib/boxci/language.rb +35 -0
- data/lib/boxci/language_factory.rb +7 -0
- data/lib/boxci/languages/ruby.rb +31 -0
- data/lib/boxci/project_config.rb +96 -0
- data/lib/boxci/provider.rb +35 -0
- data/lib/boxci/provider_config.rb +23 -0
- data/lib/boxci/provider_factory.rb +7 -0
- data/lib/boxci/providers/aws.rb +27 -0
- data/lib/boxci/providers/openstack.rb +27 -0
- data/lib/boxci/providers/virtualbox.rb +24 -0
- data/lib/boxci/templates/Vagrantfile +41 -0
- data/lib/boxci/templates/boxci/global_config.yml.tt +1 -0
- data/lib/boxci/templates/dot_boxci.yml.tt +11 -0
- data/lib/boxci/templates/languages/ruby/main.pp +27 -0
- data/lib/boxci/templates/providers/aws/Vagrantfile.erb +45 -0
- data/lib/boxci/templates/providers/aws.yml.tt +5 -0
- data/lib/boxci/templates/providers/openstack/Vagrantfile.erb +37 -0
- data/lib/boxci/templates/providers/openstack.yml.tt +16 -0
- data/lib/boxci/templates/providers/virtualbox/Vagrantfile.erb +47 -0
- data/lib/boxci/templates/providers/virtualbox.yml.tt +2 -0
- data/lib/boxci/templates/puppet/manifests/.empty_directory +0 -0
- data/lib/boxci/templates/puppet/modules/.empty_directory +0 -0
- data/lib/boxci/test_runner.rb +134 -0
- data/lib/boxci/tester.rb +287 -0
- data/lib/boxci/version.rb +3 -0
- data/lib/boxci.rb +71 -0
- data/spec/lib/boxci/builder_spec.rb +86 -0
- data/spec/lib/boxci/config_permutation_component_factory_spec.rb +17 -0
- data/spec/lib/boxci/config_permutation_component_spec.rb +19 -0
- data/spec/lib/boxci/config_permutation_components/rbenv_spec.rb +12 -0
- data/spec/lib/boxci/config_permutation_spec.rb +27 -0
- data/spec/lib/boxci/dependency_checker_spec.rb +215 -0
- data/spec/lib/boxci/global_config_spec.rb +34 -0
- data/spec/lib/boxci/initializer_spec.rb +117 -0
- data/spec/lib/boxci/language_factory_spec.rb +17 -0
- data/spec/lib/boxci/language_spec.rb +31 -0
- data/spec/lib/boxci/project_config_spec.rb +218 -0
- data/spec/lib/boxci/provider_config_spec.rb +39 -0
- data/spec/lib/boxci/provider_factory_spec.rb +17 -0
- data/spec/lib/boxci/provider_spec.rb +30 -0
- data/spec/lib/boxci/tester_spec.rb +15 -0
- data/spec/lib/boxci_spec.rb +176 -0
- data/spec/spec_helper.rb +11 -0
- metadata +213 -0
data/lib/boxci/tester.rb
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "net/ssh"
|
3
|
+
require "net/scp"
|
4
|
+
|
5
|
+
module Boxci
|
6
|
+
class Tester
|
7
|
+
include Thor::Base
|
8
|
+
include Thor::Actions
|
9
|
+
|
10
|
+
def self.exit_on_failure?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
source_root(File.dirname(__FILE__))
|
15
|
+
|
16
|
+
def test(options)
|
17
|
+
File.open('/tmp/boxci.log', 'w') do |f|
|
18
|
+
f.write('')
|
19
|
+
end
|
20
|
+
|
21
|
+
# NOTE: The Signal.trap('SIGTERM') is required for Bamboo's "Stop
|
22
|
+
# Build" functionality because Bamboo basically sends a SIGTERM to
|
23
|
+
# Boxci and then immediately closes its stdout and stderr pipes
|
24
|
+
# before Boxci has had a chance to cleanup. Therefore, it causes
|
25
|
+
# Errno::EPIPE exceptions to be raised. It does seem that in general
|
26
|
+
# the use of SIGTERM is correct however one would hope that stdout and
|
27
|
+
# stderr pipes would stay open until Boxci exits, but sadly they
|
28
|
+
# do not.
|
29
|
+
Signal.trap('SIGTERM') do
|
30
|
+
File.open('/tmp/boxci.log', 'a+') { |f| f.write("Got SIGTERM, going to cleanup...\n") }
|
31
|
+
|
32
|
+
begin
|
33
|
+
cleanup
|
34
|
+
rescue Errno::EPIPE => e
|
35
|
+
File.open('/tmp/boxci.log', 'a+') { |f| f.write("SIGTERM handler swallowed Errno::EPIPE exception\n") }
|
36
|
+
rescue => e
|
37
|
+
File.open('/tmp/boxci.log', 'a+') do |f|
|
38
|
+
f.write("SIGTERM handler caught exception")
|
39
|
+
f.write("#{e.class}\n")
|
40
|
+
f.write("#{e.message}\n")
|
41
|
+
f.write("#{e.backtrace.join("\n")}\n")
|
42
|
+
end
|
43
|
+
raise e
|
44
|
+
end
|
45
|
+
|
46
|
+
File.open('/tmp/boxci.log', 'a+') { |f| f.write("Finished cleanup process from SIGTERM\n") }
|
47
|
+
exit 255
|
48
|
+
end
|
49
|
+
|
50
|
+
Signal.trap('SIGINT') do
|
51
|
+
cleanup
|
52
|
+
exit 255
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: I don't believe this is necessary as I think Ruby's default
|
56
|
+
# handler for SIGPIPE is to ignore it. I need to test this though to
|
57
|
+
# verify.
|
58
|
+
Signal.trap('SIGPIPE', 'SIG_IGN')
|
59
|
+
|
60
|
+
@tester_exit_code = 0
|
61
|
+
# depencency_checker = Boxci::DependencyChecker.new
|
62
|
+
# depencency_checker.verify_all
|
63
|
+
initial_config(options)
|
64
|
+
|
65
|
+
create_project_folder
|
66
|
+
create_project_archive
|
67
|
+
write_vagrant_file
|
68
|
+
write_test_runner
|
69
|
+
if @provider_object.requires_plugin?
|
70
|
+
install_vagrant_plugin
|
71
|
+
add_provider_box
|
72
|
+
end
|
73
|
+
spin_up_box
|
74
|
+
setup_ssh_config
|
75
|
+
install_puppet_on_box
|
76
|
+
provision_box
|
77
|
+
create_artifact_directory
|
78
|
+
upload_test_runner
|
79
|
+
run_tests
|
80
|
+
download_artifacts
|
81
|
+
say "Finished!", :green
|
82
|
+
rescue Errno::EPIPE => e
|
83
|
+
File.open('/tmp/boxci.log', 'a+') do |f|
|
84
|
+
f.write("test() method swallowed Errno::EPIPE exception\n")
|
85
|
+
end
|
86
|
+
rescue => e
|
87
|
+
File.open('/tmp/boxci.log', 'a+') do |f|
|
88
|
+
f.write("test() method caught exception")
|
89
|
+
f.write("#{e.class}\n")
|
90
|
+
f.write("#{e.message}\n")
|
91
|
+
f.write("#{e.backtrace.join("\n")}\n")
|
92
|
+
end
|
93
|
+
raise e
|
94
|
+
ensure
|
95
|
+
cleanup
|
96
|
+
exit @tester_exit_code
|
97
|
+
end
|
98
|
+
|
99
|
+
def initial_config(options)
|
100
|
+
@gem_path = File.expand_path(File.dirname(__FILE__) + "/../..")
|
101
|
+
@puppet_path = File.join(Boxci.project_path, "puppet")
|
102
|
+
@project_uid = "#{rand(1000..9000)}-#{rand(1000..9000)}-#{rand(1000..9000)}-#{rand(1000..9000)}"
|
103
|
+
@project_workspace_folder = File.join(File.expand_path(ENV['HOME']), '.boxci', @project_uid)
|
104
|
+
@options = options
|
105
|
+
@provider_config = Boxci.provider_config(provider)
|
106
|
+
@project_config = Boxci.project_config
|
107
|
+
@provider_object = Boxci::ProviderFactory.build(provider)
|
108
|
+
end
|
109
|
+
|
110
|
+
def provider
|
111
|
+
@options["provider"]
|
112
|
+
end
|
113
|
+
|
114
|
+
def verbose?
|
115
|
+
@options["verbose"] == true
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_project_folder
|
119
|
+
empty_directory @project_workspace_folder, :verbose => verbose?
|
120
|
+
end
|
121
|
+
|
122
|
+
def create_project_archive
|
123
|
+
inside Boxci.project_path do
|
124
|
+
run "git checkout #{@options["revision"]}", :verbose => verbose?
|
125
|
+
run "git submodule update --init", :verbose => verbose?
|
126
|
+
run "tar cf #{File.join(@project_workspace_folder, "project.tar")} --exclude .git --exclude \"*.log\" --exclude node_modules .", :verbose => verbose?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def write_vagrant_file
|
131
|
+
erb_template = File.join("templates", "providers", provider, "Vagrantfile.erb")
|
132
|
+
destination = File.join(@project_workspace_folder, "Vagrantfile")
|
133
|
+
|
134
|
+
template erb_template, destination, :verbose => verbose?
|
135
|
+
end
|
136
|
+
|
137
|
+
def write_test_runner
|
138
|
+
destination = File.join(@project_workspace_folder, "test_runner.sh")
|
139
|
+
test_runner = Boxci::TestRunner.new(Boxci::LanguageFactory.build(Boxci.project_config.language))
|
140
|
+
File.open(destination, 'w+') do |f|
|
141
|
+
f.write(test_runner.generate_script)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def install_vagrant_plugin
|
146
|
+
inside @project_workspace_folder do
|
147
|
+
plugin = @provider_object.plugin
|
148
|
+
# check for vagrant plugin
|
149
|
+
if !system("vagrant plugin list | grep -q #{plugin}")
|
150
|
+
# if vagrant plugin is missing
|
151
|
+
say "You are missing the Vagrant plugin for #{provider}", :yellow
|
152
|
+
# ask user if it's ok to install for them
|
153
|
+
if yes?("Would you like to install it now?")
|
154
|
+
run "vagrant plugin install #{plugin}", :verbose => verbose?
|
155
|
+
end
|
156
|
+
else # if vagrant plugin is found
|
157
|
+
say "Provider plugin #{plugin} found", :green
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_provider_box
|
163
|
+
dummy_box_url = @provider_object.dummy_box_url
|
164
|
+
if dummy_box_url
|
165
|
+
if run "curl --output /dev/null --silent --head --fail #{dummy_box_url}"
|
166
|
+
say "Using specified VM Box URL", :green
|
167
|
+
else
|
168
|
+
say "Could not resolve the Box URL: #{dummy_box_url}", :red
|
169
|
+
end
|
170
|
+
else
|
171
|
+
inside @project_workspace_folder do
|
172
|
+
# check for box
|
173
|
+
if !system("vagrant box list | grep dummy | grep -q \"(#{provider})\"")
|
174
|
+
# if box is missing
|
175
|
+
say "No box found for #{provider}, installing now...", :blue
|
176
|
+
run "vagrant box add dummy #{dummy_box_url}", :verbose => verbose?
|
177
|
+
else # if vagrant plugin is found
|
178
|
+
say "Provider box found", :green
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def spin_up_box
|
185
|
+
inside @project_workspace_folder do
|
186
|
+
run "vagrant up --no-provision --provider #{provider}", :verbose => verbose?
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def setup_ssh_config
|
191
|
+
inside @project_workspace_folder do
|
192
|
+
run "vagrant ssh-config > ssh-config.local", :verbose => verbose?
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def install_puppet_on_box
|
197
|
+
say "Opening SSH tunnel into the box...", :blue if verbose?
|
198
|
+
Net::SSH.start("default", nil, {:config => File.join(@project_workspace_folder, "ssh-config.local")}) do |ssh|
|
199
|
+
puppet = ssh.exec! "which puppet"
|
200
|
+
unless puppet
|
201
|
+
say "Running: sudo apt-get --yes update", :blue if verbose?
|
202
|
+
ssh.exec! "sudo apt-get --yes update"
|
203
|
+
say "Running: sudo apt-get --yes install puppet", :blue if verbose?
|
204
|
+
ssh.exec! "sudo apt-get --yes install puppet"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def provision_box
|
210
|
+
say "Provisioning the box with puppet...", :blue if verbose?
|
211
|
+
inside @project_workspace_folder do
|
212
|
+
run "vagrant provision", :verbose => verbose?
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def create_artifact_directory
|
217
|
+
say "Creating the artifact directory on the box...", :blue if verbose?
|
218
|
+
Net::SSH.start("default", nil, {:config => File.join(@project_workspace_folder, "ssh-config.local")}) do |ssh|
|
219
|
+
ssh.exec! "mkdir -p #{@project_config.artifact_path}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def upload_test_runner
|
224
|
+
Net::SSH.start("default", nil, {:config => File.join(@project_workspace_folder, "ssh-config.local")}) do |ssh|
|
225
|
+
say "Uploading test_runner.sh to the box...", :blue if verbose?
|
226
|
+
ssh.scp.upload! File.join(@project_workspace_folder, "test_runner.sh"), "/vagrant/test_runner.sh"
|
227
|
+
say "Running: chmod a+x /vagrant/test_runner.sh", :blue if verbose?
|
228
|
+
puts ssh.exec! "chmod a+x /vagrant/test_runner.sh"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def run_tests
|
233
|
+
exit_code = nil
|
234
|
+
exit_signal = nil
|
235
|
+
Net::SSH.start("default", nil, {:config => File.join(@project_workspace_folder, "ssh-config.local")}) do |session|
|
236
|
+
say "Running the test steps on the box...", :blue if verbose?
|
237
|
+
session.open_channel do |channel|
|
238
|
+
channel.on_data do |ch, data|
|
239
|
+
$stdout.write(data)
|
240
|
+
end
|
241
|
+
|
242
|
+
channel.on_extended_data do |ch, type, data|
|
243
|
+
$stderr.write(data)
|
244
|
+
end
|
245
|
+
|
246
|
+
channel.on_request("exit-status") do |ch, data|
|
247
|
+
exit_code = data.read_long
|
248
|
+
@tester_exit_code = exit_code
|
249
|
+
end
|
250
|
+
|
251
|
+
channel.exec "/vagrant/test_runner.sh"
|
252
|
+
end
|
253
|
+
session.loop
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def download_artifacts
|
258
|
+
Net::SSH.start("default", nil, {:config => File.join(@project_workspace_folder, "ssh-config.local")}) do |ssh|
|
259
|
+
say "Downloading the reports...", :blue if verbose?
|
260
|
+
puts ssh.exec! "cd #{@project_config.artifact_path} && tar cf /tmp/boxci_artifacts.tar ."
|
261
|
+
ssh.scp.download! "/tmp/boxci_artifacts.tar", '.'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def cleanup
|
266
|
+
if @project_workspace_folder && File.directory?(@project_workspace_folder)
|
267
|
+
# NOTE: The begin rescue for Errno::EPIPE and the &>>
|
268
|
+
# /tmp/boxci.log in the backtick execution ARE required for
|
269
|
+
# Bamboo's "Stop Build" functionality because Bamboo basically sends
|
270
|
+
# a SIGTERM to Boxci and then immediately closes its stdout and
|
271
|
+
# stderr pipes before Boxci has had a chance to cleanup. Therefore,
|
272
|
+
# it causes Errno::EPIPE exceptions to be raised.
|
273
|
+
begin
|
274
|
+
say "Cleaning up...", :blue
|
275
|
+
rescue Errno::EPIPE => e
|
276
|
+
File.open('/tmp/boxci.log', 'a+') { |f| f.write("Cleaning up...\n") }
|
277
|
+
end
|
278
|
+
inside @project_workspace_folder do
|
279
|
+
`vagrant destroy -f >> /tmp/boxci.log 2>&1`
|
280
|
+
# run "vagrant destroy -f", :verbose => verbose?, :capture => true
|
281
|
+
end
|
282
|
+
`rm -rf #{@project_workspace_folder} >> /tmp/boxci.log 2>&1`
|
283
|
+
# remove_dir @project_workspace_folder, :verbose => verbose?, :capture => true
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
data/lib/boxci.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'boxci/version'
|
2
|
+
require 'boxci/project_config'
|
3
|
+
require 'boxci/global_config'
|
4
|
+
require 'boxci/provider_config'
|
5
|
+
require 'boxci/initializer'
|
6
|
+
require 'boxci/builder'
|
7
|
+
require 'boxci/dependency_checker'
|
8
|
+
require 'boxci/tester'
|
9
|
+
require 'boxci/language_factory'
|
10
|
+
require 'boxci/language'
|
11
|
+
require 'boxci/languages/ruby'
|
12
|
+
require 'boxci/provider_factory'
|
13
|
+
require 'boxci/provider'
|
14
|
+
require 'boxci/providers/virtualbox'
|
15
|
+
require 'boxci/providers/aws'
|
16
|
+
require 'boxci/providers/openstack'
|
17
|
+
require 'boxci/config_permutation'
|
18
|
+
require 'boxci/config_permutation_component'
|
19
|
+
require 'boxci/config_permutation_component_factory'
|
20
|
+
require 'boxci/config_permutation_components/rbenv'
|
21
|
+
require 'boxci/test_runner'
|
22
|
+
|
23
|
+
module Boxci
|
24
|
+
class MissingDependency < StandardError; end
|
25
|
+
class PureVirtualMethod < StandardError; end
|
26
|
+
|
27
|
+
def self.project_config
|
28
|
+
if @project_config
|
29
|
+
return @project_config
|
30
|
+
else
|
31
|
+
@project_config = Boxci::ProjectConfig.new
|
32
|
+
@project_config.load
|
33
|
+
return @project_config
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.global_config
|
38
|
+
if @global_config
|
39
|
+
return @global_config
|
40
|
+
else
|
41
|
+
@global_config = Boxci::GlobalConfig.new
|
42
|
+
@global_config.load
|
43
|
+
return @global_config
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.provider_config(provider)
|
48
|
+
if @provider_config
|
49
|
+
return @provider_config
|
50
|
+
else
|
51
|
+
@provider_config = Boxci::ProviderConfig.new(provider)
|
52
|
+
@provider_config.load
|
53
|
+
return @provider_config
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.default_provider
|
58
|
+
if global_config.default_provider
|
59
|
+
return global_config.default_provider
|
60
|
+
else
|
61
|
+
return ::Boxci::CLI::DEFAULT_PROVIDER
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.project_path
|
66
|
+
@project_path ||= File.expand_path(%x(pwd)).strip
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# TODO: Restructure to prevent this from needing to be here.
|
71
|
+
require 'boxci/cli'
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Boxci::Builder do
|
4
|
+
describe "#build" do
|
5
|
+
it "generates project Vagrantfile" do
|
6
|
+
allow(subject).to receive(:generate_starter_puppet_manifest)
|
7
|
+
expect(subject).to receive(:generate_project_vagrantfile)
|
8
|
+
subject.build
|
9
|
+
end
|
10
|
+
|
11
|
+
it "generates starter Puppet manifiest" do
|
12
|
+
allow(subject).to receive(:generate_project_vagrantfile)
|
13
|
+
expect(subject).to receive(:generate_starter_puppet_manifest)
|
14
|
+
subject.build
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#generate_project_vagrantfile" do
|
19
|
+
let(:project_path) { "/some/path" }
|
20
|
+
let(:dependency_checker) { double(Boxci::DependencyChecker, :verify_boxci_config => nil) }
|
21
|
+
|
22
|
+
it "verifies the boxci config file is present" do
|
23
|
+
allow(subject).to receive(:template)
|
24
|
+
allow(Boxci).to receive(:project_config)
|
25
|
+
allow(Boxci::DependencyChecker).to receive(:new).and_return(dependency_checker)
|
26
|
+
expect(dependency_checker).to receive(:verify_boxci_config)
|
27
|
+
subject.generate_project_vagrantfile
|
28
|
+
end
|
29
|
+
|
30
|
+
it "gets boxci project config hash" do
|
31
|
+
allow(subject).to receive(:template)
|
32
|
+
allow(Boxci::DependencyChecker).to receive(:new).and_return(dependency_checker)
|
33
|
+
expect(Boxci).to receive(:project_config)
|
34
|
+
subject.generate_project_vagrantfile
|
35
|
+
end
|
36
|
+
|
37
|
+
it "assigns the boxci project config to instance variable" do
|
38
|
+
allow(subject).to receive(:template)
|
39
|
+
allow(Boxci::DependencyChecker).to receive(:new).and_return(dependency_checker)
|
40
|
+
project_config_double = double
|
41
|
+
allow(Boxci).to receive(:project_config).and_return(project_config_double)
|
42
|
+
subject.generate_project_vagrantfile
|
43
|
+
expect(subject.instance_variable_get(:@project_config)).to eq(project_config_double)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "copies the Vagrantfile template for the specified language to the user's home directory" do
|
47
|
+
allow(Boxci).to receive(:project_config)
|
48
|
+
allow(Boxci::DependencyChecker).to receive(:new).and_return(dependency_checker)
|
49
|
+
expect(subject).to receive(:template).with("templates/Vagrantfile", File.join(Boxci.project_path, "Vagrantfile"))
|
50
|
+
subject.generate_project_vagrantfile
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#generate_starter_puppet_manifiest" do
|
55
|
+
let(:project_path) { "/some/path" }
|
56
|
+
|
57
|
+
before do
|
58
|
+
allow(Boxci).to receive(:project_path).and_return(project_path)
|
59
|
+
allow(Boxci).to receive(:project_config).and_return(double(:language => 'ruby'))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "copies the template to the repo" do
|
63
|
+
language_factory_double = double(:generate_starter_puppet_manifest => nil)
|
64
|
+
allow(Boxci::LanguageFactory).to receive(:build).and_return(language_factory_double)
|
65
|
+
expect(subject).to receive(:directory).with("templates/puppet", File.join(Boxci.project_path, "puppet"))
|
66
|
+
subject.generate_starter_puppet_manifest
|
67
|
+
end
|
68
|
+
|
69
|
+
it "builds a boxci language object" do
|
70
|
+
allow(subject).to receive(:directory)
|
71
|
+
language_double = double
|
72
|
+
project_config_double = double(:language => language_double)
|
73
|
+
allow(Boxci).to receive(:project_config).and_return(project_config_double)
|
74
|
+
expect(Boxci::LanguageFactory).to receive(:build).with(language_double).and_return(double.as_null_object)
|
75
|
+
subject.generate_starter_puppet_manifest
|
76
|
+
end
|
77
|
+
|
78
|
+
it "generates the language specific starter puppet manifest" do
|
79
|
+
allow(subject).to receive(:directory)
|
80
|
+
language_obj_double = double
|
81
|
+
allow(Boxci::LanguageFactory).to receive(:build).and_return(language_obj_double)
|
82
|
+
expect(language_obj_double).to receive(:generate_starter_puppet_manifest)
|
83
|
+
subject.generate_starter_puppet_manifest
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Boxci::ConfigPermutationComponentFactory do
|
4
|
+
describe ".build" do
|
5
|
+
it "gets the constant for the config permutation component class" do
|
6
|
+
expect(Boxci::ConfigPermutationComponents).to receive(:const_get).with('Rbenv').and_return(double.as_null_object)
|
7
|
+
subject.build('rbenv', 'foo')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "constructs a new instance of the config permutation component const it previously grabbed" do
|
11
|
+
comp = double
|
12
|
+
allow(Boxci::ConfigPermutationComponents).to receive(:const_get).with('Rbenv').and_return(comp)
|
13
|
+
expect(comp).to receive(:new)
|
14
|
+
subject.build('rbenv', 'foo')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Boxci::ConfigPermutationComponent do
|
4
|
+
subject { Boxci::ConfigPermutationComponent }
|
5
|
+
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'assigns the given value to an instance variable' do
|
8
|
+
config_permutation_component = subject.new('foeue')
|
9
|
+
expect(config_permutation_component.instance_variable_get(:@val)).to eq('foeue')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#switch_to_script' do
|
14
|
+
it 'raises exception stating it is pure virtual method' do
|
15
|
+
config_permutation_component = subject.new('foeue')
|
16
|
+
expect { config_permutation_component.switch_to_script }.to raise_error(Boxci::PureVirtualMethod)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Boxci::ConfigPermutationComponents::Rbenv do
|
4
|
+
subject { Boxci::ConfigPermutationComponents::Rbenv }
|
5
|
+
|
6
|
+
describe '#switch_to_script' do
|
7
|
+
it 'generates bash script to switch ruby verisons with rbenv' do
|
8
|
+
comp = subject.new('2.1.0')
|
9
|
+
expect(comp.switch_to_script).to eq("echo \"Switching to ruby 2.1.0\"\nrbenv local 2.1.0\necho \"Swithed to ruby `ruby --version`\"\n")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Boxci::ConfigPermutation do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "constructs an instance of a Boxci::ConfigPermutation given an array of config permutation components" do
|
6
|
+
config_permutation_components = [double, double, double]
|
7
|
+
config_permutation = Boxci::ConfigPermutation.new(config_permutation_components)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "assigns the given components array to an instance variable" do
|
11
|
+
config_permutation_components = [double, double, double]
|
12
|
+
config_permutation = Boxci::ConfigPermutation.new(config_permutation_components)
|
13
|
+
expect(config_permutation.instance_variable_get(:@components)).to eq(config_permutation_components)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#switch_to_script" do
|
18
|
+
it "grabs the switch to scripts of each of the components and joins them together with newlines" do
|
19
|
+
comp1 = double(:switch_to_script => 'a')
|
20
|
+
comp2 = double(:switch_to_script => 'b')
|
21
|
+
comp3 = double(:switch_to_script => 'c')
|
22
|
+
config_permutation_components = [comp1, comp2, comp3]
|
23
|
+
config_permutation = Boxci::ConfigPermutation.new(config_permutation_components)
|
24
|
+
expect(config_permutation.switch_to_script).to eq("a\nb\nc")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|