Skip to content

Commit

Permalink
Find recursive dependencies
Browse files Browse the repository at this point in the history
Follow dependencies to find indirect relationships.
  • Loading branch information
raphink committed Jul 30, 2015
1 parent 660c20d commit fdf1f46
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
43 changes: 43 additions & 0 deletions README.md
Expand Up @@ -250,6 +250,49 @@ When testing custom types, the `be_valid_type` matcher provides a range of expec
* `with_features(<feature_list>)`: check that the specified features are available
* `with_set_attributes(<param_value_hash>)`: check that the specified attributes are set

#### Recursive dependencies

The relationship matchers are recursive in two directions:

* vertical recursion, which checks for dependencies with parents of the resource
(i.e. the resource is contained, directly or not, in the class involved in the relationship).
E.g. where `Package['foo']` comes before `File['/foo']`:

```puppet
class { 'foo::install': } ->
class { 'foo::config': }
class foo::install {
package { 'foo': }
}
class foo::config {
file { '/foo': }
}
```


* horizontal recursion, which follows indirect dependencies (dependencies of dependencies).
E.g. where `Yumrepo['foo']` comes before `File['/foo']`:

```puppet
class { 'foo::repo': } ->
class { 'foo::install': } ->
class { 'foo::config': }
class foo::repo {
yumrepo { 'foo': }
}
class foo::install {
package { 'foo': }
}
class foo::config {
file { '/foo': }
}
```

### Writing tests

#### Basic test structure
Expand Down
27 changes: 19 additions & 8 deletions lib/rspec-puppet/matchers/create_generic.rb
Expand Up @@ -231,10 +231,22 @@ def check_subscribes(catalogue, resource)
end
end

def relationship_refs(array)
Array[array].flatten.map do |resource|
resource.respond_to?(:to_ref) ? resource.to_ref : resource
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 relationship_refs(resource, type)
results = []
Array[resource[type]].flatten.compact.each do |r|
res = resource_from_ref(r)
results << resource_ref(res)
results << relationship_refs(res, type)
end
results.flatten
end

def self_or_upstream(vertex)
Expand All @@ -246,8 +258,8 @@ def precedes?(first, second)

self_or_upstream(first).each do |u|
self_or_upstream(second).each do |v|
before_refs = relationship_refs(u[:before])
require_refs = relationship_refs(v[:require])
before_refs = relationship_refs(u, :before)
require_refs = relationship_refs(v, :require)

if before_refs.include?(v.to_ref) || require_refs.include?(u.to_ref)
return true
Expand All @@ -264,9 +276,8 @@ def notifies?(first, second)

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])
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
Expand Down
5 changes: 5 additions & 0 deletions spec/fixtures/modules/relationships/manifests/before.pp
Expand Up @@ -10,13 +10,18 @@
Notify['baz'] <- Notify['bar']

class { '::relationship::before::pre': } ->
class { '::relationship::before::middle': } ->
class { '::relationship::before::post': }
}

class relationship::before::pre {
notify { 'pre': }
}

class relationship::before::middle {
notify { 'middle': }
}

class relationship::before::post {
notify { 'post': }
}
5 changes: 5 additions & 0 deletions spec/fixtures/modules/relationships/manifests/notify.pp
Expand Up @@ -13,13 +13,18 @@
Notify['gronk'] <~ Notify['baz']

class { '::relationship::notify::pre': } ~>
class { '::relationship::notify::middle': } ~>
class { '::relationship::notify::post': }
}

class relationship::notify::pre {
notify { 'pre': }
}

class relationship::notify::middle {
notify { 'middle': }
}

class relationship::notify::post {
notify { 'post': }
}

0 comments on commit fdf1f46

Please sign in to comment.