tfwrapper 0.2.0.beta1

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.
@@ -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