require 'spec_helper' require 'flydata-core/mysql/compatibility_checker' module FlydataCore module Mysql describe CompatibilityChecker do let(:database) { 'test_db' } let(:tables) { %w(table_1 table_2 table_3) } let(:option) do { database: database, tables: tables } end describe TableExistenceChecker do let(:subject_object) { described_class.new(option) } describe '#create_query' do subject { subject_object.create_query } it { is_expected.to eq < 'table_1'}, {'table_name' => 'table_2'}, {'table_name' => 'table_3'}, ] end it { expect{subject}.not_to raise_error } end context 'when some tables does not exist' do let(:result) do [{"table_name" => "table_2"}] end it do expect{subject}.to raise_error {|e| expect(e).to be_kind_of(FlydataCore::MysqlCompatibilityError) expect(e.to_s.include?("table_1")).to be_truthy expect(e.to_s.include?("table_2")).to be_falsey expect(e.to_s.include?("table_3")).to be_truthy } end end end end describe PrimaryKeyChecker do let(:subject_object) { described_class.new(option) } describe '#create_query' do subject { subject_object.create_query } it { is_expected.to eq < "table_1"}, {"table_name" => "table_3"}] end it do expect{subject}.to raise_error {|e| expect(e).to be_kind_of(FlydataCore::MysqlCompatibilityError) expect(e.to_s.include?("table_1")).to be_truthy expect(e.to_s.include?("table_2")).to be_falsey expect(e.to_s.include?("table_3")).to be_truthy } end end end end end describe BinlogParameterChecker do let(:subject_object) { described_class.new({}) } describe "#check_result" do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'ROW'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, {'Variable_name'=>'net_read_timeout','Value'=>600}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>60} ] end subject { subject_object.check_result(sys_var, {}) } context "where parameters are valid" do it do expect{subject}.to_not raise_error end end context "where parameters are invalid" do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'MIXED'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, {'Variable_name'=>'net_read_timeout','Value'=>600}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>30} ] end it do expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /binlog_format.*\n.*wait_timeout/) end end context "where parameters are not returned" do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'ROW'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, {'Variable_name'=>'net_read_timeout','Value'=>600}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>60}, ] end it 'ignores missing parameters' do expect{subject}.not_to raise_error end end end describe "#compare_sys_var_values" do let(:input_val) { nil } let(:expected_val) do { 'value_1' => 'foo', 'value_2' => 50, 'value_3' => {">="=>100} } end let(:errors) { {} } subject { subject_object.send(:compare_sys_var_values, input_val, expected_val) } shared_examples "expect correct errors from values" do it { is_expected.to eq(expecting_errors) } end context "when getting valid parameters" do let(:input_val) do { 'value_1' => 'foo', 'value_2' => 50, 'value_3' => 200 } end let(:expecting_errors) { {} } it_behaves_like "expect correct errors from values" end context "when getting one invalid exact parameters for int" do let(:input_val) do { 'value_1' => 'foo', 'value_2' => 20, 'value_3' => 100 } end let(:expecting_errors) do { 'value_2' => { actual_val: 20, err_reason: "value_2 is '20' but should be '50'" } } end it_behaves_like "expect correct errors from values" end context "when getting one invalid exact parameter for string" do let(:input_val) do { 'value_1' => 'fo', 'value_2' => 50, 'value_3' => 100 } end let(:expecting_errors) do { 'value_1' => { actual_val: 'fo', err_reason: "value_1 is 'fo' but should be 'foo'" } } end it_behaves_like "expect correct errors from values" end context "when getting one invalid comparitive parameter that's lower than required" do let(:input_val) do { 'value_1' => 'foo', 'value_2' => 50, 'value_3' => 1 } end let(:expecting_errors) do { 'value_3' => { actual_val: 1, err_reason: "value_3 is '1' but should be at least '100'" } } end it_behaves_like "expect correct errors from values" end context "when getting a valid comparitive parameter that's higher than required" do let(:input_val) do { 'value_1' => 'foo', 'value_2' => 50, 'value_3' => 101 } end let(:expecting_errors) { {} } it_behaves_like "expect correct errors from values" end context "when getting muliple invalid parameters" do let(:input_val) do { 'value_1' => 'fo', 'value_2' => 50, 'value_3' => 15 } end let(:expecting_errors) { {value_1:'fo', value_3:15} } let(:expecting_errors) do { 'value_1' => { actual_val: 'fo', err_reason: "value_1 is 'fo' but should be 'foo'" }, 'value_3' => { actual_val: 15, err_reason: "value_3 is '15' but should be at least '100'" }, } end it_behaves_like "expect correct errors from values" end end end describe RequiredBinlogParameterChecker do let(:subject_object) { described_class.new({}) } describe "#check_result" do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'ROW'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, ] end subject { subject_object.check_result(sys_var) } context 'where parameters are valid' do it { expect{subject}.not_to raise_error } end context 'where parameters contain optional paramters' do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'ROW'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, {'Variable_name'=>'net_read_timeout','Value'=>1}, {'Variable_name'=>'net_write_timeout','Value'=>1}, {'Variable_name'=>'wait_timeout','Value'=>1} ] end it { expect{subject}.not_to raise_error } end context 'where parameters contain invalid parameters' do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'MIXED'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'OFF'}, ] end it { expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /binlog_format.*\n.*log_slave_updates/) } end end end describe OptionalBinlogParameterChecker do let(:subject_object) { described_class.new({}) } describe "#check_result" do let(:sys_var) do [ {'Variable_name'=>'net_read_timeout','Value'=>600}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>60} ] end subject { subject_object.check_result(sys_var) } context 'where parameters are valid' do it { expect{subject}.not_to raise_error } end context 'where parameters contain required paramters' do let(:sys_var) do [ {'Variable_name'=>'binlog_format','Value'=>'ROW'}, {'Variable_name'=>'binlog_checksum','Value'=>'NONE'}, {'Variable_name'=>'log_bin_use_v1_row_events','Value'=>'ON'}, {'Variable_name'=>'log_slave_updates','Value'=>'ON'}, {'Variable_name'=>'net_read_timeout','Value'=>600}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>60}, ] end it { expect{subject}.not_to raise_error } end context 'where parameters contain invalid parameters' do let(:sys_var) do [ {'Variable_name'=>'net_read_timeout','Value'=>2}, {'Variable_name'=>'net_write_timeout','Value'=>600}, {'Variable_name'=>'wait_timeout','Value'=>1} ] end it { expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, /^\[WARNING.*\n.*net_read_timeout.*\n.*wait_timeout/) } end end end end end