moose-inventory 0.1.0

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +0 -0
  3. data/.gitignore +17 -0
  4. data/.rubocop.yml +793 -0
  5. data/Gemfile +3 -0
  6. data/Guardfile +38 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +31 -0
  9. data/README.md.orig +35 -0
  10. data/Rakefile +1 -0
  11. data/bin/moose_inventory +10 -0
  12. data/config/dotfiles/coveralls.yml +0 -0
  13. data/config/dotfiles/gitignore +17 -0
  14. data/config/dotfiles/rubocop.yml +793 -0
  15. data/lib/moose/inventory/cli/application.rb +30 -0
  16. data/lib/moose/inventory/cli/formatter.rb +92 -0
  17. data/lib/moose/inventory/cli/group.rb +23 -0
  18. data/lib/moose/inventory/cli/group_add.rb +98 -0
  19. data/lib/moose/inventory/cli/group_addchild.rb +21 -0
  20. data/lib/moose/inventory/cli/group_addhost.rb +97 -0
  21. data/lib/moose/inventory/cli/group_addvar.rb +72 -0
  22. data/lib/moose/inventory/cli/group_get.rb +52 -0
  23. data/lib/moose/inventory/cli/group_list.rb +41 -0
  24. data/lib/moose/inventory/cli/group_rm.rb +77 -0
  25. data/lib/moose/inventory/cli/group_rmchild.rb +20 -0
  26. data/lib/moose/inventory/cli/group_rmhost.rb +89 -0
  27. data/lib/moose/inventory/cli/group_rmvar.rb +65 -0
  28. data/lib/moose/inventory/cli/host.rb +24 -0
  29. data/lib/moose/inventory/cli/host_add.rb +93 -0
  30. data/lib/moose/inventory/cli/host_addgroup.rb +88 -0
  31. data/lib/moose/inventory/cli/host_addvar.rb +76 -0
  32. data/lib/moose/inventory/cli/host_get.rb +59 -0
  33. data/lib/moose/inventory/cli/host_list.rb +40 -0
  34. data/lib/moose/inventory/cli/host_rm.rb +62 -0
  35. data/lib/moose/inventory/cli/host_rmgroup.rb +80 -0
  36. data/lib/moose/inventory/cli/host_rmvar.rb +69 -0
  37. data/lib/moose/inventory/config/config.rb +169 -0
  38. data/lib/moose/inventory/db/db.rb +249 -0
  39. data/lib/moose/inventory/db/exceptions.rb +14 -0
  40. data/lib/moose/inventory/db/models.rb +32 -0
  41. data/lib/moose/inventory/moose_inventory_cli.rb +25 -0
  42. data/lib/moose/inventory/version.rb +7 -0
  43. data/moose-inventory.gemspec +45 -0
  44. data/scripts/guard_quality.sh +3 -0
  45. data/scripts/guard_test.sh +2 -0
  46. data/scripts/reports.sh +4 -0
  47. data/spec/config/config.yml +12 -0
  48. data/spec/lib/moose/inventory/cli/application_spec.rb +15 -0
  49. data/spec/lib/moose/inventory/cli/cli_spec.rb +26 -0
  50. data/spec/lib/moose/inventory/cli/formatter_spec.rb +63 -0
  51. data/spec/lib/moose/inventory/cli/group_add_spec.rb +398 -0
  52. data/spec/lib/moose/inventory/cli/group_addhost_spec.rb +251 -0
  53. data/spec/lib/moose/inventory/cli/group_addvar_spec.rb +235 -0
  54. data/spec/lib/moose/inventory/cli/group_get_spec.rb +107 -0
  55. data/spec/lib/moose/inventory/cli/group_list_spec.rb +79 -0
  56. data/spec/lib/moose/inventory/cli/group_rm_spec.rb +191 -0
  57. data/spec/lib/moose/inventory/cli/group_rmhost_spec.rb +215 -0
  58. data/spec/lib/moose/inventory/cli/group_rmvar_spec.rb +202 -0
  59. data/spec/lib/moose/inventory/cli/group_spec.rb +15 -0
  60. data/spec/lib/moose/inventory/cli/host_add_spec.rb +330 -0
  61. data/spec/lib/moose/inventory/cli/host_addgroup_spec.rb +248 -0
  62. data/spec/lib/moose/inventory/cli/host_addvar_spec.rb +233 -0
  63. data/spec/lib/moose/inventory/cli/host_get_spec.rb +106 -0
  64. data/spec/lib/moose/inventory/cli/host_list_spec.rb +83 -0
  65. data/spec/lib/moose/inventory/cli/host_rm_spec.rb +132 -0
  66. data/spec/lib/moose/inventory/cli/host_rmgroup_spec.rb +245 -0
  67. data/spec/lib/moose/inventory/cli/host_rmvar_spec.rb +206 -0
  68. data/spec/lib/moose/inventory/cli/host_spec.rb +12 -0
  69. data/spec/lib/moose/inventory/config/config_spec.rb +80 -0
  70. data/spec/lib/moose/inventory/db/db_spec.rb +184 -0
  71. data/spec/lib/moose/inventory/db/models_spec.rb +150 -0
  72. data/spec/shared/shared_config_setup.rb +21 -0
  73. data/spec/spec_helper.rb +110 -0
  74. metadata +386 -0
@@ -0,0 +1,202 @@
1
+ require 'spec_helper'
2
+
3
+ # TODO: the usual respond_to? method doesn't seem to work on Thor objects.
4
+ # Why not? For now, we'll check against instance_methods.
5
+
6
+ RSpec.describe Moose::Inventory::Cli::Group do
7
+ before(:all) do
8
+ # Set up the configuration object
9
+ @mockarg_parts = {
10
+ config: File.join(spec_root, 'config/config.yml'),
11
+ format: 'yaml',
12
+ env: 'test'
13
+ }
14
+
15
+ @mockargs = []
16
+ @mockarg_parts.each do |key, val|
17
+ @mockargs << "--#{key}"
18
+ @mockargs << val
19
+ end
20
+
21
+ @config = Moose::Inventory::Config
22
+ @config.init(@mockargs)
23
+
24
+ @db = Moose::Inventory::DB
25
+ @db.init if @db.db.nil?
26
+
27
+ @console = Moose::Inventory::Cli::Formatter
28
+ @group = Moose::Inventory::Cli::Group
29
+ @app = Moose::Inventory::Cli::Application
30
+ end
31
+
32
+ before(:each) do
33
+ @db.reset
34
+ end
35
+
36
+ describe 'rmvar' do
37
+ it 'should be responsive' do
38
+ result = @group.instance_methods(false).include?(:rmvar)
39
+ expect(result).to eq(true)
40
+ end
41
+
42
+ #-----------------
43
+ it '<missing args> ... should abort with an error' do
44
+ actual = runner do
45
+ @app.start(%w(group rmvar))
46
+ end
47
+
48
+ # Check output
49
+ desired = { aborted: true}
50
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 2 or more.\n"
51
+ expected(actual, desired)
52
+ end
53
+
54
+ #------------------------
55
+ it 'GROUP key=value ... should abort if the group does not exist' do
56
+ group_name = "does-not-exist"
57
+ var_name = "foo=bar"
58
+ actual = runner do
59
+ @app.start(%W(group rmvar #{group_name} #{var_name}))
60
+ end
61
+
62
+ # Check output
63
+ desired = { aborted: true}
64
+ desired[:STDOUT] =
65
+ "Remove variable(s) '#{var_name}' from group '#{group_name}':\n"\
66
+ " - retrieve group '#{group_name}'...\n"
67
+ desired[:STDERR] =
68
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
69
+ "ERROR: The group '#{group_name}' does not exist.\n"
70
+ expected(actual, desired)
71
+ end
72
+
73
+ #------------------------
74
+ it '<malformed> ... should abort with an error' do
75
+ # 1. Should add the var to the db
76
+ # 2. Should associate the host with the var
77
+
78
+ group_name = 'test1'
79
+ @db.models[:group].create(name: group_name)
80
+
81
+ var = {name: 'foo', value: "bar"}
82
+ cases = %W(
83
+ =bar
84
+ foo=bar=
85
+ =foo=bar
86
+ foo=bar=extra
87
+ )
88
+
89
+ cases.each do |args|
90
+ actual = runner do
91
+ @app.start(%W(group rmvar #{group_name} #{args} ))
92
+ end
93
+ #@console.out(actual,'p')
94
+
95
+ desired = { aborted: true}
96
+ desired[:STDOUT] =
97
+ "Remove variable(s) '#{args}' from group '#{group_name}':\n"\
98
+ " - retrieve group '#{group_name}'...\n"\
99
+ " - OK\n"\
100
+ " - remove variable '#{args}'...\n"
101
+ desired[:STDERR] =
102
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
103
+ "ERROR: Incorrect format in {#{args}}. Expected 'key' or 'key=value'.\n"
104
+
105
+ expected(actual, desired)
106
+ end
107
+ end
108
+
109
+ #------------------------
110
+ it 'GROUP <valid args> ... should remove the group variable' do
111
+ group_name = 'group_test'
112
+ var = {name: 'foo', value: "bar"}
113
+ cases = %W(
114
+ #{var[:name]}
115
+ #{var[:name]}=
116
+ #{var[:name]}=#{var[:value]}
117
+ )
118
+ cases.each do |example|
119
+ # reset the db
120
+ @db.reset
121
+
122
+ # Add an initial group and groupvar
123
+ @db.models[:group].create(name: group_name)
124
+ runner do
125
+ @app.start(%W(group addvar #{group_name} #{var[:name]}=#{var[:value]} ))
126
+ end
127
+
128
+ # Try to remove the groupvar using the case example valid args
129
+ actual = runner do
130
+ @app.start(%W(group rmvar #{group_name} #{example}))
131
+ end
132
+ #@console.out(actual,'p')
133
+
134
+ # Check the output
135
+ desired = { aborted: false}
136
+ desired[:STDOUT] =
137
+ "Remove variable(s) '#{example}' from group '#{group_name}':\n"\
138
+ " - retrieve group '#{group_name}'...\n"\
139
+ " - OK\n"\
140
+ " - remove variable '#{example}'...\n"\
141
+ " - OK\n"\
142
+ " - all OK\n"\
143
+ "Succeeded.\n"
144
+
145
+ #@console.out(desired,'p')
146
+ expected(actual, desired)
147
+
148
+ # Check the db
149
+ group = @db.models[:group].find(name: group_name)
150
+ groupvars = group.groupvars_dataset
151
+ expect(groupvars.count).to eq(0)
152
+
153
+ groupvars = @db.models[:groupvar].all
154
+ expect(groupvars.count).to eq(0)
155
+ end
156
+ end
157
+
158
+ #------------------------
159
+ it 'GROUP key1=value1 key2=value2 ... should remove multiple key/value pairs' do
160
+ group_name = 'test_group'
161
+ varsarray = [
162
+ {name: 'var1', value: "val1"},
163
+ {name: 'var2', value: "val2"}
164
+ ]
165
+
166
+ vars = []
167
+ varsarray.each do |var|
168
+ vars << "#{var[:name]}=#{var[:value]}"
169
+ end
170
+
171
+ @db.models[:group].create(name: group_name)
172
+ actual = runner do
173
+ @app.start(%W(group addvar #{group_name}) + vars )
174
+ end
175
+
176
+ actual = runner do
177
+ @app.start(%W(group rmvar #{group_name}) + vars )
178
+ end
179
+ #@console.out(actual,'y')
180
+
181
+ desired = { aborted: false}
182
+ desired[:STDOUT] =
183
+ "Remove variable(s) '#{vars.join(',')}' from group '#{group_name}':\n"\
184
+ " - retrieve group '#{group_name}'...\n"\
185
+ " - OK\n"
186
+ vars.each do |var|
187
+ desired[:STDOUT] = desired[:STDOUT] +
188
+ " - remove variable '#{var}'...\n"\
189
+ " - OK\n"
190
+ end
191
+ desired[:STDOUT] = desired[:STDOUT] +
192
+ " - all OK\n"\
193
+ "Succeeded.\n"
194
+ expected(actual, desired)
195
+
196
+ # We should have the correct hostvar associations
197
+ group = @db.models[:group].find(name: group_name)
198
+ groupvars = group.groupvars_dataset
199
+ expect(groupvars.count).to eq(0)
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ require_relative 'group_add_spec'
4
+ #require_relative 'group_get_spec'
5
+ #require_relative 'group_list_spec'
6
+ #require_relative 'group_rm_spec'
7
+ #
8
+ #require_relative 'group_addchild_spec'
9
+ #require_relative 'grpi_rmchild_spec'
10
+ #
11
+ #require_relative 'group_addhost_spec'
12
+ #require_relative 'group_rmhost_spec'
13
+ #
14
+ #require_relative 'group_addvar_spec'
15
+ #require_relative 'group_rmvar_spec'
@@ -0,0 +1,330 @@
1
+ require 'spec_helper'
2
+
3
+ # TODO: the usual respond_to? method doesn't seem to work on Thor objects.
4
+ # Why not? For now, we'll check against instance_methods.
5
+
6
+ RSpec.describe Moose::Inventory::Cli::Host do
7
+ before(:all) do
8
+ # Set up the configuration object
9
+ @mockarg_parts = {
10
+ config: File.join(spec_root, 'config/config.yml'),
11
+ format: 'yaml',
12
+ env: 'test'
13
+ }
14
+
15
+ @mockargs = []
16
+ @mockarg_parts.each do |key, val|
17
+ @mockargs << "--#{key}"
18
+ @mockargs << val
19
+ end
20
+
21
+ @console = Moose::Inventory::Cli::Formatter
22
+ @config = Moose::Inventory::Config
23
+ @config.init(@mockargs)
24
+
25
+ @db = Moose::Inventory::DB
26
+ @db.init if @db.db.nil?
27
+
28
+ @host = Moose::Inventory::Cli::Host
29
+ @app = Moose::Inventory::Cli::Application
30
+ end
31
+
32
+ before(:each) do
33
+ @db.reset
34
+ end
35
+
36
+ # ============================
37
+ describe 'add' do
38
+ # --------------------
39
+ it 'Host.add() method should be responsive' do
40
+ result = @host.instance_methods(false).include?(:add)
41
+ expect(result).to eq(true)
42
+ end
43
+
44
+ # --------------------
45
+ it '<no arguments> ... should bail with an error' do
46
+ actual = runner { @app.start(%w(host add)) }
47
+
48
+ desired = { aborted: true}
49
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 1 or more.\n"
50
+ expected(actual, desired)
51
+ end
52
+
53
+ # --------------------
54
+ it 'HOST ... should add a host to the db' do
55
+ name = 'test-host-add'
56
+
57
+ actual = runner { @app.start(%W(host add #{name})) }
58
+ #@console.out(actual,'y')
59
+
60
+ # Check output
61
+ desired = {}
62
+ desired[:STDOUT] =
63
+ "Add host '#{name}':\n"\
64
+ " - Creating host '#{name}'...\n"\
65
+ " - OK\n"\
66
+ " - Adding automatic association {host:#{name} <-> group:ungrouped}...\n"\
67
+ " - OK\n"\
68
+ " - All OK\n"\
69
+ "Succeeded\n"
70
+
71
+ expected(actual, desired)
72
+
73
+ # Check db
74
+ host = @db.models[:host].find(name: name)
75
+ expect(host[:name]).to eq(name)
76
+
77
+ groups = host.groups_dataset
78
+ expect(groups.count).to eq(1)
79
+ expect(groups[name: 'ungrouped']).not_to be_nil
80
+ end
81
+
82
+ # --------------------
83
+ it 'HOST ... should skip HOST creation if HOST already exists' do
84
+ name = 'test-host-add'
85
+ runner { @app.start(%W(host add #{name})) }
86
+
87
+ actual = runner { @app.start(%W(host add #{name})) }
88
+
89
+ # Check output
90
+ desired = {}
91
+ desired[:STDOUT] =
92
+ "Add host '#{name}':\n"\
93
+ " - Creating host '#{name}'...\n"\
94
+ " - OK\n"\
95
+ " - All OK\n"\
96
+ "Succeeded\n"
97
+
98
+ desired[:STDERR] =
99
+ "WARNING: The host '#{name}' already exists, skipping creation.\n"
100
+
101
+ expected(actual, desired)
102
+ end
103
+
104
+ # --------------------
105
+ it 'HOST1 HOST2 HOST3 ... should add multiple hosts' do
106
+ names = %w(test1 test2 test3)
107
+
108
+ actual = runner { @app.start(%w(host add) + names) }
109
+
110
+ # Check output
111
+ desired = {STDOUT: ''}
112
+ names.each do |name|
113
+ desired[:STDOUT] = desired[:STDOUT] +
114
+ "Add host '#{name}':\n"\
115
+ " - Creating host '#{name}'...\n"\
116
+ " - OK\n"\
117
+ " - Adding automatic association {host:#{name} <-> group:ungrouped}...\n"\
118
+ " - OK\n"\
119
+ " - All OK\n"
120
+ end
121
+ desired[:STDOUT] = desired[:STDOUT] + "Succeeded\n"
122
+
123
+ expected(actual, desired)
124
+
125
+ # Check db
126
+ names.each do |name|
127
+ host = @db.models[:host].find(name: name)
128
+ expect(host[:name]).to eq(name)
129
+
130
+ groups = host.groups_dataset
131
+ expect(groups.count).to eq(1)
132
+ expect(groups[name: 'ungrouped']).not_to be_nil
133
+ end
134
+ end
135
+
136
+ # --------------------
137
+ it 'HOST1 --groups GROUP ... should add the '\
138
+ 'host and associate it with an existing group' do
139
+ group_name = 'testgroup'
140
+ @db.models[:group].create(name: group_name)
141
+
142
+ name = 'testhost'
143
+ actual = runner do
144
+ @app.start(%W(host add #{name} --groups #{group_name}))
145
+ end
146
+
147
+ # Check output
148
+ desired = {}
149
+ desired[:STDOUT] =
150
+ "Add host '#{name}':\n"\
151
+ " - Creating host '#{name}'...\n"\
152
+ " - OK\n"\
153
+ " - Adding association {host:#{name} <-> group:#{group_name}}...\n"\
154
+ " - OK\n"\
155
+ " - All OK\n"\
156
+ "Succeeded\n"
157
+
158
+ expected(actual, desired)
159
+
160
+ # Check db
161
+ host = @db.models[:host].find(name: name)
162
+ groups = host.groups_dataset
163
+ expect(groups).not_to be_nil
164
+ expect(groups.count).to eq(1)
165
+ expect(groups[name: group_name]).not_to be_nil # i.e. not 'ungrouped'
166
+ end
167
+
168
+ # --------------------
169
+ it 'HOST1 --groups GROUP ... should add the host and associate '\
170
+ ' it with a non-existent group, creating the group' do
171
+ group_name = 'testgroup'
172
+
173
+ # DON'T MANUALLY CREATE THE GROUP! That's the point of the test.
174
+
175
+ name = 'testhost'
176
+ actual = runner do
177
+ @app.start(%W(host add #{name} --groups #{group_name}))
178
+ end
179
+
180
+ # Check output
181
+ desired = {}
182
+ desired[:STDOUT] =
183
+ "Add host '#{name}':\n"\
184
+ " - Creating host '#{name}'...\n"\
185
+ " - OK\n"\
186
+ " - Adding association {host:#{name} <-> group:#{group_name}}...\n"\
187
+ " - OK\n"\
188
+ " - All OK\n"\
189
+ "Succeeded\n"
190
+ desired[:STDERR] =
191
+ "WARNING: The group '#{group_name}' doesn't exist, but will be created.\n"
192
+
193
+ expected(actual, desired)
194
+
195
+ # Check db
196
+ host = @db.models[:host].find(name: name)
197
+ groups = host.groups_dataset
198
+ expect(groups).not_to be_nil
199
+ expect(groups.count).to eq(1)
200
+ expect(groups[name: group_name]).not_to be_nil # i.e. not 'ungrouped'
201
+ end
202
+
203
+ # --------------------
204
+ it 'HOST1 --groups ungrouped ... should abort with an error' do
205
+ name = 'testhost'
206
+ actual = runner do
207
+ @app.start(%W(host add #{name} --groups ungrouped))
208
+ end
209
+
210
+ # Check output
211
+ desired = { aborted: true}
212
+ desired[:STDERR] =
213
+ "ERROR: Cannot manually manipulate the automatic group 'ungrouped'.\n"
214
+ expected(actual, desired)
215
+
216
+ # Check db
217
+ host = @db.models[:host].find(name: name)
218
+ expect(host).to be_nil
219
+ end
220
+
221
+ # --------------------
222
+ it 'HOST --groups GROUP1,GROUP2 ... should add the host and '\
223
+ 'associate it with multiple groups' do
224
+ group_names = %w(group1 group2 group3)
225
+
226
+ name = 'testhost'
227
+ actual = runner do
228
+ @app.start(%W(host add #{name} --groups #{group_names.join(',')}))
229
+ end
230
+
231
+ #@console.out(actual,'y')
232
+
233
+ # Check output
234
+ desired = {STDOUT: '', STDERR: ''}
235
+ desired[:STDOUT] =
236
+ "Add host '#{name}':\n"\
237
+ " - Creating host '#{name}'...\n"\
238
+ " - OK\n"\
239
+
240
+ group_names.each do |group|
241
+ desired[:STDOUT] = desired[:STDOUT] +
242
+ " - Adding association {host:#{name} <-> group:#{group}}...\n"\
243
+ " - OK\n"
244
+ desired[:STDERR] = desired[:STDERR] +
245
+ "WARNING: The group '#{group}' doesn't exist, but will be created.\n"
246
+ end
247
+ desired[:STDOUT] = desired[:STDOUT] +
248
+ " - All OK\n"\
249
+ "Succeeded\n"
250
+
251
+ expected(actual, desired)
252
+
253
+ # Check db
254
+ host = @db.models[:host].find(name: name)
255
+ groups = host.groups_dataset
256
+ expect(groups.count).to eq(group_names.count)
257
+ expect(groups[name: 'ungrouped']).to be_nil # i.e. not 'ungrouped'
258
+ group_names.each do |group|
259
+ expect(groups[name: group]).not_to be_nil
260
+ end
261
+ end
262
+
263
+ it 'HOST --groups GROUP1,ungrouped ... should bail '\
264
+ 'with an error' do
265
+ name = 'testhost'
266
+ group_names = %w(group1 ungrouped)
267
+
268
+ actual = runner do
269
+ @app.start(%W(host add #{name} --groups #{group_names.join(',')}))
270
+ end
271
+
272
+ # Check output
273
+ desired = { aborted: true}
274
+ desired[:STDERR] =
275
+ "ERROR: Cannot manually manipulate the automatic group 'ungrouped'.\n"
276
+
277
+ expected(actual, desired)
278
+ end
279
+
280
+ it 'HOST1 HOST2 --groups GROUP1,GROUP2 ... should add multiple '\
281
+ 'hosts, associating each with multiple groups' do
282
+ #
283
+ group_names = %w(group1 group2 group3)
284
+ # Note, relies on auto-generation of groups
285
+
286
+ names = %w(host1 host2 host3)
287
+ actual = runner do
288
+ @app.start(%w(host add) + names + %W(--groups #{group_names.join(',')}))
289
+ end
290
+
291
+ # Check output
292
+ desired = { aborted: false, STDERR: '', STDOUT: '' }
293
+ names.each do |name|
294
+ desired[:STDOUT] = desired[:STDOUT] +
295
+ "Add host '#{name}':\n"\
296
+ " - Creating host '#{name}'...\n"\
297
+ " - OK\n"
298
+ group_names.each do |group|
299
+ desired[:STDOUT] = desired[:STDOUT] +
300
+ " - Adding association {host:#{name} <-> group:#{group}}...\n"\
301
+ " - OK\n"
302
+ end
303
+ desired[:STDOUT] = desired[:STDOUT] +
304
+ " - All OK\n"
305
+ end
306
+
307
+ group_names.each do |group|
308
+ desired[:STDERR] = desired[:STDERR] +
309
+ "WARNING: The group '#{group}' doesn't exist, but will be created.\n"
310
+ end
311
+ desired[:STDOUT] = desired[:STDOUT] + "Succeeded\n"
312
+
313
+ #@console.out(desired,'y')
314
+
315
+ expected(actual, desired)
316
+
317
+ # Check db
318
+ names.each do |name|
319
+ host = @db.models[:host].find(name: name)
320
+ expect(host).not_to be_nil
321
+ groups = host.groups_dataset
322
+ expect(groups.count).to eq(group_names.count)
323
+ expect(groups[name: 'ungrouped']).to be_nil # i.e. not 'ungrouped'
324
+ group_names.each do |group|
325
+ expect(groups[name: group]).not_to be_nil
326
+ end
327
+ end
328
+ end
329
+ end
330
+ end