Skip to content

Commit 63381f4

Browse files
author
Vladimir Moravec
committed
Merge pull request #33 from vmoravec/ha-node-helpers
Improve nodes' search, add custom matchers
2 parents 3d123ab + c57f848 commit 63381f4

File tree

6 files changed

+70
-10
lines changed

6 files changed

+70
-10
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'rspec/expectations'
2+
3+
RSpec::Matchers.define :succeed_at_least_once do
4+
match do |actual|
5+
succeeded = actual.select {|result| result.success? }
6+
succeeded.size.nonzero?
7+
end
8+
9+
failure_message do |actual|
10+
"expected that #{actual} would contain at least one successful command result"
11+
end
12+
end
13+
14+
RSpec::Matchers.define :match_with_output_at_least_once do |expected|
15+
match do |actual|
16+
outputs = actual.map(&:output).compact
17+
matches = outputs.map {|o| o.match(expected) }.compact
18+
matches.size.nonzero?
19+
end
20+
21+
failure_message do |actual|
22+
"expected that at least one output value in #{actual} would match '#{expected}'"
23+
end
24+
end

features/support/env.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
require_relative "step_helpers"
55
require_relative "feature_helpers"
6+
require_relative "custom_matchers"
67

78
# Guess verbosity from the cli params
89
verbose = ARGV.grep(/(--verbose|-v)/).empty? ? false : true

features/support/feature_helpers.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
module FeatureHelpers
22
attr_reader :scenario_tag, :feature_tag
33

4+
def proposal name
5+
JSON.parse(admin_node.exec!("crowbar #{name} show default").output)
6+
end
7+
48
def filter_scenario_config_by scenario_tags
59
@feature_tag, @scenario_tag = scenario_tags.map(&:name)
610
end

lib/cct/cloud/node.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ def initialize options={}
2323
validate_attributes
2424
end
2525

26-
def exec! command, *params
26+
def exec! command, *params, capture_error: false
2727
params << environment unless environment.empty?
28-
@command.exec!(command, params)
28+
@command.exec!(command, params, capture_error: capture_error)
2929
end
3030

3131
def crowbar reload: false

lib/cct/cloud/nodes.rb

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,46 @@ def exept node
3636
nodes.select {|n| n.name != node.name}
3737
end
3838

39-
def find name: nil, fqdn: nil
39+
# @param name [String] Hostname of a node
40+
# @param fqdn [String] Fully qualified domain name
41+
# @param barclamp [String] Name of a barclamp assigned to a node
42+
# @param element [String] Element name in the crowbar proposal json tree
43+
# @note Parameter :barclamp requires element to be specified
44+
# @return [Array] One or multiple node instances
45+
def find name: nil, fqdn: nil, barclamp: nil, element: nil, proposal: "default"
4046
load!
41-
return nodes.find {|n| n.name == name } if name
42-
return nodes.find {|n| n.fqdn == fqdn } if fqdn
47+
return nodes.select {|n| n.name == name } if name
48+
return nodes.select {|n| n.fqdn == fqdn } if fqdn
49+
50+
if barclamp
51+
raise "Missing element for barclamp proposal" unless element
52+
53+
proposal = JSON.parse(
54+
admin_node.exec!("crowbar #{barclamp} show #{proposal}").output
55+
)
56+
57+
nodes_detected = []
58+
59+
clustered = proposal["deployment"][barclamp]["elements"][element].first.start_with?("cluster:")
60+
61+
if clustered
62+
nodes_detected.push(
63+
proposal["deployment"][barclamp]["elements_expanded"][element]
64+
)
65+
else
66+
nodes_detected.push(
67+
proposal["deployment"][barclamp]["elements"][element]
68+
)
69+
end
70+
71+
nodes_detected.flatten.compact.map do |node_fqdn|
72+
nodes.find {|n| n.fqdn == node_fqdn }
73+
end.compact
74+
end
4375
end
4476

4577
def admin_node
46-
nodes.find {|node| node.name = AdminNode::NAME }
78+
@admin_node ||= nodes.find {|node| node.name == AdminNode::NAME }
4779
end
4880

4981
def clear
@@ -69,7 +101,6 @@ def load_nodes!
69101
end
70102

71103
def load_admin name, attrs, node_details
72-
admin_node = nodes.find {|n| n.name == AdminNode::NAME}
73104
if admin_node
74105
return admin_node.reload! unless admin_node.loaded?
75106
return admin_node if admin_node.loaded?

lib/cct/remote_command.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def initialize opts
2121
validate_options
2222
end
2323

24-
def exec! command, params=[]
24+
def exec! command, params=[], capture_error: false
2525
log.base.level = ::Logger::WARN
2626
connect!
2727
host_ip = gateway ? target.ip : options.ip
@@ -38,9 +38,9 @@ def exec! command, params=[]
3838
end
3939
session.loop unless gateway
4040
result[:success?] = result.exit_code.zero?
41-
if !result.success? || result.error.length.nonzero?
41+
if !result.success? || (result.error.length.nonzero? && !result.exit_code.zero?)
4242
log.error(result.output)
43-
raise RemoteCommandFailed.new(full_command, result)
43+
raise RemoteCommandFailed.new(full_command, result) unless capture_error
4444
end
4545
result
4646
ensure

0 commit comments

Comments
 (0)