Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] New syntax #611

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/rspec-puppet.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
require 'puppet'
require 'rspec'
require 'rspec/its'
require 'fileutils'
require 'tmpdir'
require 'rspec-puppet/errors'
require 'rspec-puppet/helpers'
require 'rspec-puppet/matchers'
require 'rspec-puppet/example'
require 'rspec-puppet/setup'
require 'rspec-puppet/coverage'
require 'rspec-puppet/adapters'
require 'rspec-puppet/consts'
require 'rspec-puppet/v3'

begin
require 'puppet/test/test_helper'
Expand Down
6 changes: 6 additions & 0 deletions lib/rspec-puppet/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module RSpec::Puppet
module Helpers
end
end

require 'rspec-puppet/helpers/relationships'
112 changes: 112 additions & 0 deletions lib/rspec-puppet/helpers/relationships.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
module RSpec::Puppet::Helpers
module Relationships
def resource_ref(resource)
resource.respond_to?(:to_ref) ? resource.to_ref : resource
end

def resource_from_ref(ref)
ref.is_a?(Puppet::Resource) ? ref : catalogue.resource(ref)
end

def canonicalize_resource(resource)
res = resource_from_ref(resource_ref(resource))

if res.nil?
resource = Struct.new(:type, :title).new(*catalogue.title_key_for_ref(resource)) if resource.is_a?(String)

res = catalogue.resource_keys.select { |type, title|
type == resource.type
}.map { |type, title|
catalogue.resource(type, title)
}.compact.find { |cat_res|
cat_res.builtin_type? && cat_res.uniqueness_key.first == resource.title
}
end

res
end

def canonicalize_resource_ref(ref)
resource_ref(resource_from_ref(ref))
end

def relationship_refs(resource, relationship_type, visited = Set.new)
resource = canonicalize_resource(resource)
results = Set.new
return results if resource.nil?

if visited.include?(resource.object_id)
return [canonicalize_resource_ref(resource)]
end

visited << resource.object_id

Array[resource[relationship_type]].flatten.compact.each do |r|
results << canonicalize_resource_ref(r)
results << relationship_refs(r, relationship_type, visited)

res = canonicalize_resource(r)
if res && res.builtin_type?
results << res.to_ref
results << "#{res.type.to_s.capitalize}[#{res.uniqueness_key.first}]"
end
end

# Add any autorequires
Puppet::Type.suppress_provider
if relationship_type == :require && resource.resource_type.respond_to?(:eachautorequire)
resource.resource_type.eachautorequire do |t, b|
Array(resource.to_ral.instance_eval(&b)).each do |dep|
res = "#{t.to_s.capitalize}[#{dep}]"

if r = relationship_refs(res, relationship_type, visited)
results << res
results << r
end
end
end
end
Puppet::Type.unsuppress_provider

results.flatten
end

def self_or_upstream(vertex)
[vertex] + catalogue.upstream_from_vertex(vertex).keys
end

def precedes?(first, second)
return false if first.nil? || second.nil?

self_or_upstream(first).each do |u|
self_or_upstream(second).each do |v|
before_refs = relationship_refs(u, :before) + relationship_refs(u, :notify)
require_refs = relationship_refs(v, :require) + relationship_refs(u, :subscribe)

if before_refs.include?(v.to_ref) || require_refs.include?(u.to_ref) || (before_refs & require_refs).any?
return true
end
end
end

false
end

def notifies?(first, second)
return false if first.nil? || second.nil?

self_or_upstream(first).each do |u|
self_or_upstream(second).each do |v|
notify_refs = relationship_refs(u, :notify)
subscribe_refs = relationship_refs(v, :subscribe)

if notify_refs.include?(v.to_ref) || subscribe_refs.include?(u.to_ref)
return true
end
end
end

false
end
end
end
5 changes: 5 additions & 0 deletions lib/rspec-puppet/matchers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@
require 'rspec-puppet/matchers/dynamic_matchers'
require 'rspec-puppet/matchers/type_matchers'
require 'rspec-puppet/matchers/allow_value'

require 'rspec-puppet/matchers/notify'
require 'rspec-puppet/matchers/subscribe_to'
require 'rspec-puppet/matchers/require'
require 'rspec-puppet/matchers/come_before'
25 changes: 25 additions & 0 deletions lib/rspec-puppet/matchers/come_before.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module RSpec::Puppet
module ManifestMatchers
extend RSpec::Matchers::DSL

matcher :come_before do |*preceding_resources|
match do |resource|
preceding_resources.flatten.all? do |expected_precede|
resource.comes_before_resource?(expected_precede)
end
end

description do
"come before #{preceding_resources.flatten.join(', ')}"
end

failure_message do |resource|
"expected to come before #{preceding_resources.flatten.join(', ')}"
end

failure_message_when_negated do |resource|
"expected not to come before #{preceding_resources.flatten.join(', ')}"
end
end
end
end
111 changes: 3 additions & 108 deletions lib/rspec-puppet/matchers/create_generic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ module RSpec::Puppet
module ManifestMatchers
class CreateGeneric
include RSpec::Puppet::Errors
include RSpec::Puppet::Helpers::Relationships

attr_reader :catalogue

def initialize(*args, &block)
@exp_resource_type = args.shift.to_s.gsub(/^(create|contain)_/, '')
Expand Down Expand Up @@ -244,114 +247,6 @@ def check_subscribes(catalogue, resource)
end
end

def resource_ref(resource)
resource.respond_to?(:to_ref) ? resource.to_ref : resource
end

def resource_from_ref(ref)
ref.is_a?(Puppet::Resource) ? ref : @catalogue.resource(ref)
end

def canonicalize_resource(resource)
res = resource_from_ref(resource_ref(resource))
if res.nil?
resource = Struct.new(:type, :title).new(*@catalogue.title_key_for_ref(resource)) if resource.is_a?(String)
res = @catalogue.resource_keys.select { |type, name|
type == resource.type
}.map { |type, name|
@catalogue.resource(type, name)
}.compact.find { |cat_res|
cat_res.builtin_type? && cat_res.uniqueness_key.first == resource.title
}
end
res
end

def canonicalize_resource_ref(ref)
resource_ref(resource_from_ref(ref))
end

def relationship_refs(resource, type, visited = Set.new)
resource = canonicalize_resource(resource)
results = Set.new
return results unless resource

# guard to prevent infinite recursion
if visited.include?(resource.object_id)
return [canonicalize_resource_ref(resource)]
else
visited << resource.object_id
end

Array[resource[type]].flatten.compact.each do |r|
results << canonicalize_resource_ref(r)
results << relationship_refs(r, type, visited)

res = canonicalize_resource(r)
if res && res.builtin_type?
results << res.to_ref
results << "#{res.type.to_s.capitalize}[#{res.uniqueness_key.first}]"
end
end

Puppet::Type.suppress_provider
# Add autorequires if any
if type == :require and resource.resource_type.respond_to? :eachautorequire
resource.resource_type.eachautorequire do |t, b|
Array(resource.to_ral.instance_eval(&b)).each do |dep|
res = "#{t.to_s.capitalize}[#{dep}]"
if r = relationship_refs(res, type, visited)
results << res
results << r
end
end
end
end
Puppet::Type.unsuppress_provider

results.flatten
end

def self_or_upstream(vertex)
[vertex] + @catalogue.upstream_from_vertex(vertex).keys
end

def precedes?(first, second)
return false if first.nil? || second.nil?

self_or_upstream(first).each do |u|
self_or_upstream(second).each do |v|
before_refs = relationship_refs(u, :before) + relationship_refs(u, :notify)
require_refs = relationship_refs(v, :require) + relationship_refs(u, :subscribe)

if before_refs.include?(v.to_ref) || require_refs.include?(u.to_ref) || (before_refs & require_refs).any?
return true
end
end
end

# Nothing found
return false
end

def notifies?(first, second)
return false if first.nil? || second.nil?

self_or_upstream(first).each do |u|
self_or_upstream(second).each do |v|
notify_refs = relationship_refs(u, :notify)
subscribe_refs = relationship_refs(v, :subscribe)

if notify_refs.include?(v.to_ref) || subscribe_refs.include?(u.to_ref)
return true
end
end
end

# Nothing found
return false
end

# @param resource [Hash<Symbol, Object>] The resource in the catalog
# @param list [Array<String, Object>] The expected values of the resource
# @param type [:should, :not] Whether the given parameters should/not match
Expand Down
25 changes: 25 additions & 0 deletions lib/rspec-puppet/matchers/notify.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module RSpec::Puppet
module ManifestMatchers
extend RSpec::Matchers::DSL

matcher :notify do |*notified_resources|
match do |resource|
notified_resources.flatten.all? do |expected_notify|
resource.notifies_resource?(expected_notify)
end
end

description do
"notify #{notified_resources.flatten.join(', ')}"
end

failure_message do |resource|
"expected to notify #{notified_resources.flatten.join(', ')}"
end

failure_message_when_negated do |resource|
"expected not to notify #{notified_resources.flatten.join(', ')}"
end
end
end
end
25 changes: 25 additions & 0 deletions lib/rspec-puppet/matchers/require.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module RSpec::Puppet
module ManifestMatchers
extend RSpec::Matchers::DSL

matcher :require do |*required_resources|
match do |resource|
required_resources.flatten.all? do |expected_require|
resource.requires_resource?(expected_require)
end
end

description do
"require #{required_resources.flatten.join(', ')}"
end

failure_message do |resource|
"expected to require #{required_resources.flatten.join(', ')}"
end

failure_message_when_negated do |resource|
"expected not to require #{required_resources.flatten.join(', ')}"
end
end
end
end
25 changes: 25 additions & 0 deletions lib/rspec-puppet/matchers/subscribe_to.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module RSpec::Puppet
module ManifestMatchers
extend RSpec::Matchers::DSL

matcher :subscribe_to do |*subscribed_resources|
match do |resource|
subscribed_resources.flatten.all? do |expected_subscribe|
resource.subscribes_to_resource?(expected_subscribe)
end
end

description do
"subscribe to #{subscribed_resources.flatten.join(', ')}"
end

failure_message do |resource|
"expected to subscribe to #{subscribed_resources.flatten.join(', ')}"
end

failure_message_when_negated do |resource|
"expected not to subscribe to #{subscribed_resources.flatten.join(', ')}"
end
end
end
end
2 changes: 1 addition & 1 deletion lib/rspec-puppet/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Support
@@cache = RSpec::Puppet::Cache.new

def subject
lambda { catalogue }
described_class || lambda { catalogue }
end

def environment
Expand Down
Loading