Wednesday, September 13, 2017

chef-Testing with test-kitchen

DevOps is a two way street

§ Operations should benefit from years of
best practices surrounding software
development

Infrastructure as code
Branching/merging
testing, testing, testing
> unit tests
> functional tests
> Test Driven Development
> Behavior Driven Development

The faster your write/test/fix loop is,

the happier you are.


Workflows

new software development workflow

§ Write code alongside unit tests
ensures correctness of new code
avoids breaking old code
§ Perform integration/acceptance tests in pre-production environments
Ensures your software plays well with others

Workflows

New cookbook workflow

Write cookbook
Write ChefSpec tests alongside
Use rspec for libraries in cookbooks
Test cookbook locally
test-kitchen
Vagrant
Test cookbook remotely
test-kitchen with OpenStack
Test cookbook in a particular environment
ServerSpec

Code Correctness
Rubocop - http://batsov.com/rubocop/           Foodcritic - http://acrmp.github.io/foodcritic/


Rubocop example

$ cd cookbooks/gapMetrics/!
$ rubocop!
warning: parser/current is loading parser/ruby21, which recognizes!
warning: 2.1.7-compliant syntax, but you are running 2.1.5.!
Inspecting 20 files!
CCCCCCWWCCCCCCW.WCCC!
!
Offenses:!
!
Berksfile:1:1: C: Missing space after #.!
#site :opscode!
^^^^^^^^^^^^^^!
...!
recipes/xpolog.rb:11:3: C: Inconsistent indentation detected.!
authorized_keys_for 'xpolog'!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
recipes/xpolog.rb:11:31: C: Final newline missing.!
authorized_keys_for 'xpolog'!
!!
20 files inspected, 384 offenses detected!


Rubocop resources
§ Marks your code against the style guide
https://github.com/bbatsov/ruby-style-guide
§ Can automatically fix some errors
§ You can choose rules to ignore, create new ones
or override defaults in .rubocop.yml
https://docs.chef.io/rubocop.html

Foodcritic example

$ foodcritic .!
FC001: Use strings in preference to symbols to access node attributes: ./attributes/
graphite.rb:28!
FC002: Avoid string interpolation where not required: ./recipes/relay.rb:78!
FC007: Ensure recipe dependencies are reflected in cookbook metadata: ./recipes/
_pre_setup.rb:34!
$ !
$ foodcritic -h!
foodcritic [cookbook_paths]!
-t, --tags TAGS Check against (or exclude ~) rules with the specified
tags.!
-f, --epic-fail TAGS Fail the build based on tags. Use 'any' to fail on
all warnings.!
-c, --chef-version VERSION Only check against rules valid for this version of
Chef.!
-B, --cookbook-path PATH Cookbook path(s) to check.!
-C, --[no-]context Show lines matched against rather than the default
summary.!
-E, --environment-path PATH Environment path(s) to check.!
-I, --include PATH Additional rule file path(s) to load.!
-G, --search-gems Search rubygems for rule files with the path
foodcritic/rules/**/*.rb!
-R, --role-path PATH Role path(s) to check.!
-S, --search-grammar PATH Specify grammar to use when validating search syntax.!
-V, --version Display the foodcritic version.!
-X, --exclude PATH Exclude path(s) from being linted.!

Foodcritic resources
http://acrmp.github.io/foodcritic/

Also, look for great production-related catches from Etsy:
https://github.com/etsy/foodcritic-rules

§ Catch packages with an :upgrade action and no specific version
§ Notice dev resources being called from prod
§ Find execute resources with no metaparameters or action :ignore


Unit tests – ChefSpec (an extension of rspec)

ChefSpec simulates the convergence of resources on a node

$ chef exec rspec getValues_spec.rb --format doc!
!
Knifemanage::GetValues#get_changes!
can get a change set from jenkins!
!
Finished in 0.00964 seconds (files took 6.96 seconds to load)!
1 example, 0 failures!


Unit tests – ChefSpec (an extension of rspec)

rspec in general can mock objects or stub apis



ChefSpec and rspec resources

§ https://docs.chef.io/chefspec.html
§ http://betterspecs.org/
More on day 3 under testing.

Functional testing

§ Identify the function or purpose of the cookbook
§ Create input data
§ Expect output
§ Create and execute tests
§ Verify output

Remember, we were talking about test-kitchen?

Test-Kitchen components

Kitchen is made up of pluggable parts
§ pluggable testing framework
§ ships with ChefDK
§ rapidly create/configure/test sandboxes

$ chef --version
Chef Development Kit Version: 0.6.2
chef-client version: 12.3.0
berks version: 3.2.4
kitchen version: 1.4.0
$ vagrant -v
Vagrant 1.6.3

Test-Kitchen sandbox creation

Could be anywhere
§ Target specified by a driver
use vagrant to run locally, e.g. your laptop
use OpenStack driver to create sandboxes in an
OpenStack tenant
> You should all have a personal developer tenant in OpenStack
> The watchmen pipelines can do this for your project
§ It’s quite useful to understand how that works behind the scenes
§ No, seriously.

Test-Kitchen sandbox configuration

Configuration done by the provisioner
Could be a real chef client and server
Could be chef-solo
Could be chef-zero

Test-Kitchen sandbox configuration

Configuration done by the provisioner
Just use chef-zero

Test-Kitchen sandbox testing

Testing is performed via the busser
Lots of choices
> ChefSpec
> ServerSpec
§ You can also interactively poke at the box
most useful for our beginner case


Problem: we want to test our mysite
cookbook locally

§ Problem: We’d like a faster test cycle than constantly uploading the
cookbook
§ Solution: test kitchen!

Install Vagrant and VirtualBox

§ Vagrant wraps VirtualBox
https://www.vagrantup.com/downloads.html https://www.virtualbox.org/wiki/Downloads


Test Kitchen

§ Test Kitchen is a tool for testing cookbooks
§ Each config is specific to a given cookbook
§ Perform all commands in the cookbook under test’s directory.
Gives developer space to safely interact with distributed systems.


Update default .kitchen.yml to use our
vagrant boxes

(mysite/.kitchen.yml)

---!
driver:!
name: vagrant!
!
provisioner:!
name: chef_zero!
!
platforms:!
- name: rhel66!
driver_config:!
box: packer-rhel66!
box_url: http://repo1.phx.gapinc.dev/gapSoftware/vagrant-boxes/packer-rhel66.box!
!
suites:!
- name: mysite!
run_list:!
- recipe[mysite::default]!
attributes:!




A Brief Understanding of YAML


§ No tabs, only spaces
§ Indentation sets hierarchy
§ 2 spaces per indentation
§ use a real editor
§ http://yaml.org/refcard.html


Test-Kitchen - check your configuration

kitchen diagnose!

---!
timestamp: 2015-08-17 03:43:16 UTC!
kitchen_version: 1.4.0!
instances:!
default-rhel66:!
platform:!
os_type: unix!
shell_type: bourne!
state_file: {}!
driver:!
box: packer-rhel66!
box_check_update:!
box_url: http://repo1.phx.gapinc.dev/gapSoftware/vagrant-boxes/packer-rhel66.box!
box_version:!
customize: {}!
gui:!
kitchen_root: "/Users/lamont/tmp/mysite"!
log_level: :info!

Test-Kitchen – kitchen help

$ kitchen help

Commands:!
kitchen console # Kitchen Console!!
kitchen converge [INSTANCE|REGEXP|all] # Change instance state to converge. Use a provisioner to configure
one or more instances!
kitchen create [INSTANCE|REGEXP|all] # Change instance state to create. Start one or more instances!
kitchen destroy [INSTANCE|REGEXP|all] # Change instance state to destroy. Delete all information for one or
more instances!
kitchen diagnose [INSTANCE|REGEXP|all] # Show computed diagnostic configuration!
kitchen driver # Driver subcommands!
kitchen driver create [NAME] # Create a new Kitchen Driver gem project!
kitchen driver discover # Discover Test Kitchen drivers published on RubyGems!
kitchen driver help [COMMAND] # Describe subcommands or one specific subcommand!
kitchen exec INSTANCE|REGEXP -c REMOTE_COMMAND # Execute command on one or more instance!
kitchen help [COMMAND] # Describe available commands or one specific command!
kitchen init # Adds some configuration to your cookbook so Kitchen can rock!
kitchen list [INSTANCE|REGEXP|all] # Lists one or more instances!
kitchen login INSTANCE|REGEXP # Log in to one instance!
kitchen setup [INSTANCE|REGEXP|all] # Change instance state to setup. Prepare to run automated tests.
Install busser and related gems on one or ...!
kitchen test [INSTANCE|REGEXP|all] # Test (destroy, create, converge, setup, verify and destroy) one or
more instances!
kitchen verify [INSTANCE|REGEXP|all] # Change instance state to verify. Run automated tests on one or more
instances!
kitchen version # Print Kitchen's version information!


Test-Kitchen – kitchen list

kitchen list!

IInstance           Driver     Provisioner       Verifier     Transport Last Action!
default-rhel66    Vagrant     ChefZero       Busser       Ssh <Not Created>!


Test-Kitchen – kitchen create

kitchen create!

-----> Starting Kitchen (v1.4.0)!
-----> Creating <default-rhel66>...!
Bringing machine 'default' up with 'virtualbox' provider...!
==> default: Box 'packer-rhel66' could not be found. Attempting to find and install...!
default: Box Provider: virtualbox!
default: Box Version: >= 0!
==> default: Adding box 'packer-rhel66' (v0) for provider: virtualbox!
default: Downloading: http://repo1.phx.gapinc.dev/gapSoftware/vagrant-boxes/packer-rhel66.box!
==> default: Successfully added box 'packer-rhel66' (v0) for 'virtualbox'!!
==> default: Importing base box 'packer-rhel66'...!
==> default: Matching MAC address for NAT networking...!
==> default: Setting the name of the VM: kitchen-mysite-default-rhel66_default_1439784531236_96800!
Skipping Berkshelf with --no-provision!
==> default: Clearing any previously set network interfaces...!
==> default: Preparing network interfaces based on configuration...!
default: Adapter 1: nat!
==> default: Forwarding ports...!
default: 22 => 2222 (adapter 1)!
==> default: Booting VM...!
==> default: Waiting for machine to boot. This may take a few minutes...!
default: SSH address: 127.0.0.1:2222!
default: SSH username: vagrant!
...!
---> Kitchen is finished. (13m32.61s)!

Test-Kitchen – kitchen list, again
$
kitchen list!

Instance         Driver    Provisioner    Verifier    Transport Last Action!
default-rhel66 Vagrant ChefZero        Busser    Ssh Created!

Test-Kitchen – kitchen login

kitchen login!

Last login: Sun Aug 16 21:09:20 2015 from 10.0.2.2!
Welcome to your Vagrant-built virtual machine.!
[vagrant@default-rhel66 ~]$!

Test-Kitchen – kitchen destroy

kitchen destroy!

-----> Starting Kitchen (v1.4.0)!
-----> Destroying <default-rhel66>...!
==> default: Forcing shutdown of VM...!
==> default: Destroying VM and associated drives...!
Vagrant instance <default-rhel66> destroyed.!
Finished destroying <default-rhel66> (0m4.13s).!
-----> Kitchen is finished. (0m5.00s)!

Test-Kitchen – kitchen converge

kkitchen converge!

...!
* cookbook_file[/var/www/html/index.html] action create!
!
- update content in file /var/www/html/index.html from none to 7e1f17!
--- /var/www/html/index.html !2015-08-16 21:29:13.978725350 -0700!
+++ /var/www/html/.index.html20150816-6007-t8s9c1 !2015-08-16 21:29:13.977725849 -0700!
@@ -1 +1,10 @@!
+<html>!
+<title>Better Homepage for Gap,Inc</title>!
+<body>!
+<h1>It is SALE time at Gap!</h1>!
+<h2>Time for back to school.</h2>!
+<p>We configured this in the recipe</p>!
+</body>!
+</html>!
+!
- change mode from '' to '0644'!
- change owner from '' to 'nobody'!
!!
Running handlers:!
Running handlers complete!
Chef Client finished, 4/4 resources updated in 133.595728961 seconds!
Finished converging <default-rhel66> (2m18.42s).!
-----> Kitchen is finished. (3m10.41s)!
!

Test Kitchen – What just happened?

§ Test Kitchen automatically includes prerequisite commands
create
converge <- converge implies create
setup
verify
destroy
test <- test implies create, converge, setup, verify, destroy




No comments:

Post a Comment