puppet 2.7.6 → 2.7.8

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 (206) hide show
  1. data/CHANGELOG +168 -0
  2. data/conf/auth.conf +5 -4
  3. data/conf/redhat/puppet.spec +16 -1
  4. data/conf/solaris/pkginfo +2 -2
  5. data/conf/suse/puppet.spec +9 -3
  6. data/ext/upload_facts.rb +120 -0
  7. data/install.rb +11 -16
  8. data/lib/puppet.rb +1 -1
  9. data/lib/puppet/application/agent.rb +0 -3
  10. data/lib/puppet/application/apply.rb +0 -3
  11. data/lib/puppet/application/queue.rb +21 -1
  12. data/lib/puppet/defaults.rb +6 -4
  13. data/lib/puppet/face/file/store.rb +1 -1
  14. data/lib/puppet/feature/base.rb +2 -1
  15. data/lib/puppet/file_bucket/dipper.rb +3 -2
  16. data/lib/puppet/file_serving/content.rb +1 -1
  17. data/lib/puppet/file_serving/metadata.rb +5 -2
  18. data/lib/puppet/indirector/facts/inventory_service.rb +20 -0
  19. data/lib/puppet/indirector/file_bucket_file/file.rb +3 -2
  20. data/lib/puppet/indirector/report/processor.rb +1 -1
  21. data/lib/puppet/network/handler/filebucket.rb +2 -0
  22. data/lib/puppet/network/handler/fileserver.rb +1 -1
  23. data/lib/puppet/network/handler/master.rb +1 -0
  24. data/lib/puppet/network/handler/report.rb +2 -0
  25. data/lib/puppet/network/handler/runner.rb +1 -0
  26. data/lib/puppet/network/handler/status.rb +2 -0
  27. data/lib/puppet/network/http/mongrel/rest.rb +8 -1
  28. data/lib/puppet/network/http_server.rb +3 -0
  29. data/lib/puppet/network/http_server/mongrel.rb +129 -0
  30. data/lib/puppet/network/rest_authconfig.rb +12 -4
  31. data/lib/puppet/parameter.rb +18 -0
  32. data/lib/puppet/parser/compiler.rb +1 -1
  33. data/lib/puppet/parser/grammar.ra +1 -1
  34. data/lib/puppet/parser/parser.rb +360 -350
  35. data/lib/puppet/property.rb +3 -3
  36. data/lib/puppet/provider/augeas/augeas.rb +1 -1
  37. data/lib/puppet/provider/exec/windows.rb +6 -7
  38. data/lib/puppet/provider/file/windows.rb +9 -2
  39. data/lib/puppet/provider/group/aix.rb +8 -8
  40. data/lib/puppet/provider/group/groupadd.rb +1 -3
  41. data/lib/puppet/provider/group/ldap.rb +8 -10
  42. data/lib/puppet/provider/group/windows_adsi.rb +8 -2
  43. data/lib/puppet/provider/package/aix.rb +1 -1
  44. data/lib/puppet/provider/package/macports.rb +3 -3
  45. data/lib/puppet/provider/package/msi.rb +12 -5
  46. data/lib/puppet/provider/package/nim.rb +1 -1
  47. data/lib/puppet/provider/package/pkgdmg.rb +3 -3
  48. data/lib/puppet/provider/package/ports.rb +1 -1
  49. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +560 -0
  50. data/lib/puppet/provider/service/base.rb +2 -2
  51. data/lib/puppet/provider/service/bsd.rb +4 -3
  52. data/lib/puppet/provider/service/daemontools.rb +25 -25
  53. data/lib/puppet/provider/service/debian.rb +6 -4
  54. data/lib/puppet/provider/service/freebsd.rb +1 -1
  55. data/lib/puppet/provider/service/gentoo.rb +4 -3
  56. data/lib/puppet/provider/service/init.rb +3 -8
  57. data/lib/puppet/provider/service/launchd.rb +129 -96
  58. data/lib/puppet/provider/service/redhat.rb +2 -3
  59. data/lib/puppet/provider/service/runit.rb +20 -20
  60. data/lib/puppet/provider/service/smf.rb +8 -7
  61. data/lib/puppet/provider/service/src.rb +5 -6
  62. data/lib/puppet/provider/service/systemd.rb +1 -1
  63. data/lib/puppet/provider/service/upstart.rb +3 -5
  64. data/lib/puppet/provider/service/windows.rb +7 -7
  65. data/lib/puppet/provider/sshkey/parsed.rb +2 -3
  66. data/lib/puppet/provider/user/aix.rb +21 -21
  67. data/lib/puppet/provider/user/hpux.rb +3 -1
  68. data/lib/puppet/provider/user/ldap.rb +7 -7
  69. data/lib/puppet/provider/user/user_role_add.rb +10 -6
  70. data/lib/puppet/provider/user/useradd.rb +3 -1
  71. data/lib/puppet/provider/user/windows_adsi.rb +4 -3
  72. data/lib/puppet/rb_tree_map.rb +388 -0
  73. data/lib/puppet/reference/configuration.rb +7 -7
  74. data/lib/puppet/reference/indirection.rb +5 -6
  75. data/lib/puppet/reference/metaparameter.rb +3 -1
  76. data/lib/puppet/reference/network.rb +8 -8
  77. data/lib/puppet/reference/providers.rb +17 -21
  78. data/lib/puppet/reference/type.rb +12 -9
  79. data/lib/puppet/resource.rb +2 -5
  80. data/lib/puppet/resource/catalog.rb +1 -1
  81. data/lib/puppet/ssl/certificate_request.rb +70 -0
  82. data/lib/puppet/ssl/host.rb +6 -0
  83. data/lib/puppet/transaction.rb +158 -55
  84. data/lib/puppet/transaction/event_manager.rb +1 -1
  85. data/lib/puppet/type.rb +60 -30
  86. data/lib/puppet/type/augeas.rb +83 -49
  87. data/lib/puppet/type/computer.rb +1 -1
  88. data/lib/puppet/type/cron.rb +11 -11
  89. data/lib/puppet/type/exec.rb +28 -21
  90. data/lib/puppet/type/file.rb +17 -7
  91. data/lib/puppet/type/file/content.rb +2 -2
  92. data/lib/puppet/type/file/ensure.rb +15 -12
  93. data/lib/puppet/type/file/mode.rb +30 -5
  94. data/lib/puppet/type/file/source.rb +11 -10
  95. data/lib/puppet/type/file/target.rb +2 -2
  96. data/lib/puppet/type/filebucket.rb +1 -1
  97. data/lib/puppet/type/group.rb +4 -5
  98. data/lib/puppet/type/host.rb +1 -1
  99. data/lib/puppet/type/interface.rb +13 -10
  100. data/lib/puppet/type/k5login.rb +6 -6
  101. data/lib/puppet/type/macauthorization.rb +37 -36
  102. data/lib/puppet/type/maillist.rb +2 -2
  103. data/lib/puppet/type/mcx.rb +6 -6
  104. data/lib/puppet/type/mount.rb +3 -2
  105. data/lib/puppet/type/notify.rb +1 -1
  106. data/lib/puppet/type/package.rb +24 -23
  107. data/lib/puppet/type/router.rb +4 -1
  108. data/lib/puppet/type/schedule.rb +52 -44
  109. data/lib/puppet/type/scheduled_task.rb +222 -0
  110. data/lib/puppet/type/selmodule.rb +10 -6
  111. data/lib/puppet/type/service.rb +11 -11
  112. data/lib/puppet/type/ssh_authorized_key.rb +2 -5
  113. data/lib/puppet/type/sshkey.rb +1 -1
  114. data/lib/puppet/type/stage.rb +1 -1
  115. data/lib/puppet/type/tidy.rb +10 -8
  116. data/lib/puppet/type/user.rb +61 -53
  117. data/lib/puppet/type/vlan.rb +4 -4
  118. data/lib/puppet/type/whit.rb +6 -2
  119. data/lib/puppet/type/yumrepo.rb +33 -31
  120. data/lib/puppet/type/zfs.rb +34 -32
  121. data/lib/puppet/type/zone.rb +21 -19
  122. data/lib/puppet/type/zpool.rb +3 -3
  123. data/lib/puppet/util.rb +24 -6
  124. data/lib/puppet/util/adsi.rb +12 -7
  125. data/lib/puppet/util/checksums.rb +1 -1
  126. data/lib/puppet/util/diff.rb +1 -1
  127. data/lib/puppet/util/nagios_maker.rb +2 -2
  128. data/lib/puppet/util/reference.rb +16 -17
  129. data/lib/puppet/util/settings/file_setting.rb +14 -2
  130. data/lib/puppet/util/windows/security.rb +96 -32
  131. data/spec/integration/file_serving/terminus_helper_spec.rb +1 -1
  132. data/spec/integration/indirector/direct_file_server_spec.rb +9 -15
  133. data/spec/integration/indirector/file_content/file_server_spec.rb +1 -1
  134. data/spec/integration/indirector/file_metadata/file_server_spec.rb +1 -1
  135. data/spec/integration/provider/package_spec.rb +4 -0
  136. data/spec/integration/provider/service/init_spec.rb +8 -2
  137. data/spec/integration/reference/providers_spec.rb +1 -1
  138. data/spec/integration/ssl/certificate_request_spec.rb +1 -2
  139. data/spec/integration/ssl/certificate_revocation_list_spec.rb +1 -2
  140. data/spec/integration/ssl/host_spec.rb +1 -2
  141. data/spec/integration/transaction_spec.rb +25 -17
  142. data/spec/integration/type/exec_spec.rb +77 -0
  143. data/spec/integration/type/file_spec.rb +322 -2
  144. data/spec/integration/util/windows/security_spec.rb +393 -230
  145. data/spec/integration/util_spec.rb +16 -0
  146. data/spec/lib/puppet_spec/files.rb +3 -7
  147. data/spec/unit/application/apply_spec.rb +0 -9
  148. data/spec/unit/application/inspect_spec.rb +1 -0
  149. data/spec/unit/configurer/downloader_spec.rb +3 -3
  150. data/spec/unit/face/certificate_spec.rb +6 -2
  151. data/spec/unit/file_bucket/dipper_spec.rb +67 -10
  152. data/spec/unit/file_bucket/file_spec.rb +22 -28
  153. data/spec/unit/file_serving/content_spec.rb +1 -1
  154. data/spec/unit/file_serving/metadata_spec.rb +30 -3
  155. data/spec/unit/indirector/facts/inventory_service_spec.rb +22 -0
  156. data/spec/unit/indirector/file_bucket_file/file_spec.rb +21 -24
  157. data/spec/unit/indirector/node/store_configs_spec.rb +1 -0
  158. data/spec/unit/indirector/resource/ral_spec.rb +1 -1
  159. data/spec/unit/indirector/resource_type/parser_spec.rb +2 -2
  160. data/spec/unit/indirector/rest_spec.rb +1 -1
  161. data/spec/unit/network/handler/ca_spec.rb +1 -1
  162. data/spec/unit/network/http/mongrel/rest_spec.rb +54 -25
  163. data/spec/unit/parameter_spec.rb +36 -0
  164. data/spec/unit/parser/parser_spec.rb +4 -0
  165. data/spec/unit/property_spec.rb +2 -2
  166. data/spec/unit/provider/exec/windows_spec.rb +2 -8
  167. data/spec/unit/provider/file/posix_spec.rb +6 -0
  168. data/spec/unit/provider/file/windows_spec.rb +18 -0
  169. data/spec/unit/provider/group/windows_adsi_spec.rb +22 -6
  170. data/spec/unit/provider/mount/parsed_spec.rb +1 -1
  171. data/spec/unit/provider/package/msi_spec.rb +2 -2
  172. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +1571 -0
  173. data/spec/unit/provider/service/launchd_spec.rb +143 -130
  174. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +5 -0
  175. data/spec/unit/provider/user/user_role_add_spec.rb +39 -9
  176. data/spec/unit/provider/user/useradd_spec.rb +1 -1
  177. data/spec/unit/provider/user/windows_adsi_spec.rb +8 -1
  178. data/spec/unit/rb_tree_map_spec.rb +572 -0
  179. data/spec/unit/resource/catalog_spec.rb +1 -1
  180. data/spec/unit/simple_graph_spec.rb +9 -9
  181. data/spec/unit/ssl/host_spec.rb +60 -12
  182. data/spec/unit/transaction/report_spec.rb +3 -3
  183. data/spec/unit/transaction_spec.rb +394 -11
  184. data/spec/unit/type/exec_spec.rb +35 -15
  185. data/spec/unit/type/file/content_spec.rb +11 -10
  186. data/spec/unit/type/file/mode_spec.rb +73 -19
  187. data/spec/unit/type/file/source_spec.rb +1 -1
  188. data/spec/unit/type/file_spec.rb +15 -0
  189. data/spec/unit/type/group_spec.rb +1 -1
  190. data/spec/unit/type/mount_spec.rb +5 -5
  191. data/spec/unit/type/resources_spec.rb +3 -3
  192. data/spec/unit/type/scheduled_task_spec.rb +102 -0
  193. data/spec/unit/type/ssh_authorized_key_spec.rb +2 -3
  194. data/spec/unit/type/user_spec.rb +2 -1
  195. data/spec/unit/type_spec.rb +48 -4
  196. data/spec/unit/util/adsi_spec.rb +18 -7
  197. data/spec/unit/util/checksums_spec.rb +20 -2
  198. data/spec/unit/util/execution_stub_spec.rb +10 -5
  199. data/spec/unit/util/logging_spec.rb +6 -6
  200. data/spec/unit/util/rdoc/parser_spec.rb +1 -1
  201. data/spec/unit/util/reference_spec.rb +29 -0
  202. data/spec/unit/util/settings/file_setting_spec.rb +8 -2
  203. data/spec/unit/util_spec.rb +115 -0
  204. data/test/other/transactions.rb +5 -11
  205. data/test/ral/type/exec.rb +1 -1
  206. metadata +24 -11
@@ -0,0 +1,1571 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ require 'win32/taskscheduler' if Puppet.features.microsoft_windows?
5
+
6
+ shared_examples_for "a trigger that handles start_date and start_time" do
7
+ let(:trigger) do
8
+ described_class.new(
9
+ :name => 'Shared Test Task',
10
+ :command => 'C:\Windows\System32\notepad.exe'
11
+ ).translate_hash_to_trigger(trigger_hash)
12
+ end
13
+
14
+ before :each do
15
+ Win32::TaskScheduler.any_instance.stubs(:save)
16
+ end
17
+
18
+ describe 'the given start_date' do
19
+ before :each do
20
+ trigger_hash['start_time'] = '00:00'
21
+ end
22
+
23
+ def date_component
24
+ {
25
+ 'start_year' => trigger['start_year'],
26
+ 'start_month' => trigger['start_month'],
27
+ 'start_day' => trigger['start_day']
28
+ }
29
+ end
30
+
31
+ it 'should be able to be specified in ISO 8601 calendar date format' do
32
+ trigger_hash['start_date'] = '2011-12-31'
33
+
34
+ date_component.should == {
35
+ 'start_year' => 2011,
36
+ 'start_month' => 12,
37
+ 'start_day' => 31
38
+ }
39
+ end
40
+
41
+ it 'should fail if before 1753-01-01' do
42
+ trigger_hash['start_date'] = '1752-12-31'
43
+
44
+ expect { date_component }.to raise_error(
45
+ Puppet::Error,
46
+ 'start_date must be on or after 1753-01-01'
47
+ )
48
+ end
49
+
50
+ it 'should succeed if on 1753-01-01' do
51
+ trigger_hash['start_date'] = '1753-01-01'
52
+
53
+ date_component.should == {
54
+ 'start_year' => 1753,
55
+ 'start_month' => 1,
56
+ 'start_day' => 1
57
+ }
58
+ end
59
+
60
+ it 'should succeed if after 1753-01-01' do
61
+ trigger_hash['start_date'] = '1753-01-02'
62
+
63
+ date_component.should == {
64
+ 'start_year' => 1753,
65
+ 'start_month' => 1,
66
+ 'start_day' => 2
67
+ }
68
+ end
69
+ end
70
+
71
+ describe 'the given start_time' do
72
+ before :each do
73
+ trigger_hash['start_date'] = '2011-12-31'
74
+ end
75
+
76
+ def time_component
77
+ {
78
+ 'start_hour' => trigger['start_hour'],
79
+ 'start_minute' => trigger['start_minute']
80
+ }
81
+ end
82
+
83
+ it 'should be able to be specified as a 24-hour "hh:mm"' do
84
+ trigger_hash['start_time'] = '17:13'
85
+
86
+ time_component.should == {
87
+ 'start_hour' => 17,
88
+ 'start_minute' => 13
89
+ }
90
+ end
91
+
92
+ it 'should be able to be specified as a 12-hour "hh:mm am"' do
93
+ trigger_hash['start_time'] = '3:13 am'
94
+
95
+ time_component.should == {
96
+ 'start_hour' => 3,
97
+ 'start_minute' => 13
98
+ }
99
+ end
100
+
101
+ it 'should be able to be specified as a 12-hour "hh:mm pm"' do
102
+ trigger_hash['start_time'] = '3:13 pm'
103
+
104
+ time_component.should == {
105
+ 'start_hour' => 15,
106
+ 'start_minute' => 13
107
+ }
108
+ end
109
+ end
110
+ end
111
+
112
+ describe Puppet::Type.type(:scheduled_task).provider(:win32_taskscheduler), :if => Puppet.features.microsoft_windows? do
113
+ before :each do
114
+ Puppet::Type.type(:scheduled_task).stubs(:defaultprovider).returns(described_class)
115
+ end
116
+
117
+ describe 'when retrieving' do
118
+ before :each do
119
+ @mock_task = mock
120
+ @mock_task.responds_like(Win32::TaskScheduler.new)
121
+ described_class.any_instance.stubs(:task).returns(@mock_task)
122
+
123
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
124
+ end
125
+ let(:resource) { Puppet::Type.type(:scheduled_task).new(:name => 'Test Task', :command => 'C:\Windows\System32\notepad.exe') }
126
+
127
+ describe 'the triggers for a task' do
128
+ describe 'with only one trigger' do
129
+ before :each do
130
+ @mock_task.expects(:trigger_count).returns(1)
131
+ end
132
+
133
+ it 'should handle a single daily trigger' do
134
+ @mock_task.expects(:trigger).with(0).returns({
135
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_DAILY,
136
+ 'start_year' => 2011,
137
+ 'start_month' => 9,
138
+ 'start_day' => 12,
139
+ 'start_hour' => 13,
140
+ 'start_minute' => 20,
141
+ 'flags' => 0,
142
+ 'type' => { 'days_interval' => 2 },
143
+ })
144
+
145
+ resource.provider.trigger.should == {
146
+ 'start_date' => '2011-9-12',
147
+ 'start_time' => '13:20',
148
+ 'schedule' => 'daily',
149
+ 'every' => '2',
150
+ 'enabled' => true,
151
+ 'index' => 0,
152
+ }
153
+ end
154
+
155
+ it 'should handle a single weekly trigger' do
156
+ scheduled_days_of_week = Win32::TaskScheduler::MONDAY |
157
+ Win32::TaskScheduler::WEDNESDAY |
158
+ Win32::TaskScheduler::FRIDAY |
159
+ Win32::TaskScheduler::SUNDAY
160
+ @mock_task.expects(:trigger).with(0).returns({
161
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_WEEKLY,
162
+ 'start_year' => 2011,
163
+ 'start_month' => 9,
164
+ 'start_day' => 12,
165
+ 'start_hour' => 13,
166
+ 'start_minute' => 20,
167
+ 'flags' => 0,
168
+ 'type' => {
169
+ 'weeks_interval' => 2,
170
+ 'days_of_week' => scheduled_days_of_week
171
+ }
172
+ })
173
+
174
+ resource.provider.trigger.should == {
175
+ 'start_date' => '2011-9-12',
176
+ 'start_time' => '13:20',
177
+ 'schedule' => 'weekly',
178
+ 'every' => '2',
179
+ 'on' => ['sun', 'mon', 'wed', 'fri'],
180
+ 'enabled' => true,
181
+ 'index' => 0,
182
+ }
183
+ end
184
+
185
+ it 'should handle a single monthly date-based trigger' do
186
+ scheduled_months = Win32::TaskScheduler::JANUARY |
187
+ Win32::TaskScheduler::FEBRUARY |
188
+ Win32::TaskScheduler::AUGUST |
189
+ Win32::TaskScheduler::SEPTEMBER |
190
+ Win32::TaskScheduler::DECEMBER
191
+ # 1 3 5 15 'last'
192
+ scheduled_days = 1 | 1 << 2 | 1 << 4 | 1 << 14 | 1 << 31
193
+ @mock_task.expects(:trigger).with(0).returns({
194
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_MONTHLYDATE,
195
+ 'start_year' => 2011,
196
+ 'start_month' => 9,
197
+ 'start_day' => 12,
198
+ 'start_hour' => 13,
199
+ 'start_minute' => 20,
200
+ 'flags' => 0,
201
+ 'type' => {
202
+ 'months' => scheduled_months,
203
+ 'days' => scheduled_days
204
+ }
205
+ })
206
+
207
+ resource.provider.trigger.should == {
208
+ 'start_date' => '2011-9-12',
209
+ 'start_time' => '13:20',
210
+ 'schedule' => 'monthly',
211
+ 'months' => [1, 2, 8, 9, 12],
212
+ 'on' => [1, 3, 5, 15, 'last'],
213
+ 'enabled' => true,
214
+ 'index' => 0,
215
+ }
216
+ end
217
+
218
+ it 'should handle a single monthly day-of-week-based trigger' do
219
+ scheduled_months = Win32::TaskScheduler::JANUARY |
220
+ Win32::TaskScheduler::FEBRUARY |
221
+ Win32::TaskScheduler::AUGUST |
222
+ Win32::TaskScheduler::SEPTEMBER |
223
+ Win32::TaskScheduler::DECEMBER
224
+ scheduled_days_of_week = Win32::TaskScheduler::MONDAY |
225
+ Win32::TaskScheduler::WEDNESDAY |
226
+ Win32::TaskScheduler::FRIDAY |
227
+ Win32::TaskScheduler::SUNDAY
228
+ @mock_task.expects(:trigger).with(0).returns({
229
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_MONTHLYDOW,
230
+ 'start_year' => 2011,
231
+ 'start_month' => 9,
232
+ 'start_day' => 12,
233
+ 'start_hour' => 13,
234
+ 'start_minute' => 20,
235
+ 'flags' => 0,
236
+ 'type' => {
237
+ 'months' => scheduled_months,
238
+ 'weeks' => Win32::TaskScheduler::FIRST_WEEK,
239
+ 'days_of_week' => scheduled_days_of_week
240
+ }
241
+ })
242
+
243
+ resource.provider.trigger.should == {
244
+ 'start_date' => '2011-9-12',
245
+ 'start_time' => '13:20',
246
+ 'schedule' => 'monthly',
247
+ 'months' => [1, 2, 8, 9, 12],
248
+ 'which_occurrence' => 'first',
249
+ 'day_of_week' => ['sun', 'mon', 'wed', 'fri'],
250
+ 'enabled' => true,
251
+ 'index' => 0,
252
+ }
253
+ end
254
+
255
+ it 'should handle a single one-time trigger' do
256
+ @mock_task.expects(:trigger).with(0).returns({
257
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
258
+ 'start_year' => 2011,
259
+ 'start_month' => 9,
260
+ 'start_day' => 12,
261
+ 'start_hour' => 13,
262
+ 'start_minute' => 20,
263
+ 'flags' => 0,
264
+ })
265
+
266
+ resource.provider.trigger.should == {
267
+ 'start_date' => '2011-9-12',
268
+ 'start_time' => '13:20',
269
+ 'schedule' => 'once',
270
+ 'enabled' => true,
271
+ 'index' => 0,
272
+ }
273
+ end
274
+ end
275
+
276
+ it 'should handle multiple triggers' do
277
+ @mock_task.expects(:trigger_count).returns(3)
278
+ @mock_task.expects(:trigger).with(0).returns({
279
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
280
+ 'start_year' => 2011,
281
+ 'start_month' => 10,
282
+ 'start_day' => 13,
283
+ 'start_hour' => 14,
284
+ 'start_minute' => 21,
285
+ 'flags' => 0,
286
+ })
287
+ @mock_task.expects(:trigger).with(1).returns({
288
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
289
+ 'start_year' => 2012,
290
+ 'start_month' => 11,
291
+ 'start_day' => 14,
292
+ 'start_hour' => 15,
293
+ 'start_minute' => 22,
294
+ 'flags' => 0,
295
+ })
296
+ @mock_task.expects(:trigger).with(2).returns({
297
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
298
+ 'start_year' => 2013,
299
+ 'start_month' => 12,
300
+ 'start_day' => 15,
301
+ 'start_hour' => 16,
302
+ 'start_minute' => 23,
303
+ 'flags' => 0,
304
+ })
305
+
306
+ resource.provider.trigger.should =~ [
307
+ {
308
+ 'start_date' => '2011-10-13',
309
+ 'start_time' => '14:21',
310
+ 'schedule' => 'once',
311
+ 'enabled' => true,
312
+ 'index' => 0,
313
+ },
314
+ {
315
+ 'start_date' => '2012-11-14',
316
+ 'start_time' => '15:22',
317
+ 'schedule' => 'once',
318
+ 'enabled' => true,
319
+ 'index' => 1,
320
+ },
321
+ {
322
+ 'start_date' => '2013-12-15',
323
+ 'start_time' => '16:23',
324
+ 'schedule' => 'once',
325
+ 'enabled' => true,
326
+ 'index' => 2,
327
+ }
328
+ ]
329
+ end
330
+
331
+ it 'should skip triggers Win32::TaskScheduler cannot handle' do
332
+ @mock_task.expects(:trigger_count).returns(3)
333
+ @mock_task.expects(:trigger).with(0).returns({
334
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
335
+ 'start_year' => 2011,
336
+ 'start_month' => 10,
337
+ 'start_day' => 13,
338
+ 'start_hour' => 14,
339
+ 'start_minute' => 21,
340
+ 'flags' => 0,
341
+ })
342
+ @mock_task.expects(:trigger).with(1).raises(
343
+ Win32::TaskScheduler::Error.new('Unhandled trigger type!')
344
+ )
345
+ @mock_task.expects(:trigger).with(2).returns({
346
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
347
+ 'start_year' => 2013,
348
+ 'start_month' => 12,
349
+ 'start_day' => 15,
350
+ 'start_hour' => 16,
351
+ 'start_minute' => 23,
352
+ 'flags' => 0,
353
+ })
354
+
355
+ resource.provider.trigger.should =~ [
356
+ {
357
+ 'start_date' => '2011-10-13',
358
+ 'start_time' => '14:21',
359
+ 'schedule' => 'once',
360
+ 'enabled' => true,
361
+ 'index' => 0,
362
+ },
363
+ {
364
+ 'start_date' => '2013-12-15',
365
+ 'start_time' => '16:23',
366
+ 'schedule' => 'once',
367
+ 'enabled' => true,
368
+ 'index' => 2,
369
+ }
370
+ ]
371
+ end
372
+
373
+ it 'should skip trigger types Puppet does not handle' do
374
+ @mock_task.expects(:trigger_count).returns(3)
375
+ @mock_task.expects(:trigger).with(0).returns({
376
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
377
+ 'start_year' => 2011,
378
+ 'start_month' => 10,
379
+ 'start_day' => 13,
380
+ 'start_hour' => 14,
381
+ 'start_minute' => 21,
382
+ 'flags' => 0,
383
+ })
384
+ @mock_task.expects(:trigger).with(1).returns({
385
+ 'trigger_type' => Win32::TaskScheduler::TASK_EVENT_TRIGGER_AT_LOGON,
386
+ })
387
+ @mock_task.expects(:trigger).with(2).returns({
388
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
389
+ 'start_year' => 2013,
390
+ 'start_month' => 12,
391
+ 'start_day' => 15,
392
+ 'start_hour' => 16,
393
+ 'start_minute' => 23,
394
+ 'flags' => 0,
395
+ })
396
+
397
+ resource.provider.trigger.should =~ [
398
+ {
399
+ 'start_date' => '2011-10-13',
400
+ 'start_time' => '14:21',
401
+ 'schedule' => 'once',
402
+ 'enabled' => true,
403
+ 'index' => 0,
404
+ },
405
+ {
406
+ 'start_date' => '2013-12-15',
407
+ 'start_time' => '16:23',
408
+ 'schedule' => 'once',
409
+ 'enabled' => true,
410
+ 'index' => 2,
411
+ }
412
+ ]
413
+ end
414
+ end
415
+
416
+ it 'should get the working directory from the working_directory on the task' do
417
+ @mock_task.expects(:working_directory).returns('C:\Windows\System32')
418
+
419
+ resource.provider.working_dir.should == 'C:\Windows\System32'
420
+ end
421
+
422
+ it 'should get the command from the application_name on the task' do
423
+ @mock_task.expects(:application_name).returns('C:\Windows\System32\notepad.exe')
424
+
425
+ resource.provider.command.should == 'C:\Windows\System32\notepad.exe'
426
+ end
427
+
428
+ it 'should get the command arguments from the parameters on the task' do
429
+ @mock_task.expects(:parameters).returns('these are my arguments')
430
+
431
+ resource.provider.arguments.should == 'these are my arguments'
432
+ end
433
+
434
+ it 'should get the user from the account_information on the task' do
435
+ @mock_task.expects(:account_information).returns('this is my user')
436
+
437
+ resource.provider.user.should == 'this is my user'
438
+ end
439
+
440
+ describe 'whether the task is enabled' do
441
+ it 'should report tasks with the disabled bit set as disabled' do
442
+ @mock_task.stubs(:flags).returns(Win32::TaskScheduler::DISABLED)
443
+
444
+ resource.provider.enabled.should == :false
445
+ end
446
+
447
+ it 'should report tasks without the disabled bit set as enabled' do
448
+ @mock_task.stubs(:flags).returns(~Win32::TaskScheduler::DISABLED)
449
+
450
+ resource.provider.enabled.should == :true
451
+ end
452
+
453
+ it 'should not consider triggers for determining if the task is enabled' do
454
+ @mock_task.stubs(:flags).returns(~Win32::TaskScheduler::DISABLED)
455
+ @mock_task.stubs(:trigger_count).returns(1)
456
+ @mock_task.stubs(:trigger).with(0).returns({
457
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
458
+ 'start_year' => 2011,
459
+ 'start_month' => 10,
460
+ 'start_day' => 13,
461
+ 'start_hour' => 14,
462
+ 'start_minute' => 21,
463
+ 'flags' => Win32::TaskScheduler::TASK_TRIGGER_FLAG_DISABLED,
464
+ })
465
+
466
+ resource.provider.enabled.should == :true
467
+ end
468
+ end
469
+ end
470
+
471
+ describe '#exists?' do
472
+ before :each do
473
+ @mock_task = mock
474
+ @mock_task.responds_like(Win32::TaskScheduler.new)
475
+ described_class.any_instance.stubs(:task).returns(@mock_task)
476
+
477
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
478
+ end
479
+ let(:resource) { Puppet::Type.type(:scheduled_task).new(:name => 'Test Task', :command => 'C:\Windows\System32\notepad.exe') }
480
+
481
+ it "should delegate to Win32::TaskScheduler using the resource's name" do
482
+ @mock_task.expects(:exists?).with('Test Task').returns(true)
483
+
484
+ resource.provider.exists?.should == true
485
+ end
486
+ end
487
+
488
+ describe '#clear_task' do
489
+ before :each do
490
+ @mock_task = mock
491
+ @new_mock_task = mock
492
+ @mock_task.responds_like(Win32::TaskScheduler.new)
493
+ @new_mock_task.responds_like(Win32::TaskScheduler.new)
494
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task, @new_mock_task)
495
+
496
+ described_class.any_instance.stubs(:exists?).returns(false)
497
+ end
498
+ let(:resource) { Puppet::Type.type(:scheduled_task).new(:name => 'Test Task', :command => 'C:\Windows\System32\notepad.exe') }
499
+
500
+ it 'should clear the cached task object' do
501
+ resource.provider.task.should == @mock_task
502
+ resource.provider.task.should == @mock_task
503
+
504
+ resource.provider.clear_task
505
+
506
+ resource.provider.task.should == @new_mock_task
507
+ end
508
+
509
+ it 'should clear the cached list of triggers for the task' do
510
+ @mock_task.stubs(:trigger_count).returns(1)
511
+ @mock_task.stubs(:trigger).with(0).returns({
512
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
513
+ 'start_year' => 2011,
514
+ 'start_month' => 10,
515
+ 'start_day' => 13,
516
+ 'start_hour' => 14,
517
+ 'start_minute' => 21,
518
+ 'flags' => 0,
519
+ })
520
+ @new_mock_task.stubs(:trigger_count).returns(1)
521
+ @new_mock_task.stubs(:trigger).with(0).returns({
522
+ 'trigger_type' => Win32::TaskScheduler::TASK_TIME_TRIGGER_ONCE,
523
+ 'start_year' => 2012,
524
+ 'start_month' => 11,
525
+ 'start_day' => 14,
526
+ 'start_hour' => 15,
527
+ 'start_minute' => 22,
528
+ 'flags' => 0,
529
+ })
530
+
531
+ mock_task_trigger = {
532
+ 'start_date' => '2011-10-13',
533
+ 'start_time' => '14:21',
534
+ 'schedule' => 'once',
535
+ 'enabled' => true,
536
+ 'index' => 0,
537
+ }
538
+
539
+ resource.provider.trigger.should == mock_task_trigger
540
+ resource.provider.trigger.should == mock_task_trigger
541
+
542
+ resource.provider.clear_task
543
+
544
+ resource.provider.trigger.should == {
545
+ 'start_date' => '2012-11-14',
546
+ 'start_time' => '15:22',
547
+ 'schedule' => 'once',
548
+ 'enabled' => true,
549
+ 'index' => 0,
550
+ }
551
+ end
552
+ end
553
+
554
+ describe '.instances' do
555
+ it 'should use the list of .job files to construct the list of scheduled_tasks' do
556
+ job_files = ['foo.job', 'bar.job', 'baz.job']
557
+ Win32::TaskScheduler.any_instance.stubs(:tasks).returns(job_files)
558
+ job_files.each do |job|
559
+ job = File.basename(job, '.job')
560
+
561
+ described_class.expects(:new).with(:provider => :win32_taskscheduler, :name => job)
562
+ end
563
+
564
+ described_class.instances
565
+ end
566
+ end
567
+
568
+ describe '#user_insync?' do
569
+ let(:resource) { described_class.new(:name => 'foobar', :command => 'C:\Windows\System32\notepad.exe') }
570
+
571
+ before :each do
572
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('system').returns('SYSTEM SID')
573
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('joe').returns('SID A')
574
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('MACHINE\joe').returns('SID A')
575
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('bob').returns('SID B')
576
+ end
577
+
578
+ it 'should consider the user as in sync if the name matches' do
579
+ resource.should be_user_insync('joe', ['joe'])
580
+ end
581
+
582
+ it 'should consider the user as in sync if the current user is fully qualified' do
583
+ resource.should be_user_insync('MACHINE\joe', ['joe'])
584
+ end
585
+
586
+ it 'should consider a current user of the empty string to be the same as the system user' do
587
+ resource.should be_user_insync('', ['system'])
588
+ end
589
+
590
+ it 'should consider different users as being different' do
591
+ resource.should_not be_user_insync('joe', ['bob'])
592
+ end
593
+ end
594
+
595
+ describe '#trigger_insync?' do
596
+ let(:resource) { described_class.new(:name => 'foobar', :command => 'C:\Windows\System32\notepad.exe') }
597
+
598
+ it 'should not consider any extra current triggers as in sync' do
599
+ current = [
600
+ {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'},
601
+ {'start_date' => '2012-10-13', 'start_time' => '16:16', 'schedule' => 'once'}
602
+ ]
603
+ desired = {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'}
604
+
605
+ resource.should_not be_trigger_insync(current, desired)
606
+ end
607
+
608
+ it 'should not consider any extra desired triggers as in sync' do
609
+ current = {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'}
610
+ desired = [
611
+ {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'},
612
+ {'start_date' => '2012-10-13', 'start_time' => '16:16', 'schedule' => 'once'}
613
+ ]
614
+
615
+ resource.should_not be_trigger_insync(current, desired)
616
+ end
617
+
618
+ it 'should consider triggers to be in sync if the sets of current and desired triggers are equal' do
619
+ current = [
620
+ {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'},
621
+ {'start_date' => '2012-10-13', 'start_time' => '16:16', 'schedule' => 'once'}
622
+ ]
623
+ desired = [
624
+ {'start_date' => '2011-09-12', 'start_time' => '15:15', 'schedule' => 'once'},
625
+ {'start_date' => '2012-10-13', 'start_time' => '16:16', 'schedule' => 'once'}
626
+ ]
627
+
628
+ resource.should be_trigger_insync(current, desired)
629
+ end
630
+ end
631
+
632
+ describe '#triggers_same?' do
633
+ let(:provider) { described_class.new(:name => 'foobar', :command => 'C:\Windows\System32\notepad.exe') }
634
+
635
+ it "should not consider a disabled 'current' trigger to be the same" do
636
+ current = {'schedule' => 'once', 'enabled' => false}
637
+ desired = {'schedule' => 'once'}
638
+
639
+ provider.should_not be_triggers_same(current, desired)
640
+ end
641
+
642
+ it 'should not consider triggers with different schedules to be the same' do
643
+ current = {'schedule' => 'once'}
644
+ desired = {'schedule' => 'weekly'}
645
+
646
+ provider.should_not be_triggers_same(current, desired)
647
+ end
648
+
649
+ describe 'comparing daily triggers' do
650
+ it "should consider 'desired' triggers not specifying 'every' to have the same value as the 'current' trigger" do
651
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
652
+ desired = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30'}
653
+
654
+ provider.should be_triggers_same(current, desired)
655
+ end
656
+
657
+ it "should consider different 'start_dates' as different triggers" do
658
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
659
+ desired = {'schedule' => 'daily', 'start_date' => '2012-09-12', 'start_time' => '15:30', 'every' => 3}
660
+
661
+ provider.should_not be_triggers_same(current, desired)
662
+ end
663
+
664
+ it "should consider different 'start_times' as different triggers" do
665
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
666
+ desired = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:31', 'every' => 3}
667
+
668
+ provider.should_not be_triggers_same(current, desired)
669
+ end
670
+
671
+ it 'should not consider differences in date formatting to be different triggers' do
672
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
673
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-9-12', 'start_time' => '15:30', 'every' => 3}
674
+
675
+ provider.should be_triggers_same(current, desired)
676
+ end
677
+
678
+ it 'should not consider differences in time formatting to be different triggers' do
679
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '5:30', 'every' => 3}
680
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '05:30', 'every' => 3}
681
+
682
+ provider.should be_triggers_same(current, desired)
683
+ end
684
+
685
+ it "should consider different 'every' as different triggers" do
686
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
687
+ desired = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 1}
688
+
689
+ provider.should_not be_triggers_same(current, desired)
690
+ end
691
+
692
+ it 'should consider triggers that are the same as being the same' do
693
+ trigger = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '01:30', 'every' => 1}
694
+
695
+ provider.should be_triggers_same(trigger, trigger)
696
+ end
697
+ end
698
+
699
+ describe 'comparing one-time triggers' do
700
+ it "should consider different 'start_dates' as different triggers" do
701
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30'}
702
+ desired = {'schedule' => 'daily', 'start_date' => '2012-09-12', 'start_time' => '15:30'}
703
+
704
+ provider.should_not be_triggers_same(current, desired)
705
+ end
706
+
707
+ it "should consider different 'start_times' as different triggers" do
708
+ current = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:30'}
709
+ desired = {'schedule' => 'daily', 'start_date' => '2011-09-12', 'start_time' => '15:31'}
710
+
711
+ provider.should_not be_triggers_same(current, desired)
712
+ end
713
+
714
+ it 'should not consider differences in date formatting to be different triggers' do
715
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30'}
716
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-9-12', 'start_time' => '15:30'}
717
+
718
+ provider.should be_triggers_same(current, desired)
719
+ end
720
+
721
+ it 'should not consider differences in time formatting to be different triggers' do
722
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '1:30'}
723
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '01:30'}
724
+
725
+ provider.should be_triggers_same(current, desired)
726
+ end
727
+
728
+ it 'should consider triggers that are the same as being the same' do
729
+ trigger = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '01:30'}
730
+
731
+ provider.should be_triggers_same(trigger, trigger)
732
+ end
733
+ end
734
+
735
+ describe 'comparing monthly date-based triggers' do
736
+ it "should consider 'desired' triggers not specifying 'months' to have the same value as the 'current' trigger" do
737
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [3], 'on' => [1,'last']}
738
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'on' => [1, 'last']}
739
+
740
+ provider.should be_triggers_same(current, desired)
741
+ end
742
+
743
+ it "should consider different 'start_dates' as different triggers" do
744
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
745
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-10-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
746
+
747
+ provider.should_not be_triggers_same(current, desired)
748
+ end
749
+
750
+ it "should consider different 'start_times' as different triggers" do
751
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
752
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '22:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
753
+
754
+ provider.should_not be_triggers_same(current, desired)
755
+ end
756
+
757
+ it 'should not consider differences in date formatting to be different triggers' do
758
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
759
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-9-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
760
+
761
+ provider.should be_triggers_same(current, desired)
762
+ end
763
+
764
+ it 'should not consider differences in time formatting to be different triggers' do
765
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '5:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
766
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '05:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
767
+
768
+ provider.should be_triggers_same(current, desired)
769
+ end
770
+
771
+ it "should consider different 'months' as different triggers" do
772
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
773
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1], 'on' => [1, 3, 5, 7]}
774
+
775
+ provider.should_not be_triggers_same(current, desired)
776
+ end
777
+
778
+ it "should consider different 'on' as different triggers" do
779
+ current = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
780
+ desired = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 5, 7]}
781
+
782
+ provider.should_not be_triggers_same(current, desired)
783
+ end
784
+
785
+ it 'should consider triggers that are the same as being the same' do
786
+ trigger = {'schedule' => 'monthly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'months' => [1, 2], 'on' => [1, 3, 5, 7]}
787
+
788
+ provider.should be_triggers_same(trigger, trigger)
789
+ end
790
+ end
791
+
792
+ describe 'comparing monthly day-of-week-based triggers' do
793
+ it "should consider 'desired' triggers not specifying 'months' to have the same value as the 'current' trigger" do
794
+ current = {
795
+ 'schedule' => 'monthly',
796
+ 'start_date' => '2011-09-12',
797
+ 'start_time' => '15:30',
798
+ 'months' => [3],
799
+ 'which_occurrence' => 'first',
800
+ 'day_of_week' => ['mon', 'tues', 'sat']
801
+ }
802
+ desired = {
803
+ 'schedule' => 'monthly',
804
+ 'start_date' => '2011-09-12',
805
+ 'start_time' => '15:30',
806
+ 'which_occurrence' => 'first',
807
+ 'day_of_week' => ['mon', 'tues', 'sat']
808
+ }
809
+
810
+ provider.should be_triggers_same(current, desired)
811
+ end
812
+
813
+ it "should consider different 'start_dates' as different triggers" do
814
+ current = {
815
+ 'schedule' => 'monthly',
816
+ 'start_date' => '2011-09-12',
817
+ 'start_time' => '15:30',
818
+ 'months' => [3],
819
+ 'which_occurrence' => 'first',
820
+ 'day_of_week' => ['mon', 'tues', 'sat']
821
+ }
822
+ desired = {
823
+ 'schedule' => 'monthly',
824
+ 'start_date' => '2011-10-12',
825
+ 'start_time' => '15:30',
826
+ 'months' => [3],
827
+ 'which_occurrence' => 'first',
828
+ 'day_of_week' => ['mon', 'tues', 'sat']
829
+ }
830
+
831
+ provider.should_not be_triggers_same(current, desired)
832
+ end
833
+
834
+ it "should consider different 'start_times' as different triggers" do
835
+ current = {
836
+ 'schedule' => 'monthly',
837
+ 'start_date' => '2011-09-12',
838
+ 'start_time' => '15:30',
839
+ 'months' => [3],
840
+ 'which_occurrence' => 'first',
841
+ 'day_of_week' => ['mon', 'tues', 'sat']
842
+ }
843
+ desired = {
844
+ 'schedule' => 'monthly',
845
+ 'start_date' => '2011-09-12',
846
+ 'start_time' => '22:30',
847
+ 'months' => [3],
848
+ 'which_occurrence' => 'first',
849
+ 'day_of_week' => ['mon', 'tues', 'sat']
850
+ }
851
+
852
+ provider.should_not be_triggers_same(current, desired)
853
+ end
854
+
855
+ it "should consider different 'months' as different triggers" do
856
+ current = {
857
+ 'schedule' => 'monthly',
858
+ 'start_date' => '2011-09-12',
859
+ 'start_time' => '15:30',
860
+ 'months' => [3],
861
+ 'which_occurrence' => 'first',
862
+ 'day_of_week' => ['mon', 'tues', 'sat']
863
+ }
864
+ desired = {
865
+ 'schedule' => 'monthly',
866
+ 'start_date' => '2011-09-12',
867
+ 'start_time' => '15:30',
868
+ 'months' => [3, 5, 7, 9],
869
+ 'which_occurrence' => 'first',
870
+ 'day_of_week' => ['mon', 'tues', 'sat']
871
+ }
872
+
873
+ provider.should_not be_triggers_same(current, desired)
874
+ end
875
+
876
+ it "should consider different 'which_occurrence' as different triggers" do
877
+ current = {
878
+ 'schedule' => 'monthly',
879
+ 'start_date' => '2011-09-12',
880
+ 'start_time' => '15:30',
881
+ 'months' => [3],
882
+ 'which_occurrence' => 'first',
883
+ 'day_of_week' => ['mon', 'tues', 'sat']
884
+ }
885
+ desired = {
886
+ 'schedule' => 'monthly',
887
+ 'start_date' => '2011-09-12',
888
+ 'start_time' => '15:30',
889
+ 'months' => [3],
890
+ 'which_occurrence' => 'last',
891
+ 'day_of_week' => ['mon', 'tues', 'sat']
892
+ }
893
+
894
+ provider.should_not be_triggers_same(current, desired)
895
+ end
896
+
897
+ it "should consider different 'day_of_week' as different triggers" do
898
+ current = {
899
+ 'schedule' => 'monthly',
900
+ 'start_date' => '2011-09-12',
901
+ 'start_time' => '15:30',
902
+ 'months' => [3],
903
+ 'which_occurrence' => 'first',
904
+ 'day_of_week' => ['mon', 'tues', 'sat']
905
+ }
906
+ desired = {
907
+ 'schedule' => 'monthly',
908
+ 'start_date' => '2011-09-12',
909
+ 'start_time' => '15:30',
910
+ 'months' => [3],
911
+ 'which_occurrence' => 'first',
912
+ 'day_of_week' => ['fri']
913
+ }
914
+
915
+ provider.should_not be_triggers_same(current, desired)
916
+ end
917
+
918
+ it 'should consider triggers that are the same as being the same' do
919
+ trigger = {
920
+ 'schedule' => 'monthly',
921
+ 'start_date' => '2011-09-12',
922
+ 'start_time' => '15:30',
923
+ 'months' => [3],
924
+ 'which_occurrence' => 'first',
925
+ 'day_of_week' => ['mon', 'tues', 'sat']
926
+ }
927
+
928
+ provider.should be_triggers_same(trigger, trigger)
929
+ end
930
+ end
931
+
932
+ describe 'comparing weekly triggers' do
933
+ it "should consider 'desired' triggers not specifying 'day_of_week' to have the same value as the 'current' trigger" do
934
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
935
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3}
936
+
937
+ provider.should be_triggers_same(current, desired)
938
+ end
939
+
940
+ it "should consider different 'start_dates' as different triggers" do
941
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
942
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-10-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
943
+
944
+ provider.should_not be_triggers_same(current, desired)
945
+ end
946
+
947
+ it "should consider different 'start_times' as different triggers" do
948
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
949
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '22:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
950
+
951
+ provider.should_not be_triggers_same(current, desired)
952
+ end
953
+
954
+ it 'should not consider differences in date formatting to be different triggers' do
955
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
956
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-9-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
957
+
958
+ provider.should be_triggers_same(current, desired)
959
+ end
960
+
961
+ it 'should not consider differences in time formatting to be different triggers' do
962
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '1:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
963
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '01:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
964
+
965
+ provider.should be_triggers_same(current, desired)
966
+ end
967
+
968
+ it "should consider different 'every' as different triggers" do
969
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 1, 'day_of_week' => ['mon', 'wed', 'fri']}
970
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
971
+
972
+ provider.should_not be_triggers_same(current, desired)
973
+ end
974
+
975
+ it "should consider different 'day_of_week' as different triggers" do
976
+ current = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
977
+ desired = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['fri']}
978
+
979
+ provider.should_not be_triggers_same(current, desired)
980
+ end
981
+
982
+ it 'should consider triggers that are the same as being the same' do
983
+ trigger = {'schedule' => 'weekly', 'start_date' => '2011-09-12', 'start_time' => '15:30', 'every' => 3, 'day_of_week' => ['mon', 'wed', 'fri']}
984
+
985
+ provider.should be_triggers_same(trigger, trigger)
986
+ end
987
+ end
988
+ end
989
+
990
+ describe '#normalized_date' do
991
+ it 'should format the date without leading zeros' do
992
+ described_class.normalized_date('2011-01-01').should == '2011-1-1'
993
+ end
994
+ end
995
+
996
+ describe '#normalized_time' do
997
+ it 'should format the time as {24h}:{minutes}' do
998
+ described_class.normalized_time('8:37 PM').should == '20:37'
999
+ end
1000
+ end
1001
+
1002
+ describe '#translate_hash_to_trigger' do
1003
+ before :each do
1004
+ @puppet_trigger = {
1005
+ 'start_date' => '2011-1-1',
1006
+ 'start_time' => '01:10'
1007
+ }
1008
+ end
1009
+ let(:provider) { described_class.new(:name => 'Test Task', :command => 'C:\Windows\System32\notepad.exe') }
1010
+ let(:trigger) { provider.translate_hash_to_trigger(@puppet_trigger) }
1011
+
1012
+ describe 'when given a one-time trigger' do
1013
+ before :each do
1014
+ @puppet_trigger['schedule'] = 'once'
1015
+ end
1016
+
1017
+ it 'should set the trigger_type to Win32::TaskScheduler::ONCE' do
1018
+ trigger['trigger_type'].should == Win32::TaskScheduler::ONCE
1019
+ end
1020
+
1021
+ it 'should not set a type' do
1022
+ trigger.should_not be_has_key('type')
1023
+ end
1024
+
1025
+ it "should require 'start_date'" do
1026
+ @puppet_trigger.delete('start_date')
1027
+
1028
+ expect { trigger }.to raise_error(
1029
+ Puppet::Error,
1030
+ /Must specify 'start_date' when defining a one-time trigger/
1031
+ )
1032
+ end
1033
+
1034
+ it "should require 'start_time'" do
1035
+ @puppet_trigger.delete('start_time')
1036
+
1037
+ expect { trigger }.to raise_error(
1038
+ Puppet::Error,
1039
+ /Must specify 'start_time' when defining a trigger/
1040
+ )
1041
+ end
1042
+
1043
+ it_behaves_like "a trigger that handles start_date and start_time" do
1044
+ let(:trigger_hash) {{'schedule' => 'once' }}
1045
+ end
1046
+ end
1047
+
1048
+ describe 'when given a daily trigger' do
1049
+ before :each do
1050
+ @puppet_trigger['schedule'] = 'daily'
1051
+ end
1052
+
1053
+ it "should default 'every' to 1" do
1054
+ trigger['type']['days_interval'].should == 1
1055
+ end
1056
+
1057
+ it "should use the specified value for 'every'" do
1058
+ @puppet_trigger['every'] = 5
1059
+
1060
+ trigger['type']['days_interval'].should == 5
1061
+ end
1062
+
1063
+ it "should default 'start_date' to 'today'" do
1064
+ @puppet_trigger.delete('start_date')
1065
+ today = Time.now
1066
+
1067
+ trigger['start_year'].should == today.year
1068
+ trigger['start_month'].should == today.month
1069
+ trigger['start_day'].should == today.day
1070
+ end
1071
+
1072
+ it_behaves_like "a trigger that handles start_date and start_time" do
1073
+ let(:trigger_hash) {{'schedule' => 'daily', 'every' => 1}}
1074
+ end
1075
+ end
1076
+
1077
+ describe 'when given a weekly trigger' do
1078
+ before :each do
1079
+ @puppet_trigger['schedule'] = 'weekly'
1080
+ end
1081
+
1082
+ it "should default 'every' to 1" do
1083
+ trigger['type']['weeks_interval'].should == 1
1084
+ end
1085
+
1086
+ it "should use the specified value for 'every'" do
1087
+ @puppet_trigger['every'] = 4
1088
+
1089
+ trigger['type']['weeks_interval'].should == 4
1090
+ end
1091
+
1092
+ it "should default 'day_of_week' to be every day of the week" do
1093
+ trigger['type']['days_of_week'].should == Win32::TaskScheduler::MONDAY |
1094
+ Win32::TaskScheduler::TUESDAY |
1095
+ Win32::TaskScheduler::WEDNESDAY |
1096
+ Win32::TaskScheduler::THURSDAY |
1097
+ Win32::TaskScheduler::FRIDAY |
1098
+ Win32::TaskScheduler::SATURDAY |
1099
+ Win32::TaskScheduler::SUNDAY
1100
+ end
1101
+
1102
+ it "should use the specified value for 'day_of_week'" do
1103
+ @puppet_trigger['day_of_week'] = ['mon', 'wed', 'fri']
1104
+
1105
+ trigger['type']['days_of_week'].should == Win32::TaskScheduler::MONDAY |
1106
+ Win32::TaskScheduler::WEDNESDAY |
1107
+ Win32::TaskScheduler::FRIDAY
1108
+ end
1109
+
1110
+ it "should default 'start_date' to 'today'" do
1111
+ @puppet_trigger.delete('start_date')
1112
+ today = Time.now
1113
+
1114
+ trigger['start_year'].should == today.year
1115
+ trigger['start_month'].should == today.month
1116
+ trigger['start_day'].should == today.day
1117
+ end
1118
+
1119
+ it_behaves_like "a trigger that handles start_date and start_time" do
1120
+ let(:trigger_hash) {{'schedule' => 'weekly', 'every' => 1, 'day_of_week' => 'mon'}}
1121
+ end
1122
+ end
1123
+
1124
+ shared_examples_for 'a monthly schedule' do
1125
+ it "should default 'months' to be every month" do
1126
+ trigger['type']['months'].should == Win32::TaskScheduler::JANUARY |
1127
+ Win32::TaskScheduler::FEBRUARY |
1128
+ Win32::TaskScheduler::MARCH |
1129
+ Win32::TaskScheduler::APRIL |
1130
+ Win32::TaskScheduler::MAY |
1131
+ Win32::TaskScheduler::JUNE |
1132
+ Win32::TaskScheduler::JULY |
1133
+ Win32::TaskScheduler::AUGUST |
1134
+ Win32::TaskScheduler::SEPTEMBER |
1135
+ Win32::TaskScheduler::OCTOBER |
1136
+ Win32::TaskScheduler::NOVEMBER |
1137
+ Win32::TaskScheduler::DECEMBER
1138
+ end
1139
+
1140
+ it "should use the specified value for 'months'" do
1141
+ @puppet_trigger['months'] = [2, 8]
1142
+
1143
+ trigger['type']['months'].should == Win32::TaskScheduler::FEBRUARY |
1144
+ Win32::TaskScheduler::AUGUST
1145
+ end
1146
+ end
1147
+
1148
+ describe 'when given a monthly date-based trigger' do
1149
+ before :each do
1150
+ @puppet_trigger['schedule'] = 'monthly'
1151
+ @puppet_trigger['on'] = [7, 14]
1152
+ end
1153
+
1154
+ it_behaves_like 'a monthly schedule'
1155
+
1156
+ it "should not allow 'which_occurrence' to be specified" do
1157
+ @puppet_trigger['which_occurrence'] = 'first'
1158
+
1159
+ expect {trigger}.to raise_error(
1160
+ Puppet::Error,
1161
+ /Neither 'day_of_week' nor 'which_occurrence' can be specified when creating a monthly date-based trigger/
1162
+ )
1163
+ end
1164
+
1165
+ it "should not allow 'day_of_week' to be specified" do
1166
+ @puppet_trigger['day_of_week'] = 'mon'
1167
+
1168
+ expect {trigger}.to raise_error(
1169
+ Puppet::Error,
1170
+ /Neither 'day_of_week' nor 'which_occurrence' can be specified when creating a monthly date-based trigger/
1171
+ )
1172
+ end
1173
+
1174
+ it "should require 'on'" do
1175
+ @puppet_trigger.delete('on')
1176
+
1177
+ expect {trigger}.to raise_error(
1178
+ Puppet::Error,
1179
+ /Don't know how to create a 'monthly' schedule with the options: schedule, start_date, start_time/
1180
+ )
1181
+ end
1182
+
1183
+ it "should default 'start_date' to 'today'" do
1184
+ @puppet_trigger.delete('start_date')
1185
+ today = Time.now
1186
+
1187
+ trigger['start_year'].should == today.year
1188
+ trigger['start_month'].should == today.month
1189
+ trigger['start_day'].should == today.day
1190
+ end
1191
+
1192
+ it_behaves_like "a trigger that handles start_date and start_time" do
1193
+ let(:trigger_hash) {{'schedule' => 'monthly', 'months' => 1, 'on' => 1}}
1194
+ end
1195
+ end
1196
+
1197
+ describe 'when given a monthly day-of-week-based trigger' do
1198
+ before :each do
1199
+ @puppet_trigger['schedule'] = 'monthly'
1200
+ @puppet_trigger['which_occurrence'] = 'first'
1201
+ @puppet_trigger['day_of_week'] = 'mon'
1202
+ end
1203
+
1204
+ it_behaves_like 'a monthly schedule'
1205
+
1206
+ it "should not allow 'on' to be specified" do
1207
+ @puppet_trigger['on'] = 15
1208
+
1209
+ expect {trigger}.to raise_error(
1210
+ Puppet::Error,
1211
+ /Neither 'day_of_week' nor 'which_occurrence' can be specified when creating a monthly date-based trigger/
1212
+ )
1213
+ end
1214
+
1215
+ it "should require 'which_occurrence'" do
1216
+ @puppet_trigger.delete('which_occurrence')
1217
+
1218
+ expect {trigger}.to raise_error(
1219
+ Puppet::Error,
1220
+ /which_occurrence must be specified when creating a monthly day-of-week based trigger/
1221
+ )
1222
+ end
1223
+
1224
+ it "should require 'day_of_week'" do
1225
+ @puppet_trigger.delete('day_of_week')
1226
+
1227
+ expect {trigger}.to raise_error(
1228
+ Puppet::Error,
1229
+ /day_of_week must be specified when creating a monthly day-of-week based trigger/
1230
+ )
1231
+ end
1232
+
1233
+ it "should default 'start_date' to 'today'" do
1234
+ @puppet_trigger.delete('start_date')
1235
+ today = Time.now
1236
+
1237
+ trigger['start_year'].should == today.year
1238
+ trigger['start_month'].should == today.month
1239
+ trigger['start_day'].should == today.day
1240
+ end
1241
+
1242
+ it_behaves_like "a trigger that handles start_date and start_time" do
1243
+ let(:trigger_hash) {{'schedule' => 'monthly', 'months' => 1, 'which_occurrence' => 'first', 'day_of_week' => 'mon'}}
1244
+ end
1245
+ end
1246
+ end
1247
+
1248
+ describe '#validate_trigger' do
1249
+ let(:provider) { described_class.new(:name => 'Test Task', :command => 'C:\Windows\System32\notepad.exe') }
1250
+
1251
+ it 'should succeed if all passed triggers translate from hashes to triggers' do
1252
+ triggers_to_validate = [
1253
+ {'schedule' => 'once', 'start_date' => '2011-09-13', 'start_time' => '13:50'},
1254
+ {'schedule' => 'weekly', 'start_date' => '2011-09-13', 'start_time' => '13:50', 'day_of_week' => 'mon'}
1255
+ ]
1256
+
1257
+ provider.validate_trigger(triggers_to_validate).should == true
1258
+ end
1259
+
1260
+ it 'should use the exception from translate_hash_to_trigger when it fails' do
1261
+ triggers_to_validate = [
1262
+ {'schedule' => 'once', 'start_date' => '2011-09-13', 'start_time' => '13:50'},
1263
+ {'schedule' => 'monthly', 'this is invalid' => true}
1264
+ ]
1265
+
1266
+ expect {provider.validate_trigger(triggers_to_validate)}.to raise_error(
1267
+ Puppet::Error,
1268
+ /#{Regexp.escape("Unknown trigger option(s): ['this is invalid']")}/
1269
+ )
1270
+ end
1271
+ end
1272
+
1273
+ describe '#flush' do
1274
+ let(:resource) do
1275
+ Puppet::Type.type(:scheduled_task).new(
1276
+ :name => 'Test Task',
1277
+ :command => 'C:\Windows\System32\notepad.exe',
1278
+ :ensure => @ensure
1279
+ )
1280
+ end
1281
+
1282
+ before :each do
1283
+ @mock_task = mock
1284
+ @mock_task.responds_like(Win32::TaskScheduler.new)
1285
+ @mock_task.stubs(:exists?).returns(true)
1286
+ @mock_task.stubs(:activate)
1287
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
1288
+
1289
+ @command = 'C:\Windows\System32\notepad.exe'
1290
+ end
1291
+
1292
+ describe 'when :ensure is :present' do
1293
+ before :each do
1294
+ @ensure = :present
1295
+ end
1296
+
1297
+ it 'should save the task' do
1298
+ @mock_task.expects(:save)
1299
+
1300
+ resource.provider.flush
1301
+ end
1302
+
1303
+ it 'should fail if the command is not specified' do
1304
+ resource = Puppet::Type.type(:scheduled_task).new(
1305
+ :name => 'Test Task',
1306
+ :ensure => @ensure
1307
+ )
1308
+
1309
+ expect { resource.provider.flush }.to raise_error(
1310
+ Puppet::Error,
1311
+ 'Parameter command is required.'
1312
+ )
1313
+ end
1314
+ end
1315
+
1316
+ describe 'when :ensure is :absent' do
1317
+ before :each do
1318
+ @ensure = :absent
1319
+ @mock_task.stubs(:activate)
1320
+ end
1321
+
1322
+ it 'should not save the task if :ensure is :absent' do
1323
+ @mock_task.expects(:save).never
1324
+
1325
+ resource.provider.flush
1326
+ end
1327
+
1328
+ it 'should not fail if the command is not specified' do
1329
+ @mock_task.stubs(:save)
1330
+
1331
+ resource = Puppet::Type.type(:scheduled_task).new(
1332
+ :name => 'Test Task',
1333
+ :ensure => @ensure
1334
+ )
1335
+
1336
+ resource.provider.flush
1337
+ end
1338
+ end
1339
+ end
1340
+
1341
+ describe 'property setter methods' do
1342
+ let(:resource) do
1343
+ Puppet::Type.type(:scheduled_task).new(
1344
+ :name => 'Test Task',
1345
+ :command => 'C:\dummy_task.exe'
1346
+ )
1347
+ end
1348
+
1349
+ before :each do
1350
+ @mock_task = mock
1351
+ @mock_task.responds_like(Win32::TaskScheduler.new)
1352
+ @mock_task.stubs(:exists?).returns(true)
1353
+ @mock_task.stubs(:activate)
1354
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
1355
+ end
1356
+
1357
+ describe '#command=' do
1358
+ it 'should set the application_name on the task' do
1359
+ @mock_task.expects(:application_name=).with('C:\Windows\System32\notepad.exe')
1360
+
1361
+ resource.provider.command = 'C:\Windows\System32\notepad.exe'
1362
+ end
1363
+ end
1364
+
1365
+ describe '#arguments=' do
1366
+ it 'should set the parameters on the task' do
1367
+ @mock_task.expects(:parameters=).with(['/some /arguments /here'])
1368
+
1369
+ resource.provider.arguments = ['/some /arguments /here']
1370
+ end
1371
+ end
1372
+
1373
+ describe '#working_dir=' do
1374
+ it 'should set the working_directory on the task' do
1375
+ @mock_task.expects(:working_directory=).with('C:\Windows\System32')
1376
+
1377
+ resource.provider.working_dir = 'C:\Windows\System32'
1378
+ end
1379
+ end
1380
+
1381
+ describe '#enabled=' do
1382
+ it 'should set the disabled flag if the task should be disabled' do
1383
+ @mock_task.stubs(:flags).returns(0)
1384
+ @mock_task.expects(:flags=).with(Win32::TaskScheduler::DISABLED)
1385
+
1386
+ resource.provider.enabled = :false
1387
+ end
1388
+
1389
+ it 'should clear the disabled flag if the task should be enabled' do
1390
+ @mock_task.stubs(:flags).returns(Win32::TaskScheduler::DISABLED)
1391
+ @mock_task.expects(:flags=).with(0)
1392
+
1393
+ resource.provider.enabled = :true
1394
+ end
1395
+ end
1396
+
1397
+ describe '#trigger=' do
1398
+ let(:resource) do
1399
+ Puppet::Type.type(:scheduled_task).new(
1400
+ :name => 'Test Task',
1401
+ :command => 'C:\Windows\System32\notepad.exe',
1402
+ :trigger => @trigger
1403
+ )
1404
+ end
1405
+
1406
+ before :each do
1407
+ @mock_task = mock
1408
+ @mock_task.responds_like(Win32::TaskScheduler.new)
1409
+ @mock_task.stubs(:exists?).returns(true)
1410
+ @mock_task.stubs(:activate)
1411
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
1412
+ end
1413
+
1414
+ it 'should not consider all duplicate current triggers in sync with a single desired trigger' do
1415
+ @trigger = {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10'}
1416
+ current_triggers = [
1417
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10', 'index' => 0},
1418
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10', 'index' => 1},
1419
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10', 'index' => 2},
1420
+ ]
1421
+ resource.provider.stubs(:trigger).returns(current_triggers)
1422
+ @mock_task.expects(:delete_trigger).with(1)
1423
+ @mock_task.expects(:delete_trigger).with(2)
1424
+
1425
+ resource.provider.trigger = @trigger
1426
+ end
1427
+
1428
+ it 'should remove triggers not defined in the resource' do
1429
+ @trigger = {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10'}
1430
+ current_triggers = [
1431
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10', 'index' => 0},
1432
+ {'schedule' => 'once', 'start_date' => '2012-09-15', 'start_time' => '15:10', 'index' => 1},
1433
+ {'schedule' => 'once', 'start_date' => '2013-09-15', 'start_time' => '15:10', 'index' => 2},
1434
+ ]
1435
+ resource.provider.stubs(:trigger).returns(current_triggers)
1436
+ @mock_task.expects(:delete_trigger).with(1)
1437
+ @mock_task.expects(:delete_trigger).with(2)
1438
+
1439
+ resource.provider.trigger = @trigger
1440
+ end
1441
+
1442
+ it 'should add triggers defined in the resource, but not found on the system' do
1443
+ @trigger = [
1444
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10'},
1445
+ {'schedule' => 'once', 'start_date' => '2012-09-15', 'start_time' => '15:10'},
1446
+ {'schedule' => 'once', 'start_date' => '2013-09-15', 'start_time' => '15:10'},
1447
+ ]
1448
+ current_triggers = [
1449
+ {'schedule' => 'once', 'start_date' => '2011-09-15', 'start_time' => '15:10', 'index' => 0},
1450
+ ]
1451
+ resource.provider.stubs(:trigger).returns(current_triggers)
1452
+ @mock_task.expects(:trigger=).with(resource.provider.translate_hash_to_trigger(@trigger[1]))
1453
+ @mock_task.expects(:trigger=).with(resource.provider.translate_hash_to_trigger(@trigger[2]))
1454
+
1455
+ resource.provider.trigger = @trigger
1456
+ end
1457
+ end
1458
+
1459
+ describe '#user=' do
1460
+ before :each do
1461
+ @mock_task = mock
1462
+ @mock_task.responds_like(Win32::TaskScheduler.new)
1463
+ @mock_task.stubs(:exists?).returns(true)
1464
+ @mock_task.stubs(:activate)
1465
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
1466
+ end
1467
+
1468
+ it 'should use nil for user and password when setting the user to the SYSTEM account' do
1469
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('system').returns('SYSTEM SID')
1470
+
1471
+ resource = Puppet::Type.type(:scheduled_task).new(
1472
+ :name => 'Test Task',
1473
+ :command => 'C:\dummy_task.exe',
1474
+ :user => 'system'
1475
+ )
1476
+
1477
+ @mock_task.expects(:set_account_information).with(nil, nil)
1478
+
1479
+ resource.provider.user = 'system'
1480
+ end
1481
+
1482
+ it 'should use the specified user and password when setting the user to anything other than SYSTEM' do
1483
+ Puppet::Util::ADSI.stubs(:sid_for_account).with('my_user_name').returns('SID A')
1484
+
1485
+ resource = Puppet::Type.type(:scheduled_task).new(
1486
+ :name => 'Test Task',
1487
+ :command => 'C:\dummy_task.exe',
1488
+ :user => 'my_user_name',
1489
+ :password => 'my password'
1490
+ )
1491
+
1492
+ @mock_task.expects(:set_account_information).with('my_user_name', 'my password')
1493
+
1494
+ resource.provider.user = 'my_user_name'
1495
+ end
1496
+ end
1497
+ end
1498
+
1499
+ describe '#create' do
1500
+ let(:resource) do
1501
+ Puppet::Type.type(:scheduled_task).new(
1502
+ :name => 'Test Task',
1503
+ :enabled => @enabled,
1504
+ :command => @command,
1505
+ :arguments => @arguments,
1506
+ :working_dir => @working_dir,
1507
+ :trigger => { 'schedule' => 'once', 'start_date' => '2011-09-27', 'start_time' => '17:00' }
1508
+ )
1509
+ end
1510
+
1511
+ before :each do
1512
+ @enabled = :true
1513
+ @command = 'C:\Windows\System32\notepad.exe'
1514
+ @arguments = '/a /list /of /arguments'
1515
+ @working_dir = 'C:\Windows\Some\Directory'
1516
+
1517
+ @mock_task = mock
1518
+ @mock_task.responds_like(Win32::TaskScheduler.new)
1519
+ @mock_task.stubs(:exists?).returns(true)
1520
+ @mock_task.stubs(:activate)
1521
+ @mock_task.stubs(:application_name=)
1522
+ @mock_task.stubs(:parameters=)
1523
+ @mock_task.stubs(:working_directory=)
1524
+ @mock_task.stubs(:set_account_information)
1525
+ @mock_task.stubs(:flags)
1526
+ @mock_task.stubs(:flags=)
1527
+ @mock_task.stubs(:trigger_count).returns(0)
1528
+ @mock_task.stubs(:trigger=)
1529
+ @mock_task.stubs(:save)
1530
+ Win32::TaskScheduler.stubs(:new).returns(@mock_task)
1531
+
1532
+ described_class.any_instance.stubs(:sync_triggers)
1533
+ end
1534
+
1535
+ it 'should set the command' do
1536
+ resource.provider.expects(:command=).with(@command)
1537
+
1538
+ resource.provider.create
1539
+ end
1540
+
1541
+ it 'should set the arguments' do
1542
+ resource.provider.expects(:arguments=).with([@arguments])
1543
+
1544
+ resource.provider.create
1545
+ end
1546
+
1547
+ it 'should set the working_dir' do
1548
+ resource.provider.expects(:working_dir=).with(@working_dir)
1549
+
1550
+ resource.provider.create
1551
+ end
1552
+
1553
+ it "should set the user" do
1554
+ resource.provider.expects(:user=).with(:system)
1555
+
1556
+ resource.provider.create
1557
+ end
1558
+
1559
+ it 'should set the enabled property' do
1560
+ resource.provider.expects(:enabled=)
1561
+
1562
+ resource.provider.create
1563
+ end
1564
+
1565
+ it 'should sync triggers' do
1566
+ resource.provider.expects(:trigger=)
1567
+
1568
+ resource.provider.create
1569
+ end
1570
+ end
1571
+ end