lib/kitchen/command.rb in test-kitchen-1.8.0 vs lib/kitchen/command.rb in test-kitchen-1.9.0
- old
+ new
@@ -157,29 +157,48 @@
# concurrently.
#
# @param action [String] action to perform
# @param instances [Array<Instance>] an array of instances
def run_action(action, instances, *args)
- concurrency = 1
- if options[:concurrency]
- concurrency = options[:concurrency] || instances.size
- concurrency = instances.size if concurrency > instances.size
- end
+ concurrency = concurrency_setting(instances)
queue = Queue.new
instances.each { |i| queue << i }
concurrency.times { queue << nil }
threads = []
+ @action_errors = []
concurrency.times do
threads << Thread.new do
while instance = queue.pop
- instance.public_send(action, *args)
- instance.cleanup!
+ run_action_in_thread(action, instance, *args)
end
end
end
threads.map(&:join)
+ unless @action_errors.empty?
+ raise ActionFailed.new("#{@action_errors.length} actions failed.", @action_errors)
+ end
+ end
+
+ # private
+ def concurrency_setting(instances)
+ concurrency = 1
+ if options[:concurrency]
+ concurrency = options[:concurrency] || instances.size
+ concurrency = instances.size if concurrency > instances.size
+ end
+ concurrency
+ end
+
+ def run_action_in_thread(action, instance, *args)
+ instance.public_send(action, *args)
+ rescue Kitchen::ActionFailed => e
+ new_error = Kitchen::ActionFailed.new("#{e.message} on #{instance.name}")
+ new_error.set_backtrace(e.backtrace)
+ @action_errors << new_error
+ ensure
+ instance.cleanup!
end
end
end
end