tfwrapper 0.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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