ChefSpec for LWRPs without recipes


#1

Ohai!

Following the cookbook pattern described in the “Berkshelf Way”, I’m trying
to create a library cookbook which contains some custom LWRPs. This
library cookbook will not have any meaningful recipe on its own…it will
only supply providers and resources to be consumed by application cookbooks.

I’d like to test the library cookbook separately, and I think ChefSpec is
the correct approach for unit testing. I see that ChefSpec takes a recipe
list when “converging”, but, since my library cookbook won’t have recipes,
I don’t have one to give to ChefRunner.

I suppose I’d like some suggestions/experiences on how to do this. From my
perspective, I can see at least two ways to solve it (with a STRONG
preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out to
    each LWRP the library cookbook provides. I don’t like this cause then I’ve
    got a testing recipe floating around which COULD be applied to a node in
    production - and that’s just silly. I could prefix this recipe with a “_”
    (as in, “_lwrp_testing.rb”), but again, it feels like a hack.

  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a ChefSpec
    run, and allow for valid exercise of the underlying LWRPs during
    testing…at the same time, the recipe would not exist “for reals” in the
    cookbook, and couldn’t be assigned to a run_list. This seems like an
    elegant approach (design wise), but my Ruby skills are not to the level
    they should be to easily implement this. Anybody else try this?

Or, perhaps there’s another solution I’m overlooking?

Thanks for your thoughts.

Bryan

PS - Thanks to everybody for another great ChefConf!


#2

Hey,

I had to solve the same problem for a cookbook of my own.

My approach is similar to your second alternative. A created another (test)
cookbook which uses and depends on the main cookbook (LWRP, definitions …).
I put this cookbook under spec/support/cookbooks and adjusted the ChefSpec
cookbook_path to use also spec/support/cookbook to search for cookbooks. 1
It is undocumented but chefspec supports like the chef client also a list of
directories as cookbook_path.
In my case Chef::ChefRunner.new cookbook_path: [ ‘…’,
‘spec/support/cookbooks’ ] works great. There might be a more robust way to
set the cookbook path like 2 - but if chefspec is started from the cookbook
directory, there should no problem.

I hope this late answer helps you, too.

Malte.

On Wednesday, 01 May 2013 07:53:21 Bryan Stenson wrote:

Ohai!

Following the cookbook pattern described in the “Berkshelf Way”, I’m trying
to create a library cookbook which contains some custom LWRPs. This
library cookbook will not have any meaningful recipe on its own…it will
only supply providers and resources to be consumed by application cookbooks.

I’d like to test the library cookbook separately, and I think ChefSpec is
the correct approach for unit testing. I see that ChefSpec takes a recipe
list when “converging”, but, since my library cookbook won’t have recipes,
I don’t have one to give to ChefRunner.

I suppose I’d like some suggestions/experiences on how to do this. From my
perspective, I can see at least two ways to solve it (with a STRONG
preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out to
    each LWRP the library cookbook provides. I don’t like this cause then I’ve
    got a testing recipe floating around which COULD be applied to a node in
    production - and that’s just silly. I could prefix this recipe with a “_”
    (as in, “_lwrp_testing.rb”), but again, it feels like a hack.

  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a ChefSpec
    run, and allow for valid exercise of the underlying LWRPs during
    testing…at the same time, the recipe would not exist “for reals” in the
    cookbook, and couldn’t be assigned to a run_list. This seems like an
    elegant approach (design wise), but my Ruby skills are not to the level
    they should be to easily implement this. Anybody else try this?

Or, perhaps there’s another solution I’m overlooking?

Thanks for your thoughts.

Bryan

PS - Thanks to everybody for another great ChefConf!


#3

This is perfect. I got the same response off list from Eric Saxby, too. I
really appreciate the response here.

Ultimately, I think this type of design should be baked in to
Chefspec…seems to violate the DRY principle that I’d have to setup EVERY
cookbook like this just to test “recipe-less” LWRPs.

Cheers.

Bryan

On Wed, May 8, 2013 at 2:08 PM, Malte Swart chef@malteswart.de wrote:

Hey,

I had to solve the same problem for a cookbook of my own.

My approach is similar to your second alternative. A created another (test)
cookbook which uses and depends on the main cookbook (LWRP, definitions
…).
I put this cookbook under spec/support/cookbooks and adjusted the ChefSpec
cookbook_path to use also spec/support/cookbook to search for cookbooks.
1
It is undocumented but chefspec supports like the chef client also a list
of
directories as cookbook_path.
In my case Chef::ChefRunner.new cookbook_path: [ ‘…’,
‘spec/support/cookbooks’ ] works great. There might be a more robust way to
set the cookbook path like [2] - but if chefspec is started from the
cookbook
directory, there should no problem.

I hope this late answer helps you, too.

Malte.

[2]:

https://github.com/acrmp/chefspec/blob/master/lib/chefspec/chef_runner.rb#L161

On Wednesday, 01 May 2013 07:53:21 Bryan Stenson wrote:

Ohai!

Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying
to create a library cookbook which contains some custom LWRPs. This
library cookbook will not have any meaningful recipe on its own…it will
only supply providers and resources to be consumed by application
cookbooks.

I’d like to test the library cookbook separately, and I think ChefSpec is
the correct approach for unit testing. I see that ChefSpec takes a
recipe
list when “converging”, but, since my library cookbook won’t have
recipes,
I don’t have one to give to ChefRunner.

I suppose I’d like some suggestions/experiences on how to do this. From
my
perspective, I can see at least two ways to solve it (with a STRONG
preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out to
    each LWRP the library cookbook provides. I don’t like this cause then
    I’ve
    got a testing recipe floating around which COULD be applied to a node in
    production - and that’s just silly. I could prefix this recipe with a
    "_"
    (as in, “_lwrp_testing.rb”), but again, it feels like a hack.

  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a ChefSpec
    run, and allow for valid exercise of the underlying LWRPs during
    testing…at the same time, the recipe would not exist “for reals” in the
    cookbook, and couldn’t be assigned to a run_list. This seems like an
    elegant approach (design wise), but my Ruby skills are not to the level
    they should be to easily implement this. Anybody else try this?

Or, perhaps there’s another solution I’m overlooking?

Thanks for your thoughts.

Bryan

PS - Thanks to everybody for another great ChefConf!


#4

+1

I m too kinda similar situation.

On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!

Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying to create a library cookbook which contains some custom LWRPs. This
library cookbook will not have any meaningful recipe on its own…it will
only supply providers and resources to be consumed by application cookbooks.

I’d like to test the library cookbook separately, and I think ChefSpec is
the correct approach for unit testing. I see that ChefSpec takes a recipe
list when “converging”, but, since my library cookbook won’t have recipes,
I don’t have one to give to ChefRunner.

I suppose I’d like some suggestions/experiences on how to do this. From
my perspective, I can see at least two ways to solve it (with a STRONG
preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out to
    each LWRP the library cookbook provides. I don’t like this cause then I’ve
    got a testing recipe floating around which COULD be applied to a node in
    production - and that’s just silly. I could prefix this recipe with a “_”
    (as in, “_lwrp_testing.rb”), but again, it feels like a hack.

  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a ChefSpec
    run, and allow for valid exercise of the underlying LWRPs during
    testing…at the same time, the recipe would not exist “for reals” in the
    cookbook, and couldn’t be assigned to a run_list. This seems like an
    elegant approach (design wise), but my Ruby skills are not to the level
    they should be to easily implement this. Anybody else try this?

Or, perhaps there’s another solution I’m overlooking?

Thanks for your thoughts.

Bryan

PS - Thanks to everybody for another great ChefConf!

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com


#5

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying to create a library cookbook which contains some custom LWRPs.
This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed by
application cookbooks.
I’d like to test the library cookbook separately, and I think ChefSpec
is the correct approach for unit testing. I see that ChefSpec takes a
recipe list when “converging”, but, since my library cookbook won’t
have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do this.
From my perspective, I can see at least two ways to solve it (with a
STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out
    to each LWRP the library cookbook provides. I don’t like this cause
    then I’ve got a testing recipe floating around which COULD be applied
    to a node in production - and that’s just silly. I could prefix this
    recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it feels like
    a hack.
  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a
    ChefSpec run, and allow for valid exercise of the underlying LWRPs
    during testing…at the same time, the recipe would not exist “for
    reals” in the cookbook, and couldn’t be assigned to a run_list. This
    seems like an elegant approach (design wise), but my Ruby skills are
    not to the level they should be to easily implement this. Anybody else
    try this?
    Or, perhaps there’s another solution I’m overlooking?
    Thanks for your thoughts.
    Bryan
    PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1]http://tfm.com.np
[2]http://nepalonrails.com

References

  1. http://tfm.com.np/
  2. http://nepalonrails.com/

#6

John is right - it’s becoming common to provide an empty default.rb
for a cookbook that doesn’t have any recipes.

On Wed, May 1, 2013 at 12:34 PM, John Dewey john@dewey.ws wrote:

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying to create a library cookbook which contains some custom LWRPs.
This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed by
application cookbooks.
I’d like to test the library cookbook separately, and I think ChefSpec
is the correct approach for unit testing. I see that ChefSpec takes a
recipe list when “converging”, but, since my library cookbook won’t
have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do this.
From my perspective, I can see at least two ways to solve it (with a
STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out
    to each LWRP the library cookbook provides. I don’t like this cause
    then I’ve got a testing recipe floating around which COULD be applied
    to a node in production - and that’s just silly. I could prefix this
    recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it feels like
    a hack.
  2. Create a recipe fixture for testing the LWRP for use only during
    ChefSpec runs. The recipe would only exist in the context of a
    ChefSpec run, and allow for valid exercise of the underlying LWRPs
    during testing…at the same time, the recipe would not exist “for
    reals” in the cookbook, and couldn’t be assigned to a run_list. This
    seems like an elegant approach (design wise), but my Ruby skills are
    not to the level they should be to easily implement this. Anybody else
    try this?
    Or, perhaps there’s another solution I’m overlooking?
    Thanks for your thoughts.
    Bryan
    PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1]http://tfm.com.np
[2]http://nepalonrails.com

References

  1. http://tfm.com.np/
  2. http://nepalonrails.com/

#7

An empty default recipe, I suppose, I understand.

But, I think “:step_into => [‘foo’]” only ALLOWS the ChefRunner to descend
into the “foo” provider…it doesn’t actually exercise it (how would it
know the parameters to test?!)

At this point, I think I’m planning on copying the entire cookbook into a
"temp" directory, applying “fixture recipes” to the copy, and pointing the
ChefRunner to that directory as the :cookbook_path

This will allow me to write “fixture recipes” for testing, and leave them
out of the actual recipe folder (so they’re unable to be used in a
run_list).

If/when I get something worthy of sharing, I will.

Bryan

On Wed, May 1, 2013 at 9:38 AM, Mike miketheman@gmail.com wrote:

John is right - it’s becoming common to provide an empty default.rb
for a cookbook that doesn’t have any recipes.

On Wed, May 1, 2013 at 12:34 PM, John Dewey john@dewey.ws wrote:

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying to create a library cookbook which contains some custom LWRPs.
This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed by
application cookbooks.
I’d like to test the library cookbook separately, and I think
ChefSpec

is the correct approach for unit testing. I see that ChefSpec takes
a

recipe list when “converging”, but, since my library cookbook won’t
have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do this.
From my perspective, I can see at least two ways to solve it (with a
STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call out
    to each LWRP the library cookbook provides. I don’t like this cause
    then I’ve got a testing recipe floating around which COULD be applied
    to a node in production - and that’s just silly. I could prefix this
    recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it feels
    like

a hack.
2. Create a recipe fixture for testing the LWRP for use only during
ChefSpec runs. The recipe would only exist in the context of a
ChefSpec run, and allow for valid exercise of the underlying LWRPs
during testing…at the same time, the recipe would not exist “for
reals” in the cookbook, and couldn’t be assigned to a run_list. This
seems like an elegant approach (design wise), but my Ruby skills are
not to the level they should be to easily implement this. Anybody
else

try this?
Or, perhaps there’s another solution I’m overlooking?
Thanks for your thoughts.
Bryan
PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1]http://tfm.com.np
[2]http://nepalonrails.com

References

  1. http://tfm.com.np/
  2. http://nepalonrails.com/

#8

You test it like anything else. A trivial example:
https://github.com/retr0h/cookbook-parted/blob/master/spec/_test_spec.rb

John

On Wed, May 01, 2013 at 09:49:49AM -0700, Bryan Stenson wrote:

An empty default recipe, I suppose, I understand.
But, I think “:step_into => [‘foo’]” only ALLOWS the ChefRunner to
descend into the “foo” provider…it doesn’t actually exercise it (how
would it know the parameters to test?!)
At this point, I think I’m planning on copying the entire cookbook into
a “temp” directory, applying “fixture recipes” to the copy, and
pointing the ChefRunner to that directory as the :cookbook_path
This will allow me to write “fixture recipes” for testing, and leave
them out of the actual recipe folder (so they’re unable to be used in a
run_list).
If/when I get something worthy of sharing, I will.
Bryan

On Wed, May 1, 2013 at 9:38 AM, Mike <[1]miketheman@gmail.com> wrote:

 John is right - it's becoming common to provide an empty default.rb
 for a cookbook that doesn't have any recipes.

On Wed, May 1, 2013 at 12:34 PM, John Dewey <[2]john@dewey.ws> wrote:

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”,
I’m

trying to create a library cookbook which contains some custom
LWRPs.

This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed
by

application cookbooks.
I’d like to test the library cookbook separately, and I think
ChefSpec

is the correct approach for unit testing. I see that ChefSpec
takes a

recipe list when “converging”, but, since my library cookbook
won’t

have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do
this.

From my perspective, I can see at least two ways to solve it
(with a

STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call
    out

to each LWRP the library cookbook provides. I don’t like this
cause

then I’ve got a testing recipe floating around which COULD be
applied

to a node in production - and that’s just silly. I could prefix
this

recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it
feels like

a hack.
2. Create a recipe fixture for testing the LWRP for use only
during

ChefSpec runs. The recipe would only exist in the context of a
ChefSpec run, and allow for valid exercise of the underlying
LWRPs

during testing…at the same time, the recipe would not exist
"for

reals" in the cookbook, and couldn’t be assigned to a run_list.
This

seems like an elegant approach (design wise), but my Ruby skills
are

not to the level they should be to easily implement this.
Anybody else

try this?
Or, perhaps there’s another solution I’m overlooking?
Thanks for your thoughts.
Bryan
PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1][3]http://tfm.com.np
[2][4]http://nepalonrails.com

References

  1. [5]http://tfm.com.np/
  2. [6]http://nepalonrails.com/

References

  1. mailto:miketheman@gmail.com
  2. mailto:john@dewey.ws
  3. http://tfm.com.np/
  4. http://nepalonrails.com/
  5. http://tfm.com.np/
  6. http://nepalonrails.com/

#9

While it isn’t an especially useful answer, Chris Andrews at Venda added
LWRP support to rspec-chef. I think that predated everyone rallying around
chefspec, and rspec-chef seems to be abandoned.

The PR adding support is here: https://github.com/calavera/rspec-chef/pull/5

You can see an example of its use to test a provider here:

I really wish something similar existed for chefspec, as I think it’s a
vastly superior way of writing tests for LWRPs.

Zac
(who also lacks the ruby-fu to add something similar to chefspec)

On Wed, May 1, 2013 at 5:49 PM, Bryan Stenson bryan.stenson@gmail.comwrote:

An empty default recipe, I suppose, I understand.

But, I think “:step_into => [‘foo’]” only ALLOWS the ChefRunner to descend
into the “foo” provider…it doesn’t actually exercise it (how would it
know the parameters to test?!)

At this point, I think I’m planning on copying the entire cookbook into a
"temp" directory, applying “fixture recipes” to the copy, and pointing the
ChefRunner to that directory as the :cookbook_path

This will allow me to write “fixture recipes” for testing, and leave them
out of the actual recipe folder (so they’re unable to be used in a
run_list).

If/when I get something worthy of sharing, I will.

Bryan

On Wed, May 1, 2013 at 9:38 AM, Mike miketheman@gmail.com wrote:

John is right - it’s becoming common to provide an empty default.rb
for a cookbook that doesn’t have any recipes.

On Wed, May 1, 2013 at 12:34 PM, John Dewey john@dewey.ws wrote:

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”, I’m
trying to create a library cookbook which contains some custom
LWRPs.

This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed by
application cookbooks.
I’d like to test the library cookbook separately, and I think
ChefSpec

is the correct approach for unit testing. I see that ChefSpec
takes a

recipe list when “converging”, but, since my library cookbook won’t
have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do this.
From my perspective, I can see at least two ways to solve it (with a
STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically call
    out

to each LWRP the library cookbook provides. I don’t like this cause
then I’ve got a testing recipe floating around which COULD be
applied

to a node in production - and that’s just silly. I could prefix
this

recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it feels
like

a hack.
2. Create a recipe fixture for testing the LWRP for use only during
ChefSpec runs. The recipe would only exist in the context of a
ChefSpec run, and allow for valid exercise of the underlying LWRPs
during testing…at the same time, the recipe would not exist “for
reals” in the cookbook, and couldn’t be assigned to a run_list.
This

seems like an elegant approach (design wise), but my Ruby skills are
not to the level they should be to easily implement this. Anybody
else

try this?
Or, perhaps there’s another solution I’m overlooking?
Thanks for your thoughts.
Bryan
PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1]http://tfm.com.np
[2]http://nepalonrails.com

References

  1. http://tfm.com.np/
  2. http://nepalonrails.com/

#10

Thanks John.

As described, I’m hoping to NOT have any testing recipes exist to be
assigned to a node’s run_list. The purist in me rejects the idea that I
have to have a recipe ("_test.rb", in your example) just to test my LWRPs.

Having said that, I’m open to suggestions. Maybe my resistance to an “only
used for testing recipe” is misguided or uninformed. If so, I’d like to
hear why.

Bryan

On Wed, May 1, 2013 at 9:54 AM, John Dewey john@dewey.ws wrote:

You test it like anything else. A trivial example:
https://github.com/retr0h/cookbook-parted/blob/master/spec/_test_spec.rb

John

On Wed, May 01, 2013 at 09:49:49AM -0700, Bryan Stenson wrote:

An empty default recipe, I suppose, I understand.
But, I think “:step_into => [‘foo’]” only ALLOWS the ChefRunner to
descend into the “foo” provider…it doesn’t actually exercise it (how
would it know the parameters to test?!)
At this point, I think I’m planning on copying the entire cookbook
into
a “temp” directory, applying “fixture recipes” to the copy, and
pointing the ChefRunner to that directory as the :cookbook_path
This will allow me to write “fixture recipes” for testing, and leave
them out of the actual recipe folder (so they’re unable to be used in
a
run_list).
If/when I get something worthy of sharing, I will.
Bryan

On Wed, May 1, 2013 at 9:38 AM, Mike <[1]miketheman@gmail.com> wrote:

 John is right - it's becoming common to provide an empty default.rb
 for a cookbook that doesn't have any recipes.

On Wed, May 1, 2013 at 12:34 PM, John Dewey <[2]john@dewey.ws> wrote:

I believe you can simply create an empty default.rb,
and “step into” the LWRP you wish to test.

John

On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:

+1

I m too kinda similar situation.
On Wednesday, May 1, 2013, Bryan Stenson wrote:

Ohai!
Following the cookbook pattern described in the “Berkshelf Way”,
I’m

trying to create a library cookbook which contains some custom
LWRPs.

This library cookbook will not have any meaningful recipe on its
own…it will only supply providers and resources to be consumed
by

application cookbooks.
I’d like to test the library cookbook separately, and I think
ChefSpec

is the correct approach for unit testing. I see that ChefSpec
takes a

recipe list when “converging”, but, since my library cookbook
won’t

have recipes, I don’t have one to give to ChefRunner.
I suppose I’d like some suggestions/experiences on how to do
this.

From my perspective, I can see at least two ways to solve it
(with a

STRONG preference on the latter):

  1. Create a “lwrp_testing.rb” recipe which will specifically
    call
    out

to each LWRP the library cookbook provides. I don’t like this
cause

then I’ve got a testing recipe floating around which COULD be
applied

to a node in production - and that’s just silly. I could prefix
this

recipe with a “_” (as in, “_lwrp_testing.rb”), but again, it
feels like

a hack.
2. Create a recipe fixture for testing the LWRP for use only
during

ChefSpec runs. The recipe would only exist in the context of a
ChefSpec run, and allow for valid exercise of the underlying
LWRPs

during testing…at the same time, the recipe would not exist
"for

reals" in the cookbook, and couldn’t be assigned to a run_list.
This

seems like an elegant approach (design wise), but my Ruby skills
are

not to the level they should be to easily implement this.
Anybody else

try this?
Or, perhaps there’s another solution I’m overlooking?
Thanks for your thoughts.
Bryan
PS - Thanks to everybody for another great ChefConf!


@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
[1][3]http://tfm.com.np
[2][4]http://nepalonrails.com

References

  1. [5]http://tfm.com.np/
  2. [6]http://nepalonrails.com/

References

  1. mailto:miketheman@gmail.com
  2. mailto:john@dewey.ws
  3. http://tfm.com.np/
  4. http://nepalonrails.com/
  5. http://tfm.com.np/
  6. http://nepalonrails.com/

#11

Bryan,

I’d suggest to look at this in a different way. Creating test (or
_test) recipes you can create test scenarios for your lwrp to pass (or
fail) on.

I have several cookbooks that exhibit this behavior such as
https://github.com/damm/diamond and https://github.com/damm/carbon for
example. Testing to make sure your cookbook compiles is great, making
sure it does what you want, fantastic.

Testing the ways you use the cookbook (or don’t use it) is even better.

As an early adopter of Chef, let alone testing my Chef Cookbooks I can
tell you it’s made my life a whole lot easier. It’s not a far stretch
to do write your tests before your cookbook.

P.S. if your worried about pollution or creating cruft, look at your
tests as examples of how to use your LWRP.

Scott

On 5/1/13 10:30 AM, Bryan Stenson wrote:

Thanks John.

As described, I’m hoping to NOT have any testing recipes exist to be
assigned to a node’s run_list. The purist in me rejects the idea that
I have to have a recipe ("_test.rb", in your example) just to test my
LWRPs.

Having said that, I’m open to suggestions. Maybe my resistance to an
"only used for testing recipe" is misguided or uninformed. If so, I’d
like to hear why.

Bryan

On Wed, May 1, 2013 at 9:54 AM, John Dewey <john@dewey.ws
mailto:john@dewey.ws> wrote:

You test it like anything else.  A trivial example:
https://github.com/retr0h/cookbook-parted/blob/master/spec/_test_spec.rb

John

On Wed, May 01, 2013 at 09:49:49AM -0700, Bryan Stenson wrote:
>    An empty default recipe, I suppose, I understand.
>    But, I think ":step_into => ['foo']" only ALLOWS the
ChefRunner to
>    descend into the "foo" provider...it doesn't actually
exercise it (how
>    would it know the parameters to test?!)
>    At this point, I think I'm planning on copying the entire
cookbook into
>    a "temp" directory, applying "fixture recipes" to the copy, and
>    pointing the ChefRunner to that directory as the :cookbook_path
>    This will allow me to write "fixture recipes" for testing,
and leave
>    them out of the actual recipe folder (so they're unable to be
used in a
>    run_list).
>    If/when I get something worthy of sharing, I will.
>    Bryan
>
>    On Wed, May 1, 2013 at 9:38 AM, Mike <[1]miketheman@gmail.com
<mailto:miketheman@gmail.com>> wrote:
>
>      John is right - it's becoming common to provide an empty
default.rb
>      for a cookbook that doesn't have any recipes.
>
>    On Wed, May 1, 2013 at 12:34 PM, John Dewey <[2]john@dewey.ws
<mailto:john@dewey.ws>> wrote:
>    >
>    > I believe you can simply create an empty default.rb,
>    > and "step into" the LWRP you wish to test.
>    >
>    > John
>    >
>    > On Wed, May 01, 2013 at 10:12:18PM +0545, millisami r wrote:
>    >>    +1
>    >>
>    >>    I m too kinda similar situation.
>    >>    On Wednesday, May 1, 2013, Bryan Stenson wrote:
>    >>
>    >>    Ohai!
>    >>    Following the cookbook pattern described in the
"Berkshelf Way",
>    I'm
>    >>    trying to create a library cookbook which contains some
custom
>    LWRPs.
>    >>    This library cookbook will not have any meaningful
recipe on its
>    >>    own...it will only supply providers and resources to be
consumed
>    by
>    >>    application cookbooks.
>    >>    I'd like to test the library cookbook separately, and I
think
>    ChefSpec
>    >>    is the correct approach for unit testing.  I see that
ChefSpec
>    takes a
>    >>    recipe list when "converging", but, since my library
cookbook
>    won't
>    >>    have recipes, I don't have one to give to ChefRunner.
>    >>    I suppose I'd like some suggestions/experiences on how
to do
>    this.
>    >>    From my perspective, I can see at least two ways to
solve it
>    (with a
>    >>    STRONG preference on the latter):
>    >>    1. Create a "lwrp_testing.rb" recipe which will
specifically call
>    out
>    >>    to each LWRP the library cookbook provides.  I don't
like this
>    cause
>    >>    then I've got a testing recipe floating around which
COULD be
>    applied
>    >>    to a node in production - and that's just silly.  I
could prefix
>    this
>    >>    recipe with a "_" (as in, "_lwrp_testing.rb"), but
again, it
>    feels like
>    >>    a hack.
>    >>    2. Create a recipe fixture for testing the LWRP for use
only
>    during
>    >>    ChefSpec runs.  The recipe would only exist in the
context of a
>    >>    ChefSpec run, and allow for valid exercise of the
underlying
>    LWRPs
>    >>    during testing...at the same time, the recipe would not
exist
>    "for
>    >>    reals" in the cookbook, and couldn't be assigned to a
run_list.
>    This
>    >>    seems like an elegant approach (design wise), but my
Ruby skills
>    are
>    >>    not to the level they should be to easily implement this.
>    Anybody else
>    >>    try this?
>    >>    Or, perhaps there's another solution I'm overlooking?
>    >>    Thanks for your thoughts.
>    >>    Bryan
>    >>    PS - Thanks to everybody for another great ChefConf!
>    >>
>    >>    --
>    >>    @millisami
>    >>    ~Sachin Sagar Rai
>    >>    Ruby on Rails Developer
>    >>    [1][3]http://tfm.com.np
>    >>    [2][4]http://nepalonrails.com
>    >>
>    >> References
>    >>
>    >>    1. [5]http://tfm.com.np/
>    >>    2. [6]http://nepalonrails.com/
>
> References
>
>    1. mailto:miketheman@gmail.com <mailto:miketheman@gmail.com>
>    2. mailto:john@dewey.ws <mailto:john@dewey.ws>
>    3. http://tfm.com.np/
>    4. http://nepalonrails.com/
>    5. http://tfm.com.np/
>    6. http://nepalonrails.com/

!DSPAM:51815157182592060713880!


#12

I think I’ve not been clear on what I’m advocating, or why I’m confused.

I’m 100% behind testing cookbooks and LWRPs. Clearly, it’s the
distinguishing factor between “hacking” and professionalism. I’m even 100%
behind including the tests with the cookbook (in the spec/testing/etc
folders in the root of the cookbook).

What I’m arguing against is the need for creating a "_test_myLWRP.rb"
recipe in the “/cookbooks/mylibrarycookbook/recipes/” folder.

If a recipe is in that folder, it should be suitable for use by any other
cookbook/role/run_list. A “_test_myLWRP.rb” recipe would ONLY be useful
for testing “myLWRP.rb” in
"/cookbooks/mylibrarycookbook/{resource|provider}" directories, and
SHOULDN’T be in the general “/cookbooks/mylibrarycookbook/recipes” folder.

It’s the equivalent of putting a RSpec file in your RoR lib directory, or
including JUnit test class in your java classpath during normal execution.

My conclusion? Chefspec needs a way to test LWRPs without the creating a
"real" recipe (similar to what rspec-chef does - thanks Zac!)

I’m suggesting a mechanism which allows Chefspec to inject “fixture
recipes” into “/cookbooks/mylibrarycookbook/recipes” dynamically, before
handing execution to ChefRunner. One possibly layout might be:

/cookbooks
/mylibrarycookbook
/recipes
(empty - or perhaps an empty default.rb recipe)
/providers
myLWRP.rb
/resources
myLWRP.rb
/spec
default_spec.rb
/fixtures
/recipes
testing_myLWRP.rb

“testing_myLWRP.rb” would be copied into the "/mylibrarycookbook/recipes"
for the purpose of the Chefspec run, but wouldn’t be there for general LWRP
consumption.

Anyway, I think this is a pretty fundamental need, and I haven’t found a
great way to do it yet. Perhaps I’ll file feature request and dabble until
I’ve got something worth of a pull request.

Bryan