Mocking data in Test Kitchen (Part 2)

This content is more than 4 years old and the cloud moves fast so some information may be slightly out of date.

Going beyond the easier use case of mocking attributes and databags, we sometimes want to fake some data about the system itself.

Ohai Attributes

Sometimes, you encounter systems where you want to make distrinctions based on Ohai attributes like the hostname or domain name. This is not very common, but worth noting that you can use similar techniques for mocking in those cases.

Let’s say we have a recipe which sets a specific networking configuration based on the hostname. Well, the problem with testing this, is that hostnames are automatic attributes and as you can see from the famous [Precedence Table], there is no way these can be overwritten.

There is a way, though - but first we have to look at an elusive concept in the Chef world: Fixture Cookbooks

Fixture Cookbook

This is a minimalist cookbook which helps you set up your machines so they can be tested with your unchanged recipe. This often involves some configuration which would normally happen outside of Chef. An example could be that in production your VMs are created based on images where another department made some changes. There could be base packages pre-installed or some DNS configuration done.

If we want to replicate this, we write a Fixture Cookbook. Not much effort in there, it is just meant for a pre-test setup. I prefer to put it into a directory test/integration/fixtures as they are clearly related to integration tests 1.

A fixture cookbook can exist out of only two files. A minimalistic metadata.rb:

name 'fixtures'

# depends 'other_cookbook', '~> 1.0'

There is no extra information needed, just the name and maybe some dependencies for your planned setup tasks.

Then, there is the default recipe recipe.rb. It sits right in the main directory, no need for a recipes/ subdirectory 2.

So how would we use this? Let’s look at our kitchen.yml:

suites:
 - name: standard
   provisioner:
     run_list:
        - recipe[fixtures]
        - recipe[sql_server::configure]

Of course, Chef does not yet know how to map this new cookbook and the path we created it in. This needs a slight adjustment to the Berksfile of your main cookbook:

source 'https://supermarket.chef.io'

metadata

cookbook 'fixtures', path: 'test/integration/fixtures', group: :integration

Test Kitchen starts tests with the :integration group, which tells Chef to add the path to our fixtures and the runlist then executes it.

Ohai Attributes with kitchen-ohai

Back to our example of overriding a hostname.

Now that we know how to tweak our environment with Fixture Cookbooks, we are only missing one piece of this puzzle: the knowledge about the kitchen-ohai cookbook.

This small gem allows us to override Ohai attributes. And now that we know how to set it up, our plan can come together.

As we already prepared our Berksfile and our kitchen.yml runlist, we only need to adjust the fixture cookbook contents.

metadata.rb:

name 'fixtures'
  
depends 'kitchen-ohai'

recipe.rb:

include_recipe 'kitchen-ohai'

And now we can override those attributes in the kitchen.yml:

suites:
  - name: standard
    provisioner:
      run_list:
        - recipe[fixtures]
        - recipe[sql_server::configure]
      attributes:
        kitchen_ohai:
          values:
            hostname: 'NEWHOSTNAME'

This is a pretty complex construct, so you should always ask yourself if using a Fixture Cookbook or overriding Ohai attributes is really the only way you can reach your goals. Try to avoid complexity, if possible. But know about your options, if you need them.


  1. Actually, this location is specifically mentioned to be used for fixtures in the Test Kitchen sources ↩︎

  2. This uses a concept called “Root Aliases” detailed in the RFC033-based documentation ↩︎

Similar Posts You Might Enjoy

Mocking data in Test Kitchen

The more complex your cookbooks, the bigger the need to supply some external information to your test machines. Passing specific attributes, values of databags or secrets for testing become necessary. We will go through these use cases and show how to mock the data in this post. - by Thomas Heinen

Update your Style in Test Kitchen

It is surprising how many resources on the Internet are carrying on outdated or deprecated information - the Chef ecosystem is no exception to this. While outdated style in Ruby files has been detected via cookstyle for a while, Test Kitchen files still have no sanity checks yet. Let’s see what changed in this short post. - by Thomas Heinen

Testing Physical Machines with kitchen-static (Part 2)

Testing on Physical Machines - Part 2 After introducing how to work with physical machines and Test Kitchen last time, we will look at a feature to allow central orchestration of available machines. - by Thomas Heinen