diff --git a/db/migrate/20171025122732_move_ems_refresh_args_to_data.rb b/db/migrate/20171025122732_move_ems_refresh_args_to_data.rb new file mode 100644 index 000000000..b4c64c249 --- /dev/null +++ b/db/migrate/20171025122732_move_ems_refresh_args_to_data.rb @@ -0,0 +1,36 @@ +class MoveEmsRefreshArgsToData < ActiveRecord::Migration[5.0] + class MiqQueue < ActiveRecord::Base + serialize :args, Array + end + + def up + say_with_time('Move MiqQueue refresh args to data') do + MiqQueue.where(:class_name => 'EmsRefresh', :method_name => 'refresh').each do |queue_item| + begin + targets = queue_item.args.first + data = Marshal.dump(targets) unless targets.nil? + + queue_item.update_attributes(:msg_data => data, :args => []) + rescue + # If Marshal.load fails we want to delete the queue item + queue_item.delete + end + end + end + end + + def down + say_with_time('Move MiqQueue refresh data to args') do + MiqQueue.where(:class_name => 'EmsRefresh', :method_name => 'refresh').each do |queue_item| + begin + args = queue_item.msg_data && Marshal.load(queue_item.msg_data) + + queue_item.update_attributes(:args => args, :msg_data => nil) + rescue + # If Marshal.load fails we want to delete the queue item + queue_item.delete + end + end + end + end +end diff --git a/spec/migrations/20171025122732_move_ems_refresh_args_to_data_spec.rb b/spec/migrations/20171025122732_move_ems_refresh_args_to_data_spec.rb new file mode 100644 index 000000000..3821f0ab8 --- /dev/null +++ b/spec/migrations/20171025122732_move_ems_refresh_args_to_data_spec.rb @@ -0,0 +1,88 @@ +require_migration + +describe MoveEmsRefreshArgsToData do + let(:miq_queue_stub) { migration_stub(:MiqQueue) } + let(:targets) { [['Vm', 1], ['Host', 2]] } + let(:refresh_queue_options) do + { + :class_name => 'EmsRefresh', + :method_name => 'refresh', + :role => 'ems_inventory', + :queue_name => 'ems_1', + :zone => 'default', + } + end + let(:refresh_new_target_queue_options) do + { + :class_name => 'EmsRefresh', + :method_name => 'refresh_new_target', + :role => 'ems_inventory', + :queue_name => 'ems_1', + :zone => 'default', + } + end + + migration_context :up do + it "Moves EmsRefresh.refresh queue args to data" do + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:args => [targets])) + + migrate + + expect(Marshal.load(q_item.reload.msg_data)).to match_array(targets) + end + + it "Leaves EmsRefresh.refresh args empty" do + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:args => [targets])) + + migrate + + expect(q_item.reload.args).to match_array([]) + end + + it "Ignores unrelated queue items" do + args = [{:ems_ref => "vm-123"}] + q_item = miq_queue_stub.create!(refresh_new_target_queue_options.merge(:args => args)) + + migrate + + expect(q_item.reload.args).to match_array(args) + end + end + + migration_context :down do + it "Moves EmsRefresh.refresh data to args" do + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:msg_data => Marshal.dump(targets))) + + migrate + + expect(q_item.reload.args).to match_array(targets) + end + + it "If there are no args" do + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:msg_data => nil)) + + migrate + + expect(q_item.reload.args).to match_array([]) + end + + it "Handle invalid marshal format errors" do + # "\x03\x00\x00" is an empty array in Marshal version 3.0 + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:msg_data => "\x03\x00\x00")) + + migrate + + expect { q_item.reload }.to raise_exception(ActiveRecord::RecordNotFound) + end + + it "Deletes invalid queue items but migrates the rest" do + # "\x03\x00\x00" is an empty array in Marshal version 3.0 + miq_queue_stub.create!(refresh_queue_options.merge(:msg_data => "\x03\x00\x00")) + q_item = miq_queue_stub.create!(refresh_queue_options.merge(:msg_data => Marshal.dump(targets))) + + migrate + + expect(q_item.reload.args).to match_array(targets) + end + end +end