puppet 2.6.17 → 2.6.18

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 (43) hide show
  1. data/CHANGELOG +25 -0
  2. data/conf/auth.conf +3 -3
  3. data/conf/redhat/puppet.spec +5 -2
  4. data/lib/puppet.rb +1 -1
  5. data/lib/puppet/indirector/catalog/compiler.rb +13 -2
  6. data/lib/puppet/indirector/errors.rb +5 -0
  7. data/lib/puppet/indirector/file_bucket_file/file.rb +4 -0
  8. data/lib/puppet/indirector/file_bucket_file/selector.rb +4 -0
  9. data/lib/puppet/indirector/indirection.rb +1 -0
  10. data/lib/puppet/indirector/request.rb +4 -0
  11. data/lib/puppet/indirector/resource/ral.rb +4 -0
  12. data/lib/puppet/indirector/resource/validator.rb +8 -0
  13. data/lib/puppet/indirector/rest.rb +4 -0
  14. data/lib/puppet/indirector/run/local.rb +4 -0
  15. data/lib/puppet/indirector/terminus.rb +20 -0
  16. data/lib/puppet/network/http/handler.rb +9 -0
  17. data/lib/puppet/network/http/rack/rest.rb +7 -2
  18. data/lib/puppet/network/http/webrick.rb +1 -0
  19. data/lib/puppet/network/http_pool.rb +17 -8
  20. data/lib/puppet/network/rest_authconfig.rb +1 -1
  21. data/lib/puppet/parser/templatewrapper.rb +13 -12
  22. data/lib/puppet/util/monkey_patches.rb +43 -0
  23. data/spec/integration/indirector/bucket_file/rest_spec.rb +1 -1
  24. data/spec/integration/indirector/catalog/compiler_spec.rb +1 -0
  25. data/spec/integration/indirector/catalog/queue_spec.rb +1 -1
  26. data/spec/integration/indirector/certificate_request/rest_spec.rb +1 -1
  27. data/spec/integration/indirector/report/rest_spec.rb +1 -1
  28. data/spec/integration/resource/catalog_spec.rb +1 -0
  29. data/spec/unit/indirector/catalog/compiler_spec.rb +30 -3
  30. data/spec/unit/indirector/indirection_spec.rb +18 -1
  31. data/spec/unit/indirector/request_spec.rb +22 -0
  32. data/spec/unit/indirector/terminus_spec.rb +186 -174
  33. data/spec/unit/network/http/handler_spec.rb +1 -0
  34. data/spec/unit/network/http/rack/rest_spec.rb +17 -0
  35. data/spec/unit/network/http/webrick_spec.rb +4 -0
  36. data/spec/unit/network/http_pool_spec.rb +93 -80
  37. data/spec/unit/network/rest_authconfig_spec.rb +16 -3
  38. data/spec/unit/parser/functions/inline_template_spec.rb +14 -1
  39. data/spec/unit/parser/functions/template_spec.rb +18 -1
  40. data/spec/unit/parser/templatewrapper_spec.rb +24 -9
  41. data/spec/unit/util/monkey_patches_spec.rb +11 -1
  42. data/test/language/snippets.rb +1 -1
  43. metadata +7 -5
@@ -54,7 +54,7 @@ describe "Filebucket REST Terminus" do
54
54
  # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
55
55
  # return.
56
56
  @file_bucket_file = stub_everything 'file_bucket_file'
57
- @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file)
57
+ @mock_model = stub('faked model', :name => "file_bucket_file", :convert_from => @file_bucket_file, :=== => true)
58
58
  Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
59
59
 
60
60
  Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
@@ -15,6 +15,7 @@ describe Puppet::Resource::Catalog::Compiler do
15
15
 
16
16
  @two = Puppet::Resource.new(:file, "/two")
17
17
  @catalog.add_resource(@one, @two)
18
+ Puppet::Resource::Catalog.indirection.terminus.stubs(:validate)
18
19
  end
19
20
 
20
21
  after { Puppet.settings.clear }
@@ -7,7 +7,7 @@ require 'puppet/resource/catalog'
7
7
  describe "Puppet::Resource::Catalog::Queue", :if => Puppet.features.pson? do
8
8
  before do
9
9
  Puppet::Resource::Catalog.indirection.terminus(:queue)
10
- @catalog = Puppet::Resource::Catalog.new
10
+ @catalog = Puppet::Resource::Catalog.new("foo")
11
11
 
12
12
  @one = Puppet::Resource.new(:file, "/one")
13
13
  @two = Puppet::Resource.new(:file, "/two")
@@ -50,7 +50,7 @@ describe "Certificate Request REST Terminus" do
50
50
  # LAK:NOTE We need to have a fake model here so that our indirected methods get
51
51
  # passed through REST; otherwise we'd be stubbing 'find', which would cause an immediate
52
52
  # return.
53
- @mock_model = stub('faked model', :name => "certificate request")
53
+ @mock_model = stub('faked model', :name => "certificate request", :=== => true)
54
54
  Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
55
55
 
56
56
  Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization).returns(true)
@@ -47,7 +47,7 @@ describe "Report REST Terminus" do
47
47
  # passed through REST; otherwise we'd be stubbing 'save', which would cause an immediate
48
48
  # return.
49
49
  @report = stub_everything 'report'
50
- @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report
50
+ @mock_model = stub_everything 'faked model', :name => "report", :convert_from => @report, :=== => true
51
51
  Puppet::Indirector::Request.any_instance.stubs(:model).returns(@mock_model)
52
52
 
53
53
  Puppet::Network::HTTP::WEBrickREST.any_instance.stubs(:check_authorization)
@@ -53,6 +53,7 @@ describe Puppet::Resource::Catalog do
53
53
  Puppet::Resource::Catalog.indirection.stubs(:terminus).returns terminus
54
54
 
55
55
  node = mock 'node'
56
+ terminus.stubs(:validate)
56
57
  terminus.expects(:find).with { |request| request.options[:use_node] == node }
57
58
  Puppet::Resource::Catalog.find("me", :use_node => node)
58
59
  end
@@ -74,13 +74,22 @@ describe Puppet::Resource::Catalog::Compiler do
74
74
  @request = stub 'request', :key => @name, :node => @name, :options => {}
75
75
  end
76
76
 
77
- it "should directly use provided nodes" do
77
+ it "should directly use provided nodes for a local request" do
78
78
  Puppet::Node.expects(:find).never
79
79
  @compiler.expects(:compile).with(@node)
80
80
  @request.stubs(:options).returns(:use_node => @node)
81
+ @request.stubs(:remote?).returns(false)
81
82
  @compiler.find(@request)
82
83
  end
83
84
 
85
+ it "rejects a provided node if the request is remote" do
86
+ @request.stubs(:options).returns(:use_node => @node)
87
+ @request.stubs(:remote?).returns(true)
88
+ expect {
89
+ @compiler.find(@request)
90
+ }.to raise_error Puppet::Error, /invalid option use_node/i
91
+ end
92
+
84
93
  it "should use the authenticated node name if no request key is provided" do
85
94
  @request.stubs(:key).returns(nil)
86
95
  Puppet::Node.expects(:find).with(@name).returns(@node)
@@ -120,6 +129,24 @@ describe Puppet::Resource::Catalog::Compiler do
120
129
  @compiler.find(@request)
121
130
  end
122
131
 
132
+ it "requires `facts_format` option if facts are passed in" do
133
+ facts = Puppet::Node::Facts.new("mynode", :afact => "avalue")
134
+ request = Puppet::Indirector::Request.new(:catalog, :find, "mynode", :facts => facts)
135
+ expect {
136
+ @compiler.find(request)
137
+ }.to raise_error ArgumentError, /no fact format provided for mynode/
138
+ end
139
+
140
+ it "rejects facts in the request from a different node" do
141
+ facts = Puppet::Node::Facts.new("differentnode", :afact => "avalue")
142
+ request = Puppet::Indirector::Request.new(
143
+ :catalog, :find, "mynode", :facts => facts, :facts_format => "unused"
144
+ )
145
+ expect {
146
+ @compiler.find(request)
147
+ }.to raise_error Puppet::Error, /fact definition for the wrong node/i
148
+ end
149
+
123
150
  it "should return the results of compiling as the catalog" do
124
151
  Puppet::Node.stubs(:find).returns(@node)
125
152
  config = mock 'config'
@@ -154,9 +181,9 @@ describe Puppet::Resource::Catalog::Compiler do
154
181
  before do
155
182
  Facter.stubs(:value).returns "something"
156
183
  @compiler = Puppet::Resource::Catalog::Compiler.new
157
- @request = stub 'request', :options => {}
184
+ @request = Puppet::Indirector::Request.new(:catalog, :find, "hostname", nil)
158
185
 
159
- @facts = stub 'facts', :save => nil
186
+ @facts = stub 'facts', :save => nil, :name => "hostname"
160
187
  end
161
188
 
162
189
  it "should do nothing if no facts are provided" do
@@ -41,7 +41,7 @@ shared_examples_for "Indirection Delegator" do
41
41
  end
42
42
  end
43
43
 
44
- request = stub 'request', :key => "me", :options => {}
44
+ request = Puppet::Indirector::Request.new(:indirection, :find, "me", nil)
45
45
 
46
46
  @indirection.stubs(:request).returns request
47
47
 
@@ -102,6 +102,16 @@ shared_examples_for "Delegation Authorizer" do
102
102
  end
103
103
  end
104
104
 
105
+ shared_examples_for "Request validator" do
106
+ it "asks the terminus to validate the request" do
107
+ @terminus.expects(:validate).raises(Puppet::Indirector::ValidationError, "Invalid")
108
+ @terminus.expects(@method).never
109
+ expect {
110
+ @indirection.send(@method, "key")
111
+ }.to raise_error Puppet::Indirector::ValidationError
112
+ end
113
+ end
114
+
105
115
  describe Puppet::Indirector::Indirection do
106
116
  after do
107
117
  Puppet::Util::Cacher.expire
@@ -145,6 +155,7 @@ describe Puppet::Indirector::Indirection do
145
155
  before :each do
146
156
  @terminus_class = mock 'terminus_class'
147
157
  @terminus = mock 'terminus'
158
+ @terminus.stubs(:validate)
148
159
  @terminus_class.stubs(:new).returns(@terminus)
149
160
  @cache = stub 'cache', :name => "mycache"
150
161
  @cache_class = mock 'cache_class'
@@ -215,6 +226,7 @@ describe Puppet::Indirector::Indirection do
215
226
 
216
227
  it_should_behave_like "Indirection Delegator"
217
228
  it_should_behave_like "Delegation Authorizer"
229
+ it_should_behave_like "Request validator"
218
230
 
219
231
  it "should return the results of the delegation" do
220
232
  @terminus.expects(:find).returns(@instance)
@@ -255,6 +267,7 @@ describe Puppet::Indirector::Indirection do
255
267
  before do
256
268
  @indirection.cache_class = :cache_terminus
257
269
  @cache_class.stubs(:new).returns(@cache)
270
+ @cache.stubs(:validate)
258
271
 
259
272
  @instance.stubs(:expired?).returns false
260
273
  end
@@ -388,6 +401,7 @@ describe Puppet::Indirector::Indirection do
388
401
 
389
402
  it_should_behave_like "Indirection Delegator"
390
403
  it_should_behave_like "Delegation Authorizer"
404
+ it_should_behave_like "Request validator"
391
405
 
392
406
  it "should return true if the head method returned true" do
393
407
  @terminus.expects(:head).returns(true)
@@ -508,6 +522,7 @@ describe Puppet::Indirector::Indirection do
508
522
 
509
523
  it_should_behave_like "Indirection Delegator"
510
524
  it_should_behave_like "Delegation Authorizer"
525
+ it_should_behave_like "Request validator"
511
526
 
512
527
  it "should return the result of removing the instance" do
513
528
  @terminus.stubs(:destroy).returns "yayness"
@@ -546,6 +561,7 @@ describe Puppet::Indirector::Indirection do
546
561
 
547
562
  it_should_behave_like "Indirection Delegator"
548
563
  it_should_behave_like "Delegation Authorizer"
564
+ it_should_behave_like "Request validator"
549
565
 
550
566
  it "should set the expiration date on any instances without one set" do
551
567
  @terminus.stubs(:search).returns([@instance])
@@ -715,6 +731,7 @@ describe Puppet::Indirector::Indirection do
715
731
  before do
716
732
  @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
717
733
  @terminus = mock 'terminus'
734
+ @terminus.stubs(:validate)
718
735
  @terminus_class = stub 'terminus class', :new => @terminus
719
736
  end
720
737
 
@@ -301,4 +301,26 @@ describe Puppet::Indirector::Request do
301
301
  lambda { @request.query_string }.should raise_error(ArgumentError)
302
302
  end
303
303
  end
304
+
305
+ describe "#remote?" do
306
+ def request(options = {})
307
+ Puppet::Indirector::Request.new('node', 'find', 'localhost', options)
308
+ end
309
+
310
+ it "should not be unless node or ip is set" do
311
+ request.should_not be_remote
312
+ end
313
+
314
+ it "should be remote if node is set" do
315
+ request(:node => 'example.com').should be_remote
316
+ end
317
+
318
+ it "should be remote if ip is set" do
319
+ request(:ip => '127.0.0.1').should be_remote
320
+ end
321
+
322
+ it "should be remote if node and ip are set" do
323
+ request(:node => 'example.com', :ip => '127.0.0.1').should be_remote
324
+ end
325
+ end
304
326
  end
@@ -1,245 +1,257 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.dirname(__FILE__) + '/../../spec_helper'
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
4
3
  require 'puppet/defaults'
5
4
  require 'puppet/indirector'
6
5
  require 'puppet/indirector/memory'
7
6
 
8
7
  describe Puppet::Indirector::Terminus do
9
- before :each do
10
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
11
- @indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil
12
- Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
13
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
14
- def self.to_s
15
- "Testing::Abstract"
8
+ before :all do
9
+ class Puppet::AbstractConcept
10
+ extend Puppet::Indirector
11
+ indirects :abstract_concept
12
+ attr_accessor :name
13
+ def initialize(name = "name")
14
+ @name = name
16
15
  end
17
16
  end
18
- @terminus_class = Class.new(@abstract_terminus) do
19
- def self.to_s
20
- "MyStuff::TermType"
21
- end
17
+
18
+ class Puppet::AbstractConcept::Freedom < Puppet::Indirector::Code
22
19
  end
23
- @terminus = @terminus_class.new
24
20
  end
25
21
 
26
- describe Puppet::Indirector::Terminus do
22
+ after :all do
23
+ # Remove the class, unlinking it from the rest of the system.
24
+ Puppet.send(:remove_const, :AbstractConcept)
25
+ end
27
26
 
28
- it "should provide a method for setting terminus class documentation" do
29
- @terminus_class.should respond_to(:desc)
30
- end
27
+ let :terminus_class do Puppet::AbstractConcept::Freedom end
28
+ let :terminus do terminus_class.new end
29
+ let :indirection do Puppet::AbstractConcept.indirection end
30
+ let :model do Puppet::AbstractConcept end
31
31
 
32
- it "should support a class-level name attribute" do
33
- @terminus_class.should respond_to(:name)
34
- end
32
+ it "should provide a method for setting terminus class documentation" do
33
+ terminus_class.should respond_to(:desc)
34
+ end
35
35
 
36
- it "should support a class-level indirection attribute" do
37
- @terminus_class.should respond_to(:indirection)
38
- end
36
+ it "should support a class-level name attribute" do
37
+ terminus_class.should respond_to(:name)
38
+ end
39
39
 
40
- it "should support a class-level terminus-type attribute" do
41
- @terminus_class.should respond_to(:terminus_type)
42
- end
40
+ it "should support a class-level indirection attribute" do
41
+ terminus_class.should respond_to(:indirection)
42
+ end
43
43
 
44
- it "should support a class-level model attribute" do
45
- @terminus_class.should respond_to(:model)
46
- end
44
+ it "should support a class-level terminus-type attribute" do
45
+ terminus_class.should respond_to(:terminus_type)
46
+ end
47
47
 
48
- it "should accept indirection instances as its indirection" do
49
- indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
50
- proc { @terminus_class.indirection = indirection }.should_not raise_error
51
- @terminus_class.indirection.should equal(indirection)
52
- end
48
+ it "should support a class-level model attribute" do
49
+ terminus_class.should respond_to(:model)
50
+ end
53
51
 
54
- it "should look up indirection instances when only a name has been provided" do
55
- indirection = mock 'indirection'
56
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
57
- @terminus_class.indirection = :myind
58
- @terminus_class.indirection.should equal(indirection)
59
- end
52
+ it "should accept indirection instances as its indirection" do
53
+ # The test is that this shouldn't raise, and should preserve the object
54
+ # instance exactly, hence "equal", not just "==".
55
+ terminus_class.indirection = indirection
56
+ terminus_class.indirection.should equal indirection
57
+ end
60
58
 
61
- it "should fail when provided a name that does not resolve to an indirection" do
62
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
63
- proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
59
+ it "should look up indirection instances when only a name has been provided" do
60
+ terminus_class.indirection = :abstract_concept
61
+ terminus_class.indirection.should equal indirection
62
+ end
64
63
 
65
- # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
66
- # anything).
67
- @terminus_class.indirection.should equal(@indirection)
68
- end
64
+ it "should fail when provided a name that does not resolve to an indirection" do
65
+ expect {
66
+ terminus_class.indirection = :exploding_whales
67
+ }.to raise_error(ArgumentError, /Could not find indirection instance/)
68
+
69
+ # We should still have the default indirection.
70
+ terminus_class.indirection.should equal indirection
69
71
  end
70
72
 
71
- describe Puppet::Indirector::Terminus, " when creating terminus classes" do
72
- it "should associate the subclass with an indirection based on the subclass constant" do
73
- @terminus.indirection.should equal(@indirection)
73
+ describe "when a terminus instance" do
74
+ it "should return the class's name as its name" do
75
+ terminus.name.should == :freedom
74
76
  end
75
77
 
76
- it "should set the subclass's type to the abstract terminus name" do
77
- @terminus.terminus_type.should == :abstract
78
+ it "should return the class's indirection as its indirection" do
79
+ terminus.indirection.should equal indirection
78
80
  end
79
81
 
80
- it "should set the subclass's name to the indirection name" do
81
- @terminus.name.should == :term_type
82
+ it "should set the instances's type to the abstract terminus type's name" do
83
+ terminus.terminus_type.should == :code
82
84
  end
83
85
 
84
- it "should set the subclass's model to the indirection model" do
85
- @indirection.expects(:model).returns :yay
86
- @terminus.model.should == :yay
86
+ it "should set the instances's model to the indirection's model" do
87
+ terminus.model.should equal indirection.model
87
88
  end
88
89
  end
89
90
 
90
- describe Puppet::Indirector::Terminus, " when a terminus instance" do
91
+ describe "when managing terminus classes" do
92
+ it "should provide a method for registering terminus classes" do
93
+ Puppet::Indirector::Terminus.should respond_to(:register_terminus_class)
94
+ end
91
95
 
92
- it "should return the class's name as its name" do
93
- @terminus.name.should == :term_type
96
+ it "should provide a method for returning terminus classes by name and type" do
97
+ terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever
98
+ Puppet::Indirector::Terminus.register_terminus_class(terminus)
99
+ Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus)
94
100
  end
95
101
 
96
- it "should return the class's indirection as its indirection" do
97
- @terminus.indirection.should equal(@indirection)
102
+ it "should set up autoloading for any terminus class types requested" do
103
+ Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2")
104
+ Puppet::Indirector::Terminus.terminus_class(:test2, :whatever)
98
105
  end
99
106
 
100
- it "should set the instances's type to the abstract terminus type's name" do
101
- @terminus.terminus_type.should == :abstract
107
+ it "should load terminus classes that are not found" do
108
+ # Set up instance loading; it would normally happen automatically
109
+ Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1"
110
+
111
+ Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay)
112
+ Puppet::Indirector::Terminus.terminus_class(:test1, :yay)
102
113
  end
103
114
 
104
- it "should set the instances's model to the indirection's model" do
105
- @indirection.expects(:model).returns :yay
106
- @terminus.model.should == :yay
115
+ it "should fail when no indirection can be found" do
116
+ Puppet::Indirector::Indirection.expects(:instance).with(:abstract_concept).returns(nil)
117
+ expect {
118
+ class Puppet::AbstractConcept::Physics < Puppet::Indirector::Code
119
+ end
120
+ }.to raise_error(ArgumentError, /Could not find indirection instance/)
107
121
  end
108
- end
109
- end
110
122
 
111
- # LAK: This could reasonably be in the Indirection instances, too. It doesn't make
112
- # a whole heckuva lot of difference, except that with the instance loading in
113
- # the Terminus base class, we have to have a check to see if we're already
114
- # instance-loading a given terminus class type.
115
- describe Puppet::Indirector::Terminus, " when managing terminus classes" do
116
- it "should provide a method for registering terminus classes" do
117
- Puppet::Indirector::Terminus.should respond_to(:register_terminus_class)
118
- end
123
+ it "should register the terminus class with the terminus base class" do
124
+ Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type|
125
+ type.indirection_name == :abstract_concept and type.name == :intellect
126
+ end
119
127
 
120
- it "should provide a method for returning terminus classes by name and type" do
121
- terminus = stub 'terminus_type', :name => :abstract, :indirection_name => :whatever
122
- Puppet::Indirector::Terminus.register_terminus_class(terminus)
123
- Puppet::Indirector::Terminus.terminus_class(:whatever, :abstract).should equal(terminus)
128
+ begin
129
+ class Puppet::AbstractConcept::Intellect < Puppet::Indirector::Code
130
+ end
131
+ ensure
132
+ Puppet::AbstractConcept.send(:remove_const, :Intellect) rescue nil
133
+ end
134
+ end
124
135
  end
125
136
 
126
- it "should set up autoloading for any terminus class types requested" do
127
- Puppet::Indirector::Terminus.expects(:instance_load).with(:test2, "puppet/indirector/test2")
128
- Puppet::Indirector::Terminus.terminus_class(:test2, :whatever)
129
- end
137
+ describe "when parsing class constants for indirection and terminus names" do
138
+ before :each do
139
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
140
+ end
130
141
 
131
- it "should load terminus classes that are not found" do
132
- # Set up instance loading; it would normally happen automatically
133
- Puppet::Indirector::Terminus.instance_load :test1, "puppet/indirector/test1"
142
+ let :subclass do
143
+ subclass = mock 'subclass'
144
+ subclass.stubs(:to_s).returns("TestInd::OneTwo")
145
+ subclass.stubs(:mark_as_abstract_terminus)
146
+ subclass
147
+ end
134
148
 
135
- Puppet::Indirector::Terminus.instance_loader(:test1).expects(:load).with(:yay)
136
- Puppet::Indirector::Terminus.terminus_class(:test1, :yay)
137
- end
149
+ it "should fail when anonymous classes are used" do
150
+ expect {
151
+ Puppet::Indirector::Terminus.inherited(Class.new)
152
+ }.to raise_error(Puppet::DevError, /Terminus subclasses must have associated constants/)
153
+ end
138
154
 
139
- it "should fail when no indirection can be found" do
140
- Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(nil)
155
+ it "should use the last term in the constant for the terminus class name" do
156
+ subclass.expects(:name=).with(:one_two)
157
+ subclass.stubs(:indirection=)
158
+ Puppet::Indirector::Terminus.inherited(subclass)
159
+ end
141
160
 
142
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
143
- def self.to_s
144
- "Abstract"
145
- end
161
+ it "should convert the terminus name to a downcased symbol" do
162
+ subclass.expects(:name=).with(:one_two)
163
+ subclass.stubs(:indirection=)
164
+ Puppet::Indirector::Terminus.inherited(subclass)
146
165
  end
147
- proc {
148
- @terminus = Class.new(@abstract_terminus) do
149
- def self.to_s
150
- "MyIndirection::TestType"
151
- end
152
- end
153
- }.should raise_error(ArgumentError)
154
- end
155
166
 
156
- it "should register the terminus class with the terminus base class" do
157
- Puppet::Indirector::Terminus.expects(:register_terminus_class).with do |type|
158
- type.indirection_name == :my_indirection and type.name == :test_terminus
167
+ it "should use the second to last term in the constant for the indirection name" do
168
+ subclass.expects(:indirection=).with(:test_ind)
169
+ subclass.stubs(:name=)
170
+ subclass.stubs(:terminus_type=)
171
+ Puppet::Indirector::Memory.inherited(subclass)
159
172
  end
160
- @indirection = stub 'indirection', :name => :my_indirection, :register_terminus_type => nil
161
- Puppet::Indirector::Indirection.expects(:instance).with(:my_indirection).returns(@indirection)
162
173
 
163
- @abstract_terminus = Class.new(Puppet::Indirector::Terminus) do
164
- def self.to_s
165
- "Abstract"
166
- end
174
+ it "should convert the indirection name to a downcased symbol" do
175
+ subclass.expects(:indirection=).with(:test_ind)
176
+ subclass.stubs(:name=)
177
+ subclass.stubs(:terminus_type=)
178
+ Puppet::Indirector::Memory.inherited(subclass)
167
179
  end
168
180
 
169
- @terminus = Class.new(@abstract_terminus) do
170
- def self.to_s
171
- "MyIndirection::TestTerminus"
172
- end
181
+ it "should convert camel case to lower case with underscores as word separators" do
182
+ subclass.expects(:name=).with(:one_two)
183
+ subclass.stubs(:indirection=)
184
+
185
+ Puppet::Indirector::Terminus.inherited(subclass)
173
186
  end
174
187
  end
175
- end
176
188
 
177
- describe Puppet::Indirector::Terminus, " when parsing class constants for indirection and terminus names" do
178
- before do
179
- @subclass = mock 'subclass'
180
- @subclass.stubs(:to_s).returns("TestInd::OneTwo")
181
- @subclass.stubs(:mark_as_abstract_terminus)
182
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
183
- end
189
+ describe "when creating terminus class types" do
190
+ before :all do
191
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
184
192
 
185
- it "should fail when anonymous classes are used" do
186
- proc { Puppet::Indirector::Terminus.inherited(Class.new) }.should raise_error(Puppet::DevError)
187
- end
193
+ class Puppet::Indirector::Terminus::TestTerminusType < Puppet::Indirector::Terminus
194
+ end
195
+ end
188
196
 
189
- it "should use the last term in the constant for the terminus class name" do
190
- @subclass.expects(:name=).with(:one_two)
191
- @subclass.stubs(:indirection=)
192
- Puppet::Indirector::Terminus.inherited(@subclass)
193
- end
197
+ after :all do
198
+ Puppet::Indirector::Terminus.send(:remove_const, :TestTerminusType)
199
+ end
194
200
 
195
- it "should convert the terminus name to a downcased symbol" do
196
- @subclass.expects(:name=).with(:one_two)
197
- @subclass.stubs(:indirection=)
198
- Puppet::Indirector::Terminus.inherited(@subclass)
199
- end
201
+ let :subclass do
202
+ Puppet::Indirector::Terminus::TestTerminusType
203
+ end
200
204
 
201
- it "should use the second to last term in the constant for the indirection name" do
202
- @subclass.expects(:indirection=).with(:test_ind)
203
- @subclass.stubs(:name=)
204
- @subclass.stubs(:terminus_type=)
205
- Puppet::Indirector::Memory.inherited(@subclass)
206
- end
205
+ it "should set the name of the abstract subclass to be its class constant" do
206
+ subclass.name.should == :test_terminus_type
207
+ end
208
+
209
+ it "should mark abstract terminus types as such" do
210
+ subclass.should be_abstract_terminus
211
+ end
207
212
 
208
- it "should convert the indirection name to a downcased symbol" do
209
- @subclass.expects(:indirection=).with(:test_ind)
210
- @subclass.stubs(:name=)
211
- @subclass.stubs(:terminus_type=)
212
- Puppet::Indirector::Memory.inherited(@subclass)
213
+ it "should not allow instances of abstract subclasses to be created" do
214
+ expect { subclass.new }.to raise_error(Puppet::DevError)
215
+ end
213
216
  end
214
217
 
215
- it "should convert camel case to lower case with underscores as word separators" do
216
- @subclass.expects(:name=).with(:one_two)
217
- @subclass.stubs(:indirection=)
218
+ describe "when validating a request" do
219
+ let :request do
220
+ Puppet::Indirector::Request.new(indirection.name, :find, "the_key", instance)
221
+ end
218
222
 
219
- Puppet::Indirector::Terminus.inherited(@subclass)
220
- end
221
- end
223
+ describe "`instance.name` does not match the key in the request" do
224
+ let(:instance) { model.new("wrong_key") }
222
225
 
223
- describe Puppet::Indirector::Terminus, " when creating terminus class types" do
224
- before do
225
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
226
- @subclass = Class.new(Puppet::Indirector::Terminus) do
227
- def self.to_s
228
- "Puppet::Indirector::Terminus::MyTermType"
226
+ it "raises an error " do
227
+ expect {
228
+ terminus.validate(request)
229
+ }.to raise_error(
230
+ Puppet::Indirector::ValidationError,
231
+ /Instance name .* does not match requested key/
232
+ )
229
233
  end
230
234
  end
231
- end
232
235
 
233
- it "should set the name of the abstract subclass to be its class constant" do
234
- @subclass.name.should equal(:my_term_type)
235
- end
236
+ describe "`instance` is not an instance of the model class" do
237
+ let(:instance) { mock "instance" }
236
238
 
237
- it "should mark abstract terminus types as such" do
238
- @subclass.should be_abstract_terminus
239
- end
239
+ it "raises an error" do
240
+ expect {
241
+ terminus.validate(request)
242
+ }.to raise_error(
243
+ Puppet::Indirector::ValidationError,
244
+ /Invalid instance type/
245
+ )
246
+ end
247
+ end
240
248
 
241
- it "should not allow instances of abstract subclasses to be created" do
242
- proc { @subclass.new }.should raise_error(Puppet::DevError)
249
+ describe "the instance key and class match the request key and model class" do
250
+ let(:instance) { model.new("the_key") }
251
+
252
+ it "passes" do
253
+ terminus.validate(request)
254
+ end
255
+ end
243
256
  end
244
257
  end
245
-