Skip to content

Commit

Permalink
Add tests for barclamp pacemaker
Browse files Browse the repository at this point in the history
  • Loading branch information
mmnelemane committed Oct 5, 2015
1 parent c419e13 commit 3926c07
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 0 deletions.
46 changes: 46 additions & 0 deletions features/barclamp_pacemaker.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@pacemaker
Feature: Tests Pacemaker barclamp deployment
As an administrator
I want to make sure the pacemaker cluster is deployed successfully
And I can perform few operations on the components of the pacemaker cluster

Background:
Given the chef role "pacemaker-cluster-member" exists on admin node
And the chef role "hawk-server" exists on admin node
And the "pacemaker" cookbook exists on the admin node

@packages
Scenario: Verify packages required for pacemaker deployment
Given the barclamp proposal for "pacemaker" is deployed
And the relevant chef roles for pacemaker configs exists on admin node
When the node with "pacemaker-cluster-member" role has been detected successfully
And the node with "hawk-server" role has been detected successfully
Then I can identify the primary and secondary nodes for the cluster
When the package "pacemaker" is installed in the cluster node
And the package "corosync" is installed in the cluster node
And the package "hawk" is installed in the cluster node
And the package "drbd" is installed in the cluster node

@drbd
Scenario: Verify functionality of DRBD deployment of rabbitmq and postgresql
Given I can identify the primary and secondary nodes for the cluster
Then I can check if the status of all crm nodes are ok
And I can identify the name of the Designated Controller node
And I can verify the location of rabbitmq and postgresql resources
And I can get the mountpoints for devices "drbd0" and "drbd1"
And I can ensure both primary and secondary nodes of drbd are UpToDate

@crm
Scenario: Verify Cluster Resource Manager features of deployed cluster
Given I can identify the primary and secondary nodes for the cluster
And I can identify the name of the Designated Controller node
Then I can list the available stonith devices
And I can obtain metadata for an arbitrary fencing agent
And I can check if cluster is configured with stonith-enabled
And I can check the failcount of stonith resources
And I can ensure that start operations for haproxy, rabbitmq, postgresql are complete
And I can update and delete new attribute to a crm node
And I can verify the status of corosync being active with no faults and correct ring addresses
And I can move a cluster node to standby and back to online without affecting resources
And I can run a cluster health check on the cluster

196 changes: 196 additions & 0 deletions features/step_definitions/barclamp_pacemaker/pacemaker_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
Given(/^the barclamp proposal for "([^"]*)" is deployed$/) do |package_name|
response = admin_node.exec!("crowbar #{package_name} list").output
@node_list = response.strip!.split(/\n/)
expect(@node_list).not_to be_empty
end

And(/^the relevant chef roles for pacemaker configs exists on admin node$/) do
@node_list.each do |node_type|
admin_node.exec!("knife role show pacemaker-config-#{node_type}")
end
end

When(/^the node with "([^"]*)" role has been detected successfully$/) do |role_name|
@node_list.each do |node_name|
json_response = JSON.parse(admin_node.exec!("crowbar pacemaker show #{node_name}").output)
node_elements = nodes.find(barclamp: "pacemaker", element: "#{role_name}", proposal: "#{node_name}")
expect(node_elements).not_to be_empty
end
end

Then(/^I can identify the primary and secondary nodes for the cluster$/) do
@primary_node = nil
@secondary_node = nil
response = admin_node.exec!("crowbar pacemaker list").output
node_list = response.strip!.split(/\n/)
node_list.each do |node_name|
results = nodes.find(barclamp: "pacemaker", element: "pacemaker-cluster-member", proposal: "#{node_name}").map do |node|
dev_priority = node.exec!("drbdsetup role 0").output.strip!
if dev_priority == "Primary/Secondary"
@primary_node = node
elsif dev_priority == "Secondary/Primary"
@secondary_node = node
end
end
expect(@primary_node.attributes()[:name]).not_to be_empty
expect(@secondary_node.attributes()[:name]).not_to be_empty
end
end

When(/^the package "([^"]*)" is installed in the cluster node$/) do |package_name|
@primary_node.rpm_q(package_name)
@secondary_node.rpm_q(package_name)
end

And(/^I can check if the status of all crm nodes are ok$/) do
response = @primary_node.exec!("crmadmin --nodes").output
node_list = response.split(/\n/).reject { |c| c.empty?}
exp_states = ["S_IDLE (ok)", "S_NOT_DC (ok)"]
node_list.each do |node_entry|
node_name = node_entry.split(/ /)[3].strip!
stat_response = @primary_node.exec!("crmadmin --status=#{node_name}").output
node_state = stat_response.split(/:/)[1].strip!
expect(exp_states).to include(node_state)
end
end

And(/^I can identify the name of the Designated Controller node$/) do
response = @primary_node.exec!("crmadmin --dc_lookup").output
@dc_node = response.split(/:/)[-1].strip!
expect(@dc_node).not_to be_empty
end

And(/^I can verify the location of rabbitmq and postgresql resources$/) do
response = @primary_node.exec!("crm_resource --resource drbd-rabbitmq --locate").output
location = response.split(/:/)[-1].split(/ /).reject{ |c| c.empty?}[0]
exp_location = ["#{@primary_node.attributes()[:name]}", "#{@secondary_node.attributes()[:name]}"]
expect(exp_location).to include(location)
response = @primary_node.exec!("crm_resource --resource drbd-postgresql --locate").output
location = response.split(/:/)[-1].split(/ /).reject{ |c| c.empty?}[0]
expect(exp_location).to include(location)
end

And(/^I can get the mountpoints for devices "drbd0" and "drbd1"$/) do
response = @primary_node.exec!("mount | grep drbd").output
mount_lines = response.split(/\n/)
mount_lines.each do |line|
drbd_dev = line.split(/ /)[0]
mount_pt = line.split(/ /)[2]
expect(mount_pt).not_to be_empty
end
end

And(/^I can ensure both primary and secondary nodes of drbd are UpToDate$/) do
response = @primary_node.exec!("drbdadm dstate rabbitmq").output
expect(response.strip!).to eq("UpToDate/UpToDate")
response = @primary_node.exec!("drbdadm dstate postgresql").output
expect(response.strip!).to eq("UpToDate/UpToDate")
end

Then(/^I can list the available stonith devices$/) do
response = @primary_node.exec!("stonith_admin --list-registered").output
@stonith_device = response.split(/\n/)[0].strip!
expect(@stonith_device).to eq("stonith-#{@secondary_node.attributes()[:name]}")
end

And(/^I can obtain metadata for an arbitrary fencing agent$/) do
response = @primary_node.exec!("stonith_admin -M #{@stonith_device} --agent fence_pcmk").output
expect(response).not_to be_empty
end

And(/^I can check if cluster is configured with stonith-enabled$/) do
response = @primary_node.exec!("crm configure show type:property").output
expect(response).not_to be_empty
end

And(/^I can check the failcount of stonith resources$/) do
response = @primary_node.exec!("crm_failcount --resource-id=rabbitmq").output
fail_count = response.tr("\n", "").split(/ /)[-1]
expect(fail_count).to eq("value=0")
end

And(/^I can ensure that start operations for haproxy, rabbitmq, postgresql are complete$/) do
def get_node_resource_operations_status(node_to_check, resource_name)
response = @primary_node.exec!("crm_resource --list-operations --resource #{resource_name} --node #{node_to_check}").output
status = response.tr("\n","").split(/ /)[-1]
return status
end
prim_node_name = @primary_node.attributes()[:name]
expect(get_node_resource_operations_status(@dc_node, "haproxy")).to eq("complete")
expect(get_node_resource_operations_status(prim_node_name, "rabbitmq")).to eq("complete")
expect(get_node_resource_operations_status(prim_node_name, "postgresql")).to eq("complete")
end

And(/^I can update and delete new attribute to a crm node$/) do
@primary_node.exec!("crm_attribute --node d52-54-01-77-77-01 --name location --update office")
@primary_node.exec!("crm_attribute --node d52-54-01-77-77-01 --name location --query")
@primary_node.exec!("crm_attribute --node d52-54-01-77-77-01 --name location --delete")
end

And(/^I can verify the status of corosync being active with no faults and correct ring addresses$/) do
# Method to obtain Corosync ring status of a node in the cluster
def get_corosync_ring_status(node)
# Get ring status from the node
ring_addr = ""
ring_status = ""
response = node.exec!("crm corosync status").output
lines = response.tr("\t", " ").split(/\n/)
lines.each do |line|
if line.include?("id =")
ring_addr = line.split(/=/)[-1].strip!
end
if line.include?("status =")
ring_status = line.split(/=/)[-1].strip!
end
end
return ring_addr, ring_status
end

prim_ring_addr = ""
prim_status = ""
sec_ring_addr = ""
sec_status = ""

# Get ring address from node configuration
response = @primary_node.exec!("crm corosync get nodelist.node.ring0_addr").output
ring_addr_conf = response.split(/\n/)

# Get ring status from primary node
prim_ring_addr, prim_ring_status = get_corosync_ring_status(@primary_node)
sec_ring_addr, sec_ring_status = get_corosync_ring_status(@secondary_node)
expect(ring_addr_conf).to include(prim_ring_addr, sec_ring_addr)
expect(prim_ring_status).to eq("ring 0 active with no faults")
expect(sec_ring_status).to eq("ring 0 active with no faults")
end

And(/^I can move a cluster node to standby and back to online without affecting resources$/) do
# Method to return list of nodes in cluster in Standby and Online Mode
def return_standby_online_nodes (node)
response = node.exec!("crm_mon -1").output
lines = response.split(/\n/)
online_nodes = []
standby_nodes = []
lines.each do |line|
if line.include?("standby")
standby_nodes = [line.split(/ /)[1]]
elsif line.include?("Online:")
online_nodes = line.split(/:/)[-1].delete("[]").split(/ /).reject{ |c| c.empty?}
end
end
return online_nodes, standby_nodes
end

@primary_node.exec!("crm node standby")
online_nodes, standby_nodes = return_standby_online_nodes(@primary_node)
expect(online_nodes).to include(@secondary_node.attributes()[:name])
expect(standby_nodes).to include(@primary_node.attributes()[:name])
@primary_node.exec!("crm node online")
online_nodes, standby_nodes = return_standby_online_nodes(@primary_node)
expect(online_nodes).to include(@primary_node.attributes()[:name], @secondary_node.attributes()[:name])
expect(standby_nodes).to be_empty
end

And(/^I can run a cluster health check on the cluster$/) do
response = @primary_node.exec!("crm cluster health").output
end

22 changes: 22 additions & 0 deletions tasks/features/barclamp_pacemaker.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace :feature do
feature_name "Tests Pacemaker barclamp deployment"

namespace :barclamp do
desc "Barclamp Pacemaker feature"
namespace :pacemaker do
desc "Check Package Installations"
feature_task :packages, tags: :@packages

desc "Test DRBD Features"
feature_task :drbd, tags: :@drbd

desc "Test CRM Features"
feature_task :crm, tags: :@crm

feature_task :all
end

desc "Verification of Pacemaker Cluster Deployment"
task :pacemaker => "pacemaker:all"
end
end

0 comments on commit 3926c07

Please sign in to comment.