Support deployment tasks history
Changes: * send full info about task: task name, status, summary; * support to send summary from puppet and shell agents; * support to send skipped report for noop tasks; * support to send status for null node (virtual_sync_node); * convert Astute task status to Nailgun task status in report. Change-Id: Ia81f3eb6203dceaac5208efe812e44e951c478fe Implements: blueprint store-deployment-tasks-history
This commit is contained in:
parent
0a4e1ec7bc
commit
6b3f9b46a6
@ -30,6 +30,7 @@ module Astute
|
||||
@is_hung = false
|
||||
@puppet_debug = puppet_debug
|
||||
@succeed_retries = succeed_retries || Astute.config.puppet_succeed_retries
|
||||
@summary = {}
|
||||
end
|
||||
|
||||
def run
|
||||
@ -44,17 +45,17 @@ module Astute
|
||||
def status
|
||||
raise Timeout::Error unless @time_observer.enough_time?
|
||||
|
||||
last_run = puppet_status
|
||||
status = node_status(last_run)
|
||||
@summary = puppet_status
|
||||
status = node_status(@summary)
|
||||
Astute.logger.debug "Node #{@node['uid']}(#{@node['role']}) status: #{status}"
|
||||
|
||||
result = case status
|
||||
when 'succeed'
|
||||
processing_succeed_node(last_run)
|
||||
processing_succeed_node(@summary)
|
||||
when 'running'
|
||||
processing_running_node
|
||||
when 'error'
|
||||
processing_error_node(last_run)
|
||||
processing_error_node(@summary)
|
||||
end
|
||||
|
||||
#TODO(vsharshov): Should we move it to control module?
|
||||
@ -68,6 +69,10 @@ module Astute
|
||||
'error'
|
||||
end
|
||||
|
||||
def summary
|
||||
@summary
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def puppetd
|
||||
|
@ -15,7 +15,7 @@
|
||||
module Astute
|
||||
class Task
|
||||
|
||||
ALLOWED_STATUSES = [:successful, :failed, :running, :pending]
|
||||
ALLOWED_STATUSES = [:successful, :failed, :running, :pending, :skipped]
|
||||
|
||||
def initialize(task, context)
|
||||
# WARNING: this code expect that only one node will be send
|
||||
@ -69,6 +69,11 @@ module Astute
|
||||
successful?
|
||||
end
|
||||
|
||||
# Show additional info about tasks: last run summary, sdtout etc
|
||||
def summary
|
||||
{}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Run current task on node, specified in task
|
||||
@ -179,7 +184,7 @@ module Astute
|
||||
end
|
||||
|
||||
def finished?
|
||||
[:successful, :failed].include? @status
|
||||
[:successful, :failed, :skipped].include? @status
|
||||
end
|
||||
|
||||
def failed!
|
||||
@ -212,6 +217,15 @@ module Astute
|
||||
@status == :pending
|
||||
end
|
||||
|
||||
def skipped?
|
||||
@status == :skipped
|
||||
end
|
||||
|
||||
def skipped!
|
||||
self.status = :skipped
|
||||
time_summary
|
||||
end
|
||||
|
||||
def task_name
|
||||
@task['id'] || @task['diagnostic_name']
|
||||
end
|
||||
|
@ -42,8 +42,9 @@ module Astute
|
||||
'nodes' => [{
|
||||
'uid' => id,
|
||||
'status' => 'deploying',
|
||||
'task' => task.name,
|
||||
'progress' => current_progress_bar
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'progress' => current_progress_bar,
|
||||
'task_status' => task.status.to_s,
|
||||
}]
|
||||
})
|
||||
else
|
||||
@ -67,13 +68,15 @@ module Astute
|
||||
node_status = {
|
||||
'uid' => id,
|
||||
'status' => deploy_status,
|
||||
'task' => task.name,
|
||||
'progress' => current_progress_bar,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'task_status' => task.status.to_s,
|
||||
'progress' => current_progress_bar
|
||||
'custom' => @task_engine.summary,
|
||||
}
|
||||
|
||||
node_status.merge!('error_type' => 'deploy') if
|
||||
deploy_status == 'error'
|
||||
|
||||
@ctx.report('nodes' => [node_status])
|
||||
end
|
||||
|
||||
|
@ -19,6 +19,17 @@ module Astute
|
||||
STATES = ['deploying', 'ready', 'error', 'stopped']
|
||||
FINAL_STATES = ['ready', 'error', 'stopped']
|
||||
|
||||
REPORT_REAL_TASK_STATE_MAP = {
|
||||
'running' => 'running',
|
||||
'successful' => 'ready',
|
||||
'failed' => 'error',
|
||||
'skipped' => 'skipped'
|
||||
}
|
||||
|
||||
REPORT_REAL_NODE_MAP = {
|
||||
'virtual_sync_node' => 'null'
|
||||
}
|
||||
|
||||
def initialize(up_reporter, nodes_uids=[])
|
||||
@up_reporter = up_reporter
|
||||
@nodes = nodes_uids.inject({}) do |nodes, node_uid|
|
||||
@ -26,7 +37,8 @@ module Astute
|
||||
end
|
||||
end
|
||||
|
||||
def report(data)
|
||||
def report(original_data)
|
||||
data = deep_copy(original_data)
|
||||
if data['nodes']
|
||||
nodes_to_report = get_nodes_to_report(data['nodes'])
|
||||
return if nodes_to_report.empty? # Let's report only if nodes updated
|
||||
@ -44,27 +56,36 @@ module Astute
|
||||
nodes.map{ |node| node_validate(node) }.compact
|
||||
end
|
||||
|
||||
def node_validate(node)
|
||||
return if node_should_exclude?(node)
|
||||
validates_basic_fields(node)
|
||||
def node_validate(original_node)
|
||||
node = deep_copy(original_node)
|
||||
return unless node_should_include?(node)
|
||||
validates_node_basic_fields(node)
|
||||
validates_task_basic_fields(node)
|
||||
conver_node_name_to_original(node)
|
||||
conver_task_status_to_status(node)
|
||||
normalization_progress(node)
|
||||
compare_with_previous_state(node)
|
||||
end
|
||||
|
||||
def node_should_exclude?(node)
|
||||
node['uid'].to_i == 0 && node['uid'] != 'master'
|
||||
def node_should_include?(node)
|
||||
is_num?(node['uid']) ||
|
||||
['master', 'virtual_sync_node'].include?(node['uid'])
|
||||
end
|
||||
|
||||
def valid_status?(status)
|
||||
STATES.include? status.to_s
|
||||
end
|
||||
|
||||
def valid_task_status?(status)
|
||||
REPORT_REAL_TASK_STATE_MAP.keys.include? status.to_s
|
||||
end
|
||||
|
||||
def final_status?(status)
|
||||
FINAL_STATES.include? status.to_s
|
||||
end
|
||||
|
||||
# Validate of basic fields in message about nodes
|
||||
def validates_basic_fields(node)
|
||||
# Validate of basic fields in message about node
|
||||
def validates_node_basic_fields(node)
|
||||
err = []
|
||||
|
||||
err << "Status provided '#{node['status']}' is not supported" if
|
||||
@ -73,12 +94,23 @@ module Astute
|
||||
!node['status'] && node['progress']
|
||||
err << "Node uid is not provided" unless node['uid']
|
||||
|
||||
if err.any?
|
||||
msg = "Validation of node:\n#{node.pretty_inspect} for " \
|
||||
"report failed: #{err.join('; ')}"
|
||||
Astute.logger.error(msg)
|
||||
raise msg
|
||||
end
|
||||
fail_validation(node, err) if err.any?
|
||||
end
|
||||
|
||||
# Validate of basic fields in message about task
|
||||
def validates_task_basic_fields(node)
|
||||
err = []
|
||||
|
||||
err << "Task status provided '#{node['task_status']}' is not supported" if
|
||||
!valid_task_status?(node['task_status'])
|
||||
err << "Task name is not provided" if node['deployment_graph_task_name'].blank?
|
||||
|
||||
fail_validation(node, err) if err.any?
|
||||
end
|
||||
|
||||
|
||||
def conver_task_status_to_status(node)
|
||||
node['task_status'] = REPORT_REAL_TASK_STATE_MAP.fetch(node['task_status'])
|
||||
end
|
||||
|
||||
# Normalization of progress field: ensures that the scaling progress was
|
||||
@ -105,7 +137,8 @@ module Astute
|
||||
!final_status?(node['status'])
|
||||
# Allow to send only node progress/status update
|
||||
return if node_progress.to_i <= saved_node['progress'].to_i &&
|
||||
node['status'] == saved_node['status']
|
||||
node['status'] == saved_node['status'] &&
|
||||
node['deployment_graph_task_name'] == saved_node['deployment_graph_task_name']
|
||||
|
||||
node
|
||||
end
|
||||
@ -121,6 +154,29 @@ module Astute
|
||||
end
|
||||
end
|
||||
|
||||
def fail_validation(node, err)
|
||||
msg = "Validation of node:\n#{node.pretty_inspect} for " \
|
||||
"report failed: #{err.join('; ')}"
|
||||
Astute.logger.error(msg)
|
||||
raise Astute::AstuteError, msg
|
||||
end
|
||||
|
||||
def conver_node_name_to_original(node)
|
||||
if REPORT_REAL_NODE_MAP.keys.include?(node['uid'])
|
||||
node['uid'] = REPORT_REAL_NODE_MAP.fetch(node['uid'])
|
||||
end
|
||||
end
|
||||
|
||||
def deep_copy(data)
|
||||
data.deep_dup
|
||||
end
|
||||
|
||||
def is_num?(str)
|
||||
Integer(str)
|
||||
rescue ArgumentError, TypeError
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -22,7 +22,7 @@ module Astute
|
||||
end
|
||||
|
||||
def calculate_status
|
||||
succeed!
|
||||
skipped!
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -17,6 +17,12 @@ require 'timeout'
|
||||
module Astute
|
||||
class Puppet < Task
|
||||
|
||||
def summary
|
||||
@puppet_task.summary
|
||||
rescue
|
||||
{}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process
|
||||
|
@ -25,6 +25,12 @@ module Astute
|
||||
@puppet_task = nil
|
||||
end
|
||||
|
||||
def summary
|
||||
@puppet_task.summary
|
||||
rescue
|
||||
{}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
SHELL_MANIFEST_DIR = '/etc/puppet/shell_manifests'
|
||||
|
@ -217,7 +217,7 @@ module Deployment
|
||||
return true if @tasks_are_successful
|
||||
return false if @tasks_have_failed
|
||||
successful = all? do |task|
|
||||
task.successful?
|
||||
task.successful? || task.skipped?
|
||||
end
|
||||
if successful
|
||||
debug 'All tasks are successful'
|
||||
|
@ -46,17 +46,17 @@ describe Astute::TaskNode do
|
||||
let(:task_data) do
|
||||
{
|
||||
"parameters" => {
|
||||
"puppet_modules" => "/etc/puppet/modules",
|
||||
"puppet_manifest" => "/etc/puppet/modules/osnailyfacter/modular" \
|
||||
"/openstack-haproxy/openstack-haproxy-mysqld.pp",
|
||||
"timeout" => 300,
|
||||
"cwd" => "/"
|
||||
"puppet_modules" => "/etc/puppet/modules",
|
||||
"puppet_manifest" => "/etc/puppet/modules/osnailyfacter/modular" \
|
||||
"/openstack-haproxy/openstack-haproxy-mysqld.pp",
|
||||
"timeout" => 300,
|
||||
"cwd" => "/"
|
||||
},
|
||||
"type" => "puppet",
|
||||
"fail_on_error" => true,
|
||||
"required_for" => [],
|
||||
"requires" => [],
|
||||
"id" => "openstack-haproxy-mysqld"
|
||||
"id" => "openstack-haproxy-mysqld",
|
||||
}
|
||||
end
|
||||
|
||||
@ -86,7 +86,7 @@ describe Astute::TaskNode do
|
||||
"fail_on_error" => false,
|
||||
"required_for" => [],
|
||||
"requires" => [],
|
||||
"id" => "test-task"
|
||||
"id" => "test-task",
|
||||
}
|
||||
end
|
||||
|
||||
@ -190,7 +190,7 @@ describe Astute::TaskNode do
|
||||
"fail_on_error" => false,
|
||||
"required_for" => [],
|
||||
"requires" => [],
|
||||
"id" => "test-task"
|
||||
"id" => "test-task",
|
||||
}
|
||||
end
|
||||
|
||||
@ -214,6 +214,26 @@ describe Astute::TaskNode do
|
||||
task_node.poll
|
||||
expect(task_node.status).to eql(:online)
|
||||
end
|
||||
|
||||
context "skipped" do
|
||||
let(:task_data) do
|
||||
{
|
||||
"parameters" => {},
|
||||
"type" => "noop",
|
||||
"fail_on_error" => false,
|
||||
"required_for" => [],
|
||||
"requires" => [],
|
||||
"id" => "test-task",
|
||||
}
|
||||
end
|
||||
|
||||
it 'if task skipped' do
|
||||
ctx.stubs(:report)
|
||||
task_node.run(task)
|
||||
task_node.poll
|
||||
expect(task_node.status).to eql(:online)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'should report progress if task running' do
|
||||
@ -223,7 +243,8 @@ describe Astute::TaskNode do
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'deploying',
|
||||
'task' => task.name,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'task_status' => 'running',
|
||||
'progress' => 0}]
|
||||
})
|
||||
task_node.poll
|
||||
@ -236,13 +257,60 @@ describe Astute::TaskNode do
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'ready',
|
||||
'task' => task.name,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'successful',
|
||||
'progress' => 100}]
|
||||
})
|
||||
task_node.poll
|
||||
end
|
||||
|
||||
context 'skipped' do
|
||||
let(:task_data) do
|
||||
{
|
||||
"parameters" => {},
|
||||
"type" => "noop",
|
||||
"fail_on_error" => false,
|
||||
"required_for" => [],
|
||||
"requires" => [],
|
||||
"id" => "test-task",
|
||||
}
|
||||
end
|
||||
|
||||
it 'should report ready if task skipped and no more task' do
|
||||
task_node.run(task)
|
||||
ctx.expects(:report).with({
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'skipped',
|
||||
'progress' => 100}]
|
||||
})
|
||||
task_node.poll
|
||||
end
|
||||
|
||||
it 'should report deploy progress if task skipped and another tasks exists' do
|
||||
task_node.graph.create_task(
|
||||
'second_task',
|
||||
task_data.merge({'node_id' => 'node_id'})
|
||||
)
|
||||
|
||||
task_node.run(task)
|
||||
ctx.expects(:report).with({
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'skipped',
|
||||
'progress' => 50}]
|
||||
})
|
||||
task_node.poll
|
||||
end
|
||||
end
|
||||
|
||||
it 'should report error if task failed and no more task' do
|
||||
Astute::Puppet.any_instance.expects(:status).returns(:failed)
|
||||
task_node.run(task)
|
||||
@ -250,7 +318,8 @@ describe Astute::TaskNode do
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'error',
|
||||
'task' => task.name,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'failed',
|
||||
'error_type' => 'deploy',
|
||||
'progress' => 100}]
|
||||
@ -270,7 +339,8 @@ describe Astute::TaskNode do
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'deploying',
|
||||
'task' => task.name,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'successful',
|
||||
'progress' => 50}]
|
||||
})
|
||||
@ -289,13 +359,13 @@ describe Astute::TaskNode do
|
||||
'nodes' => [{
|
||||
'uid' => 'node_id',
|
||||
'status' => 'deploying',
|
||||
'task' => task.name,
|
||||
'deployment_graph_task_name' => task.name,
|
||||
'custom' => {},
|
||||
'task_status' => 'failed',
|
||||
'progress' => 50}]
|
||||
})
|
||||
task_node.poll
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -19,11 +19,37 @@ include Astute
|
||||
|
||||
describe "TaskProxyReporter" do
|
||||
context "Instance of ProxyReporter class" do
|
||||
let(:msg) { {'nodes' => [{'status' => 'ready', 'uid' => '1'}]} }
|
||||
let(:msg) do
|
||||
{'nodes' => [{
|
||||
'status' => 'ready',
|
||||
'uid' => '1',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'successful'}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
let(:expected_msg) do
|
||||
{'nodes' => [{
|
||||
'status' => 'ready',
|
||||
'uid' => '1',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'ready',
|
||||
'progress' => 100}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
let(:msg_pr) do
|
||||
{'nodes' => [
|
||||
msg['nodes'][0],
|
||||
{'status' => 'deploying', 'uid' => '2', 'progress' => 54}
|
||||
{
|
||||
'status' => 'deploying',
|
||||
'uid' => '2',
|
||||
'progress' => 54,
|
||||
'task_status' => 'running',
|
||||
'deployment_graph_task_name' => 'test_1'
|
||||
}
|
||||
]}
|
||||
end
|
||||
|
||||
@ -31,27 +57,34 @@ describe "TaskProxyReporter" do
|
||||
let(:reporter) { ProxyReporter::TaskProxyReporter.new(up_reporter) }
|
||||
|
||||
it "reports first-come data" do
|
||||
up_reporter.expects(:report).with(msg)
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(msg)
|
||||
end
|
||||
|
||||
it "does not report the same message" do
|
||||
up_reporter.expects(:report).with(msg).once
|
||||
up_reporter.expects(:report).with(expected_msg).once
|
||||
5.times { reporter.report(msg) }
|
||||
end
|
||||
|
||||
it "reports only updated node" do
|
||||
updated_node = msg_pr['nodes'][1]
|
||||
expected_msg = {'nodes' => [updated_node]}
|
||||
up_reporter.expects(:report).with(msg)
|
||||
expected_msg_2 = {'nodes' => [{
|
||||
'status' => 'deploying',
|
||||
'uid' => '2',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'running',
|
||||
'progress' => 54}]
|
||||
}
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
up_reporter.expects(:report).with(expected_msg_2)
|
||||
reporter.report(msg)
|
||||
reporter.report(msg_pr)
|
||||
end
|
||||
|
||||
it "reports only if progress value is greater" do
|
||||
msg1 = {'nodes' => [{'status' => 'deploying', 'uid' => '1', 'progress' => 54},
|
||||
{'status' => 'deploying', 'uid' => '2', 'progress' => 54}]}
|
||||
msg1 = {'nodes' => [{'status' => 'deploying', 'uid' => '1', 'progress' => 54,
|
||||
'deployment_graph_task_name' => 'test_1', 'task_status' => 'running'},
|
||||
{'status' => 'deploying', 'uid' => '2', 'progress' => 54,
|
||||
'deployment_graph_task_name' => 'test_1', 'task_status' => 'running'}]}
|
||||
msg2 = Marshal.load(Marshal.dump(msg1))
|
||||
msg2['nodes'][1]['progress'] = 100
|
||||
msg2['nodes'][1]['status'] = 'ready'
|
||||
@ -64,14 +97,46 @@ describe "TaskProxyReporter" do
|
||||
reporter.report(msg2)
|
||||
end
|
||||
|
||||
it "should report only nodes with integer > 0 or master uid" do
|
||||
it "reports if progress value same, but deployment graph task name different" do
|
||||
msg1 = {'nodes' => [{'status' => 'deploying', 'uid' => '1', 'progress' => 54,
|
||||
'deployment_graph_task_name' => 'test_1', 'task_status' => 'running'}]}
|
||||
msg2 = {'nodes' => [{'status' => 'deploying', 'uid' => '1', 'progress' => 54,
|
||||
'deployment_graph_task_name' => 'test_2', 'task_status' => 'running'}]}
|
||||
|
||||
up_reporter.expects(:report).with(msg1)
|
||||
up_reporter.expects(:report).with(msg2)
|
||||
reporter.report(msg1)
|
||||
reporter.report(msg2)
|
||||
end
|
||||
|
||||
it "should report only nodes with integer or master uid or virtual node" do
|
||||
input_msg = {'nodes' => [
|
||||
{'uid' => '0', 'status' => 'deploying', 'progress' => 10},
|
||||
{'uid' => 'virtual_sync_node', 'status' => 'deploying', 'progress' => 10},
|
||||
{'uid' => '1', 'status' => 'deploying', 'progress' => 10}
|
||||
{'uid' => 'master', 'status' => 'deploying', 'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2', 'task_status' => 'running'},
|
||||
{'uid' => 'virtual_sync_node', 'status' => 'deploying', 'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2', 'task_status' => 'running'},
|
||||
{'uid' => '0', 'status' => 'deploying', 'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2', 'task_status' => 'running'},
|
||||
{'uid' => 'unknown', 'status' => 'deploying', 'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2', 'task_status' => 'running'}
|
||||
]}
|
||||
|
||||
expected_msg = {'nodes' => [{'uid' => '1', 'status' => 'deploying', 'progress' => 10}]}
|
||||
expected_msg = {'nodes' => [
|
||||
{'uid' => 'master',
|
||||
'status' => 'deploying',
|
||||
'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'},
|
||||
{'uid' => 'null',
|
||||
'status' => 'deploying',
|
||||
'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'},
|
||||
{'uid' => '0',
|
||||
'status' => 'deploying',
|
||||
'progress' => 10,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
up_reporter.expects(:report).with(expected_msg).once
|
||||
reporter.report(input_msg)
|
||||
end
|
||||
@ -82,39 +147,90 @@ describe "TaskProxyReporter" do
|
||||
end
|
||||
|
||||
it "adjusts progress to 100 if passed greater" do
|
||||
input_msg = {'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 120}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 100}]}
|
||||
input_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'progress' => 120,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(input_msg)
|
||||
end
|
||||
|
||||
it "adjusts progress to 0 if passed less" do
|
||||
input_msg = {'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => -20}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 0}]}
|
||||
input_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'progress' => -20,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'progress' => 0,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(input_msg)
|
||||
end
|
||||
|
||||
it "adjusts progress to 100 if status ready and no progress given" do
|
||||
input_msg = {'nodes' => [{'uid' => 1, 'status' => 'ready'}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1, 'status' => 'ready', 'progress' => 100}]}
|
||||
input_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready'}]}
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(input_msg)
|
||||
end
|
||||
|
||||
it "adjusts progress to 100 if status ready with progress" do
|
||||
input_msg = {'nodes' => [{'uid' => 1, 'status' => 'ready', 'progress' => 50}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1, 'status' => 'ready', 'progress' => 100}]}
|
||||
input_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful',
|
||||
'progress' => 50}]}
|
||||
expected_msg = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready'}]}
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(input_msg)
|
||||
end
|
||||
|
||||
it "does not report if node was in ready, and trying to set is deploying" do
|
||||
msg1 = {'nodes' => [{'uid' => 1, 'status' => 'ready'}]}
|
||||
msg2 = {'nodes' => [{'uid' => 2, 'status' => 'ready'}]}
|
||||
msg3 = {'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 100}]}
|
||||
up_reporter.expects(:report).with(msg1)
|
||||
up_reporter.expects(:report).with(msg2)
|
||||
msg1 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]}
|
||||
msg2 = {'nodes' => [{'uid' => 2,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]}
|
||||
msg3 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]}
|
||||
expected_msg_1 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready'}]}
|
||||
expected_msg_2 = {'nodes' => [{'uid' => 2,
|
||||
'status' => 'ready',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready'}]}
|
||||
up_reporter.expects(:report).with(expected_msg_1)
|
||||
up_reporter.expects(:report).with(expected_msg_2)
|
||||
up_reporter.expects(:report).never
|
||||
reporter.report(msg1)
|
||||
reporter.report(msg2)
|
||||
@ -122,21 +238,35 @@ describe "TaskProxyReporter" do
|
||||
end
|
||||
|
||||
it "reports even not all keys provided" do
|
||||
msg1 = {'nodes' => [{'uid' => 1, 'status' => 'deploying'}]}
|
||||
msg2 = {'nodes' => [{'uid' => 2, 'status' => 'ready'}]}
|
||||
msg1 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
msg2 = {'nodes' => [{'uid' => 2,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]}
|
||||
expected_msg2 = {'nodes' => [{'uid' => 2,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready',
|
||||
'progress' => 100}]}
|
||||
up_reporter.expects(:report).with(msg1)
|
||||
up_reporter.expects(:report).with(msg2)
|
||||
up_reporter.expects(:report).with(expected_msg2)
|
||||
reporter.report(msg1)
|
||||
reporter.report(msg2)
|
||||
end
|
||||
|
||||
it "raises exception if progress provided and no status" do
|
||||
msg1 = {'nodes' => [{'uid' => 1, 'status' => 'ready'}]}
|
||||
msg1 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
msg2 = {'nodes' => [{'uid' => 1, 'progress' => 100}]}
|
||||
up_reporter.expects(:report).with(msg1)
|
||||
up_reporter.expects(:report).never
|
||||
reporter.report(msg1)
|
||||
lambda {reporter.report(msg2)}.should raise_error
|
||||
expect{ reporter.report(msg2) }.to raise_error
|
||||
end
|
||||
|
||||
it "raises exception if status of node is not supported" do
|
||||
@ -146,43 +276,112 @@ describe "TaskProxyReporter" do
|
||||
end
|
||||
|
||||
it "some other attrs are valid and passed" do
|
||||
msg1 = {'nodes' => [{'uid' => 1, 'status' => 'deploying'}]}
|
||||
msg2 = {'status' => 'error', 'error_type' => 'deploy',
|
||||
'nodes' => [{'uid' => 2, 'status' => 'error', 'message' => 'deploy'}]}
|
||||
msg1 = {'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]}
|
||||
msg2 = {'status' => 'error',
|
||||
'error_type' => 'deploy',
|
||||
'nodes' => [{'uid' => 2,
|
||||
'status' => 'error',
|
||||
'message' => 'deploy',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'failed'}]}
|
||||
expected_msg2 = {
|
||||
'status' => 'error',
|
||||
'error_type' => 'deploy',
|
||||
'nodes' => [{
|
||||
'uid' => 2,
|
||||
'status' => 'error',
|
||||
'message' => 'deploy',
|
||||
'progress' => 100,
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'error'}]}
|
||||
up_reporter.expects(:report).with(msg1)
|
||||
up_reporter.expects(:report).with(msg2)
|
||||
up_reporter.expects(:report).with(expected_msg2)
|
||||
reporter.report(msg1)
|
||||
reporter.report(msg2)
|
||||
end
|
||||
|
||||
it "reports if status is greater" do
|
||||
msgs = [
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'ready'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]},
|
||||
]
|
||||
expected_msg2 = {'nodes' => [{
|
||||
'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready',
|
||||
'progress' => 100}]}
|
||||
|
||||
up_reporter.expects(:report).with(msgs[0])
|
||||
up_reporter.expects(:report).with(msgs[1])
|
||||
up_reporter.expects(:report).with(expected_msg2)
|
||||
msgs.each {|msg| reporter.report(msg)}
|
||||
end
|
||||
|
||||
it "report if final status changed" do
|
||||
msgs = [
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'ready'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'error'}]}
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'successful'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'error',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'failed'}]},
|
||||
]
|
||||
|
||||
expected_msg2 = {'nodes' => [{
|
||||
'uid' => 1,
|
||||
'status' => 'ready',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'ready',
|
||||
'progress' => 100}]}
|
||||
|
||||
expected_msg3 = {'nodes' => [{
|
||||
'uid' => 1,
|
||||
'status' => 'error',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'error',
|
||||
'progress' => 100}]}
|
||||
|
||||
up_reporter.expects(:report).with(msgs[0])
|
||||
up_reporter.expects(:report).with(msgs[1])
|
||||
up_reporter.expects(:report).with(msgs[3])
|
||||
up_reporter.expects(:report).with(expected_msg2)
|
||||
up_reporter.expects(:report).with(expected_msg3)
|
||||
msgs.each {|msg| reporter.report(msg)}
|
||||
end
|
||||
|
||||
it "doesn't update progress if it less than previous progress with same status" do
|
||||
msgs = [
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 50}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 10}]}
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running',
|
||||
'progress' => 50}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running',
|
||||
'progress' => 10 }]},
|
||||
]
|
||||
up_reporter.expects(:report).with(msgs[0])
|
||||
up_reporter.expects(:report).never
|
||||
@ -190,11 +389,28 @@ describe "TaskProxyReporter" do
|
||||
end
|
||||
|
||||
it "doesn't forget previously reported attributes" do
|
||||
msgs = [{'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 50}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying', 'key' => 'value', 'progress' => 60}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying', 'progress' => 0}]},
|
||||
]
|
||||
msgs = [
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running',
|
||||
'progress' => 50}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running',
|
||||
'key' => 'value',
|
||||
'progress' => 60 }]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_2',
|
||||
'task_status' => 'running',
|
||||
'progress' => 0 }]},
|
||||
]
|
||||
up_reporter.expects(:report).with(msgs[0])
|
||||
up_reporter.expects(:report).with(msgs[2])
|
||||
up_reporter.expects(:report).never
|
||||
@ -203,13 +419,91 @@ describe "TaskProxyReporter" do
|
||||
|
||||
it "report stopped status" do
|
||||
msgs = [
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'deploying'}]},
|
||||
{'nodes' => [{'uid' => 1, 'status' => 'stopped'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'deploying',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'running'}]},
|
||||
{'nodes' => [{'uid' => 1,
|
||||
'status' => 'stopped',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'successful'}]},
|
||||
]
|
||||
|
||||
expected_msg_1 = {
|
||||
'nodes' => [{
|
||||
'uid' => 1,
|
||||
'status' => 'stopped',
|
||||
'deployment_graph_task_name' => 'test_1',
|
||||
'task_status' => 'ready',
|
||||
'progress' => 100}]}
|
||||
up_reporter.expects(:report).with(msgs[0])
|
||||
up_reporter.expects(:report).with(msgs[1])
|
||||
up_reporter.expects(:report).with(expected_msg_1)
|
||||
msgs.each {|msg| reporter.report(msg)}
|
||||
end
|
||||
|
||||
|
||||
context 'tasks' do
|
||||
let(:msg) do
|
||||
{'nodes' => [{'status' => 'deploying', 'uid' => '1', 'progress' => 54}.merge(task_part_msg)]
|
||||
}
|
||||
end
|
||||
|
||||
let(:task_part_msg) do
|
||||
{'deployment_graph_task_name' => 'test_1', 'task_status' => 'running'}
|
||||
end
|
||||
|
||||
context 'validation' do
|
||||
it 'should validate deployment graph task name' do
|
||||
msg['nodes'].first.delete('deployment_graph_task_name')
|
||||
up_reporter.expects(:report).never
|
||||
expect { reporter.report(msg) }.to raise_error(
|
||||
Astute::AstuteError,
|
||||
/Task name is not provided/
|
||||
)
|
||||
end
|
||||
|
||||
it 'should validate task status absent' do
|
||||
msg['nodes'].first.delete('task_status')
|
||||
up_reporter.expects(:report).never
|
||||
expect { reporter.report(msg) }.to raise_error(
|
||||
Astute::AstuteError,
|
||||
/Task status provided '' is not supported/
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'task status convertation' do
|
||||
it 'should convert task running status to running' do
|
||||
up_reporter.expects(:report).with(msg)
|
||||
reporter.report(msg)
|
||||
end
|
||||
|
||||
it 'should convert task failed status to error' do
|
||||
task_part_msg['task_status'] = 'failed'
|
||||
expected_msg = msg.deep_dup
|
||||
expected_msg['nodes'].first['task_status'] = 'error'
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(msg)
|
||||
end
|
||||
|
||||
it 'should convert task successful status to ready' do
|
||||
task_part_msg['task_status'] = 'successful'
|
||||
expected_msg = msg.deep_dup
|
||||
expected_msg['nodes'].first['task_status'] = 'ready'
|
||||
up_reporter.expects(:report).with(expected_msg)
|
||||
reporter.report(msg)
|
||||
end
|
||||
|
||||
it 'should failed if task has inccorect status' do
|
||||
task_part_msg['task_status'] = 'unknown'
|
||||
up_reporter.expects(:report).never
|
||||
expect { reporter.report(msg) }.to raise_error(
|
||||
Astute::AstuteError,
|
||||
/Task status provided 'unknown' is not supported/
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user