puppet 2.6.8 → 2.6.9

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 (60) hide show
  1. data/CHANGELOG +41 -0
  2. data/{README.rst → README.md} +17 -10
  3. data/conf/redhat/puppet.spec +93 -22
  4. data/ext/vim/README +2 -1
  5. data/ext/vim/ftplugin/puppet.vim +94 -0
  6. data/ext/vim/indent/puppet.vim +76 -0
  7. data/lib/puppet.rb +2 -3
  8. data/lib/puppet/application/agent.rb +3 -3
  9. data/lib/puppet/application/apply.rb +16 -5
  10. data/lib/puppet/configurer.rb +60 -56
  11. data/lib/puppet/configurer/fact_handler.rb +6 -1
  12. data/lib/puppet/defaults.rb +19 -0
  13. data/lib/puppet/file_serving/fileset.rb +1 -1
  14. data/lib/puppet/indirector/exec.rb +3 -3
  15. data/lib/puppet/indirector/queue.rb +1 -1
  16. data/lib/puppet/metatype/manager.rb +7 -20
  17. data/lib/puppet/parser/compiler.rb +17 -16
  18. data/lib/puppet/parser/resource.rb +18 -1
  19. data/lib/puppet/parser/scope.rb +2 -2
  20. data/lib/puppet/provider/mount/parsed.rb +1 -1
  21. data/lib/puppet/provider/naginator.rb +9 -1
  22. data/lib/puppet/provider/nameservice/directoryservice.rb +11 -8
  23. data/lib/puppet/provider/package/aptitude.rb +1 -0
  24. data/lib/puppet/rails/host.rb +7 -0
  25. data/lib/puppet/resource/catalog.rb +9 -3
  26. data/lib/puppet/transaction.rb +15 -26
  27. data/lib/puppet/transaction/report.rb +3 -3
  28. data/lib/puppet/type.rb +13 -24
  29. data/lib/puppet/util/queue.rb +1 -1
  30. data/lib/puppet/util/queue/stomp.rb +2 -2
  31. data/lib/puppet/util/settings/file_setting.rb +1 -0
  32. data/spec/integration/defaults_spec.rb +22 -0
  33. data/spec/integration/indirector/catalog/queue_spec.rb +2 -2
  34. data/spec/integration/type_spec.rb +11 -0
  35. data/spec/unit/application/agent_spec.rb +2 -2
  36. data/spec/unit/application/apply_spec.rb +62 -50
  37. data/spec/unit/configurer/fact_handler_spec.rb +43 -37
  38. data/spec/unit/configurer_spec.rb +404 -327
  39. data/spec/unit/file_serving/fileset_spec.rb +7 -0
  40. data/spec/unit/indirector/exec_spec.rb +4 -4
  41. data/spec/unit/indirector/node/exec_spec.rb +1 -1
  42. data/spec/unit/indirector/queue_spec.rb +4 -4
  43. data/spec/unit/node_spec.rb +1 -0
  44. data/spec/unit/parser/compiler_spec.rb +8 -46
  45. data/spec/unit/parser/resource_spec.rb +61 -3
  46. data/spec/unit/parser/scope_spec.rb +9 -3
  47. data/spec/unit/provider/nameservice/directoryservice_spec.rb +60 -0
  48. data/spec/unit/rails/host_spec.rb +8 -0
  49. data/spec/unit/resource/catalog_spec.rb +1 -1
  50. data/spec/unit/transaction/report_spec.rb +3 -3
  51. data/spec/unit/transaction_spec.rb +8 -2
  52. data/spec/unit/type_spec.rb +66 -0
  53. data/spec/unit/util/queue/stomp_spec.rb +10 -10
  54. data/spec/unit/util/settings/file_setting_spec.rb +4 -0
  55. metadata +1229 -1232
  56. data/README +0 -31
  57. data/lib/puppet/provider/nameservice/#directoryservice.rb# +0 -519
  58. data/lib/puppet/reference/#providers.rb# +0 -123
  59. data/spec/unit/indirector/certificate_status/#file_spec.rb# +0 -188
  60. data/spec/unit/resource/#type_collection_spec.rb# +0 -463
@@ -21,6 +21,13 @@ describe Puppet::FileServing::Fileset, " when initializing" do
21
21
  fileset.path.should == path
22
22
  end
23
23
 
24
+ it "should not fail if the path is just the file separator" do
25
+ path = File::SEPARATOR
26
+ File.stubs(:lstat).with(path).returns stub('stat')
27
+ fileset = Puppet::FileServing::Fileset.new(path)
28
+ fileset.path.should == path
29
+ end
30
+
24
31
  it "should fail if its path does not exist" do
25
32
  File.expects(:lstat).with("/some/file").returns nil
26
33
  proc { Puppet::FileServing::Fileset.new("/some/file") }.should raise_error(ArgumentError)
@@ -33,22 +33,22 @@ describe Puppet::Indirector::Exec do
33
33
  end
34
34
 
35
35
  it "should execute the command with the object name as the only argument" do
36
- @searcher.expects(:execute).with(%w{/echo foo})
36
+ @searcher.expects(:execute).with(%w{/echo foo}, :combine => false)
37
37
  @searcher.find(@request)
38
38
  end
39
39
 
40
40
  it "should return the output of the script" do
41
- @searcher.expects(:execute).with(%w{/echo foo}).returns("whatever")
41
+ @searcher.expects(:execute).with(%w{/echo foo}, :combine => false).returns("whatever")
42
42
  @searcher.find(@request).should == "whatever"
43
43
  end
44
44
 
45
45
  it "should return nil when the command produces no output" do
46
- @searcher.expects(:execute).with(%w{/echo foo}).returns(nil)
46
+ @searcher.expects(:execute).with(%w{/echo foo}, :combine => false).returns(nil)
47
47
  @searcher.find(@request).should be_nil
48
48
  end
49
49
 
50
50
  it "should raise an exception if there's an execution failure" do
51
- @searcher.expects(:execute).with(%w{/echo foo}).raises(Puppet::ExecutionFailure.new("message"))
51
+ @searcher.expects(:execute).with(%w{/echo foo}, :combine => false).raises(Puppet::ExecutionFailure.new("message"))
52
52
 
53
53
  lambda {@searcher.find(@request)}.should raise_exception(Puppet::Error, 'Failed to find foo via exec: message')
54
54
  end
@@ -32,7 +32,7 @@ describe Puppet::Node::Exec do
32
32
  @result = {}
33
33
  # Use a local variable so the reference is usable in the execute definition.
34
34
  result = @result
35
- @searcher.meta_def(:execute) do |command|
35
+ @searcher.meta_def(:execute) do |command, arguments|
36
36
  return YAML.dump(result)
37
37
  end
38
38
 
@@ -63,20 +63,20 @@ describe Puppet::Indirector::Queue, :if => Puppet.features.pson? do
63
63
  describe "when saving" do
64
64
  it 'should render the instance using pson' do
65
65
  @subject.expects(:render).with(:pson)
66
- @store.client.stubs(:send_message)
66
+ @store.client.stubs(:publish_message)
67
67
  @store.save(@request)
68
68
  end
69
69
 
70
- it "should send the rendered message to the appropriate queue on the client" do
70
+ it "should publish the rendered message to the appropriate queue on the client" do
71
71
  @subject.expects(:render).returns "mypson"
72
72
 
73
- @store.client.expects(:send_message).with(:my_queue, "mypson")
73
+ @store.client.expects(:publish_message).with(:my_queue, "mypson")
74
74
 
75
75
  @store.save(@request)
76
76
  end
77
77
 
78
78
  it "should catch any exceptions raised" do
79
- @store.client.expects(:send_message).raises ArgumentError
79
+ @store.client.expects(:publish_message).raises ArgumentError
80
80
 
81
81
  lambda { @store.save(@request) }.should raise_error(Puppet::Error)
82
82
  end
@@ -136,6 +136,7 @@ describe Puppet::Node, "when indirecting" do
136
136
  end
137
137
 
138
138
  it "should default to the 'plain' node terminus" do
139
+ Puppet::Node.indirection.reset_terminus_class
139
140
  Puppet::Node.indirection.terminus_class.should == :plain
140
141
  end
141
142
 
@@ -33,6 +33,14 @@ class CompilerTestResource
33
33
 
34
34
  def evaluate
35
35
  end
36
+
37
+ def file
38
+ "/fake/file/goes/here"
39
+ end
40
+
41
+ def line
42
+ "42"
43
+ end
36
44
  end
37
45
 
38
46
  describe Puppet::Parser::Compiler do
@@ -418,52 +426,6 @@ describe Puppet::Parser::Compiler do
418
426
  @compiler.catalog.should be_edge(@scope.resource, resource)
419
427
  end
420
428
 
421
- it "should add an edge to any specified stage for class resources" do
422
- other_stage = resource(:stage, "other")
423
- @compiler.add_resource(@scope, other_stage)
424
- resource = resource(:class, "foo")
425
- resource[:stage] = 'other'
426
-
427
- @compiler.add_resource(@scope, resource)
428
-
429
- @compiler.catalog.edge?(other_stage, resource).should be_true
430
- end
431
-
432
- it "should fail if a non-class resource attempts to set a stage" do
433
- other_stage = resource(:stage, "other")
434
- @compiler.add_resource(@scope, other_stage)
435
- resource = resource(:file, "foo")
436
- resource[:stage] = 'other'
437
-
438
- lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
439
- end
440
-
441
- it "should fail if an unknown stage is specified" do
442
- resource = resource(:class, "foo")
443
- resource[:stage] = 'other'
444
-
445
- lambda { @compiler.add_resource(@scope, resource) }.should raise_error(ArgumentError)
446
- end
447
-
448
- it "should add edges from the class resources to the parent's stage if no stage is specified" do
449
- main = @compiler.catalog.resource(:stage, :main)
450
- foo_stage = resource(:stage, :foo_stage)
451
- @compiler.add_resource(@scope, foo_stage)
452
- resource = resource(:class, "foo")
453
- @scope.stubs(:resource).returns(:stage => :foo_stage)
454
- @compiler.add_resource(@scope, resource)
455
-
456
- @compiler.catalog.should be_edge(foo_stage, resource)
457
- end
458
-
459
- it "should add edges from top-level class resources to the main stage if no stage is specified" do
460
- main = @compiler.catalog.resource(:stage, :main)
461
- resource = resource(:class, "foo")
462
- @compiler.add_resource(@scope, resource)
463
-
464
- @compiler.catalog.should be_edge(main, resource)
465
- end
466
-
467
429
  it "should not add non-class resources that don't specify a stage to the 'main' stage" do
468
430
  main = @compiler.catalog.resource(:stage, :main)
469
431
  resource = resource(:file, "foo")
@@ -132,9 +132,19 @@ describe Puppet::Parser::Resource do
132
132
  end
133
133
 
134
134
  describe "when evaluating" do
135
+ before do
136
+ @node = Puppet::Node.new "test-node"
137
+ @compiler = Puppet::Parser::Compiler.new @node
138
+ @catalog = Puppet::Resource::Catalog.new
139
+ source = stub('source')
140
+ source.stubs(:module_name)
141
+ @scope = Puppet::Parser::Scope.new(:compiler => @compiler, :source => source)
142
+ @catalog.add_resource(Puppet::Parser::Resource.new("stage", :main, :scope => @scope))
143
+ end
144
+
135
145
  it "should evaluate the associated AST definition" do
136
146
  definition = newdefine "mydefine"
137
- res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source)
147
+ res = Puppet::Parser::Resource.new("mydefine", "whatever", :scope => @scope, :source => @source, :catalog => @catalog)
138
148
  definition.expects(:evaluate_code).with(res)
139
149
 
140
150
  res.evaluate
@@ -142,17 +152,65 @@ describe Puppet::Parser::Resource do
142
152
 
143
153
  it "should evaluate the associated AST class" do
144
154
  @class = newclass "myclass"
145
- res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source)
155
+ res = Puppet::Parser::Resource.new("class", "myclass", :scope => @scope, :source => @source, :catalog => @catalog)
146
156
  @class.expects(:evaluate_code).with(res)
147
157
  res.evaluate
148
158
  end
149
159
 
150
160
  it "should evaluate the associated AST node" do
151
161
  nodedef = newnode("mynode")
152
- res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source)
162
+ res = Puppet::Parser::Resource.new("node", "mynode", :scope => @scope, :source => @source, :catalog => @catalog)
153
163
  nodedef.expects(:evaluate_code).with(res)
154
164
  res.evaluate
155
165
  end
166
+
167
+ it "should add an edge to any specified stage for class resources" do
168
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '')
169
+
170
+ other_stage = Puppet::Parser::Resource.new(:stage, "other", :scope => @scope, :catalog => @catalog)
171
+ @compiler.add_resource(@scope, other_stage)
172
+ resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog)
173
+ resource[:stage] = 'other'
174
+ @compiler.add_resource(@scope, resource)
175
+
176
+ resource.evaluate
177
+
178
+ @compiler.catalog.edge?(other_stage, resource).should be_true
179
+ end
180
+
181
+ it "should fail if an unknown stage is specified" do
182
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '')
183
+
184
+ resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog)
185
+ resource[:stage] = 'other'
186
+
187
+ lambda { resource.evaluate }.should raise_error(ArgumentError, /Could not find stage other specified by/)
188
+ end
189
+
190
+ it "should add edges from the class resources to the parent's stage if no stage is specified" do
191
+ main = @compiler.catalog.resource(:stage, :main)
192
+ foo_stage = Puppet::Parser::Resource.new(:stage, :foo_stage, :scope => @scope, :catalog => @catalog)
193
+ @compiler.add_resource(@scope, foo_stage)
194
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '')
195
+ resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog)
196
+ resource[:stage] = 'foo_stage'
197
+ @compiler.add_resource(@scope, resource)
198
+
199
+ resource.evaluate
200
+
201
+ @compiler.catalog.should be_edge(foo_stage, resource)
202
+ end
203
+
204
+ it "should add edges from top-level class resources to the main stage if no stage is specified" do
205
+ main = @compiler.catalog.resource(:stage, :main)
206
+ @compiler.known_resource_types.add Puppet::Resource::Type.new(:hostclass, "foo", '')
207
+ resource = Puppet::Parser::Resource.new(:class, "foo", :scope => @scope, :catalog => @catalog)
208
+ @compiler.add_resource(@scope, resource)
209
+
210
+ resource.evaluate
211
+
212
+ @compiler.catalog.should be_edge(main, resource)
213
+ end
156
214
  end
157
215
 
158
216
  describe "when finishing" do
@@ -123,7 +123,11 @@ describe Puppet::Parser::Scope do
123
123
 
124
124
  def create_class_scope(name)
125
125
  klass = newclass(name)
126
- Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
126
+
127
+ catalog = Puppet::Resource::Catalog.new
128
+ catalog.add_resource(Puppet::Parser::Resource.new("stage", :main, :scope => Puppet::Parser::Scope.new))
129
+
130
+ Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source'), :catalog => catalog).evaluate
127
131
 
128
132
  @scope.class_scope(klass)
129
133
  end
@@ -418,13 +422,15 @@ describe Puppet::Parser::Scope do
418
422
  before do
419
423
  @scopes = {}
420
424
  klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, ""))
421
- Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source')).evaluate
425
+ @catalog = Puppet::Resource::Catalog.new
426
+ @catalog.add_resource(Puppet::Parser::Resource.new("stage", :main, :scope => @scope))
427
+ Puppet::Parser::Resource.new("class", :main, :scope => @scope, :source => mock('source'), :catalog => @catalog).evaluate
422
428
  @scopes[""] = @scope.class_scope(klass)
423
429
  @scopes[""].setvar("test", "value")
424
430
 
425
431
  %w{one one::two one::two::three}.each do |name|
426
432
  klass = @scope.known_resource_types.add(Puppet::Resource::Type.new(:hostclass, name))
427
- Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source')).evaluate
433
+ Puppet::Parser::Resource.new("class", name, :scope => @scope, :source => mock('source'), :catalog => @catalog).evaluate
428
434
  @scopes[name] = @scope.class_scope(klass)
429
435
  @scopes[name].setvar("test", "value-#{name.sub(/.+::/,'')}")
430
436
  end
@@ -36,3 +36,63 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
36
36
  end
37
37
  end
38
38
  end
39
+
40
+ describe 'DirectoryService.single_report' do
41
+ it 'should fail on OS X < 10.4' do
42
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.3")
43
+
44
+ lambda {
45
+ Puppet::Provider::NameService::DirectoryService.single_report('resource_name')
46
+ }.should raise_error(RuntimeError, "Puppet does not support OS X versions < 10.4")
47
+ end
48
+
49
+ it 'should use url data on 10.4' do
50
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.4")
51
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_ds_path).returns('Users')
52
+ Puppet::Provider::NameService::DirectoryService.stubs(:list_all_present).returns(
53
+ ['root', 'user1', 'user2', 'resource_name']
54
+ )
55
+ Puppet::Provider::NameService::DirectoryService.stubs(:generate_attribute_hash)
56
+ Puppet::Provider::NameService::DirectoryService.stubs(:execute)
57
+ Puppet::Provider::NameService::DirectoryService.expects(:parse_dscl_url_data)
58
+
59
+ Puppet::Provider::NameService::DirectoryService.single_report('resource_name')
60
+ end
61
+
62
+ it 'should use plist data on > 10.4' do
63
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.5")
64
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_ds_path).returns('Users')
65
+ Puppet::Provider::NameService::DirectoryService.stubs(:list_all_present).returns(
66
+ ['root', 'user1', 'user2', 'resource_name']
67
+ )
68
+ Puppet::Provider::NameService::DirectoryService.stubs(:generate_attribute_hash)
69
+ Puppet::Provider::NameService::DirectoryService.stubs(:execute)
70
+ Puppet::Provider::NameService::DirectoryService.expects(:parse_dscl_plist_data)
71
+
72
+ Puppet::Provider::NameService::DirectoryService.single_report('resource_name')
73
+ end
74
+ end
75
+
76
+ describe 'DirectoryService.get_exec_preamble' do
77
+ it 'should fail on OS X < 10.4' do
78
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.3")
79
+
80
+ lambda {
81
+ Puppet::Provider::NameService::DirectoryService.get_exec_preamble('-list')
82
+ }.should raise_error(RuntimeError, "Puppet does not support OS X versions < 10.4")
83
+ end
84
+
85
+ it 'should use url data on 10.4' do
86
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.4")
87
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_ds_path).returns('Users')
88
+
89
+ Puppet::Provider::NameService::DirectoryService.get_exec_preamble('-list').should include("-url")
90
+ end
91
+
92
+ it 'should use plist data on > 10.4' do
93
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_macosx_version_major).returns("10.5")
94
+ Puppet::Provider::NameService::DirectoryService.stubs(:get_ds_path).returns('Users')
95
+
96
+ Puppet::Provider::NameService::DirectoryService.get_exec_preamble('-list').should include("-plist")
97
+ end
98
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require File.dirname(__FILE__) + '/../../spec_helper'
4
4
 
5
+ require 'puppet/node/environment'
6
+
5
7
  describe "Puppet::Rails::Host", :if => Puppet.features.rails? do
6
8
  def column(name, type)
7
9
  ActiveRecord::ConnectionAdapters::Column.new(name, nil, type, false)
@@ -43,6 +45,12 @@ describe "Puppet::Rails::Host", :if => Puppet.features.rails? do
43
45
  Puppet::Rails::Host.from_puppet(@node)
44
46
  end
45
47
 
48
+ it "should stringify the environment" do
49
+ host = Puppet::Rails::Host.new
50
+ host.environment = Puppet::Node::Environment.new("production")
51
+ host.environment.class.should == String
52
+ end
53
+
46
54
  it "should copy the ipaddress from the Puppet instance" do
47
55
  Puppet::Rails::Host.expects(:find_by_name).with("foo").returns @host
48
56
 
@@ -595,7 +595,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
595
595
  before :each do
596
596
  @catalog = Puppet::Resource::Catalog.new("host")
597
597
 
598
- @transaction = mock 'transaction'
598
+ @transaction = Puppet::Transaction.new(@catalog)
599
599
  Puppet::Transaction.stubs(:new).returns(@transaction)
600
600
  @transaction.stubs(:evaluate)
601
601
  @transaction.stubs(:add_times)
@@ -9,9 +9,9 @@ describe Puppet::Transaction::Report do
9
9
  Puppet::Util::Storage.stubs(:store)
10
10
  end
11
11
 
12
- it "should set its host name to the certname" do
13
- Puppet.settings.expects(:value).with(:certname).returns "myhost"
14
- Puppet::Transaction::Report.new("apply").host.should == "myhost"
12
+ it "should set its host name to the node_name_value" do
13
+ Puppet[:node_name_value] = 'mynode'
14
+ Puppet::Transaction::Report.new("apply").host.should == "mynode"
15
15
  end
16
16
 
17
17
  it "should return its host name as its name" do
@@ -88,13 +88,19 @@ describe Puppet::Transaction do
88
88
  @transaction.should_not be_any_failed
89
89
  end
90
90
 
91
- it "should be possible to replace the report object" do
91
+ it "should use the provided report object" do
92
92
  report = Puppet::Transaction::Report.new("apply")
93
- @transaction.report = report
93
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new, report)
94
94
 
95
95
  @transaction.report.should == report
96
96
  end
97
97
 
98
+ it "should create a report if none is provided" do
99
+ @transaction = Puppet::Transaction.new(Puppet::Resource::Catalog.new)
100
+
101
+ @transaction.report.should be_kind_of Puppet::Transaction::Report
102
+ end
103
+
98
104
  it "should consider a resource to have failed dependencies if any of its dependencies are failed"
99
105
 
100
106
  describe "when initializing" do
@@ -165,6 +165,72 @@ describe Puppet::Type do
165
165
  end
166
166
  end
167
167
 
168
+ describe "when creating a provider" do
169
+ before :each do
170
+ @type = Puppet::Type.newtype(:provider_test_type)
171
+ end
172
+
173
+ after :each do
174
+ @type.provider_hash.clear
175
+ end
176
+
177
+ it "should create a subclass of Puppet::Provider for the provider" do
178
+ provider = @type.provide(:test_provider)
179
+
180
+ provider.ancestors.should include(Puppet::Provider)
181
+ end
182
+
183
+ it "should use a parent class if specified" do
184
+ parent_provider = @type.provide(:parent_provider)
185
+ child_provider = @type.provide(:child_provider, :parent => parent_provider)
186
+
187
+ child_provider.ancestors.should include(parent_provider)
188
+ end
189
+
190
+ it "should use a parent class if specified by name" do
191
+ parent_provider = @type.provide(:parent_provider)
192
+ child_provider = @type.provide(:child_provider, :parent => :parent_provider)
193
+
194
+ child_provider.ancestors.should include(parent_provider)
195
+ end
196
+
197
+ it "should raise an error when the parent class can't be found" do
198
+ expect {
199
+ @type.provide(:child_provider, :parent => :parent_provider)
200
+ }.to raise_error(Puppet::DevError, /Could not find parent provider.+parent_provider/)
201
+ end
202
+
203
+ it "should ensure its type has a 'provider' parameter" do
204
+ @type.provide(:test_provider)
205
+
206
+ @type.parameters.should include(:provider)
207
+ end
208
+
209
+ it "should remove a previously registered provider with the same name" do
210
+ old_provider = @type.provide(:test_provider)
211
+ new_provider = @type.provide(:test_provider)
212
+
213
+ old_provider.should_not equal(new_provider)
214
+ end
215
+
216
+ it "should register itself as a provider for the type" do
217
+ provider = @type.provide(:test_provider)
218
+
219
+ provider.should == @type.provider(:test_provider)
220
+ end
221
+
222
+ it "should create a provider when a provider with the same name previously failed" do
223
+ @type.provide(:test_provider) do
224
+ raise "failed to create this provider"
225
+ end rescue nil
226
+
227
+ provider = @type.provide(:test_provider)
228
+
229
+ provider.ancestors.should include(Puppet::Provider)
230
+ provider.should == @type.provider(:test_provider)
231
+ end
232
+ end
233
+
168
234
  describe "when choosing a default provider" do
169
235
  it "should choose the provider with the highest specificity" do
170
236
  # Make a fake type