puppet 0.13.6 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (149) hide show
  1. data/CHANGELOG +57 -0
  2. data/Rakefile +38 -410
  3. data/bin/puppet +14 -12
  4. data/bin/puppetca +1 -3
  5. data/bin/puppetd +25 -7
  6. data/bin/puppetdoc +161 -104
  7. data/bin/puppetmasterd +4 -4
  8. data/conf/epm.list +8 -0
  9. data/conf/redhat/client.init +6 -1
  10. data/conf/redhat/no-chuser-0.15.1.patch +38 -0
  11. data/conf/redhat/puppet.spec +20 -5
  12. data/conf/redhat/puppetd.conf +1 -1
  13. data/conf/redhat/puppetmasterd.conf +1 -1
  14. data/conf/redhat/server.init +2 -4
  15. data/examples/code/snippets/{casestatement → casestatement.pp} +12 -1
  16. data/examples/code/snippets/selectorvalues.pp +15 -0
  17. data/examples/code/snippets/singleselector.pp +22 -0
  18. data/examples/code/snippets/tag.pp +9 -0
  19. data/ext/module_puppet +1 -1
  20. data/install.rb +303 -303
  21. data/lib/puppet.rb +7 -9
  22. data/lib/puppet/client.rb +18 -5
  23. data/lib/puppet/client/dipper.rb +12 -10
  24. data/lib/puppet/client/master.rb +113 -41
  25. data/lib/puppet/client/pelement.rb +20 -0
  26. data/lib/puppet/config.rb +113 -6
  27. data/lib/puppet/element.rb +1 -3
  28. data/lib/puppet/event.rb +12 -23
  29. data/lib/puppet/filetype.rb +93 -5
  30. data/lib/puppet/inifile.rb +201 -0
  31. data/lib/puppet/log.rb +18 -6
  32. data/lib/puppet/parameter.rb +80 -29
  33. data/lib/puppet/parser/ast.rb +6 -4
  34. data/lib/puppet/parser/ast/caseopt.rb +13 -4
  35. data/lib/puppet/parser/ast/casestatement.rb +2 -2
  36. data/lib/puppet/parser/ast/component.rb +4 -14
  37. data/lib/puppet/parser/ast/hostclass.rb +1 -1
  38. data/lib/puppet/parser/ast/leaf.rb +12 -0
  39. data/lib/puppet/parser/ast/node.rb +4 -4
  40. data/lib/puppet/parser/ast/objectdef.rb +5 -51
  41. data/lib/puppet/parser/ast/selector.rb +2 -0
  42. data/lib/puppet/parser/ast/tag.rb +26 -0
  43. data/lib/puppet/parser/interpreter.rb +89 -74
  44. data/lib/puppet/parser/lexer.rb +4 -3
  45. data/lib/puppet/parser/parser.rb +440 -378
  46. data/lib/puppet/parser/scope.rb +844 -887
  47. data/lib/puppet/server.rb +12 -1
  48. data/lib/puppet/server/authconfig.rb +166 -0
  49. data/lib/puppet/server/authstore.rb +8 -6
  50. data/lib/puppet/server/ca.rb +23 -26
  51. data/lib/puppet/server/filebucket.rb +24 -23
  52. data/lib/puppet/server/fileserver.rb +116 -47
  53. data/lib/puppet/server/master.rb +58 -19
  54. data/lib/puppet/server/pelement.rb +176 -0
  55. data/lib/puppet/server/rights.rb +78 -0
  56. data/lib/puppet/server/servlet.rb +19 -6
  57. data/lib/puppet/sslcertificates.rb +4 -2
  58. data/lib/puppet/sslcertificates/ca.rb +66 -34
  59. data/lib/puppet/storage.rb +20 -26
  60. data/lib/puppet/transaction.rb +49 -92
  61. data/lib/puppet/type.rb +142 -35
  62. data/lib/puppet/type/cron.rb +29 -14
  63. data/lib/puppet/type/exec.rb +92 -35
  64. data/lib/puppet/type/group.rb +29 -11
  65. data/lib/puppet/type/nameservice.rb +50 -1
  66. data/lib/puppet/type/nameservice/netinfo.rb +68 -1
  67. data/lib/puppet/type/nameservice/objectadd.rb +1 -0
  68. data/lib/puppet/type/package.rb +150 -109
  69. data/lib/puppet/type/package/apple.rb +27 -0
  70. data/lib/puppet/type/package/apt.rb +1 -0
  71. data/lib/puppet/type/package/darwinport.rb +97 -0
  72. data/lib/puppet/type/package/dpkg.rb +10 -2
  73. data/lib/puppet/type/package/freebsd.rb +19 -0
  74. data/lib/puppet/type/package/{bsd.rb → openbsd.rb} +36 -7
  75. data/lib/puppet/type/package/ports.rb +98 -0
  76. data/lib/puppet/type/package/rpm.rb +43 -7
  77. data/lib/puppet/type/package/sun.rb +53 -36
  78. data/lib/puppet/type/package/yum.rb +5 -16
  79. data/lib/puppet/type/parsedtype.rb +41 -29
  80. data/lib/puppet/type/parsedtype/host.rb +13 -5
  81. data/lib/puppet/type/parsedtype/mount.rb +250 -0
  82. data/lib/puppet/type/parsedtype/port.rb +8 -6
  83. data/lib/puppet/type/pfile.rb +284 -30
  84. data/lib/puppet/type/pfile/checksum.rb +96 -68
  85. data/lib/puppet/type/pfile/content.rb +16 -13
  86. data/lib/puppet/type/pfile/ensure.rb +64 -126
  87. data/lib/puppet/type/pfile/group.rb +12 -5
  88. data/lib/puppet/type/pfile/mode.rb +16 -4
  89. data/lib/puppet/type/pfile/source.rb +47 -73
  90. data/lib/puppet/type/pfile/target.rb +81 -0
  91. data/lib/puppet/type/pfile/uid.rb +10 -3
  92. data/lib/puppet/type/pfilebucket.rb +12 -3
  93. data/lib/puppet/type/schedule.rb +5 -1
  94. data/lib/puppet/type/service.rb +138 -66
  95. data/lib/puppet/type/service/debian.rb +9 -3
  96. data/lib/puppet/type/service/init.rb +51 -56
  97. data/lib/puppet/type/service/smf.rb +16 -6
  98. data/lib/puppet/type/state.rb +71 -32
  99. data/lib/puppet/type/symlink.rb +12 -7
  100. data/lib/puppet/type/tidy.rb +5 -1
  101. data/lib/puppet/type/user.rb +116 -20
  102. data/lib/puppet/type/yumrepo.rb +314 -0
  103. data/lib/puppet/util.rb +84 -14
  104. data/test/client/client.rb +41 -18
  105. data/test/client/master.rb +50 -4
  106. data/test/executables/puppetbin.rb +31 -4
  107. data/test/executables/puppetca.rb +18 -2
  108. data/test/language/ast.rb +201 -31
  109. data/test/language/interpreter.rb +8 -2
  110. data/test/{parser → language}/lexer.rb +1 -1
  111. data/test/language/node.rb +84 -0
  112. data/test/{parser → language}/parser.rb +1 -1
  113. data/test/language/scope.rb +101 -2
  114. data/test/language/snippets.rb +23 -2
  115. data/test/other/config.rb +99 -1
  116. data/test/other/filetype.rb +95 -0
  117. data/test/other/inifile.rb +114 -0
  118. data/test/other/log.rb +3 -2
  119. data/test/other/transactions.rb +55 -10
  120. data/test/puppet/utiltest.rb +25 -1
  121. data/test/puppettest.rb +140 -46
  122. data/test/server/authconfig.rb +56 -0
  123. data/test/server/bucket.rb +32 -18
  124. data/test/server/fileserver.rb +75 -30
  125. data/test/server/master.rb +27 -4
  126. data/test/server/pelement.rb +298 -0
  127. data/test/server/rights.rb +41 -0
  128. data/test/server/server.rb +2 -2
  129. data/test/tagging/tagging.rb +100 -1
  130. data/test/types/basic.rb +3 -3
  131. data/test/types/cron.rb +24 -1
  132. data/test/types/exec.rb +99 -1
  133. data/test/types/file.rb +298 -2
  134. data/test/types/filebucket.rb +4 -15
  135. data/test/types/filesources.rb +43 -14
  136. data/test/types/group.rb +1 -13
  137. data/test/types/mount.rb +277 -0
  138. data/test/types/package.rb +164 -33
  139. data/test/types/parameter.rb +107 -0
  140. data/test/types/port.rb +2 -1
  141. data/test/types/service.rb +37 -2
  142. data/test/types/state.rb +92 -0
  143. data/test/types/symlink.rb +30 -2
  144. data/test/types/tidy.rb +2 -14
  145. data/test/types/type.rb +35 -1
  146. data/test/types/user.rb +110 -1
  147. data/test/types/yumrepo.rb +95 -0
  148. metadata +316 -290
  149. data/test/types/filetype.rb +0 -160
@@ -0,0 +1,107 @@
1
+ if __FILE__ == $0
2
+ $:.unshift '..'
3
+ $:.unshift '../../lib'
4
+ $puppetbase = "../.."
5
+ end
6
+
7
+ require 'puppet/type'
8
+ require 'puppettest'
9
+ require 'test/unit'
10
+
11
+ class TestParameter < Test::Unit::TestCase
12
+ include TestPuppet
13
+
14
+ def newparam(name = :fakeparam)
15
+ assert_nothing_raised {
16
+ param = Class.new(Puppet::Parameter) do
17
+ @name = :fakeparam
18
+ end
19
+ param.initvars
20
+
21
+ return param
22
+ }
23
+ end
24
+
25
+ def newinst(param)
26
+ assert_nothing_raised {
27
+ return param.new
28
+ }
29
+ end
30
+
31
+ # Test the basic newvalue stuff.
32
+ def test_newvalue
33
+ param = newparam()
34
+
35
+ # Try it with both symbols and strings.
36
+ assert_nothing_raised {
37
+ param.newvalues(:one, "two")
38
+ }
39
+
40
+ inst = newinst(param)
41
+
42
+ assert_nothing_raised {
43
+ inst.value = "one"
44
+ }
45
+
46
+ assert_equal(:one, inst.value)
47
+
48
+ assert_nothing_raised {
49
+ inst.value = :two
50
+ }
51
+ assert_equal(:two, inst.value)
52
+
53
+ assert_raise(ArgumentError) {
54
+ inst.value = :three
55
+ }
56
+ assert_equal(:two, inst.value)
57
+ end
58
+
59
+ # Test using regexes.
60
+ def test_regexvalues
61
+ param = newparam
62
+
63
+ assert_nothing_raised {
64
+ param.newvalues(/^\d+$/)
65
+ }
66
+ assert(param.match?("14"))
67
+ assert(param.match?(14))
68
+
69
+ inst = newinst(param)
70
+
71
+ assert_nothing_raised {
72
+ inst.value = 14
73
+ }
74
+
75
+ assert_nothing_raised {
76
+ inst.value = "14"
77
+ }
78
+
79
+ assert_raise(ArgumentError) {
80
+ inst.value = "a14"
81
+ }
82
+ end
83
+
84
+ # Test using both. Equality should beat matching.
85
+ def test_regexesandnormals
86
+ param = newparam
87
+
88
+ assert_nothing_raised {
89
+ param.newvalues(:one, /^\w+$/)
90
+ }
91
+
92
+ inst = newinst(param)
93
+
94
+ assert_nothing_raised {
95
+ inst.value = "one"
96
+ }
97
+
98
+ assert_equal(:one, inst.value, "Value used regex instead of equality")
99
+
100
+ assert_nothing_raised {
101
+ inst.value = "two"
102
+ }
103
+ assert_equal("two", inst.value, "Matched value didn't take")
104
+ end
105
+ end
106
+
107
+ # $Id: parameter.rb 1000 2006-03-10 05:41:01Z luke $
@@ -182,6 +182,7 @@ class TestPort < Test::Unit::TestCase
182
182
  port.delete(:alias)
183
183
  assert(! port.state(:alias))
184
184
  assert_events([:port_changed], port)
185
+
185
186
  assert_nothing_raised {
186
187
  port.retrieve
187
188
  }
@@ -197,4 +198,4 @@ class TestPort < Test::Unit::TestCase
197
198
  end
198
199
  end
199
200
 
200
- # $Id: port.rb 915 2006-02-15 21:56:54Z luke $
201
+ # $Id: port.rb 1050 2006-04-01 20:31:47Z luke $
@@ -236,7 +236,6 @@ class TestLocalService < Test::Unit::TestCase
236
236
  else
237
237
  def test_servicestartstop
238
238
  mktestsvcs.each { |svc|
239
- svc[:check] = :enable
240
239
  startstate = nil
241
240
  assert_nothing_raised("Could not get status") {
242
241
  startstate = svc.status
@@ -253,6 +252,7 @@ class TestLocalService < Test::Unit::TestCase
253
252
  def test_serviceenabledisable
254
253
  mktestsvcs.each { |svc|
255
254
  startstate = nil
255
+ svc[:check] = :enable
256
256
  assert_nothing_raised("Could not get status") {
257
257
  startstate = svc.enabled?
258
258
  }
@@ -264,8 +264,43 @@ class TestLocalService < Test::Unit::TestCase
264
264
  Puppet.type(:component).clear
265
265
  }
266
266
  end
267
+
268
+ def test_serviceenableandrun
269
+ mktestsvcs.each do |svc|
270
+ startenable = nil
271
+ startensure = nil
272
+ svc[:check] = [:ensure, :enable]
273
+ svc.retrieve
274
+ assert_nothing_raised("Could not get status") {
275
+ startenable = svc.state(:enable).is
276
+ startensure = svc.state(:ensure).is
277
+ }
278
+
279
+ svc[:enable] = false
280
+ svc[:ensure] = :stopped
281
+ assert_apply(svc)
282
+
283
+ sleep 1
284
+ svc.retrieve
285
+ assert(svc.insync?, "Service did not sync both states")
286
+
287
+ svc[:enable] = true
288
+ svc[:ensure] = :running
289
+ assert_apply(svc)
290
+
291
+ sleep 1
292
+ svc.retrieve
293
+ assert(svc.insync?, "Service did not sync both states")
294
+
295
+ svc[:enable] = startenable
296
+ svc[:ensure] = startensure
297
+ assert_apply(svc)
298
+ Puppet.type(:service).clear
299
+ Puppet.type(:component).clear
300
+ end
301
+ end
267
302
  end
268
303
  end
269
304
  end
270
305
 
271
- # $Id: service.rb 938 2006-02-24 20:01:01Z luke $
306
+ # $Id: service.rb 1033 2006-03-14 20:00:20Z luke $
@@ -0,0 +1,92 @@
1
+ if __FILE__ == $0
2
+ $:.unshift '..'
3
+ $:.unshift '../../lib'
4
+ $puppetbase = "../.."
5
+ end
6
+
7
+ require 'puppet/type'
8
+ require 'puppettest'
9
+ require 'test/unit'
10
+
11
+ class TestState < Test::Unit::TestCase
12
+ include TestPuppet
13
+
14
+ def newinst(state)
15
+ inst = nil
16
+ assert_nothing_raised {
17
+ return state.new(:parent => nil)
18
+ }
19
+ end
20
+
21
+ def newstate(name = :fakestate)
22
+ assert_nothing_raised {
23
+ state = Class.new(Puppet::State) do
24
+ @name = :fakeparam
25
+ end
26
+ state.initvars
27
+
28
+ return state
29
+ }
30
+ end
31
+
32
+ def test_newvalue
33
+ state = newstate()
34
+
35
+ assert_nothing_raised {
36
+ state.newvalue(:one) do
37
+ @is = 1
38
+ end
39
+ }
40
+
41
+ assert_nothing_raised {
42
+ state.newvalue("two") do
43
+ @is = 2
44
+ end
45
+ }
46
+
47
+ inst = newinst(state)
48
+
49
+ assert_nothing_raised {
50
+ inst.should = "one"
51
+ }
52
+
53
+ assert_equal(:one, inst.should)
54
+ assert_nothing_raised { inst.set_one }
55
+ assert_equal(1, inst.is)
56
+
57
+ assert_nothing_raised {
58
+ inst.should = :two
59
+ }
60
+
61
+ assert_equal(:two, inst.should)
62
+ assert_nothing_raised { inst.set_two }
63
+ assert_equal(2, inst.is)
64
+ end
65
+
66
+ def test_newstatevaluewithregexes
67
+ state = newstate()
68
+
69
+ assert_nothing_raised {
70
+ state.newvalue(/^\w+$/) do
71
+ @is = self.should.upcase
72
+ return :regex_matched
73
+ end
74
+ }
75
+
76
+ inst = newinst(state)
77
+
78
+ assert_nothing_raised {
79
+ inst.should = "yayness"
80
+ }
81
+
82
+ assert_equal("yayness", inst.should)
83
+
84
+ assert_nothing_raised {
85
+ inst.sync
86
+ }
87
+
88
+ assert_equal("yayness".upcase, inst.is)
89
+ end
90
+ end
91
+
92
+ # $Id: state.rb 1000 2006-03-10 05:41:01Z luke $
@@ -8,7 +8,7 @@ require 'puppet'
8
8
  require 'puppettest'
9
9
  require 'test/unit'
10
10
 
11
- # $Id: symlink.rb 905 2006-02-13 21:49:25Z luke $
11
+ # $Id: symlink.rb 1015 2006-03-12 03:19:53Z luke $
12
12
 
13
13
  class TestSymlink < Test::Unit::TestCase
14
14
  include FileTesting
@@ -77,15 +77,43 @@ class TestSymlink < Test::Unit::TestCase
77
77
  cycle(comp)
78
78
 
79
79
  path = link.name
80
+ assert(FileTest.directory?(path), "Did not make %s" % path)
80
81
  list = file_list(path)
81
82
  FileUtils.cd(path) {
82
83
  list.each { |file|
83
84
  unless FileTest.directory?(file)
84
- assert(FileTest.symlink?(file))
85
+ assert(FileTest.symlink?(file), "file %s is not a symlink" %
86
+ file)
85
87
  target = File.readlink(file)
86
88
  assert_equal(target,File.join(source,file.sub(/^\.\//,'')))
87
89
  end
88
90
  }
89
91
  }
90
92
  end
93
+
94
+ def disabled_test_createdrecursion
95
+ source = tempfile()
96
+ file = File.join(source, "file")
97
+ dest = tempfile()
98
+ link = File.join(dest, "file")
99
+
100
+ objects = []
101
+ objects << Puppet.type(:file).create(
102
+ :path => source,
103
+ :ensure => "directory"
104
+ )
105
+ objects << Puppet.type(:file).create(
106
+ :path => file,
107
+ :ensure => "file"
108
+ )
109
+ objects << Puppet.type(:symlink).create(
110
+ :path => dest,
111
+ :ensure => source,
112
+ :recurse => true
113
+ )
114
+
115
+ assert_apply(*objects)
116
+
117
+ assert(FileTest.symlink?(link), "Link was not created")
118
+ end
91
119
  end
@@ -8,7 +8,7 @@ require 'puppet'
8
8
  require 'puppettest'
9
9
  require 'test/unit'
10
10
 
11
- # $Id: tidy.rb 965 2006-03-02 07:30:14Z luke $
11
+ # $Id: tidy.rb 984 2006-03-06 18:07:41Z luke $
12
12
 
13
13
  class TestTidy < Test::Unit::TestCase
14
14
  include FileTesting
@@ -65,25 +65,13 @@ class TestTidy < Test::Unit::TestCase
65
65
  :recurse => true
66
66
  )
67
67
 
68
- comp = newcomp("tidytesting", tidy)
69
68
 
70
69
  sleep(2)
71
- trans = nil
72
- assert_nothing_raised {
73
- trans = comp.evaluate
74
- }
75
- event = nil
76
- assert_nothing_raised {
77
- event = trans.evaluate.collect { |e| e.event }
78
- }
70
+ assert_events([:file_tidied, :file_tidied], tidy)
79
71
 
80
72
  assert(!FileTest.exists?(file), "Tidied %s still exists" % file)
81
73
  assert(!FileTest.exists?(dir), "Tidied %s still exists" % dir)
82
74
 
83
- assert_equal(2, event.length, "Got %s events instead of %s on tidy" %
84
- [event.length, 2])
85
- assert_equal([:file_tidied, :file_tidied], event,
86
- "Got incorrect events on tidy")
87
75
  end
88
76
 
89
77
  def disabled_test_recursion
@@ -251,6 +251,40 @@ class TestType < Test::Unit::TestCase
251
251
  # and make sure managed objects start with them
252
252
  assert(user.state(:ensure), "User did not get an ensure state")
253
253
  end
254
+
255
+ # Make sure removal works
256
+ def test_remove
257
+ objects = {}
258
+ top = Puppet.type(:component).create(:name => "top")
259
+ objects[top.class] = top
260
+
261
+ base = tempfile()
262
+
263
+ # now make a two-tier, 5 piece tree
264
+ %w{a b}.each do |letter|
265
+ name = "comp%s" % letter
266
+ comp = Puppet.type(:component).create(:name => name)
267
+ top.push comp
268
+ objects[comp.class] = comp
269
+
270
+ 5.times do |i|
271
+ file = base + letter + i.to_s
272
+
273
+ obj = Puppet.type(:file).create(:name => file, :ensure => "file")
274
+
275
+ comp.push obj
276
+ objects[obj.class] = obj
277
+ end
278
+ end
279
+
280
+ assert_nothing_raised do
281
+ top.remove
282
+ end
283
+
284
+ objects.each do |klass, obj|
285
+ assert_nil(klass[obj.name], "object %s was not removed" % obj.name)
286
+ end
287
+ end
254
288
  end
255
289
 
256
- # $Id: type.rb 965 2006-03-02 07:30:14Z luke $
290
+ # $Id: type.rb 1053 2006-04-02 23:39:02Z luke $
@@ -4,7 +4,7 @@ if __FILE__ == $0
4
4
  $puppetbase = "../../../../language/trunk"
5
5
  end
6
6
 
7
- # $Id: user.rb 966 2006-03-02 17:12:26Z luke $
7
+ # $Id: user.rb 1042 2006-03-22 21:56:49Z luke $
8
8
 
9
9
  require 'etc'
10
10
  require 'puppet/type'
@@ -145,6 +145,7 @@ class TestUser < Test::Unit::TestCase
145
145
  end
146
146
 
147
147
  def attrtest_comment(user)
148
+ user.retrieve
148
149
  old = user.is(:comment)
149
150
  user[:comment] = "A different comment"
150
151
 
@@ -295,6 +296,114 @@ class TestUser < Test::Unit::TestCase
295
296
  assert_equal(old, current?(:uid, user[:name]), "UID was not reverted")
296
297
  end
297
298
 
299
+ def attrtest_groups(user)
300
+ Etc.setgrent
301
+ max = 0
302
+ while group = Etc.getgrent
303
+ if group.gid > max and group.gid < 5000
304
+ max = group.gid
305
+ end
306
+ end
307
+
308
+ groups = []
309
+ main = []
310
+ extra = []
311
+ 5.times do |i|
312
+ i += 1
313
+ name = "pptstgr%s" % i
314
+ groups << Puppet.type(:group).create(
315
+ :name => name,
316
+ :gid => max + i
317
+ )
318
+
319
+ if i < 3
320
+ main << name
321
+ else
322
+ extra << name
323
+ end
324
+ end
325
+
326
+ # Create our test groups
327
+ assert_apply(*groups)
328
+
329
+ assert(user[:membership] == :minimum, "Membership did not default correctly")
330
+
331
+ assert_nothing_raised {
332
+ user.retrieve
333
+ }
334
+
335
+ # Now add some of them to our user
336
+ assert_nothing_raised {
337
+ user[:groups] = extra
338
+ }
339
+ assert_nothing_raised {
340
+ user.retrieve
341
+ }
342
+
343
+ assert(user.state(:groups).is, "Did not retrieve group list")
344
+
345
+ assert(!user.insync?, "User is incorrectly in sync")
346
+
347
+ assert_events([:user_modified], user)
348
+
349
+ assert_nothing_raised {
350
+ user.retrieve
351
+ }
352
+
353
+ list = user.state(:groups).is
354
+ assert_equal(extra.sort, list.sort, "Group list is not equal")
355
+
356
+ # Now set to our main list of groups
357
+ assert_nothing_raised {
358
+ user[:groups] = main
359
+ }
360
+
361
+ assert_equal((main + extra).sort.join(","), user.state(:groups).should)
362
+
363
+ assert_nothing_raised {
364
+ user.retrieve
365
+ }
366
+
367
+ assert(!user.insync?, "User is incorrectly in sync")
368
+
369
+ assert_events([:user_modified], user)
370
+
371
+ assert_nothing_raised {
372
+ user.retrieve
373
+ }
374
+
375
+ # We're not managing inclusively, so it should keep the old group
376
+ # memberships and add the new ones
377
+ list = user.state(:groups).is
378
+ assert_equal((main + extra).sort, list.sort, "Group list is not equal")
379
+
380
+ assert_nothing_raised {
381
+ user[:membership] = :inclusive
382
+ }
383
+ assert_nothing_raised {
384
+ user.retrieve
385
+ }
386
+
387
+ assert(!user.insync?, "User is incorrectly in sync")
388
+
389
+ assert_events([:user_modified], user)
390
+ assert_nothing_raised {
391
+ user.retrieve
392
+ }
393
+
394
+ list = user.state(:groups).is
395
+ assert_equal(main.sort, list.sort, "Group list is not equal")
396
+
397
+ # Now delete our groups
398
+ groups.each do |group|
399
+ group[:ensure] = :absent
400
+ end
401
+
402
+ user.delete(:groups)
403
+
404
+ assert_apply(*groups)
405
+ end
406
+
298
407
  # Disabled, because this is testing too much internal implementation
299
408
  def disabled_test_eachmethod
300
409
  obj = Etc.getpwuid(Process.uid)