summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerdar Sutay <serdar@opscode.com>2014-10-22 12:39:09 -0700
committerSerdar Sutay <serdar@opscode.com>2014-10-22 12:39:09 -0700
commit937db2df6a7a44b9a4c1a9f7a65508b15e1115a1 (patch)
tree96b0c94d920eeafd4b9a263c53f2ee9141bef528
parented164c6386c89c5fbe2918ebda06028332724034 (diff)
parent099b907a763cd9e531903f858eee0940c16248e2 (diff)
downloadchef-937db2df6a7a44b9a4c1a9f7a65508b15e1115a1.tar.gz
Merge pull request #2265 from opscode/sersut/resource-list-specs
Add missing specs for List
-rw-r--r--lib/chef/resource_collection/resource_list.rb30
-rw-r--r--spec/unit/resource_collection/resource_list_spec.rb137
-rw-r--r--spec/unit/resource_collection/resource_set_spec.rb2
-rw-r--r--spec/unit/resource_collection_spec.rb127
4 files changed, 209 insertions, 87 deletions
diff --git a/lib/chef/resource_collection/resource_list.rb b/lib/chef/resource_collection/resource_list.rb
index e083cc0a9f..a26bd347aa 100644
--- a/lib/chef/resource_collection/resource_list.rb
+++ b/lib/chef/resource_collection/resource_list.rb
@@ -19,6 +19,7 @@
require 'chef/resource'
require 'chef/resource_collection/stepable_iterator'
require 'chef/resource_collection/resource_collection_serialization'
+require 'forwardable'
# This class keeps the list of all known Resources in the order they are to be executed in. It also keeps a pointer
# to the most recently executed resource so we can add resources-to-execute after this point.
@@ -27,9 +28,17 @@ class Chef
class ResourceList
include ResourceCollection::ResourceCollectionSerialization
include Enumerable
+ extend Forwardable
attr_reader :iterator
+ attr_reader :resources
+ private :resources
+ # Delegate direct access methods to the @resources array
+ # 4 extra methods here are not included in the Enumerable's instance methods
+ direct_access_methods = Enumerable.instance_methods + [ :[], :each, :each_index, :empty? ]
+ def_delegators :resources, *(direct_access_methods)
+
def initialize
@resources = Array.new
@insert_after_idx = nil
@@ -67,16 +76,6 @@ class Chef
@resources
end
- def [](index)
- @resources[index]
- end
-
- def each
- @resources.each do |resource|
- yield resource
- end
- end
-
def execute_each_resource(&resource_exec_block)
@iterator = ResourceCollection::StepableIterator.for_collection(@resources)
@iterator.each_with_index do |resource, idx|
@@ -85,17 +84,6 @@ class Chef
end
end
- def each_index
- @resources.each_index do |i|
- yield i
- end
- end
-
- def empty?
- @resources.empty?
- end
-
end
end
end
-
diff --git a/spec/unit/resource_collection/resource_list_spec.rb b/spec/unit/resource_collection/resource_list_spec.rb
new file mode 100644
index 0000000000..641fe55c8d
--- /dev/null
+++ b/spec/unit/resource_collection/resource_list_spec.rb
@@ -0,0 +1,137 @@
+#
+# Author:: Serdar Sutay (<serdar@getchef.com>)
+# Copyright:: Copyright (c) 2014 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+
+describe Chef::ResourceCollection::ResourceList do
+ let(:resource_list) { Chef::ResourceCollection::ResourceList.new() }
+ let(:resource) { Chef::Resource::ZenMaster.new("makoto") }
+ let(:second_resource) { Chef::Resource::ZenMaster.new("hattori") }
+
+ def insert_resource(res)
+ expect{ resource_list.insert(res) }.not_to raise_error
+ end
+
+ describe "initialize" do
+ it "should return a Chef::ResourceList" do
+ expect(resource_list).to be_instance_of(Chef::ResourceCollection::ResourceList)
+ end
+ end
+
+ describe "insert" do
+ it "should be able to insert a Chef::Resource" do
+ insert_resource(resource)
+ expect(resource_list[0]).to be(resource)
+ end
+
+ it "should insert things in order" do
+ insert_resource(resource)
+ insert_resource(second_resource)
+ expect(resource_list[0]).to be(resource)
+ expect(resource_list[1]).to be(second_resource)
+ end
+
+ it "should raise error when trying to install something other than Chef::Resource" do
+ expect{ resource_list.insert("not a resource") }.to raise_error(ArgumentError)
+ end
+ end
+
+ describe "accessors" do
+ it "should be able to insert with []=" do
+ expect{ resource_list[0] = resource }.not_to raise_error
+ expect{ resource_list[1] = second_resource }.not_to raise_error
+ expect(resource_list[0]).to be(resource)
+ expect(resource_list[1]).to be(second_resource)
+ end
+
+ it "should be empty by default" do
+ expect(resource_list.empty?).to be_true
+ end
+
+ describe "when resources are inserted" do
+ before do
+ insert_resource(resource)
+ insert_resource(second_resource)
+ end
+
+ it "should get resources with all_resources method" do
+ resources = resource_list.all_resources
+
+ expect(resources[0]).to be(resource)
+ expect(resources[1]).to be(second_resource)
+ end
+
+ it "should be able to get resources with each" do
+ current = 0
+ expected_resources = [resource, second_resource]
+
+ resource_list.each do |r|
+ expect(r).to be(expected_resources[current])
+ current += 1
+ end
+
+ expect(current).to eq(2)
+ end
+
+ it "should be able to get resources with each_index" do
+ current = 0
+
+ resource_list.each_index do |i|
+ expect(i).to eq(current)
+ current += 1
+ end
+
+ expect(current).to eq(2)
+ end
+
+ it "should be able to check if the list is empty" do
+ expect(resource_list.empty?).to be_false
+ end
+ end
+ end
+
+ describe "during execute" do
+ before(:each) do
+ insert_resource(resource)
+ insert_resource(second_resource)
+ end
+
+ it "should execute resources in order" do
+ current = 0
+ expected_resources = [resource, second_resource]
+
+ resource_list.execute_each_resource do |r|
+ expect(r).to be(expected_resources[current])
+ current += 1
+ end
+
+ expect(current).to eq(2)
+ end
+
+ it "should be able to insert resources on the fly" do
+ resource_to_inject = Chef::Resource::ZenMaster.new("there is no spoon")
+ expected_resources = [resource, resource_to_inject, second_resource]
+
+ resource_list.execute_each_resource do |r|
+ resource_list.insert(resource_to_inject) if r == resource
+ end
+
+ expect(resource_list.all_resources).to eq(expected_resources)
+ end
+ end
+end
diff --git a/spec/unit/resource_collection/resource_set_spec.rb b/spec/unit/resource_collection/resource_set_spec.rb
index 29b676f85a..8be31cd9f6 100644
--- a/spec/unit/resource_collection/resource_set_spec.rb
+++ b/spec/unit/resource_collection/resource_set_spec.rb
@@ -29,7 +29,7 @@ describe Chef::ResourceCollection::ResourceSet do
let(:zen_follower) { Chef::Resource::ZenFollower.new(zen_follower_name) }
describe "initialize" do
- it "should return a Chef::ResourceCollection" do
+ it "should return a Chef::ResourceSet" do
expect(collection).to be_instance_of(Chef::ResourceCollection::ResourceSet)
end
end
diff --git a/spec/unit/resource_collection_spec.rb b/spec/unit/resource_collection_spec.rb
index a575d2996c..5966fdd1f2 100644
--- a/spec/unit/resource_collection_spec.rb
+++ b/spec/unit/resource_collection_spec.rb
@@ -20,80 +20,77 @@
require 'spec_helper'
describe Chef::ResourceCollection do
-
- before(:each) do
- @rc = Chef::ResourceCollection.new()
- @resource = Chef::Resource::ZenMaster.new("makoto")
- end
+ let(:rc) { Chef::ResourceCollection.new() }
+ let(:resource) { Chef::Resource::ZenMaster.new("makoto") }
it "should throw an error when calling a non-delegated method" do
- expect { @rc.not_a_method }.to raise_error(NoMethodError)
+ expect { rc.not_a_method }.to raise_error(NoMethodError)
end
describe "initialize" do
it "should return a Chef::ResourceCollection" do
- @rc.should be_kind_of(Chef::ResourceCollection)
+ rc.should be_kind_of(Chef::ResourceCollection)
end
end
describe "[]" do
it "should accept Chef::Resources through [index]" do
- lambda { @rc[0] = @resource }.should_not raise_error
- lambda { @rc[0] = "string" }.should raise_error(ArgumentError)
+ lambda { rc[0] = resource }.should_not raise_error
+ lambda { rc[0] = "string" }.should raise_error(ArgumentError)
end
it "should allow you to fetch Chef::Resources by position" do
- @rc[0] = @resource
- @rc[0].should eql(@resource)
+ rc[0] = resource
+ rc[0].should eql(resource)
end
end
describe "push" do
it "should accept Chef::Resources through pushing" do
- lambda { @rc.push(@resource) }.should_not raise_error
- lambda { @rc.push("string") }.should raise_error(ArgumentError)
+ lambda { rc.push(resource) }.should_not raise_error
+ lambda { rc.push("string") }.should raise_error(ArgumentError)
end
end
describe "<<" do
it "should accept the << operator" do
- lambda { @rc << @resource }.should_not raise_error
+ lambda { rc << resource }.should_not raise_error
end
end
describe "insert" do
it "should accept only Chef::Resources" do
- lambda { @rc.insert(@resource) }.should_not raise_error
- lambda { @rc.insert("string") }.should raise_error(ArgumentError)
+ lambda { rc.insert(resource) }.should_not raise_error
+ lambda { rc.insert("string") }.should raise_error(ArgumentError)
end
it "should accept named arguments in any order" do
- @rc.insert(@resource, :instance_name => 'foo', :resource_type =>'bar')
- expect(@rc[0]).to eq(@resource)
+ rc.insert(resource, :instance_name => 'foo', :resource_type =>'bar')
+ expect(rc[0]).to eq(resource)
end
it "should append resources to the end of the collection when not executing a run" do
zmr = Chef::Resource::ZenMaster.new("there is no spoon")
- @rc.insert(@resource)
- @rc.insert(zmr)
- @rc[0].should eql(@resource)
- @rc[1].should eql(zmr)
+ rc.insert(resource)
+ rc.insert(zmr)
+ rc[0].should eql(resource)
+ rc[1].should eql(zmr)
end
it "should insert resources to the middle of the collection if called while executing a run" do
resource_to_inject = Chef::Resource::ZenMaster.new("there is no spoon")
zmr = Chef::Resource::ZenMaster.new("morpheus")
dummy = Chef::Resource::ZenMaster.new("keanu reeves")
- @rc.insert(zmr)
- @rc.insert(dummy)
+ rc.insert(zmr)
+ rc.insert(dummy)
- @rc.execute_each_resource do |resource|
- @rc.insert(resource_to_inject) if resource == zmr
+ rc.execute_each_resource do |resource|
+ rc.insert(resource_to_inject) if resource == zmr
end
- @rc[0].should eql(zmr)
- @rc[1].should eql(resource_to_inject)
- @rc[2].should eql(dummy)
+ rc[0].should eql(zmr)
+ rc[1].should eql(resource_to_inject)
+ rc[2].should eql(dummy)
end
end
@@ -102,7 +99,7 @@ describe Chef::ResourceCollection do
load_up_resources
results = Array.new
lambda {
- @rc.each do |r|
+ rc.each do |r|
results << r.name
end
}.should_not raise_error
@@ -124,8 +121,8 @@ describe Chef::ResourceCollection do
load_up_resources
results = Array.new
lambda {
- @rc.each_index do |i|
- results << @rc[i].name
+ rc.each_index do |i|
+ results << rc[i].name
end
}.should_not raise_error
results.each_index do |i|
@@ -144,24 +141,24 @@ describe Chef::ResourceCollection do
describe "lookup" do
it "should allow you to find resources by name via lookup" do
zmr = Chef::Resource::ZenMaster.new("dog")
- @rc << zmr
- @rc.lookup(zmr.to_s).should eql(zmr)
+ rc << zmr
+ rc.lookup(zmr.to_s).should eql(zmr)
zmr = Chef::Resource::ZenMaster.new("cat")
- @rc[0] = zmr
- @rc.lookup(zmr).should eql(zmr)
+ rc[0] = zmr
+ rc.lookup(zmr).should eql(zmr)
zmr = Chef::Resource::ZenMaster.new("monkey")
- @rc.push(zmr)
- @rc.lookup(zmr).should eql(zmr)
+ rc.push(zmr)
+ rc.lookup(zmr).should eql(zmr)
end
it "should raise an exception if you send something strange to lookup" do
- lambda { @rc.lookup(:symbol) }.should raise_error(ArgumentError)
+ lambda { rc.lookup(:symbol) }.should raise_error(ArgumentError)
end
it "should raise an exception if it cannot find a resource with lookup" do
- lambda { @rc.lookup("zen_master[dog]") }.should raise_error(Chef::Exceptions::ResourceNotFound)
+ lambda { rc.lookup("zen_master[dog]") }.should raise_error(Chef::Exceptions::ResourceNotFound)
end
end
@@ -169,80 +166,80 @@ describe Chef::ResourceCollection do
it "should find a resource by symbol and name (:zen_master => monkey)" do
load_up_resources
- @rc.resources(:zen_master => "monkey").name.should eql("monkey")
+ rc.resources(:zen_master => "monkey").name.should eql("monkey")
end
it "should find a resource by symbol and array of names (:zen_master => [a,b])" do
load_up_resources
- results = @rc.resources(:zen_master => [ "monkey", "dog" ])
+ results = rc.resources(:zen_master => [ "monkey", "dog" ])
results.length.should eql(2)
check_by_names(results, "monkey", "dog")
end
it "should find resources of multiple kinds (:zen_master => a, :file => b)" do
load_up_resources
- results = @rc.resources(:zen_master => "monkey", :file => "something")
+ results = rc.resources(:zen_master => "monkey", :file => "something")
results.length.should eql(2)
check_by_names(results, "monkey", "something")
end
it "should find a resource by string zen_master[a]" do
load_up_resources
- @rc.resources("zen_master[monkey]").name.should eql("monkey")
+ rc.resources("zen_master[monkey]").name.should eql("monkey")
end
it "should find resources by strings of zen_master[a,b]" do
load_up_resources
- results = @rc.resources("zen_master[monkey,dog]")
+ results = rc.resources("zen_master[monkey,dog]")
results.length.should eql(2)
check_by_names(results, "monkey", "dog")
end
it "should find resources of multiple types by strings of zen_master[a]" do
load_up_resources
- results = @rc.resources("zen_master[monkey]", "file[something]")
+ results = rc.resources("zen_master[monkey]", "file[something]")
results.length.should eql(2)
check_by_names(results, "monkey", "something")
end
it "should raise an exception if you pass a bad name to resources" do
- lambda { @rc.resources("michael jackson") }.should raise_error(ArgumentError)
+ lambda { rc.resources("michael jackson") }.should raise_error(ArgumentError)
end
it "should raise an exception if you pass something other than a string or hash to resource" do
- lambda { @rc.resources([Array.new]) }.should raise_error(ArgumentError)
+ lambda { rc.resources([Array.new]) }.should raise_error(ArgumentError)
end
it "raises an error when attempting to find a resource that does not exist" do
- lambda {@rc.find("script[nonesuch]")}.should raise_error(Chef::Exceptions::ResourceNotFound)
+ lambda {rc.find("script[nonesuch]")}.should raise_error(Chef::Exceptions::ResourceNotFound)
end
end
describe "when validating a resource query object" do
it "accepts a string of the form 'resource_type[resource_name]'" do
- @rc.validate_lookup_spec!("resource_type[resource_name]").should be_true
+ rc.validate_lookup_spec!("resource_type[resource_name]").should be_true
end
it "accepts a single-element :resource_type => 'resource_name' Hash" do
- @rc.validate_lookup_spec!(:service => "apache2").should be_true
+ rc.validate_lookup_spec!(:service => "apache2").should be_true
end
it "accepts a chef resource object" do
res = Chef::Resource.new("foo", nil)
- @rc.validate_lookup_spec!(res).should be_true
+ rc.validate_lookup_spec!(res).should be_true
end
it "rejects a malformed query string" do
lambda do
- @rc.validate_lookup_spec!("resource_type[missing-end-bracket")
+ rc.validate_lookup_spec!("resource_type[missing-end-bracket")
end.should raise_error(Chef::Exceptions::InvalidResourceSpecification)
end
it "rejects an argument that is not a String, Hash, or Chef::Resource" do
lambda do
- @rc.validate_lookup_spec!(Object.new)
+ rc.validate_lookup_spec!(Object.new)
end.should raise_error(Chef::Exceptions::InvalidResourceSpecification)
end
@@ -250,40 +247,40 @@ describe Chef::ResourceCollection do
describe "to_json" do
it "should serialize to json" do
- json = @rc.to_json
+ json = rc.to_json
json.should =~ /json_class/
json.should =~ /instance_vars/
end
include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
- let(:jsonable) { @rc }
+ let(:jsonable) { rc }
end
end
describe "self.from_json" do
it "should not respond to this method" do
- expect(@rc.respond_to?(:from_json)).to eq(false)
+ expect(rc.respond_to?(:from_json)).to eq(false)
end
it "should convert from json using the CHEF::JSONCompat library" do
- @rc << @resource
- json = Chef::JSONCompat.to_json(@rc)
+ rc << resource
+ json = Chef::JSONCompat.to_json(rc)
s_rc = Chef::JSONCompat.from_json(json)
s_rc.should be_a_kind_of(Chef::ResourceCollection)
- s_rc[0].name.should eql(@resource.name)
+ s_rc[0].name.should eql(resource.name)
end
end
describe "provides access to the raw resources array" do
it "returns the resources via the all_resources method" do
- @rc.all_resources.should equal(@rc.instance_variable_get(:@resource_list).instance_variable_get(:@resources))
+ rc.all_resources.should equal(rc.instance_variable_get(:@resource_list).instance_variable_get(:@resources))
end
end
describe "provides access to stepable iterator" do
it "returns the iterator object" do
- @rc.instance_variable_get(:@resource_list).instance_variable_set(:@iterator, :fooboar)
- @rc.iterator.should == :fooboar
+ rc.instance_variable_get(:@resource_list).instance_variable_set(:@iterator, :fooboar)
+ rc.iterator.should == :fooboar
end
end
@@ -295,9 +292,9 @@ describe Chef::ResourceCollection do
def load_up_resources
%w{dog cat monkey}.each do |n|
- @rc << Chef::Resource::ZenMaster.new(n)
+ rc << Chef::Resource::ZenMaster.new(n)
end
- @rc << Chef::Resource::File.new("something")
+ rc << Chef::Resource::File.new("something")
end
end