diff --git a/app/models/miq_queue.rb b/app/models/miq_queue.rb index fd15bef9d3f..c3f3778ee6a 100644 --- a/app/models/miq_queue.rb +++ b/app/models/miq_queue.rb @@ -98,19 +98,17 @@ def data=(value) end def self.put(options) - options = options.reverse_merge( - :priority => NORMAL_PRIORITY, - :queue_name => "generic", - :role => nil, - :server_guid => nil, - :msg_timeout => TIMEOUT, - :deliver_on => nil - ).merge( + options = options.merge( :zone => Zone.determine_queue_zone(options), :state => STATE_READY, :handler_type => nil, :handler_id => nil, ) + + create_with_options = all.values[:create_with] || {} + options[:priority] ||= create_with_options[:priority] || NORMAL_PRIORITY + options[:queue_name] ||= create_with_options[:queue_name] || "generic" + options[:msg_timeout] ||= create_with_options[:msg_timeout] || TIMEOUT options[:task_id] = $_miq_worker_current_msg.try(:task_id) unless options.key?(:task_id) options[:role] = options[:role].to_s unless options[:role].nil? diff --git a/spec/models/miq_queue_spec.rb b/spec/models/miq_queue_spec.rb index 684215baf37..cc9b028482f 100644 --- a/spec/models/miq_queue_spec.rb +++ b/spec/models/miq_queue_spec.rb @@ -323,7 +323,7 @@ def self.some_method(single_arg) end end - it "defaults args / miq_callback to [] / {}" do + it "defaults :args" do msg = MiqQueue.put( :class_name => "Class1", :method_name => "Method1", @@ -331,9 +331,188 @@ def self.some_method(single_arg) msg_from_db = MiqQueue.find(msg.id) expect(msg_from_db.args).to eq([]) + end + + it "defaults :miq_callback" do + msg = MiqQueue.put( + :class_name => "Class1", + :method_name => "Method1", + ) + + msg_from_db = MiqQueue.find(msg.id) expect(msg_from_db.miq_callback).to eq({}) end + it "creates with :miq_callback" do + miq_callback = { + :class_name => "Class1", + :method_name => "callback_method", + } + + msg = MiqQueue.put( + :class_name => "Class1", + :method_name => "Method1", + :miq_callback => miq_callback + ) + + msg_from_db = MiqQueue.find(msg.id) + expect(msg_from_db.miq_callback).to include(miq_callback) + end + + it "creates with :miq_callback via create_with" do + miq_callback = { + :class_name => "Class1", + :method_name => "callback_method", + } + + msg = MiqQueue.create_with(:miq_callback => miq_callback).put( + :class_name => "Class1", + :method_name => "Method1", + ) + + msg_from_db = MiqQueue.find(msg.id) + expect(msg_from_db.miq_callback).to include(miq_callback) + end + + it "does not allow objects on the queue" do + expect do + MiqQueue.put(:class_name => 'MyClass', :method_name => 'method1', :args => [MiqServer.first]) + end.to raise_error(ArgumentError) + end + + it "defaults :queue_name" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.queue_name).to eq("generic") + end + + it "sets other :queue_name" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + :queue_name => "other" + ) + expect(msg.queue_name).to eq("other") + end + + it "defaults :priority" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.priority).to eq(MiqQueue::NORMAL_PRIORITY) + end + + it "sets :prority" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + :priority => MiqQueue::LOW_PRIORITY + ) + expect(msg.priority).to eq(MiqQueue::LOW_PRIORITY) + end + + it "creates with :prority via create_with" do + msg = MiqQueue.create_with(:priority => MiqQueue::LOW_PRIORITY).put( + :class_name => "Class1", + :method_name => "Method1", + ) + + expect(msg.priority).to eq(MiqQueue::LOW_PRIORITY) + end + + it "defaults :role" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.role).to eq(nil) + end + + it "defaults :server_guid" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.server_guid).to eq(nil) + end + + it "defaults :msg_timeout" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.msg_timeout).to eq(MiqQueue::TIMEOUT) + end + + it "sets :msg_timeout" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + :msg_timeout => 3.minutes + ) + expect(msg.msg_timeout).to eq(3.minutes) + end + + it "sets :msg_timeout via create_with" do + msg = MiqQueue.create_with(:msg_timeout => 3.minutes).put( + :class_name => "Class1", + :method_name => "Method1", + ) + + expect(msg.msg_timeout).to eq(3.minutes) + end + + it "defaults :deliver_on" do + msg = MiqQueue.put( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2], + ) + expect(msg.deliver_on).to eq(nil) + end + + it "creates with :deliver_on" do + deliver_on = 10.minutes.ago.change(:usec => 0) + + msg = MiqQueue.put( + :class_name => "Class1", + :method_name => "Method1", + :deliver_on => deliver_on + ) + + msg_from_db = MiqQueue.find(msg.id) + expect(msg_from_db.deliver_on).to eq(deliver_on) + end + + it "creates with :deliver_on via create_with" do + deliver_on = 10.minutes.ago.change(:usec => 0) + + msg = MiqQueue.create_with(:deliver_on => deliver_on).put( + :class_name => "Class1", + :method_name => "Method1", + ) + + msg_from_db = MiqQueue.find(msg.id) + expect(msg_from_db.deliver_on).to eq(deliver_on) + end + end + + context "#put_unless_exists" do + before do + _, @miq_server, = EvmSpecHelper.create_guid_miq_server_zone + end + it "should put a unique message on the queue if method_name is different" do msg1 = MiqQueue.put( :class_name => 'MyClass', @@ -361,25 +540,73 @@ def self.some_method(single_arg) expect(MiqQueue.first.state).to eq(MiqQueue::STATE_READY) end - it "should respect hash updates in put_unless_exists" do + it "should yield object found" do MiqQueue.put_unless_exists( :class_name => 'MyClass', :method_name => 'method1', :args => [1, 2] - ) do |_msg, find_options| - find_options.merge(:args => [3, 3]) + ) do |msg, _find_options| + expect(msg).to be_nil + nil end + MiqQueue.put_unless_exists( + :class_name => 'MyClass', + :method_name => 'method1', + :args => [1, 2] + ) do |msg, _find_options| + expect(msg).not_to be_nil + nil + end + end + + it "should not put duplicate messages on the queue" do + msg1 = MiqQueue.put_unless_exists( + :class_name => 'MyClass', + :method_name => 'method2', + :args => [1, 2] + ) + + MiqQueue.put_unless_exists( + :class_name => 'MyClass', + :method_name => 'method2', + :args => [1, 2] + ) + + expect(MiqQueue.get).to eq(msg1) + expect(MiqQueue.get).to eq(nil) + end + + it "should add create_with options" do + MiqQueue.create_with(:args => [3, 3]).put_unless_exists( + :class_name => 'MyClass', + :method_name => 'method1', + ) expect(MiqQueue.first.args).to eq([3, 3]) end - it "should not call into put_unless_exists" do - MiqQueue.put_unless_exists( + it "should not update create_with options" do + MiqQueue.create_with(:args => [3, 3]).put_unless_exists( :class_name => 'MyClass', :method_name => 'method1', - :args => [1, 2] ) - MiqQueue.put_unless_exists( + + MiqQueue.create_with(:args => [1, 2]).put_unless_exists( + :class_name => 'MyClass', + :method_name => 'method1', + ) + + expect(MiqQueue.first.args).to eq([3, 3]) + end + end + + context "#put_or_update" do + before do + _, @miq_server, = EvmSpecHelper.create_guid_miq_server_zone + end + + it "should respect hash updates in put_or_update for create" do + MiqQueue.put_or_update( :class_name => 'MyClass', :method_name => 'method1', :args => [1, 2] @@ -387,24 +614,27 @@ def self.some_method(single_arg) find_options.merge(:args => [3, 3]) end - expect(MiqQueue.first.args).to eq([1, 2]) + expect(MiqQueue.first.args).to eq([3, 3]) end - it "should not put duplicate messages on the queue" do - msg1 = MiqQueue.put_unless_exists( + it "should respect hash updates in put_or_update for update" do + MiqQueue.put_or_update( :class_name => 'MyClass', - :method_name => 'method2', + :method_name => 'method1', :args => [1, 2] ) - MiqQueue.put_unless_exists( + expect(MiqQueue.first.args).to eq([1, 2]) + + MiqQueue.put_or_update( :class_name => 'MyClass', - :method_name => 'method2', + :method_name => 'method1', :args => [1, 2] - ) + ) do |_msg, find_options| + find_options.merge(:args => [3, 3]) + end - expect(MiqQueue.get).to eq(msg1) - expect(MiqQueue.get).to eq(nil) + expect(MiqQueue.first.args).to eq([3, 3]) end it "should use args param to find messages on the queue" do @@ -460,12 +690,6 @@ def self.some_method(single_arg) expect(MiqQueue.get).to have_attributes(:args => [3, 4], :task_id => 'fun_task') expect(MiqQueue.get).to eq(nil) end - - it "does not allow objects on the queue" do - expect do - MiqQueue.put(:class_name => 'MyClass', :method_name => 'method1', :args => [MiqServer.first]) - end.to raise_error(ArgumentError) - end end describe ".unqueue" do