require 'spec_helper' require 'flydata-core/mysql/command_generator' module FlydataCore module Mysql describe CommandGenerator do let(:default_option) { { command: 'mysqldump', host: 'test-host', port: 3306, username: 'testuser', password: 'testpassword', database: 'testdb', } } let(:option) { default_option } let(:cmd_pswd_check) { 'mysqldump -h test-host -P 3306 -utestuser -p%s --default-character-set=utf8 --protocol=tcp testdb' } describe '.generate_mysql_cmd' do subject { described_class.generate_mysql_cmd(option) } context 'when option is not hash' do let(:option) { nil } it { expect{subject}.to raise_error(ArgumentError) } end context 'when option is empty' do let(:option) { {} } it { is_expected.to eq("mysql --default-character-set=utf8 --protocol=tcp --skip-auto-rehash") } end context 'when all option is specified' do it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp testdb' ) } end context 'when option conatins string key' do before { option[:database] = nil option['database'] = 'another_db' } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp another_db' ) } end context 'when password is empty' do before { option[:password] = nil } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser --default-character-set=utf8 --protocol=tcp testdb' ) } end context 'when password is not empty' do before { option[:password] = "abc`def" } it { is_expected.to eq(cmd_pswd_check % 'abc\\`def' ) } end context 'when password includes double quate' do before { option[:password] = "abc\"def" } it { is_expected.to eq(cmd_pswd_check % 'abc\\"def') } end context 'when password includes dollars sign' do before { option[:password] = "abc$def" } it { is_expected.to eq(cmd_pswd_check % 'abc\\$def' ) } end context 'when password includes multiple special characters' do before { option[:password] = "ab\"\"c$$def" } it { is_expected.to eq(cmd_pswd_check % 'ab\\"\\"c\\$\\$def' ) } end context 'when password does not includes special characters' do before { option[:password] = "abcdef" } it { is_expected.to eq(cmd_pswd_check % 'abcdef' ) } end context 'when tables are specified' do before { option[:tables] = %w(table_a table_b table_c) } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp testdb table_a table_b table_c' ) } end context 'when ssl_ca is specified' do before { option[:ssl_ca] = 'mysql_sync.ssl_ca.pem' } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --ssl-ca mysql_sync.ssl_ca.pem testdb' ) } end context 'when ssl_cipher is specified' do before { option[:ssl_cipher] = 'AES256-GCM-SHA384:AES256-SHA' } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --ssl-cipher=AES256-GCM-SHA384:AES256-SHA testdb' ) } end context 'when no_default_option is turned on' do before { option[:no_default_option] = true } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword testdb' ) } end context 'with options for mysql_protocol_tcp_compat' do before { option[:command] = 'mysql' option[:custom_option] = '-e "SHOW GRANTS;"' } it { is_expected.to eq( 'mysql -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --skip-auto-rehash -e "SHOW GRANTS;" testdb' ) } end context 'when custom_option_end is set' do before { option[:custom_option_end] = 'test_table' } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp testdb test_table' ) } end end describe '.generate_mysql_ddl_dump_cmd' do subject { described_class.generate_mysql_ddl_dump_cmd(option) } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp -d testdb' ) } end describe '.generate_mysqldump_with_master_data_cmd' do subject { described_class.generate_mysqldump_with_master_data_cmd(option) } before { option[:tables] = %w(table_a table_b) } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --skip-lock-tables --single-transaction --hex-blob --flush-logs --master-data=2 testdb table_a table_b' ) } end describe '.generate_mysqldump_without_master_data_cmd' do subject { described_class.generate_mysqldump_without_master_data_cmd(option) } before { option[:tables] = %w(table_a table_b) } it { is_expected.to eq( 'mysqldump -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --skip-lock-tables --single-transaction --hex-blob testdb table_a table_b' ) } end describe '.generate_mysql_show_grants_cmd' do subject { described_class.generate_mysql_show_grants_cmd(option) } it { is_expected.to eq( 'mysql -h test-host -P 3306 -utestuser -ptestpassword --default-character-set=utf8 --protocol=tcp --skip-auto-rehash -e "SHOW GRANTS;" testdb' ) } end describe '.each_mysql_tabledef' do context 'with empty tables' do subject { described_class.each_mysql_tabledef([], nil) } it do expect{subject}.to raise_error( ArgumentError,"tables is nil or empty") end end context 'when all tables are missing' do before do allow(described_class).to receive(:_each_mysql_tabledef). and_raise(CommandGenerator::TableMissingError.new('table, missing error', 'table1')) end subject { described_class.each_mysql_tabledef(%w(table1), nil) } it { is_expected.to eq(%w(table1)) } end end end end end