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,246 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/controlrepo'
3
+ require 'puppetlabs-onceover/vendored_modules'
4
+ require 'puppetlabs-onceover/deploy'
5
+ require 'tmpdir'
6
+ require 'fileutils'
7
+
8
+ describe PuppetlabsOnceover::Deploy do
9
+ subject(:deploy) { described_class.new }
10
+
11
+ # Every test gets its own scratch tempdir standing in for
12
+ # repo.tempdir/.onceover, cleaned up afterwards so nothing leaks into the
13
+ # real repo tree.
14
+ let(:tempdir) { Dir.mktmpdir('deploy-spec-tempdir') }
15
+
16
+ after do
17
+ FileUtils.rm_rf(tempdir)
18
+ end
19
+
20
+ def build_repo(fixture, tempdir_override: tempdir)
21
+ repo = PuppetlabsOnceover::Controlrepo.new(path: "spec/fixtures/controlrepos/#{fixture}")
22
+ repo.tempdir = tempdir_override
23
+ repo
24
+ end
25
+
26
+ describe '#deploy_local' do
27
+ context 'when the controlrepo has no Puppetfile' do
28
+ it 'defaults to skipping r10k entirely and still copies the tree' do
29
+ repo = build_repo('minimal')
30
+
31
+ expect(deploy).not_to receive(:system)
32
+
33
+ result = deploy.deploy_local(repo, {})
34
+
35
+ expect(result).to eq(tempdir)
36
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
37
+ expect(File.exist?("#{production_dir}/environment.conf")).to be true
38
+ expect(File.exist?("#{production_dir}/.onceover_manifest.json")).to be true
39
+ end
40
+ end
41
+
42
+ context 'when skip_r10k is explicitly requested' do
43
+ it 'copies the tree (including the untouched Puppetfile) but never shells out' do
44
+ repo = build_repo('basic')
45
+
46
+ expect(deploy).not_to receive(:system)
47
+
48
+ deploy.deploy_local(repo, { skip_r10k: true })
49
+
50
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
51
+ original_puppetfile = File.read('spec/fixtures/controlrepos/basic/Puppetfile')
52
+ expect(File.read("#{production_dir}/Puppetfile")).to eq(original_puppetfile)
53
+ end
54
+ end
55
+
56
+ context 'symlinks, directories, and plain files in the controlrepo' do
57
+ it 'recreates symlinks, directories, and files in the copied tree' do
58
+ repo = build_repo('deploy_test')
59
+
60
+ deploy.deploy_local(repo, { skip_r10k: true })
61
+
62
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
63
+ expect(File.symlink?("#{production_dir}/a_symlink")).to be true
64
+ expect(File.directory?("#{production_dir}/a_dir")).to be true
65
+ expect(File.read("#{production_dir}/a_dir/nested_file.txt")).to eq("nested\n")
66
+ expect(File.read("#{production_dir}/regular_file.txt")).to eq("hello\n")
67
+ end
68
+ end
69
+
70
+ context 'when a modules directory exists in the current working directory' do
71
+ it 'logs a warning' do
72
+ repo = build_repo('deploy_test')
73
+
74
+ allow(File).to receive(:directory?).and_call_original
75
+ allow(File).to receive(:directory?).with('modules').and_return(true)
76
+
77
+ expect(logger).to receive(:warn).with(/modules directory/)
78
+
79
+ deploy.deploy_local(repo, { skip_r10k: true })
80
+ end
81
+ end
82
+
83
+ context 'when a previous run left an onceover manifest behind' do
84
+ it 'removes the files listed in the old manifest before copying the new tree' do
85
+ repo = build_repo('deploy_test')
86
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
87
+ FileUtils.mkdir_p(production_dir)
88
+ stale_file = File.join(production_dir, 'stale_leftover.txt')
89
+ File.write(stale_file, 'leftover')
90
+ File.write(
91
+ File.join(production_dir, '.onceover_manifest.json'),
92
+ ['stale_leftover.txt'].to_json
93
+ )
94
+
95
+ deploy.deploy_local(repo, { skip_r10k: true })
96
+
97
+ expect(File.exist?(stale_file)).to be false
98
+ end
99
+ end
100
+
101
+ context 'when the Puppetfile references :control_branch' do
102
+ it 'substitutes the current git branch in for :control_branch' do
103
+ repo = build_repo('control_branch')
104
+
105
+ allow(deploy).to receive(:system) do |_cmd|
106
+ Kernel.system('true')
107
+ true
108
+ end
109
+
110
+ deploy.deploy_local(repo, { skip_r10k: false })
111
+
112
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
113
+ puppetfile_contents = File.read("#{production_dir}/Puppetfile")
114
+ expect(puppetfile_contents).not_to include(':control_branch')
115
+ current_branch = `git rev-parse --abbrev-ref HEAD`.chomp
116
+ expect(puppetfile_contents).to include("'#{current_branch}'")
117
+ end
118
+ end
119
+
120
+ context 'when auto_vendored is requested' do
121
+ it 'asks VendoredModules for missing modules and appends them to the Puppetfile' do
122
+ repo = build_repo('basic')
123
+
124
+ vendored_modules_double = instance_double(
125
+ 'PuppetlabsOnceover::VendoredModules',
126
+ missing_vendored: [{ 'puppetlabs-mymodule' => { git: 'https://example.com/mymodule.git', ref: 'main' } }]
127
+ )
128
+ allow(vendored_modules_double).to receive(:puppetfile_missing_vendored)
129
+ allow(PuppetlabsOnceover::VendoredModules).to receive(:new).and_return(vendored_modules_double)
130
+
131
+ allow(deploy).to receive(:system) do |_cmd|
132
+ Kernel.system('true')
133
+ true
134
+ end
135
+
136
+ deploy.deploy_local(repo, { skip_r10k: false, auto_vendored: true })
137
+
138
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
139
+ puppetfile_contents = File.read("#{production_dir}/Puppetfile")
140
+ expect(puppetfile_contents).to include('puppetlabs-mymodule')
141
+ expect(puppetfile_contents).to include('PuppetlabsOnceover Managed Vendored Modules')
142
+ end
143
+
144
+ it 'leaves the Puppetfile untouched when there are no missing vendored modules' do
145
+ repo = build_repo('basic')
146
+
147
+ vendored_modules_double = instance_double(
148
+ 'PuppetlabsOnceover::VendoredModules',
149
+ missing_vendored: []
150
+ )
151
+ allow(vendored_modules_double).to receive(:puppetfile_missing_vendored)
152
+ allow(PuppetlabsOnceover::VendoredModules).to receive(:new).and_return(vendored_modules_double)
153
+
154
+ allow(deploy).to receive(:system) do |_cmd|
155
+ Kernel.system('true')
156
+ true
157
+ end
158
+
159
+ deploy.deploy_local(repo, { skip_r10k: false, auto_vendored: true })
160
+
161
+ production_dir = "#{tempdir}/#{repo.environmentpath}/production"
162
+ puppetfile_contents = File.read("#{production_dir}/Puppetfile")
163
+ expect(puppetfile_contents).not_to include('PuppetlabsOnceover Managed Vendored Modules')
164
+ end
165
+ end
166
+
167
+ context 'when r10k succeeds' do
168
+ it 'runs r10k puppetfile install and returns the tempdir, honoring force/config/trace/debug opts' do
169
+ repo = build_repo('basic')
170
+ allow(repo).to receive(:r10k_config_file).and_return('/tmp/some-r10k.yaml')
171
+ logger.level = :debug
172
+
173
+ seen_cmd = nil
174
+ allow(deploy).to receive(:system) do |cmd|
175
+ seen_cmd = cmd
176
+ Kernel.system('true')
177
+ true
178
+ end
179
+
180
+ result = deploy.deploy_local(repo, { skip_r10k: false, force: true, trace: true })
181
+
182
+ expect(result).to eq(tempdir)
183
+ expect(seen_cmd).to include('r10k puppetfile install --color')
184
+ expect(seen_cmd).to include('--force')
185
+ expect(seen_cmd).to include('--config /tmp/some-r10k.yaml')
186
+ expect(seen_cmd).to include('--trace')
187
+ expect(seen_cmd).to include('--verbose debug')
188
+
189
+ logger.level = :info
190
+ end
191
+
192
+ it 'passes plain --verbose (not --verbose debug) when the logger is above debug level' do
193
+ repo = build_repo('basic')
194
+ logger.level = :info
195
+
196
+ seen_cmd = nil
197
+ allow(deploy).to receive(:system) do |cmd|
198
+ seen_cmd = cmd
199
+ Kernel.system('true')
200
+ true
201
+ end
202
+
203
+ deploy.deploy_local(repo, { skip_r10k: false })
204
+
205
+ expect(seen_cmd).to match(/--verbose(?! debug)/)
206
+ end
207
+ end
208
+
209
+ context 'when r10k fails' do
210
+ it 'raises an error' do
211
+ repo = build_repo('basic')
212
+
213
+ allow(deploy).to receive(:system) do |_cmd|
214
+ Kernel.system('false')
215
+ false
216
+ end
217
+
218
+ expect { deploy.deploy_local(repo, { skip_r10k: false }) }.to raise_error(
219
+ 'r10k could not install all required modules'
220
+ )
221
+ end
222
+ end
223
+
224
+ context 'when repo.tempdir is nil' do
225
+ it 'creates a fresh tempdir via Dir.mktmpdir' do
226
+ repo = build_repo('minimal', tempdir_override: nil)
227
+
228
+ result = deploy.deploy_local(repo, {})
229
+
230
+ expect(result).not_to be_nil
231
+ expect(File.directory?(result)).to be true
232
+ FileUtils.rm_rf(result)
233
+ end
234
+ end
235
+
236
+ # NOTE: the `else raise "#{repo.tempdir} is not a directory"` branch
237
+ # (deploy.rb, just after `if File.directory?(repo.tempdir)`) is left
238
+ # uncovered. Reaching it legitimately requires repo.tempdir to vanish
239
+ # between the copy step a few lines above and this check, and stubbing
240
+ # File.directory?(repo.tempdir) to force it false also fools FileUtils'
241
+ # own internal use of File.directory? earlier in the method (it calls
242
+ # mkdir_p on a path it now believes doesn't exist, which raises
243
+ # Errno::EEXIST instead of reaching the intended branch). Not worth
244
+ # fighting with a source change out of scope for this test pass.
245
+ end
246
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/group'
3
+ require 'puppetlabs-onceover/class'
4
+ require 'puppetlabs-onceover/node'
5
+ require 'puppetlabs-onceover/testconfig'
6
+ require 'puppetlabs-onceover/controlrepo'
7
+
8
+ describe "PuppetlabsOnceover::Group" do
9
+ before(:each) do
10
+ PuppetlabsOnceover::Class.class_variable_set(:@@all, [])
11
+ PuppetlabsOnceover::Node.class_variable_set(:@@all, [])
12
+ PuppetlabsOnceover::Group.class_variable_set(:@@all, [])
13
+ PuppetlabsOnceover::Test.class_variable_set(:@@all, [])
14
+ logger.level = :fatal
15
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/factsets')
16
+ end
17
+
18
+ describe "#initialize" do
19
+ it "accepts a ready-made list of Class objects as-is" do
20
+ a = PuppetlabsOnceover::Class.new('role::a')
21
+ b = PuppetlabsOnceover::Class.new('role::b')
22
+ group = PuppetlabsOnceover::Group.new('my_classes', [a, b])
23
+ expect(group.name).to eq('my_classes')
24
+ expect(group.members).to eq([a, b])
25
+ end
26
+
27
+ it "accepts a ready-made list of Node objects as-is" do
28
+ a = PuppetlabsOnceover::Node.new('node_a')
29
+ b = PuppetlabsOnceover::Node.new('node_b')
30
+ group = PuppetlabsOnceover::Group.new('my_nodes', [a, b])
31
+ expect(group.members).to eq([a, b])
32
+ end
33
+
34
+ it "defaults to an empty member list when members is nil" do
35
+ group = PuppetlabsOnceover::Group.new('empty_group', nil)
36
+ expect(group.members).to eq([])
37
+ end
38
+
39
+ it "resolves a hash into a subtractive include/exclude list via TestConfig.subtractive_to_list" do
40
+ a = PuppetlabsOnceover::Node.new('node_a')
41
+ b = PuppetlabsOnceover::Node.new('node_b')
42
+ PuppetlabsOnceover::Group.new('all_nodes', [a, b])
43
+ PuppetlabsOnceover::Group.new('excluded', [b])
44
+
45
+ group = PuppetlabsOnceover::Group.new('subtractive', { 'include' => 'all_nodes', 'exclude' => 'excluded' })
46
+ expect(group.members).to eq([a])
47
+ end
48
+
49
+ it "resolves a list of names/groups into member objects, flattening nested groups" do
50
+ a = PuppetlabsOnceover::Node.new('node_a')
51
+ b = PuppetlabsOnceover::Node.new('node_b')
52
+ PuppetlabsOnceover::Group.new('inner', [a])
53
+
54
+ group = PuppetlabsOnceover::Group.new('outer', %w[inner node_b])
55
+ expect(group.members).to eq([a, b])
56
+ end
57
+
58
+ it "raises when a resolved member list mixes classes and nodes" do
59
+ PuppetlabsOnceover::Class.new('role::a')
60
+ PuppetlabsOnceover::Node.new('node_a')
61
+
62
+ expect do
63
+ PuppetlabsOnceover::Group.new('mixed', ['role::a', 'node_a'])
64
+ end.to raise_error(RuntimeError, /must contain either all nodes or all classes/)
65
+ end
66
+
67
+ it "adds itself to .all" do
68
+ group = PuppetlabsOnceover::Group.new('g', nil)
69
+ expect(PuppetlabsOnceover::Group.all).to eq([group])
70
+ end
71
+ end
72
+
73
+ describe ".find" do
74
+ it "finds a group by name" do
75
+ group = PuppetlabsOnceover::Group.new('g', nil)
76
+ expect(PuppetlabsOnceover::Group.find('g')).to eq(group)
77
+ end
78
+
79
+ it "returns nil when no group matches" do
80
+ expect(PuppetlabsOnceover::Group.find('nope')).to be_nil
81
+ end
82
+ end
83
+
84
+ describe ".all" do
85
+ it "returns every group created so far" do
86
+ a = PuppetlabsOnceover::Group.new('a', nil)
87
+ b = PuppetlabsOnceover::Group.new('b', nil)
88
+ expect(PuppetlabsOnceover::Group.all).to eq([a, b])
89
+ end
90
+ end
91
+
92
+ describe ".valid_members?" do
93
+ it "is true for an all-Class list" do
94
+ a = PuppetlabsOnceover::Class.new('role::a')
95
+ expect(PuppetlabsOnceover::Group.valid_members?([a])).to eq(true)
96
+ end
97
+
98
+ it "is true for an all-Node list" do
99
+ a = PuppetlabsOnceover::Node.new('node_a')
100
+ expect(PuppetlabsOnceover::Group.valid_members?([a])).to eq(true)
101
+ end
102
+
103
+ it "is false for a mixed list" do
104
+ a = PuppetlabsOnceover::Class.new('role::a')
105
+ b = PuppetlabsOnceover::Node.new('node_a')
106
+ expect(PuppetlabsOnceover::Group.valid_members?([a, b])).to eq(false)
107
+ end
108
+
109
+ it "is false for an empty list (all? on empty is true for the Class check, so this actually documents current behavior)" do
110
+ expect(PuppetlabsOnceover::Group.valid_members?([])).to eq(true)
111
+ end
112
+
113
+ it "rescues any StandardError raised while checking and returns false" do
114
+ exploding = Object.new
115
+ def exploding.is_a?(*)
116
+ raise StandardError, 'boom'
117
+ end
118
+ expect(PuppetlabsOnceover::Group.valid_members?([exploding])).to eq(false)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/logger'
3
+
4
+ describe PuppetlabsOnceover::Logger do
5
+ let(:includer) do
6
+ Class.new do
7
+ include PuppetlabsOnceover::Logger
8
+ end.new
9
+ end
10
+
11
+ before(:each) do
12
+ $logger = nil
13
+ end
14
+
15
+ after(:each) do
16
+ $logger = nil
17
+ end
18
+
19
+ it 'lazily builds a Logging logger with a stdout appender on first call' do
20
+ logger = includer.logger
21
+ expect(logger).to eq(Logging.logger['Colors'])
22
+ expect(Logging::LNAMES[logger.level]).to eq('INFO')
23
+ end
24
+
25
+ it 'memoizes the logger across calls' do
26
+ first = includer.logger
27
+ second = includer.logger
28
+ expect(first).to equal(second)
29
+ end
30
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+ require 'puppetlabs-onceover/node'
3
+ require 'puppetlabs-onceover/controlrepo'
4
+
5
+ describe "PuppetlabsOnceover::Node" do
6
+ before(:each) do
7
+ PuppetlabsOnceover::Node.class_variable_set(:@@all, [])
8
+ logger.level = :fatal
9
+ end
10
+
11
+ describe "#initialize" do
12
+ context "when the controlrepo's factsets can be found" do
13
+ before(:each) do
14
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/factsets')
15
+ end
16
+
17
+ it "sets the name and a nil beaker_node" do
18
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
19
+ expect(node.name).to eq('centos7_notrusted')
20
+ expect(node.beaker_node).to be_nil
21
+ end
22
+
23
+ it "loads the fact_set from the matching factset file" do
24
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
25
+ expect(node.fact_set).to be_a(Hash)
26
+ expect(node.fact_set['operatingsystem']).to eq('CentOS')
27
+ end
28
+
29
+ it "strips the 'environment' key out of the fact_set via clean_facts" do
30
+ node = PuppetlabsOnceover::Node.new('centos_with_env')
31
+ expect(node.fact_set).not_to have_key('environment')
32
+ end
33
+
34
+ it "finds a top-level 'trusted' hash for trusted_set" do
35
+ node = PuppetlabsOnceover::Node.new('centos7_trusted_extensions_top')
36
+ expect(node.trusted_set).to eq({ 'pp_datacenter' => 'PDX' })
37
+ end
38
+
39
+ it "falls back to a nested trusted.extensions hash for trusted_set when no top-level trusted hash exists" do
40
+ node = PuppetlabsOnceover::Node.new('centos7_trusted_extensions_nested')
41
+ expect(node.trusted_set).to be_a(Hash)
42
+ end
43
+
44
+ it "falls back to an empty hash for trusted_set when neither is present" do
45
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
46
+ expect(node.trusted_set).to eq({})
47
+ end
48
+
49
+ it "falls back to a nested trusted.external hash for trusted_external_set when no top-level trusted_external hash exists" do
50
+ node = PuppetlabsOnceover::Node.new('centos7_trusted_external_nested')
51
+ expect(node.trusted_external_set).to be_a(Hash)
52
+ end
53
+
54
+ it "falls back to an empty hash for trusted_external_set when neither is present" do
55
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
56
+ expect(node.trusted_external_set).to eq({})
57
+ end
58
+
59
+ it "adds itself to .all" do
60
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
61
+ expect(PuppetlabsOnceover::Node.all).to eq([node])
62
+ end
63
+ end
64
+
65
+ context "when no factset matches the given name" do
66
+ before(:each) do
67
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/factsets')
68
+ end
69
+
70
+ # facts_file_index comes back nil, so PuppetlabsOnceover::Controlrepo.facts[nil]
71
+ # raises TypeError -- this is the rescue branch that defaults everything to {}
72
+ it "rescues the TypeError and defaults fact_set/trusted_set/trusted_external_set to {}" do
73
+ node = PuppetlabsOnceover::Node.new('no_such_factset_anywhere')
74
+ expect(node.fact_set).to eq({})
75
+ expect(node.trusted_set).to eq({})
76
+ expect(node.trusted_external_set).to eq({})
77
+ end
78
+ end
79
+ end
80
+
81
+ describe ".find" do
82
+ before(:each) do
83
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/factsets')
84
+ end
85
+
86
+ it "finds a node by name" do
87
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
88
+ expect(PuppetlabsOnceover::Node.find('centos7_notrusted')).to eq(node)
89
+ end
90
+
91
+ it "returns the same node object when passed a Node instance" do
92
+ node = PuppetlabsOnceover::Node.new('centos7_notrusted')
93
+ expect(PuppetlabsOnceover::Node.find(node)).to eq(node)
94
+ end
95
+
96
+ it "returns nil (and warns) when nothing matches" do
97
+ expect(PuppetlabsOnceover::Node.find('nonexistent')).to be_nil
98
+ end
99
+ end
100
+
101
+ describe ".all" do
102
+ before(:each) do
103
+ PuppetlabsOnceover::Controlrepo.new(path: 'spec/fixtures/controlrepos/factsets')
104
+ end
105
+
106
+ it "returns every node created so far" do
107
+ a = PuppetlabsOnceover::Node.new('centos7_notrusted')
108
+ b = PuppetlabsOnceover::Node.new('centos_with_env')
109
+ expect(PuppetlabsOnceover::Node.all).to eq([a, b])
110
+ end
111
+ end
112
+
113
+ describe ".clean_facts" do
114
+ it "deletes the 'environment' key and returns the factset" do
115
+ factset = { 'environment' => 'production', 'foo' => 'bar' }
116
+ expect(PuppetlabsOnceover::Node.clean_facts(factset)).to eq({ 'foo' => 'bar' })
117
+ end
118
+
119
+ it "is a no-op when there is no 'environment' key" do
120
+ factset = { 'foo' => 'bar' }
121
+ expect(PuppetlabsOnceover::Node.clean_facts(factset)).to eq({ 'foo' => 'bar' })
122
+ end
123
+ end
124
+ end