puppet 2.7.9 → 2.7.11

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 (187) hide show
  1. data/CHANGELOG +413 -0
  2. data/README_DEVELOPER.md +28 -0
  3. data/conf/redhat/puppet.spec +10 -1
  4. data/conf/solaris/pkginfo +1 -1
  5. data/conf/suse/puppet.spec +7 -4
  6. data/ext/envpuppet.bat +13 -0
  7. data/ext/rack/files/apache2.conf +4 -0
  8. data/install.rb +4 -8
  9. data/lib/puppet.rb +1 -1
  10. data/lib/puppet/agent.rb +7 -0
  11. data/lib/puppet/agent/disabler.rb +27 -0
  12. data/lib/puppet/agent/locker.rb +0 -10
  13. data/lib/puppet/application.rb +3 -0
  14. data/lib/puppet/application/agent.rb +13 -3
  15. data/lib/puppet/application/apply.rb +6 -6
  16. data/lib/puppet/application/cert.rb +5 -5
  17. data/lib/puppet/application/instrumentation_data.rb +4 -0
  18. data/lib/puppet/application/instrumentation_listener.rb +4 -0
  19. data/lib/puppet/application/instrumentation_probe.rb +4 -0
  20. data/lib/puppet/configurer.rb +3 -1
  21. data/lib/puppet/configurer/downloader.rb +4 -2
  22. data/lib/puppet/configurer/fact_handler.rb +0 -21
  23. data/lib/puppet/daemon.rb +3 -4
  24. data/lib/puppet/defaults.rb +2 -2
  25. data/lib/puppet/face/instrumentation_data.rb +28 -0
  26. data/lib/puppet/face/instrumentation_listener.rb +96 -0
  27. data/lib/puppet/face/instrumentation_probe.rb +77 -0
  28. data/lib/puppet/face/module/list.rb +64 -0
  29. data/lib/puppet/face/module/uninstall.rb +50 -0
  30. data/lib/puppet/face/node/clean.rb +1 -4
  31. data/lib/puppet/feature/base.rb +1 -0
  32. data/lib/puppet/file_serving/content.rb +1 -1
  33. data/lib/puppet/indirector/facts/facter.rb +20 -7
  34. data/lib/puppet/indirector/facts/inventory_active_record.rb +14 -11
  35. data/lib/puppet/indirector/indirection.rb +7 -0
  36. data/lib/puppet/indirector/instrumentation_data.rb +3 -0
  37. data/lib/puppet/indirector/instrumentation_data/local.rb +19 -0
  38. data/lib/puppet/indirector/instrumentation_data/rest.rb +5 -0
  39. data/lib/puppet/indirector/instrumentation_listener.rb +3 -0
  40. data/lib/puppet/indirector/instrumentation_listener/local.rb +23 -0
  41. data/lib/puppet/indirector/instrumentation_listener/rest.rb +5 -0
  42. data/lib/puppet/indirector/instrumentation_probe.rb +3 -0
  43. data/lib/puppet/indirector/instrumentation_probe/local.rb +24 -0
  44. data/lib/puppet/indirector/instrumentation_probe/rest.rb +5 -0
  45. data/lib/puppet/indirector/rest.rb +1 -1
  46. data/lib/puppet/module.rb +13 -17
  47. data/lib/puppet/module_tool/applications.rb +1 -0
  48. data/lib/puppet/module_tool/applications/uninstaller.rb +33 -0
  49. data/lib/puppet/module_tool/contents_description.rb +1 -1
  50. data/lib/puppet/network/server.rb +2 -3
  51. data/lib/puppet/node/environment.rb +16 -3
  52. data/lib/puppet/parser/ast/leaf.rb +1 -1
  53. data/lib/puppet/parser/functions/create_resources.rb +1 -1
  54. data/lib/puppet/parser/type_loader.rb +1 -1
  55. data/lib/puppet/property.rb +46 -14
  56. data/lib/puppet/provider.rb +13 -4
  57. data/lib/puppet/provider/augeas/augeas.rb +6 -4
  58. data/lib/puppet/provider/group/pw.rb +24 -10
  59. data/lib/puppet/provider/nameservice/directoryservice.rb +146 -37
  60. data/lib/puppet/provider/package/pip.rb +1 -1
  61. data/lib/puppet/provider/package/yum.rb +1 -2
  62. data/lib/puppet/provider/service/debian.rb +14 -0
  63. data/lib/puppet/provider/service/launchd.rb +1 -1
  64. data/lib/puppet/provider/service/smf.rb +2 -2
  65. data/lib/puppet/provider/user/pw.rb +56 -2
  66. data/lib/puppet/provider/user/user_role_add.rb +32 -22
  67. data/lib/puppet/provider/user/windows_adsi.rb +1 -0
  68. data/lib/puppet/rails/benchmark.rb +1 -1
  69. data/lib/puppet/reports/store.rb +8 -1
  70. data/lib/puppet/resource/catalog.rb +5 -1
  71. data/lib/puppet/simple_graph.rb +11 -14
  72. data/lib/puppet/transaction.rb +10 -4
  73. data/lib/puppet/transaction/report.rb +9 -3
  74. data/lib/puppet/type.rb +19 -7
  75. data/lib/puppet/type/exec.rb +1 -1
  76. data/lib/puppet/type/file.rb +4 -1
  77. data/lib/puppet/type/file/ensure.rb +5 -1
  78. data/lib/puppet/type/file/mode.rb +45 -10
  79. data/lib/puppet/type/file/source.rb +4 -0
  80. data/lib/puppet/type/host.rb +17 -3
  81. data/lib/puppet/type/k5login.rb +3 -2
  82. data/lib/puppet/type/schedule.rb +3 -2
  83. data/lib/puppet/util.rb +83 -27
  84. data/lib/puppet/util/anonymous_filelock.rb +36 -0
  85. data/lib/puppet/util/docs.rb +18 -2
  86. data/lib/puppet/util/instrumentation.rb +173 -0
  87. data/lib/puppet/util/instrumentation/data.rb +34 -0
  88. data/lib/puppet/util/instrumentation/indirection_probe.rb +29 -0
  89. data/lib/puppet/util/instrumentation/instrumentable.rb +143 -0
  90. data/lib/puppet/util/instrumentation/listener.rb +60 -0
  91. data/lib/puppet/util/instrumentation/listeners/log.rb +29 -0
  92. data/lib/puppet/util/instrumentation/listeners/performance.rb +30 -0
  93. data/lib/puppet/util/monkey_patches.rb +8 -0
  94. data/lib/puppet/util/pidlock.rb +21 -25
  95. data/lib/puppet/util/rdoc/parser.rb +2 -2
  96. data/lib/puppet/util/reference.rb +8 -23
  97. data/lib/puppet/util/retryaction.rb +48 -0
  98. data/lib/puppet/util/suidmanager.rb +70 -39
  99. data/lib/puppet/util/symbolic_file_mode.rb +140 -0
  100. data/spec/integration/configurer_spec.rb +5 -0
  101. data/spec/integration/indirector/direct_file_server_spec.rb +1 -1
  102. data/spec/integration/indirector/file_content/file_server_spec.rb +7 -7
  103. data/spec/integration/provider/package_spec.rb +7 -0
  104. data/spec/unit/agent/disabler_spec.rb +60 -0
  105. data/spec/unit/agent/locker_spec.rb +0 -12
  106. data/spec/unit/agent_spec.rb +8 -0
  107. data/spec/unit/application/agent_spec.rb +38 -1
  108. data/spec/unit/application/apply_spec.rb +34 -40
  109. data/spec/unit/application/cert_spec.rb +1 -1
  110. data/spec/unit/application_spec.rb +6 -0
  111. data/spec/unit/configurer/downloader_spec.rb +29 -10
  112. data/spec/unit/configurer/fact_handler_spec.rb +5 -29
  113. data/spec/unit/configurer_spec.rb +8 -8
  114. data/spec/unit/daemon_spec.rb +12 -26
  115. data/spec/unit/face/instrumentation_data.rb +7 -0
  116. data/spec/unit/face/instrumentation_listener.rb +38 -0
  117. data/spec/unit/face/instrumentation_probe.rb +21 -0
  118. data/spec/unit/face/node_spec.rb +111 -111
  119. data/spec/unit/file_serving/content_spec.rb +2 -2
  120. data/spec/unit/indirector/facts/facter_spec.rb +25 -3
  121. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +14 -4
  122. data/spec/unit/indirector/instrumentation_data/local_spec.rb +52 -0
  123. data/spec/unit/indirector/instrumentation_data/rest_spec.rb +11 -0
  124. data/spec/unit/indirector/instrumentation_listener/local_spec.rb +65 -0
  125. data/spec/unit/indirector/instrumentation_listener/rest_spec.rb +11 -0
  126. data/spec/unit/indirector/instrumentation_probe/local_spec.rb +65 -0
  127. data/spec/unit/indirector/instrumentation_probe/rest_spec.rb +11 -0
  128. data/spec/unit/module_spec.rb +39 -125
  129. data/spec/unit/module_tool/uninstaller_spec.rb +44 -0
  130. data/spec/unit/network/server_spec.rb +2 -20
  131. data/spec/unit/node/environment_spec.rb +76 -58
  132. data/spec/unit/parser/ast/asthash_spec.rb +1 -2
  133. data/spec/unit/parser/ast/leaf_spec.rb +16 -0
  134. data/spec/unit/property/keyvalue_spec.rb +5 -2
  135. data/spec/unit/property_spec.rb +260 -159
  136. data/spec/unit/provider/augeas/augeas_spec.rb +2 -2
  137. data/spec/unit/provider/group/pw_spec.rb +81 -0
  138. data/spec/unit/provider/nameservice/directoryservice_spec.rb +102 -0
  139. data/spec/unit/provider/package/pip_spec.rb +7 -0
  140. data/spec/unit/provider/package/yum_spec.rb +45 -1
  141. data/spec/unit/provider/service/debian_spec.rb +15 -0
  142. data/spec/unit/provider/service/launchd_spec.rb +48 -43
  143. data/spec/unit/provider/service/smf_spec.rb +3 -3
  144. data/spec/unit/provider/user/pw_spec.rb +183 -0
  145. data/spec/unit/provider/user/user_role_add_spec.rb +46 -39
  146. data/spec/unit/provider/user/windows_adsi_spec.rb +1 -0
  147. data/spec/unit/provider_spec.rb +32 -0
  148. data/spec/unit/reports/store_spec.rb +19 -1
  149. data/spec/unit/simple_graph_spec.rb +34 -19
  150. data/spec/unit/ssl/certificate_factory_spec.rb +3 -3
  151. data/spec/unit/transaction/report_spec.rb +29 -1
  152. data/spec/unit/transaction_spec.rb +32 -46
  153. data/spec/unit/type/file/mode_spec.rb +1 -1
  154. data/spec/unit/type/file/source_spec.rb +28 -3
  155. data/spec/unit/type/file_spec.rb +17 -16
  156. data/spec/unit/type/host_spec.rb +527 -0
  157. data/spec/unit/type/k5login_spec.rb +115 -0
  158. data/spec/unit/type/schedule_spec.rb +6 -6
  159. data/spec/unit/type_spec.rb +51 -0
  160. data/spec/unit/util/anonymous_filelock_spec.rb +78 -0
  161. data/spec/unit/util/execution_stub_spec.rb +2 -1
  162. data/spec/unit/util/instrumentation/data_spec.rb +44 -0
  163. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +19 -0
  164. data/spec/unit/util/instrumentation/instrumentable_spec.rb +186 -0
  165. data/spec/unit/util/instrumentation/listener_spec.rb +100 -0
  166. data/spec/unit/util/instrumentation/listeners/log_spec.rb +34 -0
  167. data/spec/unit/util/instrumentation/listeners/performance_spec.rb +36 -0
  168. data/spec/unit/util/instrumentation_spec.rb +181 -0
  169. data/spec/unit/util/pidlock_spec.rb +208 -0
  170. data/spec/unit/util/rdoc/parser_spec.rb +1 -1
  171. data/spec/unit/util/reference_spec.rb +16 -6
  172. data/spec/unit/util/retryaction_spec.rb +62 -0
  173. data/spec/unit/util/suidmanager_spec.rb +101 -83
  174. data/spec/unit/util/symbolic_file_mode_spec.rb +182 -0
  175. data/spec/unit/util_spec.rb +126 -0
  176. data/tasks/rake/apple.rake +176 -0
  177. data/tasks/rake/templates/prototype.plist.erb +38 -0
  178. metadata +61 -13
  179. data/lib/puppet/application/module.rb +0 -3
  180. data/lib/puppet/face/module.rb +0 -12
  181. data/spec/unit/face/module/build_spec.rb +0 -30
  182. data/spec/unit/face/module/changes_spec.rb +0 -30
  183. data/spec/unit/face/module/clean_spec.rb +0 -30
  184. data/spec/unit/face/module/generate_spec.rb +0 -30
  185. data/spec/unit/face/module/install_spec.rb +0 -75
  186. data/spec/unit/face/module/search_spec.rb +0 -40
  187. data/test/util/pidlock.rb +0 -126
@@ -353,7 +353,7 @@ describe provider_class do
353
353
  @augeas_stub = stub("augeas")
354
354
  @provider.aug = @augeas_stub
355
355
 
356
- @augeas_stub.stubs("get").with("/augeas/version").returns("0.7.2")
356
+ @augeas_stub.stubs("get").with("/augeas/version").returns("0.10.0")
357
357
  @augeas_stub.stubs(:set).returns(true)
358
358
  @augeas_stub.stubs(:save).returns(true)
359
359
  end
@@ -467,7 +467,7 @@ describe provider_class do
467
467
  @augeas = stub("augeas")
468
468
  @provider.aug= @augeas
469
469
  @provider.stubs(:get_augeas_version).returns("0.3.5")
470
- @augeas.stubs(:match).with("/augeas/events/saved")
470
+ @augeas.stubs(:match).with("/augeas/events/saved").returns([])
471
471
  end
472
472
 
473
473
  it "should handle set commands" do
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ provider_class = Puppet::Type.type(:group).provider(:pw)
5
+
6
+ describe provider_class do
7
+ let :resource do
8
+ Puppet::Type.type(:group).new(:name => "testgroup", :provider => :pw)
9
+ end
10
+
11
+ let :provider do
12
+ resource.provider
13
+ end
14
+
15
+ describe "when creating groups" do
16
+ let :provider do
17
+ prov = resource.provider
18
+ prov.expects(:exists?).returns nil
19
+ prov
20
+ end
21
+
22
+ it "should run pw with no additional flags when no properties are given" do
23
+ provider.addcmd.must == [provider_class.command(:pw), "groupadd", "testgroup"]
24
+ provider.expects(:execute).with([provider_class.command(:pw), "groupadd", "testgroup"])
25
+ provider.create
26
+ end
27
+
28
+ it "should use -o when allowdupe is enabled" do
29
+ resource[:allowdupe] = true
30
+ provider.expects(:execute).with(includes("-o"))
31
+ provider.create
32
+ end
33
+
34
+ it "should use -g with the correct argument when the gid property is set" do
35
+ resource[:gid] = 12345
36
+ provider.expects(:execute).with(all_of(includes("-g"), includes(12345)))
37
+ provider.create
38
+ end
39
+
40
+ it "should use -M with the correct argument when the members property is set" do
41
+ resource[:members] = "user1"
42
+ provider.expects(:execute).with(all_of(includes("-M"), includes("user1")))
43
+ provider.create
44
+ end
45
+
46
+ it "should use -M with all the given users when the members property is set to an array" do
47
+ resource[:members] = ["user1", "user2"]
48
+ provider.expects(:execute).with(all_of(includes("-M"), includes("user1,user2")))
49
+ provider.create
50
+ end
51
+ end
52
+
53
+ describe "when deleting groups" do
54
+ it "should run pw with no additional flags" do
55
+ provider.expects(:exists?).returns true
56
+ provider.deletecmd.must == [provider_class.command(:pw), "groupdel", "testgroup"]
57
+ provider.expects(:execute).with([provider_class.command(:pw), "groupdel", "testgroup"])
58
+ provider.delete
59
+ end
60
+ end
61
+
62
+ describe "when modifying groups" do
63
+ it "should run pw with the correct arguments" do
64
+ provider.modifycmd("gid", 12345).must == [provider_class.command(:pw), "groupmod", "testgroup", "-g", 12345]
65
+ provider.expects(:execute).with([provider_class.command(:pw), "groupmod", "testgroup", "-g", 12345])
66
+ provider.gid = 12345
67
+ end
68
+
69
+ it "should use -M with the correct argument when the members property is changed" do
70
+ resource[:members] = "user1"
71
+ provider.expects(:execute).with(all_of(includes("-M"), includes("user2")))
72
+ provider.members = "user2"
73
+ end
74
+
75
+ it "should use -M with all the given users when the members property is changed with an array" do
76
+ resource[:members] = ["user1", "user2"]
77
+ provider.expects(:execute).with(all_of(includes("-M"), includes("user3,user4")))
78
+ provider.members = ["user3", "user4"]
79
+ end
80
+ end
81
+ end
@@ -95,3 +95,105 @@ describe 'DirectoryService.get_exec_preamble' do
95
95
  Puppet::Provider::NameService::DirectoryService.get_exec_preamble('-list').should include("-plist")
96
96
  end
97
97
  end
98
+
99
+ describe 'DirectoryService password behavior' do
100
+ # The below is a binary plist containing a ShadowHashData key which CONTAINS
101
+ # another binary plist. The nested binary plist contains a 'SALTED-SHA512'
102
+ # key that contains a base64 encoded salted-SHA512 password hash...
103
+ let (:binary_plist) { "bplist00\324\001\002\003\004\005\006\a\bXCRAM-MD5RNT]SALTED-SHA512[RECOVERABLEO\020 \231k2\3360\200GI\201\355J\216\202\215y\243\001\206J\300\363\032\031\022\006\2359\024\257\217<\361O\020\020F\353\at\377\277\226\276c\306\254\031\037J(\235O\020D\335\006{\3744g@\377z\204\322\r\332t\021\330\n\003\246K\223\356\034!P\261\305t\035\346\352p\206\003n\247MMA\310\301Z<\366\246\023\0161W3\340\357\000\317T\t\301\311+\204\246L7\276\370\320*\245O\021\002\000k\024\221\270x\353\001\237\346D}\377?\265]\356+\243\v[\350\316a\340h\376<\322\266\327\016\306n\272r\t\212A\253L\216\214\205\016\241 [\360/\335\002#\\A\372\241a\261\346\346\\\251\330\312\365\016\n\341\017\016\225&;\322\\\004*\ru\316\372\a \362?8\031\247\231\030\030\267\315\023\v\343{@\227\301s\372h\212\000a\244&\231\366\nt\277\2036,\027bZ+\223W\212g\333`\264\331N\306\307\362\257(^~ b\262\247&\231\261t\341\231%\244\247\203eOt\365\271\201\273\330\350\363C^A\327F\214!\217hgf\e\320k\260n\315u~\336\371M\t\235k\230S\375\311\303\240\351\037d\273\321y\335=K\016`_\317\230\2612_\023K\036\350\v\232\323Y\310\317_\035\227%\237\v\340\023\016\243\233\025\306:\227\351\370\364x\234\231\266\367\016w\275\333-\351\210}\375x\034\262\272kRuHa\362T/F!\347B\231O`K\304\037'k$$\245h)e\363\365mT\b\317\\2\361\026\351\254\375Jl1~\r\371\267\352\2322I\341\272\376\243^Un\266E7\230[VocUJ\220N\2116D/\025f=\213\314\325\vG}\311\360\377DT\307m\261&\263\340\272\243_\020\271rG^BW\210\030l\344\0324\335\233\300\023\272\225Im\330\n\227*Yv[\006\315\330y'\a\321\373\273A\240\305F{S\246I#/\355\2425\031\031GGF\270y\n\331\004\023G@\331\000\361\343\350\264$\032\355_\210y\000\205\342\375\212q\024\004\026W:\205 \363v?\035\270L-\270=\022\323\2003\v\336\277\t\237\356\374\n\267n\003\367\342\330;\371S\326\016`B6@Njm>\240\021%\336\345\002(P\204Yn\3279l\0228\264\254\304\2528t\372h\217\347sA\314\345\245\337)]\000\b\000\021\000\032\000\035\000+\0007\000Z\000m\000\264\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\t\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\270" }
104
+
105
+ # The below is a base64 encoded salted-SHA512 password hash.
106
+ let (:pw_string) { "\335\006{\3744g@\377z\204\322\r\332t\021\330\n\003\246K\223\356\034!P\261\305t\035\346\352p\206\003n\247MMA\310\301Z<\366\246\023\0161W3\340\357\000\317T\t\301\311+\204\246L7\276\370\320*\245" }
107
+
108
+ # The below is a salted-SHA512 password hash in hex.
109
+ let (:sha512_hash) { 'dd067bfc346740ff7a84d20dda7411d80a03a64b93ee1c2150b1c5741de6ea7086036ea74d4d41c8c15a3cf6a6130e315733e0ef00cf5409c1c92b84a64c37bef8d02aa5' }
110
+
111
+ let :plist_path do
112
+ '/var/db/dslocal/nodes/Default/users/jeff.plist'
113
+ end
114
+
115
+ let :ds_provider do
116
+ Puppet::Provider::NameService::DirectoryService
117
+ end
118
+
119
+ let :shadow_hash_data do
120
+ {'ShadowHashData' => [StringIO.new(binary_plist)]}
121
+ end
122
+
123
+ subject do
124
+ Puppet::Provider::NameService::DirectoryService
125
+ end
126
+
127
+ before :each do
128
+ subject.expects(:get_macosx_version_major).returns("10.7")
129
+ end
130
+
131
+ it 'should execute convert_binary_to_xml once when getting the password on >= 10.7' do
132
+ subject.expects(:convert_binary_to_xml).returns({'SALTED-SHA512' => StringIO.new(pw_string)})
133
+ File.expects(:exists?).with(plist_path).once.returns(true)
134
+ Plist.expects(:parse_xml).returns(shadow_hash_data)
135
+ # On Mac OS X 10.7 we first need to convert to xml when reading the password
136
+ subject.expects(:plutil).with('-convert', 'xml1', '-o', '/dev/stdout', plist_path)
137
+ subject.get_password('uid', 'jeff')
138
+ end
139
+
140
+ it 'should fail if a salted-SHA512 password hash is not passed in >= 10.7' do
141
+ expect {
142
+ subject.set_password('jeff', 'uid', 'badpassword')
143
+ }.should raise_error(RuntimeError, /OS X 10.7 requires a Salted SHA512 hash password of 136 characters./)
144
+ end
145
+
146
+ it 'should convert xml-to-binary and binary-to-xml when setting the pw on >= 10.7' do
147
+ subject.expects(:convert_binary_to_xml).returns({'SALTED-SHA512' => StringIO.new(pw_string)})
148
+ subject.expects(:convert_xml_to_binary).returns(binary_plist)
149
+ File.expects(:exists?).with(plist_path).once.returns(true)
150
+ Plist.expects(:parse_xml).returns(shadow_hash_data)
151
+ # On Mac OS X 10.7 we first need to convert to xml
152
+ subject.expects(:plutil).with('-convert', 'xml1', '-o', '/dev/stdout', plist_path)
153
+ # And again back to a binary plist or DirectoryService will complain
154
+ subject.expects(:plutil).with('-convert', 'binary1', plist_path)
155
+ Plist::Emit.expects(:save_plist).with(shadow_hash_data, plist_path)
156
+ subject.set_password('jeff', 'uid', sha512_hash)
157
+ end
158
+ end
159
+
160
+ describe '(#4855) directoryservice group resource failure' do
161
+ let :provider_class do
162
+ Puppet::Type.type(:group).provider(:directoryservice)
163
+ end
164
+
165
+ let :group_members do
166
+ ['root','jeff']
167
+ end
168
+
169
+ let :user_account do
170
+ ['root']
171
+ end
172
+
173
+ let :stub_resource do
174
+ stub('resource')
175
+ end
176
+
177
+ subject do
178
+ provider_class.new(stub_resource)
179
+ end
180
+
181
+ before :each do
182
+ @resource = stub("resource")
183
+ @provider = provider_class.new(@resource)
184
+ end
185
+
186
+ it 'should delete a group member if the user does not exist' do
187
+ stub_resource.stubs(:[]).with(:name).returns('fake_group')
188
+ stub_resource.stubs(:name).returns('fake_group')
189
+ subject.expects(:execute).with([:dseditgroup, '-o', 'edit', '-n', '.',
190
+ '-d', 'jeff',
191
+ 'fake_group']).raises(Puppet::ExecutionFailure,
192
+ 'it broke')
193
+ subject.expects(:execute).with([:dscl, '.', '-delete',
194
+ '/Groups/fake_group', 'GroupMembership',
195
+ 'jeff'])
196
+ subject.remove_unwanted_members(group_members, user_account)
197
+ end
198
+ end
199
+
@@ -175,6 +175,13 @@ describe provider_class do
175
175
  expect { @provider.method(:lazy_pip).call("freeze") }.to raise_error(NoMethodError)
176
176
  end
177
177
 
178
+ it "should output a useful error message if pip is missing" do
179
+ @provider.expects(:pip).with('freeze').raises(NoMethodError)
180
+ @provider.expects(:which).with('pip').returns(nil)
181
+ expect { @provider.method(:lazy_pip).call("freeze") }.
182
+ to raise_error(NoMethodError, 'Could not locate the pip command.')
183
+ end
184
+
178
185
  end
179
186
 
180
187
  end
@@ -30,16 +30,19 @@ describe provider do
30
30
  @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage')
31
31
  @provider.install
32
32
  end
33
+
33
34
  it 'should use :install to update' do
34
35
  @provider.expects(:install)
35
36
  @provider.update
36
37
  end
38
+
37
39
  it 'should be able to set version' do
38
40
  @resource.stubs(:should).with(:ensure).returns '1.2'
39
41
  @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :install, 'mypackage-1.2')
40
42
  @provider.stubs(:query).returns :ensure => '1.2'
41
43
  @provider.install
42
44
  end
45
+
43
46
  it 'should be able to downgrade' do
44
47
  @resource.stubs(:should).with(:ensure).returns '1.0'
45
48
  @provider.expects(:yum).with('-d', '0', '-e', '0', '-y', :downgrade, 'mypackage-1.0')
@@ -53,6 +56,7 @@ describe provider do
53
56
  @provider.expects(:yum).with('-y', :erase, 'mypackage')
54
57
  @provider.purge
55
58
  end
59
+
56
60
  it 'should use rpm to uninstall' do
57
61
  @provider.expects(:rpm).with('-e', 'mypackage-1-1.i386')
58
62
  @provider.uninstall
@@ -62,5 +66,45 @@ describe provider do
62
66
  it 'should be versionable' do
63
67
  provider.should be_versionable
64
68
  end
65
- end
66
69
 
70
+ describe '#latest' do
71
+ describe 'when latest_info is nil' do
72
+ before :each do
73
+ @provider.stubs(:latest_info).returns(nil)
74
+ end
75
+
76
+ it 'raises if ensure is absent and latest_info is nil' do
77
+ @provider.stubs(:properties).returns({:ensure => :absent})
78
+
79
+ expect { @provider.latest }.to raise_error(
80
+ Puppet::DevError,
81
+ 'Tried to get latest on a missing package'
82
+ )
83
+ end
84
+
85
+ it 'returns the ensure value if the package is not already installed' do
86
+ @provider.stubs(:properties).returns({:ensure => '3.4.5'})
87
+
88
+ @provider.latest.should == '3.4.5'
89
+ end
90
+ end
91
+
92
+ describe 'when latest_info is populated' do
93
+ before :each do
94
+ @provider.stubs(:latest_info).returns({
95
+ :name => 'mypackage',
96
+ :epoch => '1',
97
+ :version => '2.3.4',
98
+ :release => '5',
99
+ :arch => 'i686',
100
+ :provider => :yum,
101
+ :ensure => '2.3.4-5'
102
+ })
103
+ end
104
+
105
+ it 'includes the epoch in the version string' do
106
+ @provider.latest.should == '1:2.3.4-5'
107
+ end
108
+ end
109
+ end
110
+ end
@@ -88,6 +88,21 @@ describe provider_class do
88
88
  @provider.enabled?.should == :true
89
89
  end
90
90
 
91
+ context "when invoke-rc.d exits with 105 status" do
92
+ it "links count is 4" do
93
+ @provider.stubs(:system)
94
+ $CHILD_STATUS.stubs(:exitstatus).returns(105)
95
+ @provider.stubs(:get_start_link_count).returns(4)
96
+ @provider.enabled?.should == :true
97
+ end
98
+ it "links count is less than 4" do
99
+ @provider.stubs(:system)
100
+ $CHILD_STATUS.stubs(:exitstatus).returns(105)
101
+ @provider.stubs(:get_start_link_count).returns(3)
102
+ @provider.enabled?.should == :false
103
+ end
104
+ end
105
+
91
106
  # pick a range of non-[104.106] numbers, strings and booleans to test with.
92
107
  [-100, -1, 0, 1, 100, "foo", "", :true, :false].each do |exitstatus|
93
108
  it "should return false when invoke-rc.d exits with #{exitstatus} status" do
@@ -37,22 +37,21 @@ describe Puppet::Type.type(:service).provider(:launchd) do
37
37
 
38
38
  describe "when checking whether the service is enabled on OS X 10.5" do
39
39
  it "should return true in if the job plist says disabled is false" do
40
- Facter.stubs(:value).with(:macosx_productversion_major).returns('10.5')
41
- Facter.stubs(:value).with(:kernel).returns('Darwin')
42
- Facter.stubs(:value).with(:macaddress).returns('')
43
- Facter.stubs(:value).with(:arp).returns('')
40
+ subject.expects(:has_macosx_plist_overrides?).returns(false)
44
41
  subject.expects(:plist_from_label).with(joblabel).returns(["foo", {"Disabled" => false}])
45
42
  subject.expects(:resource).returns({:name => joblabel})
46
43
  subject.enabled?.should == :true
47
44
  end
48
45
  it "should return true in if the job plist has no disabled key" do
46
+ subject.expects(:has_macosx_plist_overrides?).returns(false)
49
47
  subject.expects(:resource).returns({:name => joblabel})
50
- subject.stubs(:plist_from_label).returns(["foo", {}])
48
+ subject.expects(:plist_from_label).returns(["foo", {}])
51
49
  subject.enabled?.should == :true
52
50
  end
53
51
  it "should return false in if the job plist says disabled is true" do
52
+ subject.expects(:has_macosx_plist_overrides?).returns(false)
54
53
  subject.expects(:resource).returns({:name => joblabel})
55
- subject.stubs(:plist_from_label).returns(["foo", {"Disabled" => true}])
54
+ subject.expects(:plist_from_label).returns(["foo", {"Disabled" => true}])
56
55
  subject.enabled?.should == :false
57
56
  end
58
57
  end
@@ -61,7 +60,7 @@ describe Puppet::Type.type(:service).provider(:launchd) do
61
60
  it "should return true if the job plist says disabled is true and the global overrides says disabled is false" do
62
61
  provider.expects(:get_macosx_version_major).returns("10.6")
63
62
  subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => true}])
64
- provider.stubs(:read_plist).returns({joblabel => {"Disabled" => false}})
63
+ provider.expects(:read_plist).returns({joblabel => {"Disabled" => false}})
65
64
  FileTest.expects(:file?).with(launchd_overrides).returns(true)
66
65
  subject.stubs(:resource).returns({:name => joblabel})
67
66
  subject.enabled?.should == :true
@@ -69,7 +68,7 @@ describe Puppet::Type.type(:service).provider(:launchd) do
69
68
  it "should return false if the job plist says disabled is false and the global overrides says disabled is true" do
70
69
  provider.expects(:get_macosx_version_major).returns("10.6")
71
70
  subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => false}])
72
- provider.stubs(:read_plist).returns({joblabel => {"Disabled" => true}})
71
+ provider.expects(:read_plist).returns({joblabel => {"Disabled" => true}})
73
72
  FileTest.expects(:file?).with(launchd_overrides).returns(true)
74
73
  subject.stubs(:resource).returns({:name => joblabel})
75
74
  subject.enabled?.should == :false
@@ -77,7 +76,7 @@ describe Puppet::Type.type(:service).provider(:launchd) do
77
76
  it "should return true if the job plist and the global overrides have no disabled keys" do
78
77
  provider.expects(:get_macosx_version_major).returns("10.6")
79
78
  subject.expects(:plist_from_label).returns([joblabel, {}])
80
- provider.stubs(:read_plist).returns({})
79
+ provider.expects(:read_plist).returns({})
81
80
  FileTest.expects(:file?).with(launchd_overrides).returns(true)
82
81
  subject.stubs(:resource).returns({:name => joblabel})
83
82
  subject.enabled?.should == :true
@@ -87,61 +86,69 @@ describe Puppet::Type.type(:service).provider(:launchd) do
87
86
  describe "when starting the service" do
88
87
  it "should look for the relevant plist once" do
89
88
  subject.expects(:plist_from_label).returns([joblabel, {}]).once
90
- subject.stubs(:enabled?).returns :true
91
- subject.stubs(:execute).with([:launchctl, :load, joblabel])
89
+ subject.expects(:enabled?).returns :true
90
+ subject.expects(:execute).with([:launchctl, :load, joblabel])
92
91
  subject.stubs(:resource).returns({:name => joblabel})
93
92
  subject.start
94
93
  end
95
94
  it "should execute 'launchctl load' once without writing to the plist if the job is enabled" do
96
- subject.stubs(:plist_from_label).returns([joblabel, {}])
97
- subject.stubs(:enabled?).returns :true
95
+ subject.expects(:plist_from_label).returns([joblabel, {}])
96
+ subject.expects(:enabled?).returns :true
98
97
  subject.expects(:execute).with([:launchctl, :load, joblabel]).once
99
98
  subject.stubs(:resource).returns({:name => joblabel})
100
99
  subject.start
101
100
  end
102
101
  it "should execute 'launchctl load' with writing to the plist once if the job is disabled" do
103
- subject.stubs(:plist_from_label).returns([joblabel, {}])
104
- subject.stubs(:enabled?).returns(:false)
102
+ subject.expects(:plist_from_label).returns([joblabel, {}])
103
+ subject.expects(:enabled?).returns(:false)
105
104
  subject.stubs(:resource).returns({:name => joblabel})
106
105
  subject.expects(:execute).with([:launchctl, :load, "-w", joblabel]).once
107
106
  subject.start
108
107
  end
109
108
  it "should disable the job once if the job is disabled and should be disabled at boot" do
110
- subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => true}])
111
- subject.stubs(:enabled?).returns :false
112
- subject.stubs(:execute).with([:launchctl, :load, "-w", joblabel])
109
+ subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => true}])
110
+ subject.expects(:enabled?).returns :false
111
+ subject.expects(:execute).with([:launchctl, :load, "-w", joblabel])
113
112
  subject.stubs(:resource).returns({:name => joblabel, :enable => :false})
114
113
  subject.expects(:disable).once
115
114
  subject.start
116
115
  end
116
+ it "(#2773) should execute 'launchctl load -w' if the job is enabled but stopped" do
117
+ subject.expects(:plist_from_label).returns([joblabel, {}])
118
+ subject.expects(:enabled?).returns(:true)
119
+ subject.expects(:status).returns(:stopped)
120
+ subject.expects(:resource).returns({:name => joblabel}).twice
121
+ subject.expects(:execute).with([:launchctl, :load, '-w', joblabel])
122
+ subject.start
123
+ end
117
124
  end
118
125
 
119
126
  describe "when stopping the service" do
120
127
  it "should look for the relevant plist once" do
121
128
  subject.expects(:plist_from_label).returns([joblabel, {}]).once
122
- subject.stubs(:enabled?).returns :true
123
- subject.stubs(:execute).with([:launchctl, :unload, '-w', joblabel])
129
+ subject.expects(:enabled?).returns :true
130
+ subject.expects(:execute).with([:launchctl, :unload, '-w', joblabel])
124
131
  subject.stubs(:resource).returns({:name => joblabel})
125
132
  subject.stop
126
133
  end
127
134
  it "should execute 'launchctl unload' once without writing to the plist if the job is disabled" do
128
- subject.stubs(:plist_from_label).returns([joblabel, {}])
129
- subject.stubs(:enabled?).returns :false
135
+ subject.expects(:plist_from_label).returns([joblabel, {}])
136
+ subject.expects(:enabled?).returns :false
130
137
  subject.expects(:execute).with([:launchctl, :unload, joblabel]).once
131
138
  subject.stubs(:resource).returns({:name => joblabel})
132
139
  subject.stop
133
140
  end
134
141
  it "should execute 'launchctl unload' with writing to the plist once if the job is enabled" do
135
- subject.stubs(:plist_from_label).returns([joblabel, {}])
136
- subject.stubs(:enabled?).returns :true
142
+ subject.expects(:plist_from_label).returns([joblabel, {}])
143
+ subject.expects(:enabled?).returns :true
137
144
  subject.expects(:execute).with([:launchctl, :unload, '-w', joblabel]).once
138
145
  subject.stubs(:resource).returns({:name => joblabel})
139
146
  subject.stop
140
147
  end
141
148
  it "should enable the job once if the job is enabled and should be enabled at boot" do
142
- subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => false}])
143
- subject.stubs(:enabled?).returns :true
144
- subject.stubs(:execute).with([:launchctl, :unload, "-w", joblabel])
149
+ subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => false}])
150
+ subject.expects(:enabled?).returns :true
151
+ subject.expects(:execute).with([:launchctl, :unload, "-w", joblabel])
145
152
  subject.stubs(:resource).returns({:name => joblabel, :enable => :true})
146
153
  subject.expects(:enable).once
147
154
  subject.stop
@@ -151,15 +158,15 @@ describe Puppet::Type.type(:service).provider(:launchd) do
151
158
  describe "when enabling the service" do
152
159
  it "should look for the relevant plist once" do ### Do we need this test? Differentiating it?
153
160
  subject.expects(:plist_from_label).returns([joblabel, {}]).once
154
- subject.stubs(:enabled?).returns :false
155
- subject.stubs(:execute).with([:launchctl, :unload, joblabel])
161
+ subject.expects(:enabled?).returns :false
162
+ subject.expects(:execute).with([:launchctl, :unload, joblabel])
156
163
  subject.stubs(:resource).returns({:name => joblabel, :enable => :true})
157
164
  subject.stop
158
165
  end
159
166
  it "should check if the job is enabled once" do
160
- subject.stubs(:plist_from_label).returns([joblabel, {}]).once
167
+ subject.expects(:plist_from_label).returns([joblabel, {}]).once
161
168
  subject.expects(:enabled?).once
162
- subject.stubs(:execute).with([:launchctl, :unload, joblabel])
169
+ subject.expects(:execute).with([:launchctl, :unload, joblabel])
163
170
  subject.stubs(:resource).returns({:name => joblabel, :enable => :true})
164
171
  subject.stop
165
172
  end
@@ -168,8 +175,8 @@ describe Puppet::Type.type(:service).provider(:launchd) do
168
175
  describe "when disabling the service" do
169
176
  it "should look for the relevant plist once" do
170
177
  subject.expects(:plist_from_label).returns([joblabel, {}]).once
171
- subject.stubs(:enabled?).returns :true
172
- subject.stubs(:execute).with([:launchctl, :unload, '-w', joblabel])
178
+ subject.expects(:enabled?).returns :true
179
+ subject.expects(:execute).with([:launchctl, :unload, '-w', joblabel])
173
180
  subject.stubs(:resource).returns({:name => joblabel, :enable => :false})
174
181
  subject.stop
175
182
  end
@@ -177,8 +184,8 @@ describe Puppet::Type.type(:service).provider(:launchd) do
177
184
 
178
185
  describe "when enabling the service on OS X 10.6" do
179
186
  it "should write to the global launchd overrides file once" do
180
- provider.stubs(:get_macosx_version_major).returns("10.6")
181
- provider.stubs(:read_plist).returns({})
187
+ provider.expects(:get_macosx_version_major).returns("10.6")
188
+ provider.expects(:read_plist).returns({})
182
189
  Plist::Emit.expects(:save_plist).once
183
190
  subject.stubs(:resource).returns({:name => joblabel, :enable => :true})
184
191
  subject.enable
@@ -200,15 +207,13 @@ describe Puppet::Type.type(:service).provider(:launchd) do
200
207
  provider.instance_variable_set(:@macosx_version_major, nil)
201
208
  end
202
209
  it "should display a deprecation warning" do
203
- Facter.stubs(:value).with(:macosx_productversion_major).returns(nil)
204
- Facter.stubs(:value).with(:kernel).returns('Darwin')
205
- Facter.stubs(:value).with(:macosx_productversion).returns('10.5.8')
210
+ Facter.expects(:value).with(:macosx_productversion_major).returns(nil)
211
+ Facter.expects(:value).with(:macosx_productversion).returns('10.5.8')
212
+ Facter.expects(:loadfacts)
206
213
  Puppet::Util::Warnings.expects(:maybe_log)
207
- provider.stubs(:read_plist).returns({joblabel => {"Disabled" => false}})
208
- subject.stubs(:plist_from_label).returns([joblabel, {"Disabled" => false}])
209
- subject.stubs(:enabled?).returns :false
210
- subject.stubs(:execute).with([:launchctl, :load, '-w', joblabel]).returns('')
211
- File.stubs(:open).returns('')
214
+ subject.expects(:plist_from_label).returns([joblabel, {"Disabled" => false}])
215
+ subject.expects(:enabled?).returns :false
216
+ File.expects(:open).returns('')
212
217
  subject.stubs(:resource).returns({:name => joblabel, :enable => :true})
213
218
  subject.enable
214
219
  end