tfwrapper 0.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +54 -0
- data/.rubocop.yml +22 -0
- data/ChangeLog.md +3 -0
- data/Gemfile +4 -0
- data/Guardfile +21 -0
- data/LICENSE +21 -0
- data/README.md +320 -0
- data/Rakefile +60 -0
- data/circle.yml +24 -0
- data/lib/tfwrapper/helpers.rb +81 -0
- data/lib/tfwrapper/raketasks.rb +357 -0
- data/lib/tfwrapper/version.rb +6 -0
- data/lib/tfwrapper.rb +8 -0
- data/spec/acceptance/acceptance_helpers.rb +99 -0
- data/spec/acceptance/acceptance_spec.rb +461 -0
- data/spec/acceptance/consulserver.rb +34 -0
- data/spec/fixtures/Rakefile +7 -0
- data/spec/fixtures/testOne.tf +22 -0
- data/spec/fixtures/testThree/Rakefile +32 -0
- data/spec/fixtures/testThree/bar/testThreeBar.tf +28 -0
- data/spec/fixtures/testThree/baz/testThreeBaz.tf +22 -0
- data/spec/fixtures/testThree/foo/testThreeFoo.tf +27 -0
- data/spec/fixtures/testTwo/Rakefile +9 -0
- data/spec/fixtures/testTwo/foo/bar/testTwo.tf +28 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/unit/helpers_spec.rb +143 -0
- data/spec/unit/raketasks_spec.rb +851 -0
- data/tfwrapper.gemspec +61 -0
- metadata +419 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'simplecov-console'
|
5
|
+
require 'rspec_junit_formatter'
|
6
|
+
|
7
|
+
ENV['CONSUL_ADDR'] ||= '127.0.0.1:8500'
|
8
|
+
ENV['CONSUL_URL'] ||= "http://#{ENV['CONSUL_ADDR']}"
|
9
|
+
|
10
|
+
# for naming coverage and test results in CircleCI by ruby version tested
|
11
|
+
dir_suffix = ''
|
12
|
+
if ENV['GEM_HOME']
|
13
|
+
ver = File.basename(ENV['GEM_HOME'])
|
14
|
+
dir_suffix = "-#{ver}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# for storing artifacts in the right place for CircleCI
|
18
|
+
if ENV['CIRCLE_ARTIFACTS']
|
19
|
+
dir = File.join(ENV['CIRCLE_ARTIFACTS'], "coverage#{dir_suffix}")
|
20
|
+
SimpleCov.coverage_dir(dir)
|
21
|
+
end
|
22
|
+
|
23
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
|
24
|
+
[SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::Console]
|
25
|
+
)
|
26
|
+
|
27
|
+
SimpleCov.start do
|
28
|
+
add_filter '/vendor/'
|
29
|
+
add_filter '/spec/'
|
30
|
+
end
|
31
|
+
|
32
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
# moved from .rspec to interpolate $CIRCLE_ARTIFACTS as output directory
|
36
|
+
# see: https://circleci.com/docs/build-artifacts and
|
37
|
+
# http://blog.circleci.com/build-artifacts/
|
38
|
+
# and also use CircleCI Junit parsing:
|
39
|
+
# http://blog.circleci.com/announcing-detailed-test-failure-reporting/
|
40
|
+
if ENV.key?('CIRCLE_ARTIFACTS')
|
41
|
+
junit_results_path = "#{ENV['CIRCLE_TEST_REPORTS']}/rspec/results"\
|
42
|
+
"#{dir_suffix}.xml"
|
43
|
+
html_results_path = "#{ENV['CIRCLE_TEST_REPORTS']}/rspec/results"\
|
44
|
+
"#{dir_suffix}.html"
|
45
|
+
else
|
46
|
+
junit_results_path = 'results/results.xml'
|
47
|
+
html_results_path = 'results/results.html'
|
48
|
+
end
|
49
|
+
config.color = true
|
50
|
+
config.order = :random
|
51
|
+
# documentation format
|
52
|
+
config.add_formatter(:documentation)
|
53
|
+
# HTML format
|
54
|
+
# @see https://github.com/rspec/rspec-core/blob/v2.14.8/lib/rspec/core/configuration.rb#L1086
|
55
|
+
config.add_formatter(:html, html_results_path)
|
56
|
+
# JUnit results
|
57
|
+
config.add_formatter('RspecJunitFormatter', junit_results_path)
|
58
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'tfwrapper/helpers'
|
5
|
+
|
6
|
+
describe TFWrapper::Helpers do
|
7
|
+
describe '#run_cmd' do
|
8
|
+
it 'doesnt raise if command exits 0' do
|
9
|
+
res = `echo -n 'myout'; exit 0`
|
10
|
+
allow(TFWrapper::Helpers).to receive(:`).and_return(res)
|
11
|
+
|
12
|
+
expect(STDOUT).to receive(:puts).once.with('Running command: foo bar')
|
13
|
+
expect(TFWrapper::Helpers).to receive(:`).once.with('foo bar')
|
14
|
+
TFWrapper::Helpers.run_cmd('foo bar')
|
15
|
+
end
|
16
|
+
it 'raises if command exits non-0' do
|
17
|
+
res = `echo -n 'myout'; exit 23`
|
18
|
+
allow(TFWrapper::Helpers).to receive(:`).and_return(res)
|
19
|
+
|
20
|
+
expect(STDOUT).to receive(:puts).once.with('Running command: foo bar')
|
21
|
+
expect(TFWrapper::Helpers).to receive(:`).once.with('foo bar')
|
22
|
+
expect(STDOUT).to receive(:puts).once.with('Command exited 23:')
|
23
|
+
expect(STDOUT).to receive(:puts).once.with('myout')
|
24
|
+
expect { TFWrapper::Helpers.run_cmd('foo bar') }
|
25
|
+
.to raise_error StandardError, 'ERROR: Command failed: foo bar'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
describe '#run_cmd_stream_output' do
|
29
|
+
# test logic for this was inspired by:
|
30
|
+
# http://rxr.whitequark.org/rubinius/source/spec/ruby/core/io/select_spec.rb
|
31
|
+
before :each do
|
32
|
+
@outerrpipe_r, @outerrpipe_w = IO.pipe
|
33
|
+
@inpipe_r, @inpipe_w = IO.pipe
|
34
|
+
end
|
35
|
+
after :each do
|
36
|
+
@outerrpipe_r.close unless @outerrpipe_r.closed?
|
37
|
+
@outerrpipe_w.close unless @outerrpipe_w.closed?
|
38
|
+
@inpipe_r.close unless @inpipe_r.closed?
|
39
|
+
@inpipe_w.close unless @inpipe_w.closed?
|
40
|
+
end
|
41
|
+
context 'success' do
|
42
|
+
it 'prints and returns output' do
|
43
|
+
dbl_wait_thread = double(Thread)
|
44
|
+
@outerrpipe_w.write('mystdout')
|
45
|
+
@outerrpipe_w.close
|
46
|
+
es = double('exitstatus', exitstatus: 0)
|
47
|
+
allow(dbl_wait_thread).to receive(:value).and_return(es)
|
48
|
+
allow($stdout).to receive(:sync).and_return(false)
|
49
|
+
allow($stdout).to receive(:sync=).with(true)
|
50
|
+
allow(Open3).to receive(:popen2e).and_yield(
|
51
|
+
@inpipe_w, @outerrpipe_r, dbl_wait_thread
|
52
|
+
)
|
53
|
+
|
54
|
+
expect(Open3).to receive(:popen2e)
|
55
|
+
.once.with('foo bar', chdir: '/foo')
|
56
|
+
expect(STDOUT).to receive(:puts).once.with('mystdout')
|
57
|
+
expect($stdout).to receive(:sync=).once.with(true)
|
58
|
+
expect($stdout).to receive(:sync=).once.with(false)
|
59
|
+
expect(TFWrapper::Helpers.run_cmd_stream_output('foo bar', '/foo'))
|
60
|
+
.to eq(['mystdout', 0])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context 'IOError' do
|
64
|
+
it 'handles IOErrors gracefully' do
|
65
|
+
dbl_wait_thread = double(Thread)
|
66
|
+
@outerrpipe_w.close
|
67
|
+
@outerrpipe_r.close
|
68
|
+
es = double('exitstatus', exitstatus: 0)
|
69
|
+
allow(dbl_wait_thread).to receive(:value).and_return(es)
|
70
|
+
allow($stdout).to receive(:sync).and_return(false)
|
71
|
+
allow($stdout).to receive(:sync=).with(true)
|
72
|
+
allow(Open3).to receive(:popen2e).and_yield(
|
73
|
+
@inpipe_w, @outerrpipe_r, dbl_wait_thread
|
74
|
+
)
|
75
|
+
|
76
|
+
expect(Open3).to receive(:popen2e)
|
77
|
+
.once.with('foo bar', chdir: '/foo')
|
78
|
+
expect(STDERR).to receive(:puts).once.with('IOError: closed stream')
|
79
|
+
expect($stdout).to receive(:sync=).once.with(true)
|
80
|
+
expect($stdout).to receive(:sync=).once.with(false)
|
81
|
+
expect(TFWrapper::Helpers.run_cmd_stream_output('foo bar', '/foo'))
|
82
|
+
.to eq(['', 0])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context 'failure' do
|
86
|
+
it 'returns the non-zero exit code' do
|
87
|
+
dbl_wait_thread = double(Thread)
|
88
|
+
@outerrpipe_w.write("mystdout\n")
|
89
|
+
@outerrpipe_w.write("STDERR\n")
|
90
|
+
@outerrpipe_w.close
|
91
|
+
es = double('exitstatus', exitstatus: 23)
|
92
|
+
allow(dbl_wait_thread).to receive(:value).and_return(es)
|
93
|
+
allow($stdout).to receive(:sync).and_return(false)
|
94
|
+
allow($stdout).to receive(:sync=).with(true)
|
95
|
+
allow(Open3).to receive(:popen2e).and_yield(
|
96
|
+
@inpipe_w, @outerrpipe_r, dbl_wait_thread
|
97
|
+
)
|
98
|
+
|
99
|
+
expect(Open3).to receive(:popen2e)
|
100
|
+
.once.with('foo bar', chdir: '/foo')
|
101
|
+
expect(STDOUT).to receive(:puts).once.with("mystdout\n")
|
102
|
+
expect(STDOUT).to receive(:puts).once.with("STDERR\n")
|
103
|
+
expect($stdout).to receive(:sync=).once.with(true)
|
104
|
+
expect($stdout).to receive(:sync=).once.with(false)
|
105
|
+
expect(TFWrapper::Helpers.run_cmd_stream_output('foo bar', '/foo'))
|
106
|
+
.to eq(["mystdout\nSTDERR\n", 23])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
describe '#check_env_vars' do
|
111
|
+
it 'returns nil if vars present' do
|
112
|
+
ENV['foo'] = 'fooval'
|
113
|
+
ENV['bar'] = 'barval'
|
114
|
+
expect(TFWrapper::Helpers.check_env_vars(%w[foo bar])).to be_nil
|
115
|
+
ENV.delete('foo')
|
116
|
+
ENV.delete('bar')
|
117
|
+
end
|
118
|
+
it 'exits if not present' do
|
119
|
+
ENV.delete('foo')
|
120
|
+
ENV.delete('bar')
|
121
|
+
expect(STDOUT).to receive(:puts)
|
122
|
+
.with('ERROR: Environment variable \'foo\' must be set.')
|
123
|
+
expect(STDOUT).to receive(:puts)
|
124
|
+
.with('ERROR: Environment variable \'bar\' must be set.')
|
125
|
+
expect { TFWrapper::Helpers.check_env_vars(%w[foo bar]) }
|
126
|
+
.to raise_error StandardError, 'Missing or empty environment ' \
|
127
|
+
'variables: ["foo", "bar"]'
|
128
|
+
end
|
129
|
+
it 'exits if empty' do
|
130
|
+
ENV['foo'] = ''
|
131
|
+
ENV['bar'] = ' '
|
132
|
+
expect(STDOUT).to receive(:puts)
|
133
|
+
.with("ERROR: Environment variable 'foo' must not be empty.")
|
134
|
+
expect(STDOUT).to receive(:puts)
|
135
|
+
.with("ERROR: Environment variable 'bar' must not be empty.")
|
136
|
+
expect { TFWrapper::Helpers.check_env_vars(%w[foo bar]) }
|
137
|
+
.to raise_error StandardError, 'Missing or empty environment ' \
|
138
|
+
'variables: ["foo", "bar"]'
|
139
|
+
ENV.delete('foo')
|
140
|
+
ENV.delete('bar')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|