moose-inventory 0.1.0

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