flydata 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/flydata +1 -0
- data/flydata-core/lib/flydata-core/core_ext/module.rb +1 -1
- data/flydata-core/lib/flydata-core/core_ext/object.rb +1 -1
- data/flydata.gemspec +21 -5
- data/lib/flydata.rb +5 -8
- data/lib/flydata/api/data_entry.rb +2 -0
- data/lib/flydata/api/data_port.rb +2 -0
- data/lib/flydata/api/redshift_cluster.rb +2 -0
- data/lib/flydata/api_client.rb +3 -0
- data/lib/flydata/cli.rb +13 -2
- data/lib/flydata/command/base.rb +6 -0
- data/lib/flydata/command/conf.rb +3 -0
- data/lib/flydata/command/crontab.rb +3 -0
- data/lib/flydata/command/encrypt.rb +3 -0
- data/lib/flydata/command/kill_all.rb +3 -0
- data/lib/flydata/command/login.rb +2 -0
- data/lib/flydata/command/restart.rb +3 -0
- data/lib/flydata/command/routine.rb +3 -0
- data/lib/flydata/command/sender.rb +2 -0
- data/lib/flydata/command/setlogdel.rb +4 -1
- data/lib/flydata/command/setup.rb +7 -2
- data/lib/flydata/command/start.rb +3 -0
- data/lib/flydata/command/status.rb +3 -0
- data/lib/flydata/command/stop.rb +3 -0
- data/lib/flydata/command/sync.rb +10 -3
- data/lib/flydata/command/version.rb +2 -0
- data/lib/flydata/{command_logger.rb → command_loggable.rb} +0 -0
- data/lib/flydata/compatibility_check.rb +1 -1
- data/lib/flydata/credentials.rb +2 -0
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +8 -9
- data/lib/flydata/fluent-plugins/mysql/alter_table_query_handler.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/binlog_query_dispatcher.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/binlog_query_handler.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/binlog_record_dispatcher.rb +2 -2
- data/lib/flydata/fluent-plugins/mysql/binlog_record_handler.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/ddl_query_handler.rb +1 -1
- data/lib/flydata/fluent-plugins/mysql/dml_record_handler.rb +1 -1
- data/lib/flydata/helpers.rb +0 -10
- data/lib/flydata/heroku.rb +3 -0
- data/lib/flydata/output/forwarder.rb +1 -1
- data/lib/flydata/parser/mysql/dump_parser.rb +29 -31
- data/lib/flydata/sync_file_manager.rb +230 -232
- data/spec/fly_data_model_spec.rb +1 -0
- data/spec/flydata/api/data_entry_spec.rb +1 -0
- data/spec/flydata/api_client_spec.rb +18 -0
- data/spec/flydata/cli_spec.rb +1 -0
- data/spec/flydata/command/base_spec.rb +44 -0
- data/spec/flydata/command/conf_spec.rb +21 -0
- data/spec/flydata/command/crontab_spec.rb +17 -0
- data/spec/flydata/command/encrypt_spec.rb +28 -0
- data/spec/flydata/command/kill_all_spec.rb +17 -0
- data/spec/flydata/command/login_spec.rb +21 -0
- data/spec/flydata/command/restart_spec.rb +17 -0
- data/spec/flydata/command/routine_spec.rb +29 -0
- data/spec/flydata/command/sender_spec.rb +7 -2
- data/spec/flydata/command/setlogdel_spec.rb +18 -0
- data/spec/flydata/command/setup_spec.rb +44 -0
- data/spec/flydata/command/start_spec.rb +17 -0
- data/spec/flydata/command/status_spec.rb +17 -0
- data/spec/flydata/command/stop_spec.rb +17 -0
- data/spec/flydata/command/sync_spec.rb +1 -0
- data/spec/flydata/command/version_spec.rb +14 -0
- data/spec/flydata/fluent-plugins/in_mysql_binlog_flydata_spec.rb +1 -1
- data/spec/flydata/parser/mysql/dump_parser_spec.rb +23 -73
- data/spec/flydata/sync_file_manager_spec.rb +150 -152
- metadata +19 -4
data/spec/fly_data_model_spec.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/api_client'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
describe ApiClient do
|
6
|
+
subject { described_class.instance }
|
7
|
+
let(:resource) { double('resource') }
|
8
|
+
let(:response) { JSON.parse('{"success":true}') }
|
9
|
+
|
10
|
+
describe "#post" do
|
11
|
+
it do
|
12
|
+
expect(RestClient::Resource).to receive(:new).and_return(resource)
|
13
|
+
expect(resource).to receive(:post).with(nil, accept: :json).and_return(response.to_json)
|
14
|
+
expect(subject.post('/user')).to eq(response)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/flydata/cli_spec.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/base'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
|
7
|
+
describe Base do
|
8
|
+
subject { described_class.new }
|
9
|
+
let(:data_entries) {
|
10
|
+
[{"id"=>4, "data_port_id"=>1, "name"=>"flydata_sync_mysql_2", "log_path"=>nil, "created_at"=>"2015-03-02T03:06:25.000Z", "updated_at"=>"2015-03-02T03:08:02.000Z", "log_deletion"=>nil, "display_name"=>"synctest", "heroku_resource_id"=>nil, "heroku_log_type"=>nil, "log_file_type"=>nil, "log_file_delimiter"=>nil, "enabled"=>true, "type"=>"RedshiftMysqlDataEntry", "tag_name"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2", "tag_name_dev"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2.dev", "data_port_key"=>"c5c0eb3d", "schema_name"=>"", "table_name"=>"", "redshift_schema_name"=>"", "redshift_table_name"=>"", "mysql_data_entry_preference"=>{"host"=>"ubertas.flydata.co", "port"=>3306, "username"=>"mak", "password"=>password, "database"=>"mak_development", "tables"=>"items,orders", "tables_append_only"=>""}}]
|
11
|
+
}
|
12
|
+
let(:flydata) { double('flydata') }
|
13
|
+
let(:path) { '/data_entries' }
|
14
|
+
let(:response_body) { data_entries }
|
15
|
+
let(:response) { double('response') }
|
16
|
+
let(:response_code) { 200 }
|
17
|
+
before do
|
18
|
+
allow(response).to receive(:code).and_return(response_code)
|
19
|
+
allow(flydata).to receive(:get).with(path).and_return(response_body)
|
20
|
+
allow(flydata).to receive(:response).and_return(response)
|
21
|
+
allow(subject).to receive(:flydata).and_return(flydata)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#retrieve_data_entries' do
|
25
|
+
context "when MySQL password from server is encrypted" do
|
26
|
+
let(:password) { "8xRe5otrYkrnV5vQhufa6g==" }
|
27
|
+
let(:response_body) { data_entries }
|
28
|
+
before do
|
29
|
+
# instantiate response_body with the encrypted password
|
30
|
+
response_body
|
31
|
+
end
|
32
|
+
# override password which data_entries referes to
|
33
|
+
let(:password) { 'flydata' }
|
34
|
+
it "returns a data entry list with plain MySQL passwords" do
|
35
|
+
expect(subject.retrieve_data_entries).to eq(data_entries)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/conf'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Conf do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:de) { {'name' => 'foo'} }
|
9
|
+
let(:data_entries) { [de] }
|
10
|
+
describe "#run" do
|
11
|
+
it do
|
12
|
+
expect(subject).to receive(:retrieve_data_entries).and_return(data_entries)
|
13
|
+
expect(Flydata::Preference::DataEntryPreference).to receive(:copy_template).with(de).and_return(false)
|
14
|
+
expect(Flydata::Preference::DataEntryPreference).to receive(:configurable?).with(de).and_return(false)
|
15
|
+
|
16
|
+
subject.run
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/crontab'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Crontab do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:cron) { double("cron") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Cron).to receive(:new).and_return(cron)
|
12
|
+
expect(cron).to receive(:update)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/encrypt'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Encrypt do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:flydata) { double('flydata') }
|
9
|
+
let(:data_port) { double('data_port') }
|
10
|
+
let(:key) { 'abcd' }
|
11
|
+
let(:dp) { {'key' => key} }
|
12
|
+
let(:password) { 'P@ssword' }
|
13
|
+
let(:encrypted_password) { '@#$@#' }
|
14
|
+
|
15
|
+
before do
|
16
|
+
expect(subject).to receive(:flydata).and_return(flydata)
|
17
|
+
expect(flydata).to receive(:data_port).and_return(data_port)
|
18
|
+
expect(data_port).to receive(:get).and_return(dp)
|
19
|
+
expect(subject).to receive(:ask).and_return(password)
|
20
|
+
end
|
21
|
+
it "loads without an error" do
|
22
|
+
expect(Flydata::Util::Encryptor).to receive(:encrypt).with(password, key).and_return(encrypted_password)
|
23
|
+
|
24
|
+
subject.run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/kill_all'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Kill_all do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
|
12
|
+
expect(sender).to receive(:kill_all)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/login'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Login do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:ask_text) { "answer" }
|
9
|
+
let(:flydata) { double('flydata') }
|
10
|
+
|
11
|
+
before do
|
12
|
+
allow(subject).to receive(:flydata).and_return(flydata)
|
13
|
+
allow(subject).to receive(:ask).and_return(ask_text)
|
14
|
+
end
|
15
|
+
it do
|
16
|
+
expect(flydata).to receive(:post)
|
17
|
+
expect(subject.run).to eq true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/restart'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Restart do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
|
12
|
+
expect(sender).to receive(:restart)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/routine'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Routine do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:flydata) { double('flydata') }
|
9
|
+
let(:credentials) { double('credentials') }
|
10
|
+
let(:path) { '/tmp' }
|
11
|
+
|
12
|
+
before do
|
13
|
+
expect(subject).to receive(:flydata).and_return(flydata)
|
14
|
+
expect(flydata).to receive(:credentials).and_return(credentials)
|
15
|
+
expect(credentials).to receive(:authenticated?).and_return(true)
|
16
|
+
expect(subject).to receive(:retrieve_log_paths).and_return([path])
|
17
|
+
end
|
18
|
+
let(:log_monitor) { double('log_monitor') }
|
19
|
+
let(:setup) { double('setup') }
|
20
|
+
it "loads without an error" do
|
21
|
+
expect(Flydata::LogMonitor).to receive(:new).with(path).and_return(log_monitor)
|
22
|
+
expect(log_monitor).to receive(:setup).and_return(setup)
|
23
|
+
expect(setup).to receive(:rotate)
|
24
|
+
|
25
|
+
subject.run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require '
|
2
|
+
require 'flydata/command/sender'
|
3
3
|
|
4
4
|
module Flydata
|
5
5
|
module Command
|
6
6
|
describe Sender do
|
7
|
+
let(:flydata) { double("flydata") }
|
8
|
+
let(:data_port) { double("data_port") }
|
7
9
|
let(:opts) do
|
8
10
|
slop = Sender.slop_start
|
9
11
|
slop.parse(args)
|
@@ -16,7 +18,10 @@ module Flydata
|
|
16
18
|
expect(subject).to receive(:wait_until_server_ready)
|
17
19
|
expect(subject).to receive(:wait_until_client_ready)
|
18
20
|
allow(Kernel).to receive(:sleep)
|
19
|
-
|
21
|
+
allow(subject).to receive(:flydata).and_return(flydata)
|
22
|
+
allow(flydata).to receive(:data_port).and_return(data_port)
|
23
|
+
allow(data_port).to receive(:get).and_return("Wibble")
|
24
|
+
|
20
25
|
allow_any_instance_of(Flydata::AgentCompatibilityCheck).to receive(:check).and_return(true)
|
21
26
|
Flydata::Command::Sync.any_instance.should_receive(:try_mysql_sync).and_return("Wobble")
|
22
27
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/setlogdel'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Setlogdel do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:login) { double("login") }
|
9
|
+
|
10
|
+
it "loads without an error" do
|
11
|
+
expect(Flydata::Command::Login).to receive(:new).and_return(login)
|
12
|
+
expect(login).to receive(:run)
|
13
|
+
expect(subject).to receive(:retrieve_data_entries).and_return([])
|
14
|
+
subject.run
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/setup'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Setup do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
let(:de) { {'type' => 'RedshiftMysqlDataEntry'} }
|
10
|
+
let(:data_entries) { [ de ] }
|
11
|
+
let(:flydata) { double('flydata') }
|
12
|
+
let(:data_port) { double('data_port') }
|
13
|
+
let(:dp) { double('dp') }
|
14
|
+
let(:conf) { double('conf') }
|
15
|
+
let(:sync_fm) { double('sync_fm') }
|
16
|
+
let(:credentials) { double('credentials') }
|
17
|
+
let(:login) { double('login') }
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(subject).to receive(:retrieve_data_entries).and_return(data_entries)
|
21
|
+
allow(subject).to receive(:flydata).and_return(flydata)
|
22
|
+
expect(flydata).to receive(:data_port).and_return(data_port)
|
23
|
+
allow(flydata).to receive(:flydata_api_host).and_return('localhost')
|
24
|
+
expect(flydata).to receive(:credentials).and_return(credentials)
|
25
|
+
expect(credentials).to receive(:authenticated?).and_return(false)
|
26
|
+
expect(data_port).to receive(:get).and_return(dp)
|
27
|
+
expect(sender).to receive(:process_exist?).and_return(true)
|
28
|
+
expect(sender).to receive(:stop)
|
29
|
+
expect(sync_fm).to receive(:binlog_path).and_return('/tmp')
|
30
|
+
expect(conf).to receive(:copy_templates)
|
31
|
+
expect(login).to receive(:run)
|
32
|
+
expect(sender).to receive(:restart)
|
33
|
+
end
|
34
|
+
it do
|
35
|
+
expect(Flydata::Command::Conf).to receive(:new).and_return(conf)
|
36
|
+
expect(Flydata::SyncFileManager).to receive(:new).with(de).and_return(sync_fm)
|
37
|
+
expect(Flydata::Command::Login).to receive(:new).and_return(login)
|
38
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender).twice
|
39
|
+
|
40
|
+
subject.initial_run
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/start'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Start do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
|
12
|
+
expect(sender).to receive(:start)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/status'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Status do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
|
12
|
+
expect(sender).to receive(:status)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'flydata/command/stop'
|
3
|
+
|
4
|
+
module Flydata
|
5
|
+
module Command
|
6
|
+
describe Stop do
|
7
|
+
subject { described_class.new }
|
8
|
+
let(:sender) { double("sender") }
|
9
|
+
|
10
|
+
it do
|
11
|
+
expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
|
12
|
+
expect(sender).to receive(:stop)
|
13
|
+
subject.run
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -526,7 +526,7 @@ EOT
|
|
526
526
|
# Need to make sure no event is sent... how do I do that
|
527
527
|
let(:sync_fm) { double('sync_fm') }
|
528
528
|
before do
|
529
|
-
Flydata::
|
529
|
+
Flydata::SyncFileManager.any_instance.should_receive(:get_new_table_list).with(TEST_TABLES.split(","), "pos").and_return([TEST_TABLE])
|
530
530
|
|
531
531
|
Test.configure_plugin(plugin, TEST_CONFIG)
|
532
532
|
plugin.event_listener(rotate_event)
|
@@ -82,83 +82,33 @@ module Flydata
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
86
|
-
let(:status) { double(:status) }
|
87
|
-
let(:dump_io) { File.open(file_path, 'r', encoding: "utf-8") }
|
88
|
-
let(:default_dump_generator) { MysqlDumpGeneratorMasterData.new(default_conf) }
|
89
|
-
|
90
|
-
describe '#initialize' do
|
91
|
-
context 'with password' do
|
92
|
-
subject { default_dump_generator.instance_variable_get(:@dump_cmd) }
|
93
|
-
it { is_expected.to eq('mysqldump -h localhost -P 3306 -uadmin -p"pass" --default-character-set=utf8 --protocol=tcp --skip-lock-tables ' +
|
94
|
-
'--single-transaction --hex-blob --flush-logs --master-data=2 dev users groups') }
|
95
|
-
end
|
96
|
-
context 'without password' do
|
97
|
-
let (:dump_generator) do
|
98
|
-
MysqlDumpGeneratorMasterData.new(default_conf.merge({'password' => ''}))
|
99
|
-
end
|
100
|
-
subject { dump_generator.instance_variable_get(:@dump_cmd) }
|
101
|
-
it { is_expected.to eq('mysqldump -h localhost -P 3306 -uadmin --default-character-set=utf8 --protocol=tcp --skip-lock-tables ' +
|
102
|
-
'--single-transaction --hex-blob --flush-logs --master-data=2 dev users groups') }
|
103
|
-
end
|
104
|
-
end
|
85
|
+
end
|
105
86
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
context 'when exit status is 0 but no file' do
|
121
|
-
before do
|
122
|
-
expect(status).to receive(:exitstatus).and_return 0
|
123
|
-
expect(Open3).to receive(:capture3).and_return(
|
124
|
-
['(dummy std out)', '(dummy std err)', status]
|
125
|
-
)
|
126
|
-
end
|
127
|
-
it do
|
128
|
-
expect{ default_dump_generator.dump(file_path) }.to raise_error
|
129
|
-
expect(File.exists?(file_path)).to be_falsey
|
130
|
-
end
|
131
|
-
end
|
132
|
-
context 'when exit status is 0 but file size is 0' do
|
133
|
-
before do
|
134
|
-
`touch #{file_path}`
|
135
|
-
expect(status).to receive(:exitstatus).and_return 0
|
136
|
-
expect(Open3).to receive(:capture3).and_return(
|
137
|
-
['(dummy std out)', '(dummy std err)', status]
|
138
|
-
)
|
139
|
-
end
|
140
|
-
it do
|
141
|
-
expect{ default_dump_generator.dump(file_path) }.to raise_error
|
142
|
-
expect(File.exists?(file_path)).to be_truthy
|
143
|
-
end
|
144
|
-
end
|
145
|
-
context 'when exit status is 0' do
|
146
|
-
before do
|
147
|
-
`echo "something..." > #{file_path}`
|
148
|
-
expect(status).to receive(:exitstatus).and_return 0
|
149
|
-
expect(Open3).to receive(:capture3).and_return(
|
150
|
-
['(dummy std out)', '(dummy std err)', status]
|
151
|
-
)
|
152
|
-
end
|
153
|
-
it do
|
154
|
-
expect(default_dump_generator.dump(file_path)).to be_truthy
|
155
|
-
expect(File.exists?(file_path)).to be_truthy
|
156
|
-
end
|
87
|
+
describe FdMysqlClient do
|
88
|
+
let(:db_opts) do
|
89
|
+
{
|
90
|
+
host: 'localhost',
|
91
|
+
port: 3306,
|
92
|
+
username: 'admin',
|
93
|
+
password: 'pass',
|
94
|
+
database: 'dev'
|
95
|
+
}
|
96
|
+
end
|
97
|
+
describe '#query' do
|
98
|
+
module DummyMysqlClient
|
99
|
+
def initialize(opts = {})
|
157
100
|
end
|
158
|
-
|
159
|
-
|
101
|
+
def query(sql, opts = {})
|
102
|
+
raise Mysql2::Error.new("Timeout waiting for a response from the last query. (waited 600 seconds)")
|
160
103
|
end
|
161
104
|
end
|
105
|
+
it 'raises appropriate error when query times out' do
|
106
|
+
described_class.instance_eval { include DummyMysqlClient }
|
107
|
+
sql = "FLUSH LOCAL TABLES"
|
108
|
+
test_client = described_class.new(db_opts)
|
109
|
+
expect{test_client.query(sql)}.to raise_error(RuntimeError, /query timed out when running/)
|
110
|
+
expect(test_client.last_query).to eq(sql)
|
111
|
+
end
|
162
112
|
end
|
163
113
|
end
|
164
114
|
|