rails_redshift_replicator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/rails_redshift_replicator/application.js +13 -0
- data/app/assets/stylesheets/rails_redshift_replicator/application.css +15 -0
- data/app/controllers/rails_redshift_replicator/application_controller.rb +5 -0
- data/app/helpers/rails_redshift_replicator/application_helper.rb +4 -0
- data/app/models/rails_redshift_replicator/replication.rb +98 -0
- data/app/views/layouts/rails_redshift_replicator/application.html.erb +14 -0
- data/config/locales/rails_redshift_replicator.en.yml +20 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20160503214955_create_rails_redshift_replicator_replications.rb +24 -0
- data/db/migrate/20160509193335_create_table_rails_redshift_replicator_deleted_ids.rb +8 -0
- data/lib/generators/rails_redshift_replicator/install_generator.rb +25 -0
- data/lib/generators/templates/rails_redshift_replicator.rb +74 -0
- data/lib/rails_redshift_replicator.rb +229 -0
- data/lib/rails_redshift_replicator/adapters/generic.rb +40 -0
- data/lib/rails_redshift_replicator/adapters/mysql2.rb +22 -0
- data/lib/rails_redshift_replicator/adapters/postgresql.rb +37 -0
- data/lib/rails_redshift_replicator/adapters/sqlite.rb +27 -0
- data/lib/rails_redshift_replicator/deleter.rb +67 -0
- data/lib/rails_redshift_replicator/engine.rb +14 -0
- data/lib/rails_redshift_replicator/exporters/base.rb +215 -0
- data/lib/rails_redshift_replicator/exporters/full_replicator.rb +9 -0
- data/lib/rails_redshift_replicator/exporters/identity_replicator.rb +9 -0
- data/lib/rails_redshift_replicator/exporters/timed_replicator.rb +9 -0
- data/lib/rails_redshift_replicator/file_manager.rb +134 -0
- data/lib/rails_redshift_replicator/importers/base.rb +158 -0
- data/lib/rails_redshift_replicator/importers/full_replicator.rb +17 -0
- data/lib/rails_redshift_replicator/importers/identity_replicator.rb +15 -0
- data/lib/rails_redshift_replicator/importers/timed_replicator.rb +18 -0
- data/lib/rails_redshift_replicator/model/extension.rb +45 -0
- data/lib/rails_redshift_replicator/model/hair_trigger_extension.rb +8 -0
- data/lib/rails_redshift_replicator/replicable.rb +143 -0
- data/lib/rails_redshift_replicator/rlogger.rb +12 -0
- data/lib/rails_redshift_replicator/tools/analyze.rb +18 -0
- data/lib/rails_redshift_replicator/tools/vacuum.rb +77 -0
- data/lib/rails_redshift_replicator/version.rb +3 -0
- data/lib/tasks/rails_redshift_replicator_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/post.rb +4 -0
- data/spec/dummy/app/models/tag.rb +4 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +37 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/rails_redshift_replicator.rb +59 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/locales/rails_redshift_replicator.en.yml +19 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20160504120421_create_test_tables.rb +40 -0
- data/spec/dummy/db/migrate/20160509225445_create_triggers_posts_delete_or_tags_delete_or_users_delete.rb +33 -0
- data/spec/dummy/db/migrate/20160511000937_create_rails_redshift_replicator_replications.rails_redshift_replicator.rb +25 -0
- data/spec/dummy/db/migrate/20160511000938_create_table_rails_redshift_replicator_deleted_ids.rails_redshift_replicator.rb +9 -0
- data/spec/dummy/db/schema.rb +99 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +1623 -0
- data/spec/dummy/log/test.log +95379 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/rails_redshift_replicator_development +0 -0
- data/spec/factories/rails_redshift_replicator_replications.rb +31 -0
- data/spec/integration/rails_redshift_replicator_spec.rb +148 -0
- data/spec/integration/setup_spec.rb +149 -0
- data/spec/lib/rails_redshift_replicator/deleter_spec.rb +90 -0
- data/spec/lib/rails_redshift_replicator/exporters/base_spec.rb +326 -0
- data/spec/lib/rails_redshift_replicator/exporters/full_replicator_spec.rb +33 -0
- data/spec/lib/rails_redshift_replicator/exporters/identity_replicator_spec.rb +40 -0
- data/spec/lib/rails_redshift_replicator/exporters/timed_replicator_spec.rb +43 -0
- data/spec/lib/rails_redshift_replicator/file_manager_spec.rb +90 -0
- data/spec/lib/rails_redshift_replicator/importers/base_spec.rb +102 -0
- data/spec/lib/rails_redshift_replicator/importers/full_replicator_spec.rb +27 -0
- data/spec/lib/rails_redshift_replicator/importers/identity_replicator_spec.rb +26 -0
- data/spec/lib/rails_redshift_replicator/importers/timed_replicator_spec.rb +26 -0
- data/spec/lib/rails_redshift_replicator/model/extension_spec.rb +36 -0
- data/spec/lib/rails_redshift_replicator/replicable_spec.rb +230 -0
- data/spec/lib/rails_redshift_replicator/rlogger_spec.rb +22 -0
- data/spec/lib/rails_redshift_replicator/tools/analyze_spec.rb +15 -0
- data/spec/lib/rails_redshift_replicator/tools/vacuum_spec.rb +65 -0
- data/spec/lib/rails_redshift_replicator_spec.rb +110 -0
- data/spec/models/rails_redshift_replicator/replication_spec.rb +104 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/csv/invalid_user.csv +12 -0
- data/spec/support/csv/valid_post.csv +2 -0
- data/spec/support/csv/valid_tags_users.csv +1 -0
- data/spec/support/csv/valid_user.csv +2 -0
- data/spec/support/rails_redshift_replicator_helpers.rb +95 -0
- metadata +430 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RailsRedshiftReplicator::RLogger do
|
|
4
|
+
@messages = []
|
|
5
|
+
let!(:logger) { RailsRedshiftReplicator::RLogger.new(STDOUT) }
|
|
6
|
+
it 'emits info notification' do
|
|
7
|
+
expect(ActiveSupport::Notifications).to receive(:instrument).with('rails_redshift_replicator', type: :info, message: 'hello')
|
|
8
|
+
logger.info 'hello'
|
|
9
|
+
end
|
|
10
|
+
it 'emits warn notification' do
|
|
11
|
+
expect(ActiveSupport::Notifications).to receive(:instrument).with('rails_redshift_replicator', type: :warn, message: 'hello')
|
|
12
|
+
logger.warn 'hello'
|
|
13
|
+
end
|
|
14
|
+
it 'emits debug notification' do
|
|
15
|
+
expect(ActiveSupport::Notifications).to receive(:instrument).with('rails_redshift_replicator', type: :debug, message: 'hello')
|
|
16
|
+
logger.debug 'hello'
|
|
17
|
+
end
|
|
18
|
+
it 'emits error notification' do
|
|
19
|
+
expect(ActiveSupport::Notifications).to receive(:instrument).with('rails_redshift_replicator', type: :error, message: 'hello')
|
|
20
|
+
logger.error 'hello'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
describe RailsRedshiftReplicator::Tools::Analyze do
|
|
3
|
+
context "when uses :all for all tables" do
|
|
4
|
+
it "executes" do
|
|
5
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with("ANALYZE ;")
|
|
6
|
+
RailsRedshiftReplicator.analyze(:all)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
context "with one table" do
|
|
10
|
+
it "executes" do
|
|
11
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with("ANALYZE users;")
|
|
12
|
+
RailsRedshiftReplicator.analyze("users")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
describe RailsRedshiftReplicator::Tools::Vacuum do
|
|
3
|
+
describe ".vacuum" do
|
|
4
|
+
context "with :all" do
|
|
5
|
+
let(:sql) { "VACUUM ;" }
|
|
6
|
+
it "performs vacuum on all tables" do
|
|
7
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with(sql)
|
|
8
|
+
RailsRedshiftReplicator.vacuum(:all)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
context "without tables" do
|
|
12
|
+
let(:sql) { "VACUUM ;" }
|
|
13
|
+
it "performs vacuum on all tables" do
|
|
14
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with(sql)
|
|
15
|
+
RailsRedshiftReplicator.vacuum
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
context "when using auto_tune" do
|
|
19
|
+
it "perfoms vacuum on all tables" do
|
|
20
|
+
expect_any_instance_of(RailsRedshiftReplicator::Tools::Vacuum).to receive(:auto_tuned_vacuum).with(:posts)
|
|
21
|
+
RailsRedshiftReplicator.vacuum(:posts, "auto_tune")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe ".auto_tuned_vacuum" do
|
|
27
|
+
before do
|
|
28
|
+
allow_any_instance_of(RailsRedshiftReplicator::Tools::Vacuum)
|
|
29
|
+
.to receive(:sort_types)
|
|
30
|
+
.and_return( [{"sort_type"=>"compound", "tablename"=>"users"}, {"sort_type"=>"interleaved", "tablename"=>"posts"}])
|
|
31
|
+
end
|
|
32
|
+
context "using :all" do
|
|
33
|
+
let(:vacuum) { RailsRedshiftReplicator::Tools::Vacuum.new(:all) }
|
|
34
|
+
it "performs vacuum on all tables" do
|
|
35
|
+
expect(vacuum).to receive(:exec_vacuum_command).with("users", "compound")
|
|
36
|
+
expect(vacuum).to receive(:exec_vacuum_command).with("posts", "interleaved")
|
|
37
|
+
vacuum.auto_tuned_vacuum(:all)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
context "with a given table" do
|
|
41
|
+
let(:vacuum) { RailsRedshiftReplicator::Tools::Vacuum.new(:users) }
|
|
42
|
+
it "performs vacuum on the given table" do
|
|
43
|
+
expect(vacuum).to receive(:exec_vacuum_command).with("users", "compound")
|
|
44
|
+
expect(vacuum).not_to receive(:exec_vacuum_command).with("posts", "interleaved")
|
|
45
|
+
vacuum.auto_tuned_vacuum("users")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "exec_vacuum_command" do
|
|
51
|
+
let(:vacuum) { RailsRedshiftReplicator::Tools::Vacuum.new(:all) }
|
|
52
|
+
context "with a compound key table" do
|
|
53
|
+
it "builds the command" do
|
|
54
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with("VACUUM FULL users;")
|
|
55
|
+
vacuum.exec_vacuum_command("users", "compound")
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
context "with an interleaved key table" do
|
|
59
|
+
it "builds the command" do
|
|
60
|
+
expect(RailsRedshiftReplicator.connection).to receive(:exec).with("VACUUM REINDEX posts;")
|
|
61
|
+
vacuum.exec_vacuum_command("posts", "interleaved")
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RailsRedshiftReplicator do
|
|
4
|
+
describe "Config" do
|
|
5
|
+
%w(redshift_connection_params aws_credentials s3_bucket_params redshift_slices local_replication_path debug_mode history_cap).each do |param|
|
|
6
|
+
it "responde para configuração #{param}" do
|
|
7
|
+
expect(RailsRedshiftReplicator).to respond_to param
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '.add_replicable', broken: true do
|
|
13
|
+
let(:replicable) { RailsRedshiftReplicator::Replicable.new(:identity_replicator, source_table: :users) }
|
|
14
|
+
around do |example|
|
|
15
|
+
old = RailsRedshiftReplicator.replicables
|
|
16
|
+
RailsRedshiftReplicator.replicables = {}
|
|
17
|
+
example.run
|
|
18
|
+
RailsRedshiftReplicator.replicables = old
|
|
19
|
+
end
|
|
20
|
+
it 'keeps a list of replicable tables' do
|
|
21
|
+
RailsRedshiftReplicator.add_replicable({ users: replicable })
|
|
22
|
+
expect(RailsRedshiftReplicator.replicables.keys).to contain_exactly(:users)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe ".connection" do
|
|
27
|
+
it "retorna uma conexão para o redshift" do
|
|
28
|
+
expect(RailsRedshiftReplicator.connection).to be_instance_of PG::Connection
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe '#tables_to_perform' do
|
|
33
|
+
context 'when exporting all tables' do
|
|
34
|
+
before { RailsRedshiftReplicator.add_replicable(tags_users: RailsRedshiftReplicator::Replicable.new(:full_replicator, source_table: :tags_users)) }
|
|
35
|
+
it 'returns all tables' do
|
|
36
|
+
expect(RailsRedshiftReplicator.tables_to_perform(:all)).to contain_exactly('users', 'posts', 'tags', 'tags_users')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
context 'when exporting selected tables' do
|
|
40
|
+
context 'and all given tables are replicable' do
|
|
41
|
+
it 'returns all given tables' do
|
|
42
|
+
expect(RailsRedshiftReplicator.tables_to_perform([:users, :posts])).to contain_exactly('users', 'posts')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
context 'and some given tables are not replicable' do
|
|
46
|
+
it 'returns only the tables that are eligible for replication' do
|
|
47
|
+
expect(RailsRedshiftReplicator.tables_to_perform([:users, :posts, :nonrep])).to contain_exactly('users','posts')
|
|
48
|
+
end
|
|
49
|
+
it 'warns about unreplicable' do
|
|
50
|
+
expect(RailsRedshiftReplicator).to receive(:warn_if_unreplicable).with(['nonrep'])
|
|
51
|
+
RailsRedshiftReplicator.tables_to_perform([:users, :posts, :nonrep])
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
describe '#check_args' do
|
|
57
|
+
context 'when no tables were given' do
|
|
58
|
+
it 'raises error' do
|
|
59
|
+
expect{ RailsRedshiftReplicator.check_args([]) }.to raise_error(StandardError)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
context 'when tables were given' do
|
|
63
|
+
it 'returns nil' do
|
|
64
|
+
expect(RailsRedshiftReplicator.check_args([:users])).to be_nil
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe '.debug_mode=' do
|
|
70
|
+
context 'enabling debug_mode' do
|
|
71
|
+
before { RailsRedshiftReplicator.debug_mode = false }
|
|
72
|
+
it 'changes logger level to debug' do
|
|
73
|
+
expect { RailsRedshiftReplicator.setup {|config| config.debug_mode = true} }.to change(RailsRedshiftReplicator.logger, :level).to(Logger::DEBUG)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
context 'disabling debug_mode' do
|
|
77
|
+
before { RailsRedshiftReplicator.debug_mode = true }
|
|
78
|
+
it 'changes logger level to error' do
|
|
79
|
+
expect { RailsRedshiftReplicator.setup {|config| config.debug_mode = false} }.to change(RailsRedshiftReplicator.logger, :level).to(Logger::WARN)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
describe '.history_cap=', :focus do
|
|
84
|
+
context 'when nil' do
|
|
85
|
+
it 'assigns nil' do
|
|
86
|
+
RailsRedshiftReplicator.history_cap = nil
|
|
87
|
+
expect(RailsRedshiftReplicator.history_cap).to be_nil
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
context 'when 2' do
|
|
91
|
+
it 'assigns 2' do
|
|
92
|
+
RailsRedshiftReplicator.history_cap = 2
|
|
93
|
+
expect(RailsRedshiftReplicator.history_cap).to eq 2
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
context 'when > 2' do
|
|
97
|
+
it 'assigns given cap' do
|
|
98
|
+
RailsRedshiftReplicator.history_cap = 5
|
|
99
|
+
expect(RailsRedshiftReplicator.history_cap).to eq 5
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
context 'when < 2' do
|
|
103
|
+
it 'assigns 2' do
|
|
104
|
+
RailsRedshiftReplicator.history_cap = 1
|
|
105
|
+
expect(RailsRedshiftReplicator.history_cap).to eq 2
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe RailsRedshiftReplicator::Replication, type: :model do
|
|
5
|
+
|
|
6
|
+
it { is_expected.to validate_presence_of(:replication_type) }
|
|
7
|
+
it { is_expected.to validate_presence_of(:key) }
|
|
8
|
+
it { is_expected.to validate_presence_of(:source_table) }
|
|
9
|
+
it { is_expected.to validate_presence_of(:target_table) }
|
|
10
|
+
it { is_expected.to validate_inclusion_of(:state).in_array RailsRedshiftReplicator::Replication::STATES }
|
|
11
|
+
it { is_expected.to validate_inclusion_of(:export_format).in_array RailsRedshiftReplicator::Replication::FORMATS }
|
|
12
|
+
|
|
13
|
+
let(:redshift_replication) { build :redshift_replication }
|
|
14
|
+
describe "Format helper methods" do
|
|
15
|
+
RailsRedshiftReplicator::Replication::FORMATS.each do |format|
|
|
16
|
+
it "responds to ##{format}?" do
|
|
17
|
+
expect(redshift_replication).to respond_to "#{format}?"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
describe '.cap_id' do
|
|
22
|
+
context 'when there are more replications than cap number' do
|
|
23
|
+
it 'returns the id of the replication based on the cap number' do
|
|
24
|
+
2.times { create :redshift_replication, source_table: 'users' }
|
|
25
|
+
rep = create :redshift_replication, source_table: 'users'
|
|
26
|
+
3.times { create :redshift_replication, source_table: 'users' }
|
|
27
|
+
expect(RailsRedshiftReplicator::Replication.cap_id('users', 4)).to eq rep.id
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
context 'when there are no replications' do
|
|
31
|
+
it 'returns nil' do
|
|
32
|
+
expect(RailsRedshiftReplicator::Replication.cap_id('users', 4)).to be_nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
context 'when there are less replications then the cap number' do
|
|
36
|
+
it 'retuns nil' do
|
|
37
|
+
3.times { create :redshift_replication, source_table: 'users' }
|
|
38
|
+
expect(RailsRedshiftReplicator::Replication.cap_id('users', 4)).to be_nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
describe "State helper methods" do
|
|
43
|
+
RailsRedshiftReplicator::Replication::STATES.each do |state|
|
|
44
|
+
it "responds to ##{state}?" do
|
|
45
|
+
expect(redshift_replication).to respond_to "#{state}?"
|
|
46
|
+
end
|
|
47
|
+
it "responds to ##{state}!" do
|
|
48
|
+
expect(redshift_replication).to respond_to "#{state}!"
|
|
49
|
+
end
|
|
50
|
+
it "responds to scope .#{state}" do
|
|
51
|
+
expect(RailsRedshiftReplicator::Replication).to respond_to state
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
describe "format #csv?" do
|
|
56
|
+
let(:redshift_replication) { build :redshift_replication, export_format: "csv" }
|
|
57
|
+
context "when format matches" do
|
|
58
|
+
it "returns true" do
|
|
59
|
+
expect(redshift_replication.csv?).to be true
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
context "when format does not match" do
|
|
63
|
+
it "returns false" do
|
|
64
|
+
expect(redshift_replication.gzip?).to be false
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
describe "state #uploading" do
|
|
69
|
+
let(:redshift_replication) { build :redshift_replication, state: "uploading" }
|
|
70
|
+
context "when state matches" do
|
|
71
|
+
it "returns true" do
|
|
72
|
+
expect(redshift_replication.uploading?).to be true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
context "when state does not match" do
|
|
76
|
+
it "returns false" do
|
|
77
|
+
expect(redshift_replication.exporting?).to be false
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
describe "state #exported!" do
|
|
82
|
+
let(:redshift_replication) { create(:redshift_replication, state: 'enqueued') }
|
|
83
|
+
it "changes stage to :exporting" do
|
|
84
|
+
redshift_replication.exported!
|
|
85
|
+
expect(redshift_replication.state).to eq 'exported'
|
|
86
|
+
end
|
|
87
|
+
it "updates aditional fields" do
|
|
88
|
+
redshift_replication.exported!(export_duration: 10)
|
|
89
|
+
expect(redshift_replication.export_duration).to eq 10
|
|
90
|
+
end
|
|
91
|
+
it "returns update time" do
|
|
92
|
+
allow(Time).to receive(:now).and_return(Time.new(2016,1,1))
|
|
93
|
+
now = Time.now
|
|
94
|
+
expect(redshift_replication.exported!).to eq(now)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
describe "scope .exporting" do
|
|
98
|
+
let!(:rep1) { create(:redshift_replication, state: 'enqueued') }
|
|
99
|
+
let!(:rep2) { create(:redshift_replication, state: 'exporting') }
|
|
100
|
+
it "returns replications in :exporting state" do
|
|
101
|
+
expect(RailsRedshiftReplicator::Replication.exporting.to_a).to eq [rep2]
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
|
2
|
+
|
|
3
|
+
require 'dotenv'
|
|
4
|
+
Dotenv.load File.expand_path("../dummy/.env", __FILE__)
|
|
5
|
+
|
|
6
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
|
7
|
+
|
|
8
|
+
require 'rspec/rails'
|
|
9
|
+
require 'rspec/autorun'
|
|
10
|
+
require 'factory_girl_rails'
|
|
11
|
+
require 'shoulda-matchers'
|
|
12
|
+
require 'climate_control'
|
|
13
|
+
require 'pry-byebug'
|
|
14
|
+
require 'timecop'
|
|
15
|
+
|
|
16
|
+
Rails.backtrace_cleaner.remove_silencers!
|
|
17
|
+
|
|
18
|
+
# Load support files
|
|
19
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
20
|
+
|
|
21
|
+
RSpec.configure do |config|
|
|
22
|
+
config.mock_with :rspec
|
|
23
|
+
config.use_transactional_fixtures = true
|
|
24
|
+
config.infer_base_class_for_anonymous_controllers = false
|
|
25
|
+
config.order = "random"
|
|
26
|
+
config.filter_run_excluding :broken => true
|
|
27
|
+
config.include FactoryGirl::Syntax::Methods
|
|
28
|
+
config.include RailsRedshiftReplicatorHelpers
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Shoulda::Matchers.configure do |config|
|
|
32
|
+
config.integrate do |with|
|
|
33
|
+
with.test_framework :rspec
|
|
34
|
+
with.library :rails
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1,2
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module RailsRedshiftReplicatorHelpers
|
|
2
|
+
def with_modified_env(options = {}, &block)
|
|
3
|
+
env = { REDSHIFT_HOST: '1',
|
|
4
|
+
REDSHIFT_DATABASE: '2',
|
|
5
|
+
REDSHIFT_PORT: '3',
|
|
6
|
+
REDSHIFT_USER: '4',
|
|
7
|
+
REDSHIFT_PASSWORD: '5',
|
|
8
|
+
REDSHIFT_SLICES: '6',
|
|
9
|
+
AWS_ACCESS_KEY_ID: '7',
|
|
10
|
+
AWS_SECRET_ACCESS_KEY: '8',
|
|
11
|
+
RDP_REPLICATION_REGION: '9',
|
|
12
|
+
LOCAL_REPLICATION_PATH: '10',
|
|
13
|
+
RDP_ANALYTICS_BUCKET: '11'}.merge(options)
|
|
14
|
+
ClimateControl.modify(env, &block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def replication_file(name)
|
|
18
|
+
File.open("spec/support/csv/#{name}")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Changes ActiveRecord connection to Redshift for the duration of the example
|
|
22
|
+
# and restablishes connection to the original database right afterwards.
|
|
23
|
+
def with_engine_connection
|
|
24
|
+
original = ActiveRecord::Base.remove_connection
|
|
25
|
+
ActiveRecord::Base.establish_connection(
|
|
26
|
+
adapter: "redshift",
|
|
27
|
+
host: RailsRedshiftReplicator.redshift_connection_params[:host],
|
|
28
|
+
database: RailsRedshiftReplicator.redshift_connection_params[:dbname],
|
|
29
|
+
port: RailsRedshiftReplicator.redshift_connection_params[:port],
|
|
30
|
+
username: RailsRedshiftReplicator.redshift_connection_params[:user],
|
|
31
|
+
password: RailsRedshiftReplicator.redshift_connection_params[:password])
|
|
32
|
+
yield
|
|
33
|
+
ensure
|
|
34
|
+
ActiveRecord::Base.establish_connection(original)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Recreates the test users table on redshift
|
|
38
|
+
def recreate_users_table(custom_table_name = nil)
|
|
39
|
+
table_name = custom_table_name || :users
|
|
40
|
+
with_engine_connection do
|
|
41
|
+
ActiveRecord::Migration.create_table table_name, force: true do |t|
|
|
42
|
+
t.string :login
|
|
43
|
+
t.integer :age
|
|
44
|
+
t.boolean :confirmed
|
|
45
|
+
t.timestamps
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Recreates the posts users table on redshift
|
|
51
|
+
def recreate_posts_table(custom_table_name = nil)
|
|
52
|
+
table_name = custom_table_name || :posts
|
|
53
|
+
with_engine_connection do
|
|
54
|
+
ActiveRecord::Migration.create_table table_name, force: true do |t|
|
|
55
|
+
t.belongs_to :user
|
|
56
|
+
t.text :content
|
|
57
|
+
t.timestamps
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Recreates the test tags table on redshift
|
|
63
|
+
def recreate_tags_table(custom_table_name = nil)
|
|
64
|
+
table_name = custom_table_name || :tags
|
|
65
|
+
with_engine_connection do
|
|
66
|
+
ActiveRecord::Migration.create_table table_name, force: true do |t|
|
|
67
|
+
t.string :name
|
|
68
|
+
t.timestamps
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Recreates the test tags table on redshift
|
|
74
|
+
def recreate_tags_users_table(custom_table_name = nil)
|
|
75
|
+
table_name = custom_table_name || :tags_users
|
|
76
|
+
with_engine_connection do
|
|
77
|
+
ActiveRecord::Migration.create_table table_name, id: false, force: true do |t|
|
|
78
|
+
t.integer :user_id
|
|
79
|
+
t.integer :tag_id
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Drops a given test table on redshift
|
|
85
|
+
# @param table [String,Symbol] test table's name
|
|
86
|
+
def drop_redshift_table(table)
|
|
87
|
+
with_engine_connection do
|
|
88
|
+
begin
|
|
89
|
+
ActiveRecord::Migration.drop_table table.to_s
|
|
90
|
+
rescue => e
|
|
91
|
+
puts "Coudn't drop table #{table}: #{e.message}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|