The better way of doing this is by making use of ensure_resource function from puppetlabs stdlib
It takes a resource type, title, and a list of attributes that describe a resource as parameters.
say you have test case to only create the resource if it does not already exist-
ensure_resource('package', 'test-pkg', {'ensure' => 'present'})
In short, this is a non trivial problem and not easily solved by parsing the manifests. Compiling the catalog can expand the scope of testing, but it's not a panacea. puppet master --compile require access to the node facts, and ideally a dummy node that fully test all classes. You still have to deal with the limitations of:
- classes that are can't be in the same catalog (apache, apache::disable)
- cross class dependency.
- different OS platforms.
- nodes with different parameters.
For example, if node one include a and b, it's fine, but node two only require b, it's only a failure you'll see with node two.
class a {
notify { 'hi': }
}
class b {
notify { 'bye':
require => Notify['hi'],
}
}
If you have the resources, you can compile catalog for all nodes and that will provide fairly comprehensive coverages.
puppet apply --noop have it's limitations as well, off the top of my head: it will fail an exec that's deployed by a package, it will fail files depending on a staging location, and it's not going to test multiple platforms unless you expand testing to a representative sample of your systems. In general it providers sufficient coverage to ensure no compilation issues, give you an idea what systems are affected, what are the changes, and you can judge by the reports whether the changes are ok or a real problem.
In most cases noop is sufficient, I've seen varying degrees of automated testing, such as jenkins where each modules tests files are simulated with --noop (limitations above applies), or using Vagrant to spawn off VMs to perform full blown testing.
Best Answer
Workaround for this: use onlyif on an exec "test" and require it in your action you want to execute: