Skip to content

Commit

Permalink
Merge branch 'master' of github.com:dylanratcliffe/onceover
Browse files Browse the repository at this point in the history
  • Loading branch information
Dylan Ratcliffe committed Feb 5, 2019
2 parents e8e0870 + 6557925 commit 111a6db
Show file tree
Hide file tree
Showing 18 changed files with 139 additions and 92 deletions.
18 changes: 14 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ cache:
script: bundle exec rake full_tests
bundler_args: --path vendor/bundle

rvm:
- 2.3.8
- 2.4.4
- 2.5.3
matrix:
include:
# 2016.x -> 2017.2
- rvm: 2.1.9
env: PUPPET_VERSION="~>4.0"

# 2017.3 -> 2018.1
- rvm: 2.4.4
env: PUPPET_VERSION="~>5.0"

# 2019.0 -> now
- rvm: 2.5.1
env: PUPPET_VERSION="~>6.0"

4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ source 'https://rubygems.org'

gemspec

if ENV['PUPPET_VERSION']
gem 'puppet', ENV['PUPPET_VERSION']
end

# Evaluate Gemfile.local if it exists
if File.exists? "#{__FILE__}.local"
eval(File.read("#{__FILE__}.local"), binding)
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ Why an array of hashes? Well, that is so that we can refer to the same node or n
In the example below we have referred to `centos6a` and `centos7b` in all of our tests as they are in `all_nodes`, `non_windows_servers` and `centos_severs`. However we have *left the more specific references to last*. This is because entries in the test_matrix will override entries above them if applicable. Meaning that we are still only testing each class on the two Centos servers once (Because the gem does de-duplication before running the tests), but also making sure we run `roles::frontend_webserver` twice before checking for idempotency.

**functions** In this section we can add functions that we want to mock when running spec tests. Each function takes the following arguments:
- **type** *statement or rvalue*
- **returns** *Optional: A value to return*

- **returns** *Optional: A value to return*

**before and after conditions** We can set `before` and `after` blocks before each spec test. These are usually used when the functions to stub are conditional: stub functionx if the OS is windows, stub functiony if the fact java_installed is true. The facts are available through the `node_facts` hash and the trusted facts as `trusted_facts`.

Expand Down Expand Up @@ -196,8 +196,9 @@ test_matrix:

functions:
query_resources:
type: rvalue
returns: []
profile::custom_function:
returns: ["one", "two"]

opts:
:facts_dirs:
Expand Down
18 changes: 12 additions & 6 deletions features/run.feature
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,23 @@ Feature: Run rspec and acceptance test suites
And I run onceover command "run spec --force"
Then I should see message pattern "Overwriting local modifications"

Scenario: Run advanced spec tests
Given control repo "puppet_controlrepo"
When I run onceover command "run spec"
Then I should not see any errors

Scenario: Check that control_branch functionality works
Given initialized control repo "control_branch"
When I run onceover command "run spec"
Then the temporary Puppetfile should contain the git branch

Scenario: Mocking functions should work and return the correct data types
Given control repo "function_mocking"
When I run onceover command "run spec"
When I run onceover command "run spec" with class "role::test_data_return"
Then I should not see any errors

Scenario: Mocking functions that use the new :: pathing
Given control repo "function_mocking"
When I run onceover command "run spec" with class "role::test_new_functions"
Then I should not see any errors

# This test is a full test using my controlrepo. It should remain at the end because it takes ages
Scenario: Run advanced spec tests
Given control repo "puppet_controlrepo"
When I run onceover command "run spec"
Then I should not see any errors
6 changes: 6 additions & 0 deletions features/step_definitions/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
@cmd.run
end

When(/^I run onceover command "([^"]*)" with class "([^"]*)"$/) do |command, cls|
@cmd.command = "#{command} --classes #{cls}"
puts @cmd
@cmd.run
end

Then(/^I see help for commands: "([^"]*)"$/) do |commands|
# Get chunk of output between COMMANDS and OPTION, there should be help section
commands_help = @cmd.output[/COMMANDS(.*)OPTIONS/m, 1]
Expand Down
5 changes: 5 additions & 0 deletions lib/onceover/testconfig.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ def initialize(file, opts = {})
@skip_r10k = opts[:skip_r10k] ? true : false
@force = opts[:force] || false

# Validate the mock_functions
if @mock_functions && @mock_functions.any? { |name, details| details.has_key? 'type' }
logger.warn "The 'type' key for mocked functions is deprecated and will be ignored, please remove it."
end

# Loop over all of the items in the test matrix and add those as test
# objects to the list of tests
config['test_matrix'].each do |test_hash|
Expand Down
1 change: 0 additions & 1 deletion onceover.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Gem::Specification.new do |s|
s.add_runtime_dependency 'rspec-puppet', ">= 2.4.0"
s.add_runtime_dependency 'parallel_tests', ">= 2.0.0"
s.add_runtime_dependency 'puppetlabs_spec_helper', ">= 0.4.0"
s.add_runtime_dependency 'rspec-puppet-utils', '>= 2.0.0'
s.add_runtime_dependency 'rspec', '>= 3.0.0'
s.add_runtime_dependency 'r10k', '>=2.1.0'
s.add_runtime_dependency 'puppet', '>=3.4.0'
Expand Down
3 changes: 0 additions & 3 deletions spec/fixtures/controlrepos/function_mocking/Gemfile

This file was deleted.

13 changes: 0 additions & 13 deletions spec/fixtures/controlrepos/function_mocking/Puppetfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,3 @@ forge "http://forge.puppetlabs.com"
#
# I want to download some modules to check if r10k feature in Onceover works correctly.
#

# Versions should be updated to be the latest at the time you start
mod "puppetlabs/stdlib", '4.11.0'

# Modules from Git
# Examples: https://github.com/puppetlabs/r10k/blob/master/doc/puppetfile.mkd#examples
mod 'apache',
:git => 'https://github.com/puppetlabs/puppetlabs-apache',
:commit => '83401079053dca11d61945bd9beef9ecf7576cbf'

#mod 'apache',
# :git => 'https://github.com/puppetlabs/puppetlabs-apache',
# :branch => 'docs_experiment'
32 changes: 0 additions & 32 deletions spec/fixtures/controlrepos/function_mocking/manifests/site.pp

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function profile::fail_puppet (
String $message,
) {
fail($message)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Puppet::Functions.create_function(:'profile::fail_ruby') do
dispatch :fail do
param 'String', :message
end

def fail(message)
call_function('fail', message)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Class: profile::base
#
#
class profile::base {
# This function should fail unless it is mocked
profile::fail_puppet('Puppet language function still failed!')

# So should this
profile::fail_ruby('Ruby function failed!')
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# == Class: role::test_functions
#
class role::test_functions {
unless string('foo') =~ String {
class role::test_data_return {
unless return_string() =~ String {
fail('string() did not return a string')
}
unless number('foo') =~ Numeric {
unless return_number('foo','bar') =~ Numeric {
fail('string() did not return a string')
}
unless boolean('foo') =~ Boolean {
unless return_boolean('foo') =~ Boolean {
fail('string() did not return a string')
}
unless array('foo') =~ Array {
unless return_array('foo') =~ Array {
fail('string() did not return a string')
}
unless hash('foo') =~ Hash {
unless return_hash('foo') =~ Hash {
fail('string() did not return a string')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Class: role::test_new_functions
#
#
class role::test_new_functions {

# This function should fail unless it is mocked
profile::fail_puppet('Puppet language function still failed!')

# So should this
profile::fail_ruby('Ruby function failed!')

}
18 changes: 12 additions & 6 deletions spec/fixtures/controlrepos/function_mocking/spec/onceover.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Classes to be tested
classes:
- role::test_functions
- /role::/

# Nodes to tests classes on, this refers to a 'factset' or 'nodeset'
# depending on whether you are running 'spec' or 'acceptance' tests
Expand All @@ -22,25 +22,31 @@ test_matrix:
tests: 'spec'

functions:
string:
return_string:
type: rvalue
returns: string
number:
return_number:
type: rvalue
returns: 400
boolean:
return_boolean:
type: rvalue
returns: true
array:
return_array:
type: rvalue
returns:
- 1
- 2
- 3
hash:
return_hash:
type: rvalue
returns:
foo: bar
profile::fail_puppet:
type: rvalue
returns: null
profile::fail_ruby:
type: rvalue
returns: null

opts:
:debug: true
15 changes: 14 additions & 1 deletion templates/spec_helper.rb.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Yes it's strange that we have to call `RSpec.configure` more than once. The
# reason we are doing this is to silence the incredibly annoying warning:
#
# puppetlabs_spec_helper: defaults `mock_with` to `:mocha`
#
# In order to do this we have configure the
# mocking, THEN require puppetlabs_spec_helper.
#
# Yes, I know. Someone buy me a 🍺 for fixing this.
#
RSpec.configure do |c|
c.mock_with :mocha
end

require 'puppetlabs_spec_helper/module_spec_helper'
require 'rspec-puppet-utils'
require 'rspec_junit_formatter'

RSpec.configure do |c|
Expand Down
43 changes: 26 additions & 17 deletions templates/test_spec.rb.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,6 @@ require 'spec_helper'
<% test.classes.each do |cls| -%>
describe "<%= cls.name %>" do

<% if @mock_functions -%>
<% @mock_functions.each do |function,params| -%>
<% if params['type'] == 'statement' -%>
MockFunction.new('<%= function %>', {:type => :statement})
<% else -%>
let!(:<%= function %>) { MockFunction.new('<%= function %>') { |f|
f.stubbed.returns(<%= params['returns'].inspect %>)
}
}
<% end -%>

<% end -%>
<% end -%>
<% test.nodes.each do |node| -%>
context "using fact set <%= node.name %>" do
node_facts = <%= node.fact_set %>
Expand All @@ -31,22 +18,44 @@ let!(:<%= function %>) { MockFunction.new('<%= function %>') { |f|
<% end -%>
end
<% end -%>

<% if @mock_functions -%>
# Create a from_json function so that we can parse the output of json for mocked functions
before :each do
Puppet::Parser::Functions.newfunction(:from_json, :type => :rvalue) { |args|
require 'json'
JSON.parse(args[0])
}
end
<% end -%>

<% if @after_conditions -%>
after :each do
<% @after_conditions.each do |function| -%>
<%= function %>
<% end -%>
end
<% end -%>
<% if pre_condition -%>
let(:pre_condition) {
pp = <%= '<<' %>-END
$onceover_class = '<%= cls.name %>'
$onceover_node = '<%= node.name %>'
<%= pre_condition.chomp %>
$onceover_node = '<%= node.name %>'

# Begin user-specified pre_condition
<%= (pre_condition || "").chomp %>
# End user-specified pre_condition

<% if @mock_functions -%>
<% require 'json' -%>
# Mocking functions
<% @mock_functions.each do |function,params| -%>
function <%= function %> (*$args) { from_json('<%= params['returns'].to_json %>') }
<% end -%>
<% end -%>

END
}
<% end -%>

it { should compile }
end
<% end -%>
Expand Down

0 comments on commit 111a6db

Please sign in to comment.