Merge pull request #51 from aspiers/order

refactoring and implement order LWRP
This commit is contained in:
Vincent Untz 2014-03-26 12:02:49 +01:00
commit 73edd77d1a
42 changed files with 591 additions and 430 deletions

View File

@ -7,9 +7,16 @@ guard_opts = {
all_after_pass: true,
}
def all_specs; 'spec' end
def library_specs; 'spec/libraries' end
def provider_specs; 'spec/providers' end
DEBUG = false
def reload(target)
puts "-> #{target}" if DEBUG
target
end
def all_specs; reload 'all_specs'; 'spec' end
def library_specs; reload 'library_specs'; 'spec/libraries' end
def provider_specs; reload 'provider_specs'; 'spec/providers' end
group :rspec do
guard 'rspec', guard_opts do
@ -20,14 +27,14 @@ group :rspec do
watch(%r{^spec/fixtures/(.+)\.rb$}) { all_specs }
watch(%r{^libraries/pacemaker\.rb$}) { all_specs }
watch(%r{^libraries/(.*mixin.*)\.rb$}) { library_specs }
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^(spec/.+_spec\.rb)$}) { |m| reload m[1] }
watch(%r{^libraries/(.+)\.rb$}) { |m|
"spec/libraries/#{m[1]}_spec.rb"
reload "spec/libraries/#{m[1]}_spec.rb"
}
watch(%r{^providers/common\.rb$}) { provider_specs }
watch(%r{^providers/(.*mixin.*)\.rb$}) { provider_specs }
watch(%r{^(?:resources|providers)/(.+)\.rb$}) { |m|
"spec/providers/#{m[1]}_spec.rb"
reload "spec/providers/#{m[1]}_spec.rb"
}
end
end

View File

@ -1,2 +1,3 @@
require File.expand_path('pacemaker/standard_cib_object.rb', File.dirname(__FILE__))
require File.expand_path('pacemaker/runnable_resource.rb', File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('pacemaker/standard_cib_object.rb', this_dir)
require File.expand_path('pacemaker/runnable_resource.rb', this_dir)

View File

@ -1,5 +1,4 @@
require 'chef/application'
require ::File.expand_path('standard_cib_object', ::File.dirname(__FILE__))
require ::File.expand_path('standard_cib_object', File.dirname(__FILE__))
# Common code used by Pacemaker LWRP providers for resources supporting
# the :run action.

View File

@ -1,6 +1,5 @@
require 'chef/application'
require ::File.expand_path('../../../pacemaker/cib_object',
::File.dirname(__FILE__))
File.dirname(__FILE__))
# Common code used by Pacemaker LWRP providers

View File

@ -0,0 +1,31 @@
require File.expand_path('../constraint', File.dirname(__FILE__))
class Pacemaker::Constraint::Order < Pacemaker::Constraint
TYPE = 'order'
register_type TYPE
attr_accessor :score, :ordering
def self.attrs_to_copy_from_chef
%w(score ordering)
end
def parse_definition
# FIXME: add support for symmetrical=<bool>
# Currently we take the easy way out and don't bother parsing the ordering.
# See the crm(8) man page for the official BNF grammar.
score_regexp = %r{\d+|[-+]?inf|Mandatory|Optional|Serialize}
unless definition =~ /^#{self.class::TYPE} (\S+) (#{score_regexp}): (.+?)\s*$/
raise Pacemaker::CIBObject::DefinitionParseError, \
"Couldn't parse definition '#{definition}'"
end
self.name = $1
self.score = $2
self.ordering = $3
end
def definition_string
"#{self.class::TYPE} #{name} #{score}: #{ordering}"
end
end

View File

@ -1,5 +1,6 @@
require File.expand_path('../resource', File.dirname(__FILE__))
require File.expand_path('../mixins/resource_meta', File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../resource', this_dir)
require File.expand_path('../mixins/resource_meta', this_dir)
class Pacemaker::Resource::Clone < Pacemaker::Resource
TYPE = 'clone'

View File

@ -1,5 +1,6 @@
require File.expand_path('../resource', File.dirname(__FILE__))
require File.expand_path('../mixins/resource_meta', File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../resource', this_dir)
require File.expand_path('../mixins/resource_meta', this_dir)
class Pacemaker::Resource::Group < Pacemaker::Resource
TYPE = 'group'

View File

@ -1,6 +1,8 @@
require 'shellwords'
require File.expand_path('../resource', File.dirname(__FILE__))
require File.expand_path('../mixins/resource_meta', File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../resource', this_dir)
require File.expand_path('../mixins/resource_meta', this_dir)
class Pacemaker::Resource::Primitive < Pacemaker::Resource
TYPE = 'primitive'

View File

@ -17,9 +17,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::RunnableResource

View File

@ -17,9 +17,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::StandardCIBObject

View File

@ -16,9 +16,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::RunnableResource

View File

@ -17,9 +17,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::StandardCIBObject

View File

@ -17,9 +17,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::RunnableResource

View File

@ -1,8 +1,8 @@
# Author:: Robert Choi
# Cookbook Name:: pacemaker
# Provider:: order
#
# Copyright:: 2013, Robert Choi
# Copyright:: 2014, SUSE
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -17,46 +17,57 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker/cib_object',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker/cib_object', this_dir)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::StandardCIBObject
action :create do
name = new_resource.name
priority = new_resource.priority
resources = new_resource.resources
unless resource_exists?(name)
cmd = "crm configure order #{name} #{priority}:"
resources.each do |rsc|
cmd << " #{rsc}"
end
cmd_ = Mixlib::ShellOut.new(cmd)
cmd_.environment['HOME'] = ENV.fetch('HOME', '/root')
cmd_.run_command
begin
cmd_.error!
if resource_exists?(name)
new_resource.updated_by_last_action(true)
Chef::Log.info "Successfully configured order '#{name}'."
else
Chef::Log.error "Failed to configure order #{name}."
end
rescue
Chef::Log.error "Failed to configure order #{name}."
end
if @current_resource_definition.nil?
create_resource(name)
else
maybe_modify_resource(name)
end
end
action :delete do
name = new_resource.name
cmd = "crm resource stop #{name}; crm configure delete #{name}"
e = execute "delete order #{name}" do
command cmd
only_if { resource_exists?(name) }
end
new_resource.updated_by_last_action(true)
Chef::Log.info "Deleted order '#{name}'."
next unless @current_resource
standard_delete_resource
end
def cib_object_class
::Pacemaker::Constraint::Order
end
def load_current_resource
standard_load_current_resource
end
def init_current_resource
name = @new_resource.name
@current_resource = Chef::Resource::PacemakerOrder.new(name)
attrs = [:score, :ordering]
@current_cib_object.copy_attrs_to_chef_resource(@current_resource, *attrs)
end
def create_resource(name)
standard_create_resource
end
def maybe_modify_resource(name)
Chef::Log.info "Checking existing #{@current_cib_object} for modifications"
desired_order = cib_object_class.from_chef_resource(new_resource)
if desired_order.definition_string != @current_cib_object.definition_string
Chef::Log.debug "changed from [#{@current_cib_object.definition_string}] to [#{desired_order.definition_string}]"
cmd = desired_order.reconfigure_command
execute cmd do
action :nothing
end.run_action(:run)
new_resource.updated_by_last_action(true)
end
end

View File

@ -17,9 +17,9 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker', ::File.dirname(__FILE__))
require ::File.expand_path('../libraries/chef/mixin/pacemaker',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker', this_dir)
require ::File.expand_path('../libraries/chef/mixin/pacemaker', this_dir)
include Chef::Mixin::Pacemaker::RunnableResource

View File

@ -17,8 +17,8 @@
# limitations under the License.
#
require ::File.expand_path('../libraries/pacemaker/cib_object',
::File.dirname(__FILE__))
this_dir = ::File.dirname(__FILE__)
require ::File.expand_path('../libraries/pacemaker/cib_object', this_dir)
action :create do
name = new_resource.name

View File

@ -21,6 +21,6 @@ actions :create, :delete
default_action :create
attribute :name, :kind_of => String, :name_attribute => true
attribute :priority, :kind_of => String
attribute :resources, :kind_of => Array
attribute :name, :kind_of => String, :name_attribute => true
attribute :score, :kind_of => String
attribute :ordering, :kind_of => String

View File

@ -1,5 +1,5 @@
require ::File.expand_path('../../libraries/pacemaker/constraint/colocation',
::File.dirname(__FILE__))
File.dirname(__FILE__))
module Chef::RSpec
module Pacemaker

View File

@ -1,5 +1,5 @@
require ::File.expand_path('../../libraries/pacemaker/resource/primitive',
::File.dirname(__FILE__))
File.dirname(__FILE__))
module Chef::RSpec
module Pacemaker

View File

@ -1,5 +1,5 @@
require ::File.expand_path('../../libraries/pacemaker/constraint/location',
::File.dirname(__FILE__))
File.dirname(__FILE__))
module Chef::RSpec
module Pacemaker

14
spec/fixtures/order_constraint.rb vendored Normal file
View File

@ -0,0 +1,14 @@
require ::File.expand_path('../../libraries/pacemaker/constraint/order',
File.dirname(__FILE__))
module Chef::RSpec
module Pacemaker
module Config
ORDER_CONSTRAINT = \
::Pacemaker::Constraint::Order.new('order1')
ORDER_CONSTRAINT.score = 'Mandatory'
ORDER_CONSTRAINT.ordering = 'primitive1 clone1'
ORDER_CONSTRAINT_DEFINITION = 'order order1 Mandatory: primitive1 clone1'
end
end
end

View File

@ -1,79 +1,13 @@
# Shared code used to test providers of CIB objects
# Shared code used to test subclasses of Pacemaker::CIBObject
require 'mixlib/shellout'
require File.expand_path('../../libraries/pacemaker/cib_object',
File.dirname(__FILE__))
module Chef::RSpec
module Pacemaker
module CIBObject
# Return a Mixlib::ShellOut double which mimics successful
# execution of a command, returning the given string on STDOUT.
def succeeding_shellout_double(string)
shellout = double(Mixlib::ShellOut)
shellout.stub(:environment).and_return({})
shellout.stub(:run_command)
shellout.stub(:error!)
expect(shellout).to receive(:stdout).and_return(string)
shellout
end
# Return a Mixlib::ShellOut double which mimics failed
# execution of a command, raising an exception when #error! is
# called. We expect #error! to be called, because if it isn't,
# that probably indicates the code isn't robust enough. This
# may need to be relaxed in the future.
def failing_shellout_double(stdout='', stderr='', exitstatus=1)
shellout = double(Mixlib::ShellOut)
shellout.stub(:environment).and_return({})
shellout.stub(:run_command)
shellout.stub(:stdout).and_return(stdout)
shellout.stub(:stderr).and_return(stderr)
shellout.stub(:exitstatus).and_return(exitstatus)
exception = Mixlib::ShellOut::ShellCommandFailed.new(
"Expected process to exit with 0, " +
"but received '#{exitstatus}'"
)
expect(shellout).to receive(:error!).and_raise(exception)
shellout
end
# This stubs Mixlib::ShellOut.new with a sequence of doubles
# with a corresponding sequence of behaviours. This allows us
# to simulate the output of a series of shell commands being run
# via Mixlib::ShellOut. Each double either mimics a successful
# command execution whose #stdout method returns the given
# string, or a failed execution with the given exit code and
# STDOUT/STDERR.
#
# results is an Array describing the sequence of behaviours;
# each element is either a string mimicking STDOUT from
# successful command execution, or a [stdout, stderr, exitcode]
# status mimicking command execution failure.
#
# For example, "crm configure show" is executed by
# #load_current_resource, and again later on for the :create
# action, to see whether to create or modify. So the first
# double in the sequence would return an empty definition if we
# wanted to test creation of a new CIB object, or an existing
# definition if we wanted to test modification of an existing
# one. If the test needs subsequent doubles to return different
# values then stdout_strings can have more than one element.
def stub_shellout(*results)
doubles = results.map { |result|
result.is_a?(String) ?
succeeding_shellout_double(result)
: failing_shellout_double(*result)
}
Mixlib::ShellOut.stub(:new).and_return(*doubles)
end
end
end
end
this_dir = File.dirname(__FILE__)
require File.expand_path('../../libraries/pacemaker/cib_object', this_dir)
require File.expand_path('shellout', this_dir)
shared_examples "a CIB object" do
include Chef::RSpec::Pacemaker::CIBObject
include Chef::RSpec::Mixlib::ShellOut
def expect_to_match_fixture(obj)
expect(obj.class).to eq(pacemaker_object_class)
@ -101,21 +35,3 @@ shared_examples "a CIB object" do
"Expected #{object_type} type but loaded definition was type sometype")
end
end
shared_examples "action on non-existent resource" do |action, cmd, expected_error|
include Chef::RSpec::Pacemaker::CIBObject
it "should not attempt to #{action.to_s} a non-existent resource" do
stub_shellout("")
if expected_error
expect { provider.run_action action }.to \
raise_error(RuntimeError, expected_error)
else
provider.run_action action
end
expect(@chef_run).not_to run_execute(cmd)
expect(@resource).not_to be_updated
end
end

View File

@ -0,0 +1,26 @@
# Shared code used to test providers of non-runnable Chef resources
# representing Pacemaker CIB objects. For example the provider for
# primitives is runnable (since primitives can be started and stopped)
# but constraints cannot.
this_dir = File.dirname(__FILE__)
require File.expand_path('provider', this_dir)
require File.expand_path('shellout', this_dir)
shared_examples "a non-runnable resource" do |fixture|
include Chef::RSpec::Mixlib::ShellOut
it_should_behave_like "all Pacemaker LWRPs", fixture
describe ":delete action" do
it "should delete a resource" do
stub_shellout(fixture.definition_string)
provider.run_action :delete
cmd = "crm configure delete '#{fixture.name}'"
expect(@chef_run).to run_execute(cmd)
expect(@resource).to be_updated
end
end
end

71
spec/helpers/provider.rb Normal file
View File

@ -0,0 +1,71 @@
# Shared code used to test providers of CIB objects
this_dir = File.dirname(__FILE__)
require File.expand_path('shellout', this_dir)
require File.expand_path('cib_object', this_dir)
shared_context "a Pacemaker LWRP" do
before(:each) do
runner_opts = {
:step_into => [lwrp_name]
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
camelized_subclass_name = "Pacemaker" + lwrp_name.capitalize
@resource_class = ::Chef::Resource.const_get(camelized_subclass_name)
@provider_class = ::Chef::Provider.const_get(camelized_subclass_name)
@resource = @resource_class.new(fixture.name, @run_context)
end
let (:provider) { @provider_class.new(@resource, @run_context) }
end
module Chef::RSpec
module Pacemaker
module CIBObject
include Chef::RSpec::Mixlib::ShellOut
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
end
end
end
shared_examples "action on non-existent resource" do |action, cmd, expected_error|
include Chef::RSpec::Mixlib::ShellOut
it "should not attempt to #{action.to_s} a non-existent resource" do
stub_shellout("")
if expected_error
expect { provider.run_action action }.to \
raise_error(RuntimeError, expected_error)
else
provider.run_action action
end
expect(@chef_run).not_to run_execute(cmd)
expect(@resource).not_to be_updated
end
end
shared_examples "all Pacemaker LWRPs" do |fixture|
describe ":delete action" do
it_should_behave_like "action on non-existent resource", \
:delete, "crm configure delete #{fixture.name}", nil
end
end

View File

@ -1,25 +1,24 @@
require File.expand_path('cib_object', File.dirname(__FILE__))
# Shared code used to test providers of runnable Chef resources
# representing Pacemaker CIB objects. For example the provider
# for primitives is runnable (since primitives can be started
# and stopped) but constraints cannot.
module Chef::RSpec
module Pacemaker
module RunnableResource
def expect_running(running)
expect_any_instance_of(cib_object_class) \
.to receive(:running?) \
.and_return(running)
end
end
end
end
this_dir = File.dirname(__FILE__)
require File.expand_path('provider', this_dir)
require File.expand_path('shellout', this_dir)
shared_examples "a runnable resource" do |fixture|
def expect_running(running)
expect_any_instance_of(cib_object_class) \
.to receive(:running?) \
.and_return(running)
end
include Chef::RSpec::Pacemaker::RunnableResource
it_should_behave_like "all Pacemaker LWRPs", fixture
include Chef::RSpec::Mixlib::ShellOut
describe ":delete action" do
it_should_behave_like "action on non-existent resource", \
:delete, "crm configure delete #{fixture.name}", nil
it "should not delete a running resource" do
stub_shellout(fixture.definition_string)
expect_running(true)

68
spec/helpers/shellout.rb Normal file
View File

@ -0,0 +1,68 @@
require 'mixlib/shellout'
module Chef::RSpec
module Mixlib
module ShellOut
# Return a Mixlib::ShellOut double which mimics successful
# execution of a command, returning the given string on STDOUT.
def succeeding_shellout_double(string)
shellout = double(Mixlib::ShellOut)
shellout.stub(:environment).and_return({})
shellout.stub(:run_command)
shellout.stub(:error!)
expect(shellout).to receive(:stdout).and_return(string)
shellout
end
# Return a Mixlib::ShellOut double which mimics failed
# execution of a command, raising an exception when #error! is
# called. We expect #error! to be called, because if it isn't,
# that probably indicates the code isn't robust enough. This
# may need to be relaxed in the future.
def failing_shellout_double(stdout='', stderr='', exitstatus=1)
shellout = double(Mixlib::ShellOut)
shellout.stub(:environment).and_return({})
shellout.stub(:run_command)
shellout.stub(:stdout).and_return(stdout)
shellout.stub(:stderr).and_return(stderr)
shellout.stub(:exitstatus).and_return(exitstatus)
exception = ::Mixlib::ShellOut::ShellCommandFailed.new(
"Expected process to exit with 0, " +
"but received '#{exitstatus}'"
)
expect(shellout).to receive(:error!).and_raise(exception)
shellout
end
# This stubs Mixlib::ShellOut.new with a sequence of doubles
# with a corresponding sequence of behaviours. This allows us
# to simulate the output of a series of shell commands being run
# via Mixlib::ShellOut. Each double either mimics a successful
# command execution whose #stdout method returns the given
# string, or a failed execution with the given exit code and
# STDOUT/STDERR.
#
# results is an Array describing the sequence of behaviours;
# each element is either a string mimicking STDOUT from
# successful command execution, or a [stdout, stderr, exitcode]
# status mimicking command execution failure.
#
# For example, "crm configure show" is executed by
# #load_current_resource, and again later on for the :create
# action, to see whether to create or modify. So the first
# double in the sequence would return an empty definition if we
# wanted to test creation of a new CIB object, or an existing
# definition if we wanted to test modification of an existing
# one. If the test needs subsequent doubles to return different
# values then stdout_strings can have more than one element.
def stub_shellout(*results)
doubles = results.map { |result|
result.is_a?(String) ?
succeeding_shellout_double(result)
: failing_shellout_double(*result)
}
::Mixlib::ShellOut.stub(:new).and_return(*doubles)
end
end
end
end

View File

@ -1,8 +1,10 @@
require 'spec_helper'
require 'mixlib/shellout'
require File.expand_path('../../../libraries/pacemaker', File.dirname(__FILE__))
require File.expand_path('../../fixtures/keystone_primitive', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../libraries/pacemaker', this_dir)
require File.expand_path('../../fixtures/keystone_primitive', this_dir)
describe Pacemaker::CIBObject do

View File

@ -1,8 +1,10 @@
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/constraint/colocation',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/colocation_constraint', File.dirname(__FILE__))
require File.expand_path('../../../helpers/cib_object', File.dirname(__FILE__))
this_dir)
require File.expand_path('../../../fixtures/colocation_constraint', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
describe Pacemaker::Constraint::Colocation do
let(:fixture) { Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT.dup }
@ -10,10 +12,6 @@ describe Pacemaker::Constraint::Colocation do
Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT_DEFINITION
}
before(:each) do
Mixlib::ShellOut.any_instance.stub(:run_command)
end
def object_type
'colocation'
end

View File

@ -1,8 +1,10 @@
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/constraint/location',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/location_constraint', File.dirname(__FILE__))
require File.expand_path('../../../helpers/cib_object', File.dirname(__FILE__))
this_dir)
require File.expand_path('../../../fixtures/location_constraint', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
describe Pacemaker::Constraint::Location do
let(:fixture) { Chef::RSpec::Pacemaker::Config::LOCATION_CONSTRAINT.dup }
@ -10,10 +12,6 @@ describe Pacemaker::Constraint::Location do
Chef::RSpec::Pacemaker::Config::LOCATION_CONSTRAINT_DEFINITION
}
before(:each) do
Mixlib::ShellOut.any_instance.stub(:run_command)
end
def object_type
'location'
end

View File

@ -0,0 +1,61 @@
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/constraint/order',
this_dir)
require File.expand_path('../../../fixtures/order_constraint', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
describe Pacemaker::Constraint::Order do
let(:fixture) { Chef::RSpec::Pacemaker::Config::ORDER_CONSTRAINT.dup }
let(:fixture_definition) {
Chef::RSpec::Pacemaker::Config::ORDER_CONSTRAINT_DEFINITION
}
def object_type
'order'
end
def pacemaker_object_class
Pacemaker::Constraint::Order
end
def fields
%w(name score ordering)
end
it_should_behave_like "a CIB object"
describe "#definition_string" do
it "should return the definition string" do
expect(fixture.definition_string).to eq(fixture_definition)
end
it "should return a short definition string" do
order = pacemaker_object_class.new('foo')
order.definition = \
%!order order1 Mandatory: rsc1 rsc2!
order.parse_definition
expect(order.definition_string).to eq(<<'EOF'.chomp)
order order1 Mandatory: rsc1 rsc2
EOF
end
end
describe "#parse_definition" do
before(:each) do
@parsed = pacemaker_object_class.new(fixture.name)
@parsed.definition = fixture_definition
@parsed.parse_definition
end
it "should parse the score" do
expect(@parsed.score).to eq(fixture.score)
end
it "should parse the ordering" do
expect(@parsed.ordering).to eq(fixture.ordering)
end
end
end

View File

@ -1,10 +1,10 @@
require 'spec_helper'
require File.expand_path('../../../../libraries/pacemaker/resource/clone',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/clone_resource', File.dirname(__FILE__))
require File.expand_path('../../../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../../../helpers/meta_examples',
File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/resource/clone', this_dir)
require File.expand_path('../../../fixtures/clone_resource', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
require File.expand_path('../../../helpers/meta_examples', this_dir)
describe Pacemaker::Resource::Clone do
let(:fixture) { Chef::RSpec::Pacemaker::Config::CLONE_RESOURCE.dup }
@ -12,10 +12,6 @@ describe Pacemaker::Resource::Clone do
Chef::RSpec::Pacemaker::Config::CLONE_RESOURCE_DEFINITION
}
before(:each) do
Mixlib::ShellOut.any_instance.stub(:run_command)
end
def object_type
'clone'
end

View File

@ -1,4 +1,5 @@
require 'spec_helper'
require File.expand_path('../../../../libraries/pacemaker/resource/group',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/resource_group', File.dirname(__FILE__))
@ -12,10 +13,6 @@ describe Pacemaker::Resource::Group do
Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP_DEFINITION
}
before(:each) do
Mixlib::ShellOut.any_instance.stub(:run_command)
end
def object_type
'group'
end

View File

@ -1,10 +1,10 @@
require 'spec_helper'
require File.expand_path('../../../../libraries/pacemaker/resource/ms',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/ms_resource', File.dirname(__FILE__))
require File.expand_path('../../../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../../../helpers/meta_examples',
File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/resource/ms', this_dir)
require File.expand_path('../../../fixtures/ms_resource', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
require File.expand_path('../../../helpers/meta_examples', this_dir)
describe Pacemaker::Resource::MasterSlave do
let(:fixture) { Chef::RSpec::Pacemaker::Config::MS_RESOURCE.dup }
@ -12,10 +12,6 @@ describe Pacemaker::Resource::MasterSlave do
Chef::RSpec::Pacemaker::Config::MS_RESOURCE_DEFINITION
}
before(:each) do
Mixlib::ShellOut.any_instance.stub(:run_command)
end
def object_type
'ms'
end

View File

@ -1,12 +1,11 @@
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../../libraries/pacemaker/resource/primitive',
File.dirname(__FILE__))
require File.expand_path('../../../fixtures/keystone_primitive',
File.dirname(__FILE__))
require File.expand_path('../../../helpers/cib_object',
File.dirname(__FILE__))
require File.expand_path('../../../helpers/meta_examples',
File.dirname(__FILE__))
this_dir)
require File.expand_path('../../../fixtures/keystone_primitive', this_dir)
require File.expand_path('../../../helpers/cib_object', this_dir)
require File.expand_path('../../../helpers/meta_examples', this_dir)
describe Pacemaker::Resource::Primitive do
let(:fixture) { Chef::RSpec::Pacemaker::Config::KEYSTONE_PRIMITIVE.dup }

View File

@ -1,8 +1,10 @@
require 'mixlib/shellout'
require 'spec_helper'
require File.expand_path('../../../libraries/pacemaker/resource',
File.dirname(__FILE__))
require File.expand_path('../../fixtures/keystone_primitive',
File.dirname(__FILE__))
this_dir = File.dirname(__FILE__)
require File.expand_path('../../../libraries/pacemaker/resource', this_dir)
require File.expand_path('../../fixtures/keystone_primitive', this_dir)
describe Pacemaker::Resource do
describe "#running?" do

View File

@ -1,8 +1,8 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../helpers/runnable_resource', File.dirname(__FILE__))
require File.expand_path('../fixtures/clone_resource', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/runnable_resource', this_dir)
require File.expand_path('../fixtures/clone_resource', this_dir)
describe "Chef::Provider::PacemakerClone" do
# for use inside examples:
@ -10,41 +10,25 @@ describe "Chef::Provider::PacemakerClone" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::CLONE_RESOURCE.dup
before(:each) do
runner_opts = {
:step_into => ['pacemaker_clone']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
@resource = Chef::Resource::PacemakerClone.new(fixture.name, @run_context)
@resource.rsc fixture.rsc.dup
@resource.meta Hash[fixture.meta.dup]
def lwrp_name
'clone'
end
let (:provider) { Chef::Provider::PacemakerClone.new(@resource, @run_context) }
include_context "a Pacemaker LWRP"
before(:each) do
@resource.rsc fixture.rsc.dup
@resource.meta Hash[fixture.meta.dup]
end
def cib_object_class
Pacemaker::Resource::Clone
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the clone if the resource is changed" do
expected = fixture.dup

View File

@ -1,7 +1,9 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../fixtures/colocation_constraint', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/provider', this_dir)
require File.expand_path('../helpers/non_runnable_resource', this_dir)
require File.expand_path('../fixtures/colocation_constraint', this_dir)
describe "Chef::Provider::PacemakerColocation" do
# for use inside examples:
@ -9,41 +11,25 @@ describe "Chef::Provider::PacemakerColocation" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::COLOCATION_CONSTRAINT.dup
before(:each) do
runner_opts = {
:step_into => ['pacemaker_colocation']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
@resource = Chef::Resource::PacemakerColocation.new(fixture.name, @run_context)
@resource.score fixture.score
@resource.resources fixture.resources.dup
def lwrp_name
'colocation'
end
let (:provider) { Chef::Provider::PacemakerColocation.new(@resource, @run_context) }
include_context "a Pacemaker LWRP"
before(:each) do
@resource.score fixture.score
@resource.resources fixture.resources.dup
end
def cib_object_class
Pacemaker::Constraint::Colocation
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the constraint if it has a different score" do
new_score = '100'
@ -75,9 +61,6 @@ describe "Chef::Provider::PacemakerColocation" do
end
describe ":delete action" do
it_should_behave_like "action on non-existent resource", \
:delete, "crm configure delete #{fixture.name}", nil
end
it_should_behave_like "a non-runnable resource", fixture
end

View File

@ -1,8 +1,8 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../helpers/runnable_resource', File.dirname(__FILE__))
require File.expand_path('../fixtures/resource_group', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/runnable_resource', this_dir)
require File.expand_path('../fixtures/resource_group', this_dir)
describe "Chef::Provider::PacemakerGroup" do
# for use inside examples:
@ -10,41 +10,25 @@ describe "Chef::Provider::PacemakerGroup" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::RESOURCE_GROUP.dup
before(:each) do
runner_opts = {
:step_into => ['pacemaker_group']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
@resource = Chef::Resource::PacemakerGroup.new(fixture.name, @run_context)
@resource.members fixture.members.dup
@resource.meta Hash[fixture.meta.dup]
def lwrp_name
'group'
end
let (:provider) { Chef::Provider::PacemakerGroup.new(@resource, @run_context) }
include_context "a Pacemaker LWRP"
before(:each) do
@resource.members fixture.members.dup
@resource.meta Hash[fixture.meta.dup]
end
def cib_object_class
Pacemaker::Resource::Group
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the group if it has a member resource added" do
expected = fixture.dup

View File

@ -1,7 +1,9 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../fixtures/location_constraint', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/provider', this_dir)
require File.expand_path('../helpers/non_runnable_resource', this_dir)
require File.expand_path('../fixtures/location_constraint', this_dir)
describe "Chef::Provider::PacemakerLocation" do
# for use inside examples:
@ -9,42 +11,25 @@ describe "Chef::Provider::PacemakerLocation" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::LOCATION_CONSTRAINT.dup
before(:each) do
runner_opts = {
:step_into => ['pacemaker_location']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
def lwrp_name
'location'
end
@resource = Chef::Resource::PacemakerLocation.new(fixture.name, @run_context)
include_context "a Pacemaker LWRP"
before(:each) do
@resource.rsc fixture.rsc
@resource.score fixture.score
@resource.node fixture.node.dup
end
let (:provider) { Chef::Provider::PacemakerLocation.new(@resource, @run_context) }
end
def cib_object_class
Pacemaker::Constraint::Location
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the constraint if it has a different resource" do
new_resource = 'group2'
@ -75,9 +60,6 @@ describe "Chef::Provider::PacemakerLocation" do
end
describe ":delete action" do
it_should_behave_like "action on non-existent resource", \
:delete, "crm configure delete #{fixture.name}", nil
end
it_should_behave_like "a non-runnable resource", fixture
end

View File

@ -1,8 +1,8 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../helpers/runnable_resource', File.dirname(__FILE__))
require File.expand_path('../fixtures/ms_resource', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/runnable_resource', this_dir)
require File.expand_path('../fixtures/ms_resource', this_dir)
describe "Chef::Provider::PacemakerMs" do
# for use inside examples:
@ -10,41 +10,25 @@ describe "Chef::Provider::PacemakerMs" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::MS_RESOURCE.dup
before(:each) do
runner_opts = {
:step_into => ['pacemaker_ms']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
@resource = Chef::Resource::PacemakerMs.new(fixture.name, @run_context)
@resource.rsc fixture.rsc.dup
@resource.meta Hash[fixture.meta.dup]
def lwrp_name
'ms'
end
let (:provider) { Chef::Provider::PacemakerMs.new(@resource, @run_context) }
include_context "a Pacemaker LWRP"
before(:each) do
@resource.rsc fixture.rsc.dup
@resource.meta Hash[fixture.meta.dup]
end
def cib_object_class
Pacemaker::Resource::MasterSlave
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the resource if it's changed" do
expected = fixture.dup

View File

@ -0,0 +1,66 @@
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/provider', this_dir)
require File.expand_path('../helpers/non_runnable_resource', this_dir)
require File.expand_path('../fixtures/order_constraint', this_dir)
describe "Chef::Provider::PacemakerOrder" do
# for use inside examples:
let(:fixture) { Chef::RSpec::Pacemaker::Config::ORDER_CONSTRAINT.dup }
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::ORDER_CONSTRAINT.dup
def lwrp_name
'order'
end
include_context "a Pacemaker LWRP"
before(:each) do
@resource.score fixture.score
@resource.ordering fixture.ordering.dup
end
def cib_object_class
Pacemaker::Constraint::Order
end
describe ":create action" do
include Chef::RSpec::Pacemaker::CIBObject
it "should modify the constraint if it has a different score" do
new_score = '100'
fixture.score = new_score
expected_configure_cmd_args = [fixture.reconfigure_command]
test_modify(expected_configure_cmd_args) do
@resource.score new_score
end
end
it "should modify the constraint if it has a resource added" do
new_resource = 'bar:Stopped'
expected = fixture.dup
expected.ordering = expected.ordering.dup + ' ' + new_resource
expected_configure_cmd_args = [expected.reconfigure_command]
test_modify(expected_configure_cmd_args) do
@resource.ordering expected.ordering
end
end
it "should modify the constraint if it has a different ordering" do
new_ordering = 'clone1 primitive1'
fixture.ordering = new_ordering
expected_configure_cmd_args = [fixture.reconfigure_command]
test_modify(expected_configure_cmd_args) do
@resource.ordering new_ordering
end
end
end
it_should_behave_like "a non-runnable resource", fixture
end

View File

@ -1,8 +1,8 @@
require 'chef/application'
require File.expand_path('../spec_helper', File.dirname(__FILE__))
require File.expand_path('../helpers/cib_object', File.dirname(__FILE__))
require File.expand_path('../helpers/runnable_resource', File.dirname(__FILE__))
require File.expand_path('../fixtures/keystone_primitive', File.dirname(__FILE__))
require 'spec_helper'
this_dir = File.dirname(__FILE__)
require File.expand_path('../helpers/runnable_resource', this_dir)
require File.expand_path('../fixtures/keystone_primitive', this_dir)
describe "Chef::Provider::PacemakerPrimitive" do
# for use inside examples:
@ -10,43 +10,26 @@ describe "Chef::Provider::PacemakerPrimitive" do
# for use outside examples (e.g. when invoking shared_examples)
fixture = Chef::RSpec::Pacemaker::Config::KEYSTONE_PRIMITIVE
before(:each) do
runner_opts = {
:step_into => ['pacemaker_primitive']
}
@chef_run = ::ChefSpec::Runner.new(runner_opts)
@chef_run.converge "pacemaker::default"
@node = @chef_run.node
@run_context = @chef_run.run_context
def lwrp_name
'primitive'
end
@resource = Chef::Resource::PacemakerPrimitive.new(fixture.name, @run_context)
include_context "a Pacemaker LWRP"
before(:each) do
@resource.agent fixture.agent
@resource.params Hash[fixture.params]
@resource.meta Hash[fixture.meta]
@resource.op Hash[fixture.op]
end
let (:provider) { Chef::Provider::PacemakerPrimitive.new(@resource, @run_context) }
def cib_object_class
Pacemaker::Resource::Primitive
end
include Chef::RSpec::Pacemaker::CIBObject
describe ":create action" do
def test_modify(expected_cmds)
yield
stub_shellout(fixture.definition_string)
provider.run_action :create
expected_cmds.each do |cmd|
expect(@chef_run).to run_execute(cmd)
end
expect(@resource).to be_updated
end
include Chef::RSpec::Pacemaker::CIBObject
include Chef::RSpec::Mixlib::ShellOut
it "should modify the primitive if it has different params" do
expected_configure_cmd_args = [