backup_checksum 3.0.23
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.
- data/.gitignore +7 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +130 -0
- data/Guardfile +21 -0
- data/LICENSE.md +24 -0
- data/README.md +476 -0
- data/backup_checksum.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +217 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/checksum/base.rb +44 -0
- data/lib/backup/checksum/shasum.rb +16 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +88 -0
- data/lib/backup/cli/utility.rb +247 -0
- data/lib/backup/compressor/base.rb +29 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/gzip.rb +47 -0
- data/lib/backup/compressor/lzma.rb +50 -0
- data/lib/backup/compressor/pbzip2.rb +56 -0
- data/lib/backup/config.rb +173 -0
- data/lib/backup/configuration/base.rb +15 -0
- data/lib/backup/configuration/checksum/base.rb +9 -0
- data/lib/backup/configuration/checksum/shasum.rb +9 -0
- data/lib/backup/configuration/compressor/base.rb +9 -0
- data/lib/backup/configuration/compressor/bzip2.rb +23 -0
- data/lib/backup/configuration/compressor/gzip.rb +23 -0
- data/lib/backup/configuration/compressor/lzma.rb +23 -0
- data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
- data/lib/backup/configuration/database/base.rb +19 -0
- data/lib/backup/configuration/database/mongodb.rb +49 -0
- data/lib/backup/configuration/database/mysql.rb +42 -0
- data/lib/backup/configuration/database/postgresql.rb +41 -0
- data/lib/backup/configuration/database/redis.rb +39 -0
- data/lib/backup/configuration/database/riak.rb +29 -0
- data/lib/backup/configuration/encryptor/base.rb +9 -0
- data/lib/backup/configuration/encryptor/gpg.rb +17 -0
- data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
- data/lib/backup/configuration/helpers.rb +52 -0
- data/lib/backup/configuration/notifier/base.rb +28 -0
- data/lib/backup/configuration/notifier/campfire.rb +25 -0
- data/lib/backup/configuration/notifier/hipchat.rb +41 -0
- data/lib/backup/configuration/notifier/mail.rb +112 -0
- data/lib/backup/configuration/notifier/presently.rb +25 -0
- data/lib/backup/configuration/notifier/prowl.rb +23 -0
- data/lib/backup/configuration/notifier/twitter.rb +21 -0
- data/lib/backup/configuration/storage/base.rb +18 -0
- data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
- data/lib/backup/configuration/storage/dropbox.rb +58 -0
- data/lib/backup/configuration/storage/ftp.rb +29 -0
- data/lib/backup/configuration/storage/local.rb +17 -0
- data/lib/backup/configuration/storage/ninefold.rb +20 -0
- data/lib/backup/configuration/storage/rsync.rb +29 -0
- data/lib/backup/configuration/storage/s3.rb +25 -0
- data/lib/backup/configuration/storage/scp.rb +25 -0
- data/lib/backup/configuration/storage/sftp.rb +25 -0
- data/lib/backup/configuration/syncer/base.rb +10 -0
- data/lib/backup/configuration/syncer/cloud.rb +23 -0
- data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
- data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
- data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
- data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
- data/lib/backup/configuration/syncer/s3.rb +23 -0
- data/lib/backup/database/base.rb +59 -0
- data/lib/backup/database/mongodb.rb +232 -0
- data/lib/backup/database/mysql.rb +163 -0
- data/lib/backup/database/postgresql.rb +146 -0
- data/lib/backup/database/redis.rb +139 -0
- data/lib/backup/database/riak.rb +69 -0
- data/lib/backup/dependency.rb +114 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +80 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +386 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +168 -0
- data/lib/backup/notifier/hipchat.rb +99 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/presently.rb +88 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +51 -0
- data/lib/backup/packager.rb +108 -0
- data/lib/backup/pipeline.rb +107 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +119 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +181 -0
- data/lib/backup/storage/ftp.rb +119 -0
- data/lib/backup/storage/local.rb +82 -0
- data/lib/backup/storage/ninefold.rb +116 -0
- data/lib/backup/storage/rsync.rb +149 -0
- data/lib/backup/storage/s3.rb +94 -0
- data/lib/backup/storage/scp.rb +99 -0
- data/lib/backup/storage/sftp.rb +108 -0
- data/lib/backup/syncer/base.rb +42 -0
- data/lib/backup/syncer/cloud.rb +190 -0
- data/lib/backup/syncer/cloud_files.rb +56 -0
- data/lib/backup/syncer/rsync/base.rb +52 -0
- data/lib/backup/syncer/rsync/local.rb +53 -0
- data/lib/backup/syncer/rsync/pull.rb +38 -0
- data/lib/backup/syncer/rsync/push.rb +113 -0
- data/lib/backup/syncer/s3.rb +47 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +176 -0
- data/spec/cli/utility_spec.rb +363 -0
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +83 -0
- data/spec/compressor/gzip_spec.rb +83 -0
- data/spec/compressor/lzma_spec.rb +83 -0
- data/spec/compressor/pbzip2_spec.rb +124 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +35 -0
- data/spec/configuration/compressor/bzip2_spec.rb +29 -0
- data/spec/configuration/compressor/gzip_spec.rb +29 -0
- data/spec/configuration/compressor/lzma_spec.rb +29 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +17 -0
- data/spec/configuration/database/mongodb_spec.rb +56 -0
- data/spec/configuration/database/mysql_spec.rb +53 -0
- data/spec/configuration/database/postgresql_spec.rb +53 -0
- data/spec/configuration/database/redis_spec.rb +50 -0
- data/spec/configuration/database/riak_spec.rb +35 -0
- data/spec/configuration/encryptor/gpg_spec.rb +26 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +32 -0
- data/spec/configuration/notifier/hipchat_spec.rb +44 -0
- data/spec/configuration/notifier/mail_spec.rb +71 -0
- data/spec/configuration/notifier/presently_spec.rb +35 -0
- data/spec/configuration/notifier/prowl_spec.rb +29 -0
- data/spec/configuration/notifier/twitter_spec.rb +35 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
- data/spec/configuration/storage/dropbox_spec.rb +38 -0
- data/spec/configuration/storage/ftp_spec.rb +44 -0
- data/spec/configuration/storage/local_spec.rb +29 -0
- data/spec/configuration/storage/ninefold_spec.rb +32 -0
- data/spec/configuration/storage/rsync_spec.rb +41 -0
- data/spec/configuration/storage/s3_spec.rb +38 -0
- data/spec/configuration/storage/scp_spec.rb +41 -0
- data/spec/configuration/storage/sftp_spec.rb +41 -0
- data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
- data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
- data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
- data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
- data/spec/configuration/syncer/s3_spec.rb +38 -0
- data/spec/database/base_spec.rb +54 -0
- data/spec/database/mongodb_spec.rb +428 -0
- data/spec/database/mysql_spec.rb +335 -0
- data/spec/database/postgresql_spec.rb +278 -0
- data/spec/database/redis_spec.rb +260 -0
- data/spec/database/riak_spec.rb +108 -0
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +134 -0
- data/spec/encryptor/open_ssl_spec.rb +129 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/logger_spec.rb +363 -0
- data/spec/model_spec.rb +649 -0
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +199 -0
- data/spec/notifier/hipchat_spec.rb +188 -0
- data/spec/notifier/mail_spec.rb +280 -0
- data/spec/notifier/presently_spec.rb +181 -0
- data/spec/notifier/prowl_spec.rb +117 -0
- data/spec/notifier/twitter_spec.rb +132 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +225 -0
- data/spec/pipeline_spec.rb +257 -0
- data/spec/spec_helper.rb +59 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +160 -0
- data/spec/storage/cloudfiles_spec.rb +230 -0
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +370 -0
- data/spec/storage/ftp_spec.rb +247 -0
- data/spec/storage/local_spec.rb +235 -0
- data/spec/storage/ninefold_spec.rb +319 -0
- data/spec/storage/rsync_spec.rb +345 -0
- data/spec/storage/s3_spec.rb +221 -0
- data/spec/storage/scp_spec.rb +209 -0
- data/spec/storage/sftp_spec.rb +220 -0
- data/spec/syncer/base_spec.rb +22 -0
- data/spec/syncer/cloud_files_spec.rb +192 -0
- data/spec/syncer/rsync/base_spec.rb +118 -0
- data/spec/syncer/rsync/local_spec.rb +121 -0
- data/spec/syncer/rsync/pull_spec.rb +90 -0
- data/spec/syncer/rsync/push_spec.rb +327 -0
- data/spec/syncer/s3_spec.rb +192 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +7 -0
- data/templates/cli/utility/compressor/gzip +7 -0
- data/templates/cli/utility/compressor/lzma +7 -0
- data/templates/cli/utility/compressor/pbzip2 +7 -0
- data/templates/cli/utility/config +31 -0
- data/templates/cli/utility/database/mongodb +18 -0
- data/templates/cli/utility/database/mysql +21 -0
- data/templates/cli/utility/database/postgresql +17 -0
- data/templates/cli/utility/database/redis +16 -0
- data/templates/cli/utility/database/riak +11 -0
- data/templates/cli/utility/encryptor/gpg +12 -0
- data/templates/cli/utility/encryptor/openssl +9 -0
- data/templates/cli/utility/model.erb +23 -0
- data/templates/cli/utility/notifier/campfire +12 -0
- data/templates/cli/utility/notifier/hipchat +15 -0
- data/templates/cli/utility/notifier/mail +22 -0
- data/templates/cli/utility/notifier/presently +13 -0
- data/templates/cli/utility/notifier/prowl +11 -0
- data/templates/cli/utility/notifier/twitter +13 -0
- data/templates/cli/utility/splitter +7 -0
- data/templates/cli/utility/storage/cloud_files +22 -0
- data/templates/cli/utility/storage/dropbox +20 -0
- data/templates/cli/utility/storage/ftp +12 -0
- data/templates/cli/utility/storage/local +7 -0
- data/templates/cli/utility/storage/ninefold +9 -0
- data/templates/cli/utility/storage/rsync +11 -0
- data/templates/cli/utility/storage/s3 +19 -0
- data/templates/cli/utility/storage/scp +11 -0
- data/templates/cli/utility/storage/sftp +11 -0
- data/templates/cli/utility/syncer/cloud_files +48 -0
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/rsync_pull +17 -0
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/cli/utility/syncer/s3 +45 -0
- data/templates/general/links +11 -0
- data/templates/general/version.erb +2 -0
- data/templates/notifier/mail/failure.erb +9 -0
- data/templates/notifier/mail/success.erb +7 -0
- data/templates/notifier/mail/warning.erb +9 -0
- data/templates/storage/dropbox/authorization_url.erb +6 -0
- data/templates/storage/dropbox/authorized.erb +4 -0
- data/templates/storage/dropbox/cache_file_written.erb +10 -0
- metadata +311 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Database::PostgreSQL do
|
|
6
|
+
let(:model) { Backup::Model.new('foo', 'foo') }
|
|
7
|
+
let(:db) do
|
|
8
|
+
Backup::Database::PostgreSQL.new(model) do |db|
|
|
9
|
+
db.name = 'mydatabase'
|
|
10
|
+
db.username = 'someuser'
|
|
11
|
+
db.password = 'secret'
|
|
12
|
+
db.host = 'localhost'
|
|
13
|
+
db.port = '123'
|
|
14
|
+
db.socket = '/pgsql.sock'
|
|
15
|
+
|
|
16
|
+
db.skip_tables = ['logs', 'profiles']
|
|
17
|
+
db.only_tables = ['users', 'pirates']
|
|
18
|
+
db.additional_options = ['--single-transaction', '--quick']
|
|
19
|
+
db.pg_dump_utility = '/path/to/pg_dump'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe '#initialize' do
|
|
24
|
+
it 'should read the adapter details correctly' do
|
|
25
|
+
db.name.should == 'mydatabase'
|
|
26
|
+
db.username.should == 'someuser'
|
|
27
|
+
db.password.should == 'secret'
|
|
28
|
+
db.host.should == 'localhost'
|
|
29
|
+
db.port.should == '123'
|
|
30
|
+
db.socket.should == '/pgsql.sock'
|
|
31
|
+
|
|
32
|
+
db.skip_tables.should == ['logs', 'profiles']
|
|
33
|
+
db.only_tables.should == ['users', 'pirates']
|
|
34
|
+
db.additional_options.should == ['--single-transaction', '--quick']
|
|
35
|
+
db.pg_dump_utility.should == '/path/to/pg_dump'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'when options are not set' do
|
|
39
|
+
before do
|
|
40
|
+
Backup::Database::PostgreSQL.any_instance.expects(:utility).
|
|
41
|
+
with(:pg_dump).returns('/real/pg_dump')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'should use default values' do
|
|
45
|
+
db = Backup::Database::PostgreSQL.new(model)
|
|
46
|
+
|
|
47
|
+
db.name.should be_nil
|
|
48
|
+
db.username.should be_nil
|
|
49
|
+
db.password.should be_nil
|
|
50
|
+
db.host.should be_nil
|
|
51
|
+
db.port.should be_nil
|
|
52
|
+
db.socket.should be_nil
|
|
53
|
+
|
|
54
|
+
db.skip_tables.should == []
|
|
55
|
+
db.only_tables.should == []
|
|
56
|
+
db.additional_options.should == []
|
|
57
|
+
db.pg_dump_utility.should == '/real/pg_dump'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context 'when configuration defaults have been set' do
|
|
62
|
+
after { Backup::Configuration::Database::PostgreSQL.clear_defaults! }
|
|
63
|
+
|
|
64
|
+
it 'should use configuration defaults' do
|
|
65
|
+
Backup::Configuration::Database::PostgreSQL.defaults do |db|
|
|
66
|
+
db.name = 'db_name'
|
|
67
|
+
db.username = 'db_username'
|
|
68
|
+
db.password = 'db_password'
|
|
69
|
+
db.host = 'db_host'
|
|
70
|
+
db.port = 789
|
|
71
|
+
db.socket = '/foo.sock'
|
|
72
|
+
|
|
73
|
+
db.skip_tables = ['skip', 'tables']
|
|
74
|
+
db.only_tables = ['only', 'tables']
|
|
75
|
+
db.additional_options = ['--add', '--opts']
|
|
76
|
+
db.pg_dump_utility = '/default/path/to/pg_dump'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
db = Backup::Database::PostgreSQL.new(model)
|
|
80
|
+
db.name.should == 'db_name'
|
|
81
|
+
db.username.should == 'db_username'
|
|
82
|
+
db.password.should == 'db_password'
|
|
83
|
+
db.host.should == 'db_host'
|
|
84
|
+
db.port.should == 789
|
|
85
|
+
db.socket.should == '/foo.sock'
|
|
86
|
+
|
|
87
|
+
db.skip_tables.should == ['skip', 'tables']
|
|
88
|
+
db.only_tables.should == ['only', 'tables']
|
|
89
|
+
db.additional_options.should == ['--add', '--opts']
|
|
90
|
+
db.pg_dump_utility.should == '/default/path/to/pg_dump'
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end # describe '#initialize'
|
|
94
|
+
|
|
95
|
+
describe '#perform!' do
|
|
96
|
+
let(:s) { sequence '' }
|
|
97
|
+
let(:pipeline) { mock }
|
|
98
|
+
|
|
99
|
+
before do
|
|
100
|
+
# superclass actions
|
|
101
|
+
db.expects(:prepare!).in_sequence(s)
|
|
102
|
+
db.expects(:log!).in_sequence(s)
|
|
103
|
+
db.instance_variable_set(:@dump_path, '/dump/path')
|
|
104
|
+
|
|
105
|
+
db.stubs(:pgdump).returns('pgdump_command')
|
|
106
|
+
Backup::Pipeline.expects(:new).returns(pipeline)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context 'when no compressor is configured' do
|
|
110
|
+
before do
|
|
111
|
+
model.expects(:compressor).returns(nil)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'should run pgdump without compression' do
|
|
115
|
+
pipeline.expects(:<<).in_sequence(s).with('pgdump_command')
|
|
116
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
117
|
+
"cat > '/dump/path/mydatabase.sql'"
|
|
118
|
+
)
|
|
119
|
+
pipeline.expects(:run).in_sequence(s)
|
|
120
|
+
pipeline.expects(:success?).in_sequence(s).returns(true)
|
|
121
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
122
|
+
'Database::PostgreSQL Complete!'
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
db.perform!
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context 'when a compressor is configured' do
|
|
130
|
+
before do
|
|
131
|
+
compressor = mock
|
|
132
|
+
model.expects(:compressor).twice.returns(compressor)
|
|
133
|
+
compressor.expects(:compress_with).yields('gzip', '.gz')
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'should run pgdump with compression' do
|
|
137
|
+
pipeline.expects(:<<).in_sequence(s).with('pgdump_command')
|
|
138
|
+
pipeline.expects(:<<).in_sequence(s).with('gzip')
|
|
139
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
140
|
+
"cat > '/dump/path/mydatabase.sql.gz'"
|
|
141
|
+
)
|
|
142
|
+
pipeline.expects(:run).in_sequence(s)
|
|
143
|
+
pipeline.expects(:success?).in_sequence(s).returns(true)
|
|
144
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
145
|
+
'Database::PostgreSQL Complete!'
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
db.perform!
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context 'when pipeline command fails' do
|
|
153
|
+
before do
|
|
154
|
+
model.expects(:compressor).returns(nil)
|
|
155
|
+
pipeline.stubs(:<<)
|
|
156
|
+
pipeline.expects(:run)
|
|
157
|
+
pipeline.expects(:success?).returns(false)
|
|
158
|
+
pipeline.expects(:error_messages).returns('pipeline_errors')
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should raise an error' do
|
|
162
|
+
expect do
|
|
163
|
+
db.perform!
|
|
164
|
+
end.to raise_error(
|
|
165
|
+
Backup::Errors::Database::PipelineError,
|
|
166
|
+
"Database::PipelineError: Database::PostgreSQL Dump Failed!\n" +
|
|
167
|
+
" pipeline_errors"
|
|
168
|
+
)
|
|
169
|
+
end
|
|
170
|
+
end # context 'when pipeline command fails'
|
|
171
|
+
|
|
172
|
+
end # describe '#perform!'
|
|
173
|
+
|
|
174
|
+
describe '#pgdump' do
|
|
175
|
+
it 'should return the pgdump command string' do
|
|
176
|
+
db.send(:pgdump).should ==
|
|
177
|
+
"PGPASSWORD='secret' /path/to/pg_dump --username='someuser' " +
|
|
178
|
+
"--host='localhost' --port='123' --host='/pgsql.sock' " +
|
|
179
|
+
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
180
|
+
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
context 'without a password' do
|
|
184
|
+
before { db.password = nil }
|
|
185
|
+
it 'should not leave a preceeding space' do
|
|
186
|
+
db.send(:pgdump).should ==
|
|
187
|
+
"/path/to/pg_dump --username='someuser' " +
|
|
188
|
+
"--host='localhost' --port='123' --host='/pgsql.sock' " +
|
|
189
|
+
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
190
|
+
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe '#password_options' do
|
|
196
|
+
it 'returns the environment variable set for the password' do
|
|
197
|
+
db.send(:password_options).should == "PGPASSWORD='secret' "
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
context 'when password is not set' do
|
|
201
|
+
before { db.password = nil }
|
|
202
|
+
it 'should return an empty string' do
|
|
203
|
+
db.send(:password_options).should == ''
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe '#username_options' do
|
|
209
|
+
it 'should return the postgresql syntax for the username options' do
|
|
210
|
+
db.send(:username_options).should == "--username='someuser'"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context 'when username is not set' do
|
|
214
|
+
before { db.username = nil }
|
|
215
|
+
it 'should return an empty string' do
|
|
216
|
+
db.send(:username_options).should == ''
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
describe '#connectivity_options' do
|
|
222
|
+
it 'should return the postgresql syntax for the connectivity options' do
|
|
223
|
+
db.send(:connectivity_options).should ==
|
|
224
|
+
"--host='localhost' --port='123' --host='/pgsql.sock'"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
context 'when only the socket is set' do
|
|
228
|
+
before do
|
|
229
|
+
db.host = ''
|
|
230
|
+
db.port = nil
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it 'should return only the socket' do
|
|
234
|
+
db.send(:connectivity_options).should == "--host='/pgsql.sock'"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
describe '#user_options' do
|
|
240
|
+
it 'should return a string of additional options specified by the user' do
|
|
241
|
+
db.send(:user_options).should == '--single-transaction --quick'
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context 'when #additional_options is not set' do
|
|
245
|
+
before { db.additional_options = [] }
|
|
246
|
+
it 'should return an empty string' do
|
|
247
|
+
db.send(:user_options).should == ''
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
describe '#tables_to_dump' do
|
|
253
|
+
it 'should return a string for the pg_dump selected table to dump option' do
|
|
254
|
+
db.send(:tables_to_dump).should == "--table='users' --table='pirates'"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
context 'when #only_tables is not set' do
|
|
258
|
+
before { db.only_tables = [] }
|
|
259
|
+
it 'should return an empty string' do
|
|
260
|
+
db.send(:tables_to_dump).should == ''
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
describe '#tables_to_skip' do
|
|
266
|
+
it 'should return a string for the pg_dump --ignore-tables option' do
|
|
267
|
+
db.send(:tables_to_skip).should == "--exclude-table='logs' --exclude-table='profiles'"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context 'when #skip_tables is not set' do
|
|
271
|
+
before { db.skip_tables = [] }
|
|
272
|
+
it 'should return an empty string' do
|
|
273
|
+
db.send(:tables_to_skip).should == ''
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
end
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Database::Redis do
|
|
6
|
+
let(:model) { Backup::Model.new('foo', 'foo') }
|
|
7
|
+
let(:db) do
|
|
8
|
+
Backup::Database::Redis.new(model) do |db|
|
|
9
|
+
db.name = 'mydatabase'
|
|
10
|
+
db.path = '/var/lib/redis/db/'
|
|
11
|
+
db.password = 'secret'
|
|
12
|
+
db.host = 'localhost'
|
|
13
|
+
db.port = '123'
|
|
14
|
+
db.socket = '/redis.sock'
|
|
15
|
+
db.invoke_save = true
|
|
16
|
+
|
|
17
|
+
db.additional_options = ['--query', '--foo']
|
|
18
|
+
db.redis_cli_utility = '/path/to/redis-cli'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#initialize' do
|
|
23
|
+
it 'should read the adapter details correctly' do
|
|
24
|
+
db.name.should == 'mydatabase'
|
|
25
|
+
db.path.should == '/var/lib/redis/db/'
|
|
26
|
+
db.password.should == 'secret'
|
|
27
|
+
db.host.should == 'localhost'
|
|
28
|
+
db.port.should == '123'
|
|
29
|
+
db.socket.should == '/redis.sock'
|
|
30
|
+
db.invoke_save.should == true
|
|
31
|
+
|
|
32
|
+
db.additional_options.should == ['--query', '--foo']
|
|
33
|
+
db.redis_cli_utility.should == '/path/to/redis-cli'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'when options are not set' do
|
|
37
|
+
before do
|
|
38
|
+
Backup::Database::Redis.any_instance.expects(:utility).
|
|
39
|
+
with('redis-cli').returns('/real/redis-cli')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should use default values' do
|
|
43
|
+
db = Backup::Database::Redis.new(model)
|
|
44
|
+
|
|
45
|
+
db.name.should == 'dump'
|
|
46
|
+
db.path.should be_nil
|
|
47
|
+
db.password.should be_nil
|
|
48
|
+
db.host.should be_nil
|
|
49
|
+
db.port.should be_nil
|
|
50
|
+
db.socket.should be_nil
|
|
51
|
+
db.invoke_save.should be_nil
|
|
52
|
+
|
|
53
|
+
db.additional_options.should == []
|
|
54
|
+
db.redis_cli_utility.should == '/real/redis-cli'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when configuration defaults have been set' do
|
|
59
|
+
after { Backup::Configuration::Database::Redis.clear_defaults! }
|
|
60
|
+
|
|
61
|
+
it 'should use configuration defaults' do
|
|
62
|
+
Backup::Configuration::Database::Redis.defaults do |db|
|
|
63
|
+
db.name = 'db_name'
|
|
64
|
+
db.path = 'db_path'
|
|
65
|
+
db.password = 'db_password'
|
|
66
|
+
db.host = 'db_host'
|
|
67
|
+
db.port = 789
|
|
68
|
+
db.socket = '/foo.sock'
|
|
69
|
+
db.invoke_save = true
|
|
70
|
+
|
|
71
|
+
db.additional_options = ['--add', '--opts']
|
|
72
|
+
db.redis_cli_utility = '/default/path/to/redis-cli'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
db = Backup::Database::Redis.new(model)
|
|
76
|
+
db.name.should == 'db_name'
|
|
77
|
+
db.path.should == 'db_path'
|
|
78
|
+
db.password.should == 'db_password'
|
|
79
|
+
db.host.should == 'db_host'
|
|
80
|
+
db.port.should == 789
|
|
81
|
+
db.socket.should == '/foo.sock'
|
|
82
|
+
db.invoke_save.should == true
|
|
83
|
+
|
|
84
|
+
db.additional_options.should == ['--add', '--opts']
|
|
85
|
+
db.redis_cli_utility.should == '/default/path/to/redis-cli'
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end # describe '#initialize'
|
|
89
|
+
|
|
90
|
+
describe '#perform!' do
|
|
91
|
+
let(:s) { sequence '' }
|
|
92
|
+
before do
|
|
93
|
+
# superclass actions
|
|
94
|
+
db.expects(:prepare!).in_sequence(s)
|
|
95
|
+
db.expects(:log!).in_sequence(s)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context 'when #invoke_save is true' do
|
|
99
|
+
before { db.invoke_save = true }
|
|
100
|
+
it 'should copy over after persisting (saving) the most recent updates' do
|
|
101
|
+
db.expects(:invoke_save!).in_sequence(s)
|
|
102
|
+
db.expects(:copy!).in_sequence(s)
|
|
103
|
+
|
|
104
|
+
db.perform!
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'when #invoke_save is not true' do
|
|
109
|
+
before { db.invoke_save = nil }
|
|
110
|
+
it 'should copy over without persisting (saving) first' do
|
|
111
|
+
db.expects(:invoke_save!).never
|
|
112
|
+
db.expects(:copy!).in_sequence(s)
|
|
113
|
+
|
|
114
|
+
db.perform!
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end # describe '#perform!'
|
|
119
|
+
|
|
120
|
+
describe '#invoke_save!' do
|
|
121
|
+
before do
|
|
122
|
+
db.stubs(:credential_options).returns(:credential_options_output)
|
|
123
|
+
db.stubs(:connectivity_options).returns(:connectivity_options_output)
|
|
124
|
+
db.stubs(:user_options).returns(:user_options_output)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context 'when response is OK' do
|
|
128
|
+
it 'should run the redis-cli command string' do
|
|
129
|
+
db.expects(:run).with(
|
|
130
|
+
'/path/to/redis-cli credential_options_output ' +
|
|
131
|
+
'connectivity_options_output user_options_output SAVE'
|
|
132
|
+
).returns('result OK for command')
|
|
133
|
+
|
|
134
|
+
expect do
|
|
135
|
+
db.send(:invoke_save!)
|
|
136
|
+
end.not_to raise_error
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context 'when response is not OK' do
|
|
141
|
+
it 'should raise an error' do
|
|
142
|
+
db.stubs(:run).returns('result not ok for command')
|
|
143
|
+
db.stubs(:database).returns('database_filename')
|
|
144
|
+
|
|
145
|
+
expect do
|
|
146
|
+
db.send(:invoke_save!)
|
|
147
|
+
end.to raise_error {|err|
|
|
148
|
+
err.should be_an_instance_of Backup::Errors::Database::Redis::CommandError
|
|
149
|
+
err.message.should match(/Could not invoke the Redis SAVE command/)
|
|
150
|
+
err.message.should match(/The database_filename file/)
|
|
151
|
+
err.message.should match(/Redis CLI response: result not ok/)
|
|
152
|
+
}
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
end # describe '#invoke_save!'
|
|
157
|
+
|
|
158
|
+
describe '#copy!' do
|
|
159
|
+
let(:src_path) { '/var/lib/redis/db/mydatabase.rdb' }
|
|
160
|
+
let(:dst_path) { '/dump/path/mydatabase.rdb' }
|
|
161
|
+
let(:compressor) { mock }
|
|
162
|
+
|
|
163
|
+
context 'when the database exists' do
|
|
164
|
+
before do
|
|
165
|
+
db.instance_variable_set(:@dump_path, '/dump/path')
|
|
166
|
+
File.expects(:exist?).with(src_path).returns(true)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
context 'when no compressor is configured' do
|
|
170
|
+
it 'should copy the database' do
|
|
171
|
+
db.expects(:run).never
|
|
172
|
+
|
|
173
|
+
FileUtils.expects(:cp).with(src_path, dst_path)
|
|
174
|
+
db.send(:copy!)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context 'when a compressor is configured' do
|
|
179
|
+
before do
|
|
180
|
+
model.stubs(:compressor).returns(compressor)
|
|
181
|
+
compressor.expects(:compress_with).yields('compressor_command', '.gz')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it 'should copy the database using the compressor' do
|
|
185
|
+
FileUtils.expects(:cp).never
|
|
186
|
+
|
|
187
|
+
db.expects(:run).with(
|
|
188
|
+
"compressor_command -c #{ src_path } > #{ dst_path }.gz"
|
|
189
|
+
)
|
|
190
|
+
db.send(:copy!)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context 'when the database does not exist' do
|
|
196
|
+
it 'should raise an error if the database dump file is not found' do
|
|
197
|
+
File.expects(:exist?).returns(false)
|
|
198
|
+
expect do
|
|
199
|
+
db.send(:copy!)
|
|
200
|
+
end.to raise_error do |err|
|
|
201
|
+
err.should be_an_instance_of Backup::Errors::Database::Redis::NotFoundError
|
|
202
|
+
err.message.should match(/Redis database dump not found/)
|
|
203
|
+
err.message.should match(/File path was #{src_path}/)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end # describe '#copy!'
|
|
208
|
+
|
|
209
|
+
describe '#database' do
|
|
210
|
+
it 'should return the database name with the extension added' do
|
|
211
|
+
db.send(:database).should == 'mydatabase.rdb'
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
describe '#credential_options' do
|
|
216
|
+
context 'when #password is set' do
|
|
217
|
+
it 'should return the redis-cli syntax for the credential options' do
|
|
218
|
+
db.send(:credential_options).should == "-a 'secret'"
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context 'when password is not set' do
|
|
223
|
+
it 'should return an empty string' do
|
|
224
|
+
db.password = nil
|
|
225
|
+
db.send(:credential_options).should == ''
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
describe '#connectivity_options' do
|
|
231
|
+
it 'should return the redis syntax for the connectivity options' do
|
|
232
|
+
db.send(:connectivity_options).should ==
|
|
233
|
+
"-h 'localhost' -p '123' -s '/redis.sock'"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
context 'when only the #port is set' do
|
|
237
|
+
it 'should return only the port' do
|
|
238
|
+
db.host = nil
|
|
239
|
+
db.socket = nil
|
|
240
|
+
db.send(:connectivity_options).should == "-p '123'"
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe '#user_options' do
|
|
246
|
+
context 'when #additional_options are set' do
|
|
247
|
+
it 'should return the options' do
|
|
248
|
+
db.send(:user_options).should == '--query --foo'
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
context 'when #additional_options is not set' do
|
|
253
|
+
it 'should return an empty string' do
|
|
254
|
+
db.additional_options = []
|
|
255
|
+
db.send(:user_options).should == ''
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
end
|