puppetlabs-onceover 5.0.3 → 5.0.4

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rubocop_todo.yml +35 -15
  4. data/CHANGELOG.md +387 -3
  5. data/Gemfile +1 -0
  6. data/lib/puppetlabs-onceover/cli/plugins.rb +3 -3
  7. data/lib/puppetlabs-onceover/controlrepo.rb +8 -7
  8. data/lib/puppetlabs-onceover/version.rb +1 -1
  9. data/spec/fixtures/controlrepos/deploy_test/Puppetfile +3 -0
  10. data/spec/fixtures/controlrepos/deploy_test/a_dir/nested_file.txt +1 -0
  11. data/spec/fixtures/controlrepos/deploy_test/a_symlink +1 -0
  12. data/spec/fixtures/controlrepos/deploy_test/environment.conf +1 -0
  13. data/spec/fixtures/controlrepos/deploy_test/regular_file.txt +1 -0
  14. data/spec/puppetlabs-onceover/beaker_spec.rb +293 -0
  15. data/spec/puppetlabs-onceover/class_spec.rb +89 -0
  16. data/spec/puppetlabs-onceover/cli/run_spec.rb +80 -0
  17. data/spec/puppetlabs-onceover/cli/show_spec.rb +67 -0
  18. data/spec/puppetlabs-onceover/cli_spec.rb +79 -0
  19. data/spec/puppetlabs-onceover/controlrepo_spec.rb +787 -5
  20. data/spec/puppetlabs-onceover/deploy_spec.rb +246 -0
  21. data/spec/puppetlabs-onceover/group_spec.rb +121 -0
  22. data/spec/puppetlabs-onceover/logger_spec.rb +30 -0
  23. data/spec/puppetlabs-onceover/node_spec.rb +124 -0
  24. data/spec/puppetlabs-onceover/rake_tasks_spec.rb +173 -0
  25. data/spec/puppetlabs-onceover/rspec/formatters_spec.rb +361 -0
  26. data/spec/puppetlabs-onceover/runner_spec.rb +307 -0
  27. data/spec/puppetlabs-onceover/test_spec.rb +177 -0
  28. data/spec/puppetlabs-onceover/testconfig_spec.rb +451 -0
  29. data/spec/puppetlabs-onceover/vendored_modules_spec.rb +302 -0
  30. data/spec/puppetlabs-onceover/version_spec.rb +10 -0
  31. data/spec/spec_helper.rb +8 -0
  32. metadata +22 -1
@@ -0,0 +1,293 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/beaker'
3
+
4
+ # The `beaker`/`beaker-rspec` gems are intentionally NOT in this project's Gemfile
5
+ # (removing that dependency is the whole point of this fork -- see CAT-2770 et al).
6
+ # beaker.rb's deprecated, still-shippped `deploy_controlrepo_on`/`provision_and_test`/
7
+ # `host_create` methods `require 'beaker-rspec'` / `require 'beaker/network_manager'`
8
+ # and reference `::Beaker::NetworkManager` inline. To cover those code paths without
9
+ # pulling the real (large, unmaintained-for-this-repo's-purposes) beaker gems back in,
10
+ # stand in a minimal fake `::Beaker::NetworkManager` and make the specific `require`
11
+ # calls those methods make into no-ops.
12
+ module ::Beaker
13
+ unless defined?(::Beaker::NetworkManager)
14
+ class NetworkManager
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "PuppetlabsOnceover::Beaker" do
20
+ before(:each) do
21
+ allow(Kernel).to receive(:warn)
22
+ allow_any_instance_of(Object).to receive(:require).and_wrap_original do |original, name|
23
+ %w[beaker-rspec beaker/network_manager].include?(name) || original.call(name)
24
+ end
25
+ end
26
+
27
+ describe ".facts_to_vagrant_box" do
28
+ it "maps Ubuntu facts to a puppetlabs vagrant box name" do
29
+ facts = { 'os' => { 'distro' => { 'id' => 'Ubuntu', 'release' => { 'major' => '20.04' } }, 'architecture' => 'x86_64' } }
30
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)).to eq('puppetlabs/ubuntu-20.04-64-puppet')
31
+ end
32
+
33
+ it "maps Debian facts to a puppetlabs vagrant box name" do
34
+ facts = { 'os' => { 'distro' => { 'id' => 'Debian', 'release' => { 'full' => '10.9' } }, 'architecture' => 'x86_64' } }
35
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)).to eq('puppetlabs/Debian-10.9-64-puppet')
36
+ end
37
+
38
+ it "maps RedHat family facts to a centos vagrant box name" do
39
+ facts = { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '7', 'minor' => '9' }, 'architecture' => 'x86_64' } }
40
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)).to eq('puppetlabs/centos-7.9-64-puppet')
41
+ end
42
+
43
+ it "returns UNKNOWN when the OS cannot be determined" do
44
+ facts = { 'os' => { 'family' => 'SomeWeirdOS', 'architecture' => 'x86_64' } }
45
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)).to eq('UNKNOWN')
46
+ end
47
+
48
+ it "detects 32-bit architectures" do
49
+ facts = { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '6', 'minor' => '0' } }, 'architecture' => 'i386' }
50
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)).to eq('puppetlabs/centos-6.0-32-puppet')
51
+ end
52
+
53
+ it "recurses over an array of factsets" do
54
+ facts = [
55
+ { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '7', 'minor' => '0' }, 'architecture' => 'x86_64' } },
56
+ { 'os' => { 'family' => 'SomeWeirdOS', 'architecture' => 'x86_64' } }
57
+ ]
58
+ result = PuppetlabsOnceover::Beaker.facts_to_vagrant_box(facts)
59
+ expect(result).to eq(['puppetlabs/centos-7.0-64-puppet', 'UNKNOWN'])
60
+ end
61
+
62
+ it "does not blow up when the facts hash does not have the expected 'os' shape" do
63
+ expect(PuppetlabsOnceover::Beaker.facts_to_vagrant_box({ 'architecture' => 'x86_64' })).to eq('UNKNOWN')
64
+ end
65
+ end
66
+
67
+ describe ".facts_to_platform" do
68
+ it "maps RedHat family facts to an 'el' platform string" do
69
+ facts = { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '7' }, 'architecture' => 'x86_64' } }
70
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq('el-7-64')
71
+ end
72
+
73
+ it "maps Ubuntu facts to an 'ubuntu' platform string" do
74
+ facts = { 'os' => { 'family' => 'Debian', 'distro' => { 'id' => 'Ubuntu', 'release' => { 'major' => '20.04' } }, 'architecture' => 'x86_64' } }
75
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq('ubuntu-20.04-64')
76
+ end
77
+
78
+ it "maps Debian facts to a 'debian' platform string" do
79
+ facts = { 'os' => { 'family' => 'Debian', 'distro' => { 'id' => 'Debian', 'release' => { 'full' => '10.9' } }, 'architecture' => 'x86_64' } }
80
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq('debian-10.9-64')
81
+ end
82
+
83
+ it "detects 32-bit architectures" do
84
+ facts = { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '6' }, 'architecture' => 'i386' } }
85
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq('el-6-32')
86
+ end
87
+
88
+ it "produces a nil-nil platform string when nothing matches" do
89
+ facts = { 'os' => { 'family' => 'SomeWeirdOS', 'architecture' => 'x86_64' } }
90
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq('--64')
91
+ end
92
+
93
+ it "recurses over an array of factsets" do
94
+ facts = [
95
+ { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '7' }, 'architecture' => 'x86_64' } },
96
+ { 'os' => { 'family' => 'RedHat', 'release' => { 'major' => '8' }, 'architecture' => 'x86_64' } }
97
+ ]
98
+ expect(PuppetlabsOnceover::Beaker.facts_to_platform(facts)).to eq(['el-7-64', 'el-8-64'])
99
+ end
100
+ end
101
+
102
+ describe ".deploy_controlrepo_on" do
103
+ it "installs r10k, git, copies the r10k config, and deploys via r10k on a single host" do
104
+ host = double('host')
105
+ repo = double('repo', r10k_config_file: '/tmp/r10k.yaml')
106
+
107
+ allow(PuppetlabsOnceover::Beaker).to receive(:require).and_return(true)
108
+ allow(host).to receive(:is_a?).with(Array).and_return(false)
109
+ allow(PuppetlabsOnceover::Beaker).to receive(:install_r10k_on)
110
+ allow(host).to receive(:install_package).with('git')
111
+ allow(PuppetlabsOnceover::Beaker).to receive(:scp_to)
112
+ allow(PuppetlabsOnceover::Beaker).to receive(:r10k_deploy)
113
+
114
+ PuppetlabsOnceover::Beaker.deploy_controlrepo_on(host, repo)
115
+
116
+ expect(PuppetlabsOnceover::Beaker).to have_received(:install_r10k_on).with(host)
117
+ expect(host).to have_received(:install_package).with('git')
118
+ expect(PuppetlabsOnceover::Beaker).to have_received(:scp_to).with(host, '/tmp/r10k.yaml', '/tmp/r10k.yaml')
119
+ expect(PuppetlabsOnceover::Beaker).to have_received(:r10k_deploy).with(host, { puppetfile: true, configfile: '/tmp/r10k.yaml' })
120
+ end
121
+
122
+ it "recurses when given an array of hosts (accepted quirk: iterates `hosts`, an undefined local, not the `host` array param)" do
123
+ host_array = double('host_array')
124
+ allow(host_array).to receive(:is_a?).with(Array).and_return(true)
125
+ repo = double('repo', r10k_config_file: '/tmp/r10k.yaml')
126
+
127
+ allow(PuppetlabsOnceover::Beaker).to receive(:install_r10k_on)
128
+ allow(host_array).to receive(:install_package)
129
+ allow(PuppetlabsOnceover::Beaker).to receive(:scp_to)
130
+ allow(PuppetlabsOnceover::Beaker).to receive(:r10k_deploy)
131
+
132
+ # `hosts.each { ... }` inside the `if host.is_a?(Array)` branch references an
133
+ # undefined local `hosts` (not the `host` param) -- a real bug in the source.
134
+ # It raises NameError immediately, so the array-recursion branch never actually
135
+ # recurses; we assert the crash rather than pretending it works.
136
+ expect { PuppetlabsOnceover::Beaker.deploy_controlrepo_on(host_array, repo) }.to raise_error(NameError, /hosts/)
137
+ end
138
+ end
139
+
140
+ describe ".provision_and_test" do
141
+ # provision_and_test's 4th positional param defaults to `PuppetlabsOnceover::Controlrepo.new`
142
+ # -- Ruby evaluates that default for any omitted arg before the method body (and its own
143
+ # raise checks) ever runs, and a real `Controlrepo.new` throws outside an actual controlrepo.
144
+ # Always pass an explicit (unused) repo double as the 4th arg to avoid tripping that default.
145
+ let(:unused_repo) { double('repo') }
146
+
147
+ it "raises when given an array of hosts" do
148
+ expect do
149
+ PuppetlabsOnceover::Beaker.provision_and_test([double('host')], 'role::example', {}, unused_repo)
150
+ end.to raise_error(RuntimeError, /must be a single host object/)
151
+ end
152
+
153
+ it "raises when puppet_class is not a String" do
154
+ expect do
155
+ PuppetlabsOnceover::Beaker.provision_and_test(double('host'), :not_a_string, {}, unused_repo)
156
+ end.to raise_error(RuntimeError, /must be a single Class/)
157
+ end
158
+
159
+ it "provisions (when host is not up), applies the manifest, checks idempotency, and cleans up" do
160
+ host = double('host', up?: false)
161
+ network_manager = double('network_manager')
162
+ allow(network_manager).to receive(:instance_variable_set)
163
+ allow(network_manager).to receive(:provision)
164
+ allow(network_manager).to receive(:proxy_package_manager)
165
+ allow(network_manager).to receive(:validate)
166
+ allow(network_manager).to receive(:configure)
167
+ allow(network_manager).to receive(:cleanup)
168
+ allow(Beaker::NetworkManager).to receive(:new).and_return(network_manager)
169
+
170
+ apply_calls = []
171
+ allow(PuppetlabsOnceover::Beaker).to receive(:apply_manifest_on) do |h, manifest, opts|
172
+ apply_calls << [h, manifest, opts]
173
+ end
174
+ allow(PuppetlabsOnceover::Beaker).to receive(:options).and_return({})
175
+ allow(PuppetlabsOnceover::Beaker).to receive(:logger).and_return(double('logger'))
176
+
177
+ PuppetlabsOnceover::Beaker.provision_and_test(host, 'role::example', {}, unused_repo)
178
+
179
+ expect(network_manager).to have_received(:provision)
180
+ expect(network_manager).to have_received(:cleanup)
181
+ expect(apply_calls.map { |c| c[2] }).to include({ catch_failures: true }, { catch_changes: true })
182
+ end
183
+
184
+ it "skips provisioning when the host is already up, and skips idempotency check when disabled" do
185
+ host = double('host', up?: true)
186
+ network_manager = double('network_manager')
187
+ allow(network_manager).to receive(:instance_variable_set)
188
+ allow(network_manager).to receive(:cleanup)
189
+ allow(Beaker::NetworkManager).to receive(:new).and_return(network_manager)
190
+
191
+ apply_calls = []
192
+ allow(PuppetlabsOnceover::Beaker).to receive(:apply_manifest_on) do |h, manifest, opts|
193
+ apply_calls << [h, manifest, opts]
194
+ end
195
+ allow(PuppetlabsOnceover::Beaker).to receive(:options).and_return({})
196
+ allow(PuppetlabsOnceover::Beaker).to receive(:logger).and_return(double('logger'))
197
+
198
+ PuppetlabsOnceover::Beaker.provision_and_test(host, 'role::example', { check_idempotency: false, runs_before_idempotency: 2 }, unused_repo)
199
+
200
+ expect(apply_calls.size).to eq(2)
201
+ expect(apply_calls.map { |c| c[2] }).to eq([{ catch_failures: true }, { catch_failures: true }])
202
+ end
203
+ end
204
+
205
+ describe ".match_indentation" do
206
+ it "sets the logger's line_prefix based on the scoped_id depth" do
207
+ test = double('test', metadata: { scoped_id: '1:2:3' })
208
+ logger = double('logger')
209
+ expect(logger).to receive(:line_prefix=).with(' ')
210
+ PuppetlabsOnceover::Beaker.match_indentation(test, logger)
211
+ end
212
+
213
+ it "uses no prefix for a top-level scoped_id" do
214
+ test = double('test', metadata: { scoped_id: '1' })
215
+ logger = double('logger')
216
+ expect(logger).to receive(:line_prefix=).with('')
217
+ PuppetlabsOnceover::Beaker.match_indentation(test, logger)
218
+ end
219
+ end
220
+
221
+ describe ".host_create" do
222
+ it "builds a single host via a NetworkManager, wires up a down! method, and returns it" do
223
+ nodes = { HOSTS: { 'centos7' => { platform: 'el-7-x86_64' }, 'other' => { platform: 'ubuntu' } }, other_opt: 'value' }
224
+
225
+ host_double = double('host')
226
+ allow(host_double).to receive(:instance_variable_set)
227
+ allow(host_double).to receive(:define_singleton_method)
228
+
229
+ network_manager = double('network_manager')
230
+ allow(network_manager).to receive(:provision)
231
+ allow(network_manager).to receive(:proxy_package_manager)
232
+ allow(network_manager).to receive(:validate)
233
+ allow(network_manager).to receive(:configure)
234
+ allow(network_manager).to receive(:instance_variable_get).with(:@hosts).and_return([host_double])
235
+ allow(Beaker::NetworkManager).to receive(:new).and_return(network_manager)
236
+ allow(PuppetlabsOnceover::Beaker).to receive(:logger).and_return(double('logger'))
237
+ allow(PuppetlabsOnceover::Beaker).to receive(:hosts).and_return([host_double])
238
+
239
+ result = PuppetlabsOnceover::Beaker.host_create('centos7', nodes)
240
+
241
+ expect(result).to eq(host_double)
242
+ expect(Beaker::NetworkManager).to have_received(:new) do |opts, _logger|
243
+ expect(opts[:HOSTS]).to eq({ 'centos7' => { platform: 'el-7-x86_64' } })
244
+ expect(opts[:other_opt]).to eq('value')
245
+ end
246
+ end
247
+
248
+ it "supports the default_proc string/symbol key fallback on current_opts" do
249
+ nodes = { HOSTS: { 'centos7' => {} } }
250
+ captured_opts = nil
251
+
252
+ host_double = double('host')
253
+ allow(host_double).to receive(:instance_variable_set)
254
+ allow(host_double).to receive(:define_singleton_method)
255
+
256
+ network_manager = double('network_manager')
257
+ allow(network_manager).to receive(:provision)
258
+ allow(network_manager).to receive(:proxy_package_manager)
259
+ allow(network_manager).to receive(:validate)
260
+ allow(network_manager).to receive(:configure)
261
+ allow(network_manager).to receive(:instance_variable_get).with(:@hosts).and_return([host_double])
262
+ allow(Beaker::NetworkManager).to receive(:new) do |opts, _logger|
263
+ captured_opts = opts
264
+ network_manager
265
+ end
266
+ allow(PuppetlabsOnceover::Beaker).to receive(:logger).and_return(double('logger'))
267
+ allow(PuppetlabsOnceover::Beaker).to receive(:hosts).and_return([host_double])
268
+
269
+ PuppetlabsOnceover::Beaker.host_create('centos7', nodes)
270
+
271
+ expect(captured_opts[:HOSTS]).to eq({ 'centos7' => {} })
272
+ expect(captured_opts['HOSTS']).to eq({ 'centos7' => {} })
273
+ end
274
+
275
+ it "raises if the network manager created more than one host" do
276
+ nodes = { HOSTS: { 'centos7' => {} } }
277
+
278
+ network_manager = double('network_manager')
279
+ allow(network_manager).to receive(:provision)
280
+ allow(network_manager).to receive(:proxy_package_manager)
281
+ allow(network_manager).to receive(:validate)
282
+ allow(network_manager).to receive(:configure)
283
+ allow(network_manager).to receive(:instance_variable_get).with(:@hosts).and_return([double('a'), double('b')])
284
+ allow(Beaker::NetworkManager).to receive(:new).and_return(network_manager)
285
+ allow(PuppetlabsOnceover::Beaker).to receive(:logger).and_return(double('logger'))
286
+ allow(PuppetlabsOnceover::Beaker).to receive(:hosts).and_return([double('a'), double('b')])
287
+
288
+ expect do
289
+ PuppetlabsOnceover::Beaker.host_create('centos7', nodes)
290
+ end.to raise_error(RuntimeError, /too many machines/)
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/class'
3
+ require 'puppetlabs-onceover/controlrepo'
4
+
5
+ describe "PuppetlabsOnceover::Class" do
6
+ before(:each) do
7
+ PuppetlabsOnceover::Class.class_variable_set(:@@all, [])
8
+ # Silence the info/warn logging noise from the shared $logger global
9
+ logger.level = :fatal
10
+ end
11
+
12
+ describe ".name_is_regexp?" do
13
+ it "returns true for a /.../ delimited string" do
14
+ expect(PuppetlabsOnceover::Class.name_is_regexp?('/role::/')).to eq(true)
15
+ end
16
+
17
+ it "returns false for a plain string" do
18
+ expect(PuppetlabsOnceover::Class.name_is_regexp?('role::webserver')).to eq(false)
19
+ end
20
+
21
+ it "returns false for a string that only starts with /" do
22
+ expect(PuppetlabsOnceover::Class.name_is_regexp?('/role::webserver')).to eq(false)
23
+ end
24
+ end
25
+
26
+ describe ".string_to_regexp" do
27
+ it "converts a /.../ delimited string into a Regexp" do
28
+ expect(PuppetlabsOnceover::Class.string_to_regexp('/role::/')).to eq(Regexp.new('role::'))
29
+ end
30
+
31
+ it "raises when the string is not regexp-shaped" do
32
+ expect { PuppetlabsOnceover::Class.string_to_regexp('role::webserver') }.to raise_error(
33
+ RuntimeError, /does not start and end with/
34
+ )
35
+ end
36
+ end
37
+
38
+ describe "#initialize" do
39
+ it "sets the name and adds itself to .all for a plain class name" do
40
+ cls = PuppetlabsOnceover::Class.new('role::webserver')
41
+ expect(cls.name).to eq('role::webserver')
42
+ expect(PuppetlabsOnceover::Class.all).to eq([cls])
43
+ end
44
+
45
+ context "when given a regexp name" do
46
+ before(:each) do
47
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/function_mocking')
48
+ end
49
+
50
+ it "expands into one Class object per matching controlrepo class, and does not add the regexp itself" do
51
+ PuppetlabsOnceover::Class.new('/role::/')
52
+ names = PuppetlabsOnceover::Class.all.map(&:name)
53
+ expect(names).not_to be_empty
54
+ expect(names).to all(match(/role::/))
55
+ end
56
+
57
+ it "creates no objects when nothing matches" do
58
+ PuppetlabsOnceover::Class.new('/nothing_matches_this_prefix_xyz::/')
59
+ expect(PuppetlabsOnceover::Class.all).to eq([])
60
+ end
61
+ end
62
+ end
63
+
64
+ describe ".find" do
65
+ it "finds an exact match by name" do
66
+ cls = PuppetlabsOnceover::Class.new('role::webserver')
67
+ expect(PuppetlabsOnceover::Class.find('role::webserver')).to eq(cls)
68
+ end
69
+
70
+ it "returns nil (and warns) when nothing matches" do
71
+ expect(PuppetlabsOnceover::Class.find('role::does_not_exist')).to be_nil
72
+ end
73
+
74
+ it "finds all matches when given a regexp name" do
75
+ a = PuppetlabsOnceover::Class.new('role::a')
76
+ b = PuppetlabsOnceover::Class.new('profile::b')
77
+ expect(PuppetlabsOnceover::Class.find('/role::/')).to eq([a])
78
+ expect(PuppetlabsOnceover::Class.find('/role::/')).not_to include(b)
79
+ end
80
+ end
81
+
82
+ describe ".all" do
83
+ it "returns every class created so far" do
84
+ a = PuppetlabsOnceover::Class.new('role::a')
85
+ b = PuppetlabsOnceover::Class.new('role::b')
86
+ expect(PuppetlabsOnceover::Class.all).to eq([a, b])
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/cli/run'
3
+
4
+ describe PuppetlabsOnceover::CLI::Run do
5
+ describe '.command' do
6
+ it 'builds a memoized Cri::Command named run' do
7
+ cmd = described_class.command
8
+ expect(cmd).to be_a(Cri::Command)
9
+ expect(cmd.name).to eq('run')
10
+ expect(described_class.command).to equal(cmd)
11
+ end
12
+
13
+ it 'prints help and exits 0 when run directly' do
14
+ allow_any_instance_of(Object).to receive(:exit)
15
+ expect { described_class.command.run([]) }.to output(/Runs either the spec or acceptance tests/).to_stdout
16
+ end
17
+
18
+ it 'registers the spec and acceptance subcommands' do
19
+ names = described_class.command.subcommands.map(&:name)
20
+ expect(names).to include('spec', 'acceptance')
21
+ end
22
+ end
23
+
24
+ describe PuppetlabsOnceover::CLI::Run::Spec do
25
+ describe '.command' do
26
+ it 'builds a memoized Cri::Command named spec' do
27
+ cmd = described_class.command
28
+ expect(cmd).to be_a(Cri::Command)
29
+ expect(cmd.name).to eq('spec')
30
+ expect(described_class.command).to equal(cmd)
31
+ end
32
+
33
+ it 'deploys locally then prepares and runs the spec suite' do
34
+ repo = double('repo', onceover_yaml: '/some/repo/.onceover.yaml')
35
+ config = double('config')
36
+ deploy = double('deploy', deploy_local: nil)
37
+ runner = double('runner', prepare!: nil, run_spec!: nil)
38
+
39
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
40
+ allow(PuppetlabsOnceover::TestConfig).to receive(:new).and_return(config)
41
+ allow(PuppetlabsOnceover::Deploy).to receive(:new).and_return(deploy)
42
+ allow(PuppetlabsOnceover::Runner).to receive(:new).and_return(runner)
43
+
44
+ described_class.command.run([])
45
+
46
+ expect(deploy).to have_received(:deploy_local).with(repo, anything)
47
+ expect(PuppetlabsOnceover::Runner).to have_received(:new).with(repo, config, :spec)
48
+ expect(runner).to have_received(:prepare!)
49
+ expect(runner).to have_received(:run_spec!)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe PuppetlabsOnceover::CLI::Run::Acceptance do
55
+ describe '.command' do
56
+ it 'builds a memoized Cri::Command named acceptance' do
57
+ cmd = described_class.command
58
+ expect(cmd).to be_a(Cri::Command)
59
+ expect(cmd.name).to eq('acceptance')
60
+ expect(described_class.command).to equal(cmd)
61
+ end
62
+
63
+ it 'warns about deprecation then prepares and runs the acceptance suite' do
64
+ repo = double('repo', onceover_yaml: '/some/repo/.onceover.yaml')
65
+ config = double('config')
66
+ runner = double('runner', prepare!: nil, run_acceptance!: nil)
67
+
68
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
69
+ allow(PuppetlabsOnceover::TestConfig).to receive(:new).and_return(config)
70
+ allow(PuppetlabsOnceover::Runner).to receive(:new).and_return(runner)
71
+
72
+ expect { described_class.command.run([]) }.to output(/DEPRECATION/).to_stderr
73
+
74
+ expect(PuppetlabsOnceover::Runner).to have_received(:new).with(repo, config, :acceptance)
75
+ expect(runner).to have_received(:prepare!)
76
+ expect(runner).to have_received(:run_acceptance!)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/cli/show'
3
+
4
+ describe PuppetlabsOnceover::CLI::Show do
5
+ describe '.command' do
6
+ it 'builds a memoized Cri::Command named show' do
7
+ cmd = described_class.command
8
+ expect(cmd).to be_a(Cri::Command)
9
+ expect(cmd.name).to eq('show')
10
+ expect(described_class.command).to equal(cmd)
11
+ end
12
+
13
+ it 'prints help and exits 0 when run directly' do
14
+ allow_any_instance_of(Object).to receive(:exit)
15
+ expect { described_class.command.run([]) }.to output(/Shows the current state of things/).to_stdout
16
+ end
17
+
18
+ it 'registers the repo and puppetfile subcommands' do
19
+ names = described_class.command.subcommands.map(&:name)
20
+ expect(names).to include('repo', 'puppetfile')
21
+ end
22
+ end
23
+
24
+ describe PuppetlabsOnceover::CLI::Show::Repo do
25
+ describe '.command' do
26
+ it 'builds a memoized Cri::Command named repo' do
27
+ cmd = described_class.command
28
+ expect(cmd).to be_a(Cri::Command)
29
+ expect(cmd.name).to eq('repo')
30
+ expect(described_class.command).to equal(cmd)
31
+ end
32
+
33
+ it 'prints repo and test config information and exits 0' do
34
+ allow_any_instance_of(Object).to receive(:exit)
35
+ repo = double('repo', to_s: 'REPO INFO', onceover_yaml: '/some/repo/.onceover.yaml')
36
+ config = double('config', to_s: 'CONFIG INFO')
37
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
38
+ allow(PuppetlabsOnceover::TestConfig).to receive(:new).and_return(config)
39
+
40
+ expect { described_class.command.run([]) }.to output(/REPO INFO/).to_stdout
41
+ expect { described_class.command.run([]) }.to output(/CONFIG INFO/).to_stdout
42
+ expect(PuppetlabsOnceover::TestConfig).to have_received(:new).with(repo.onceover_yaml, anything).at_least(:once)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe PuppetlabsOnceover::CLI::Show::Puppetfile do
48
+ describe '.command' do
49
+ it 'builds a memoized Cri::Command named puppetfile' do
50
+ cmd = described_class.command
51
+ expect(cmd).to be_a(Cri::Command)
52
+ expect(cmd.name).to eq('puppetfile')
53
+ expect(described_class.command).to equal(cmd)
54
+ end
55
+
56
+ it 'prints the puppetfile table and exits 0' do
57
+ allow_any_instance_of(Object).to receive(:exit)
58
+ repo = double('repo', print_puppetfile_table: nil)
59
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
60
+
61
+ described_class.command.run([])
62
+
63
+ expect(repo).to have_received(:print_puppetfile_table)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/cli'
3
+ require 'puppetlabs-onceover/cli/init'
4
+ require 'puppetlabs-onceover/cli/update'
5
+ require 'puppetlabs-onceover/cli/plugins'
6
+
7
+ describe PuppetlabsOnceover::CLI do
8
+ describe '.command' do
9
+ it 'builds a memoized Cri::Command named onceover' do
10
+ cmd = described_class.command
11
+ expect(cmd).to be_a(Cri::Command)
12
+ expect(cmd.name).to eq('onceover')
13
+ expect(described_class.command).to equal(cmd)
14
+ end
15
+
16
+ it 'prints help and exits 0 when run with no subcommand' do
17
+ allow_any_instance_of(Object).to receive(:exit)
18
+ expect { described_class.command.run([]) }.to output(/Tool for testing Puppet controlrepos/).to_stdout
19
+ end
20
+
21
+ it 'prints help and exits 0 when given -h' do
22
+ allow_any_instance_of(Object).to receive(:exit)
23
+ expect { described_class.command.run(['-h']) }.to output(/onceover/).to_stdout
24
+ end
25
+
26
+ it 'registers the show, run, init, and update subcommands' do
27
+ names = described_class.command.subcommands.map(&:name)
28
+ expect(names).to include('show', 'run', 'init', 'update')
29
+ end
30
+ end
31
+ end
32
+
33
+ describe PuppetlabsOnceover::CLI::Init do
34
+ describe '.command' do
35
+ it 'builds a memoized Cri::Command named init' do
36
+ cmd = described_class.command
37
+ expect(cmd).to be_a(Cri::Command)
38
+ expect(cmd.name).to eq('init')
39
+ expect(described_class.command).to equal(cmd)
40
+ end
41
+
42
+ it 'calls Controlrepo.init with a freshly built Controlrepo' do
43
+ repo = double('repo')
44
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
45
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:init)
46
+
47
+ described_class.command.run([])
48
+
49
+ expect(PuppetlabsOnceover::Controlrepo).to have_received(:init).with(repo)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe PuppetlabsOnceover::CLI::Update do
55
+ describe '.command' do
56
+ it 'prints help and exits 0 when run directly' do
57
+ allow_any_instance_of(Object).to receive(:exit)
58
+ expect { described_class.command.run([]) }.to output(/Updates stuff/).to_stdout
59
+ end
60
+ end
61
+
62
+ describe PuppetlabsOnceover::CLI::Update::Puppetfile do
63
+ it 'calls update_puppetfile on a freshly built Controlrepo and exits 0' do
64
+ allow_any_instance_of(Object).to receive(:exit)
65
+ repo = double('repo', update_puppetfile: nil)
66
+ allow(PuppetlabsOnceover::Controlrepo).to receive(:new).and_return(repo)
67
+
68
+ described_class.command.run([])
69
+
70
+ expect(repo).to have_received(:update_puppetfile)
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'cli/plugins.rb' do
76
+ it 'requires the plugins file without error, discovering zero or more onceover-* gems' do
77
+ expect { load File.expand_path('../../lib/puppetlabs-onceover/cli/plugins.rb', __dir__) }.not_to raise_error
78
+ end
79
+ end