backup 3.0.20 → 3.0.21
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/Gemfile +1 -5
- data/Gemfile.lock +46 -50
- data/README.md +54 -27
- data/lib/backup.rb +16 -39
- data/lib/backup/archive.rb +42 -18
- data/lib/backup/cleaner.rb +110 -25
- data/lib/backup/cli/helpers.rb +17 -32
- data/lib/backup/cli/utility.rb +46 -107
- data/lib/backup/compressor/base.rb +14 -2
- data/lib/backup/compressor/bzip2.rb +10 -24
- data/lib/backup/compressor/gzip.rb +10 -24
- data/lib/backup/compressor/lzma.rb +10 -23
- data/lib/backup/compressor/pbzip2.rb +12 -32
- data/lib/backup/config.rb +171 -0
- data/lib/backup/configuration/compressor/base.rb +1 -2
- data/lib/backup/configuration/compressor/pbzip2.rb +4 -4
- data/lib/backup/configuration/database/base.rb +2 -1
- data/lib/backup/configuration/database/mongodb.rb +8 -0
- data/lib/backup/configuration/database/mysql.rb +4 -0
- data/lib/backup/configuration/database/postgresql.rb +4 -0
- data/lib/backup/configuration/database/redis.rb +4 -0
- data/lib/backup/configuration/database/riak.rb +5 -1
- data/lib/backup/configuration/encryptor/base.rb +1 -2
- data/lib/backup/configuration/encryptor/open_ssl.rb +1 -1
- data/lib/backup/configuration/helpers.rb +7 -2
- data/lib/backup/configuration/notifier/base.rb +4 -28
- data/lib/backup/configuration/storage/base.rb +1 -1
- data/lib/backup/configuration/storage/dropbox.rb +14 -4
- data/lib/backup/configuration/syncer/base.rb +10 -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 +0 -4
- data/lib/backup/database/base.rb +25 -7
- data/lib/backup/database/mongodb.rb +112 -75
- data/lib/backup/database/mysql.rb +54 -29
- data/lib/backup/database/postgresql.rb +60 -42
- data/lib/backup/database/redis.rb +61 -39
- data/lib/backup/database/riak.rb +35 -11
- data/lib/backup/dependency.rb +4 -5
- data/lib/backup/encryptor/base.rb +13 -1
- data/lib/backup/encryptor/gpg.rb +39 -39
- data/lib/backup/encryptor/open_ssl.rb +28 -38
- data/lib/backup/logger.rb +20 -11
- data/lib/backup/model.rb +206 -163
- data/lib/backup/notifier/base.rb +27 -25
- data/lib/backup/notifier/campfire.rb +7 -13
- data/lib/backup/notifier/hipchat.rb +28 -28
- data/lib/backup/notifier/mail.rb +24 -26
- data/lib/backup/notifier/presently.rb +10 -18
- data/lib/backup/notifier/prowl.rb +9 -17
- data/lib/backup/notifier/twitter.rb +11 -18
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +81 -16
- data/lib/backup/splitter.rb +48 -35
- data/lib/backup/storage/base.rb +44 -172
- data/lib/backup/storage/cloudfiles.rb +31 -46
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +92 -76
- data/lib/backup/storage/ftp.rb +30 -40
- data/lib/backup/storage/local.rb +44 -45
- data/lib/backup/storage/ninefold.rb +55 -49
- data/lib/backup/storage/rsync.rb +49 -56
- data/lib/backup/storage/s3.rb +33 -44
- data/lib/backup/storage/scp.rb +21 -48
- data/lib/backup/storage/sftp.rb +26 -40
- data/lib/backup/syncer/base.rb +7 -0
- data/lib/backup/syncer/rsync/base.rb +78 -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 +42 -32
- data/lib/backup/version.rb +1 -1
- data/spec/archive_spec.rb +235 -69
- data/spec/cleaner_spec.rb +304 -0
- data/spec/cli/helpers_spec.rb +142 -1
- data/spec/cli/utility_spec.rb +338 -13
- data/spec/compressor/base_spec.rb +31 -0
- data/spec/compressor/bzip2_spec.rb +60 -35
- data/spec/compressor/gzip_spec.rb +60 -35
- data/spec/compressor/lzma_spec.rb +60 -35
- data/spec/compressor/pbzip2_spec.rb +98 -37
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/base_spec.rb +4 -4
- data/spec/configuration/compressor/bzip2_spec.rb +1 -0
- data/spec/configuration/compressor/gzip_spec.rb +1 -0
- data/spec/configuration/compressor/lzma_spec.rb +1 -0
- data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
- data/spec/configuration/database/base_spec.rb +2 -1
- data/spec/configuration/database/mongodb_spec.rb +26 -16
- data/spec/configuration/database/mysql_spec.rb +4 -0
- data/spec/configuration/database/postgresql_spec.rb +4 -0
- data/spec/configuration/database/redis_spec.rb +4 -0
- data/spec/configuration/database/riak_spec.rb +4 -0
- data/spec/configuration/encryptor/gpg_spec.rb +1 -0
- data/spec/configuration/encryptor/open_ssl_spec.rb +1 -0
- data/spec/configuration/notifier/base_spec.rb +32 -0
- data/spec/configuration/notifier/campfire_spec.rb +1 -0
- data/spec/configuration/notifier/hipchat_spec.rb +1 -0
- data/spec/configuration/notifier/mail_spec.rb +1 -0
- data/spec/configuration/notifier/presently_spec.rb +1 -0
- data/spec/configuration/notifier/prowl_spec.rb +1 -0
- data/spec/configuration/notifier/twitter_spec.rb +1 -0
- data/spec/configuration/storage/cloudfiles_spec.rb +1 -0
- data/spec/configuration/storage/dropbox_spec.rb +4 -3
- data/spec/configuration/storage/ftp_spec.rb +1 -0
- data/spec/configuration/storage/local_spec.rb +1 -0
- data/spec/configuration/storage/ninefold_spec.rb +1 -0
- data/spec/configuration/storage/rsync_spec.rb +3 -1
- data/spec/configuration/storage/s3_spec.rb +1 -0
- data/spec/configuration/storage/scp_spec.rb +1 -0
- data/spec/configuration/storage/sftp_spec.rb +1 -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_spec.rb → rsync/push_spec.rb} +12 -15
- data/spec/configuration/syncer/s3_spec.rb +2 -3
- data/spec/database/base_spec.rb +35 -20
- data/spec/database/mongodb_spec.rb +298 -119
- data/spec/database/mysql_spec.rb +147 -72
- data/spec/database/postgresql_spec.rb +155 -100
- data/spec/database/redis_spec.rb +200 -97
- data/spec/database/riak_spec.rb +82 -24
- data/spec/dependency_spec.rb +49 -0
- data/spec/encryptor/base_spec.rb +30 -0
- data/spec/encryptor/gpg_spec.rb +105 -28
- data/spec/encryptor/open_ssl_spec.rb +85 -114
- data/spec/logger_spec.rb +74 -8
- data/spec/model_spec.rb +528 -220
- data/spec/notifier/base_spec.rb +89 -0
- data/spec/notifier/campfire_spec.rb +147 -119
- data/spec/notifier/hipchat_spec.rb +140 -145
- data/spec/notifier/mail_spec.rb +190 -248
- data/spec/notifier/presently_spec.rb +147 -282
- data/spec/notifier/prowl_spec.rb +79 -111
- data/spec/notifier/twitter_spec.rb +87 -106
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +154 -0
- data/spec/spec_helper.rb +36 -13
- data/spec/splitter_spec.rb +90 -41
- data/spec/storage/base_spec.rb +95 -239
- data/spec/storage/cloudfiles_spec.rb +185 -75
- data/spec/storage/cycler_spec.rb +239 -0
- data/spec/storage/dropbox_spec.rb +318 -87
- data/spec/storage/ftp_spec.rb +165 -152
- data/spec/storage/local_spec.rb +206 -54
- data/spec/storage/ninefold_spec.rb +264 -128
- data/spec/storage/rsync_spec.rb +244 -163
- data/spec/storage/s3_spec.rb +175 -64
- data/spec/storage/scp_spec.rb +156 -150
- data/spec/storage/sftp_spec.rb +153 -135
- data/spec/syncer/base_spec.rb +22 -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 +180 -91
- data/templates/cli/utility/config +1 -1
- data/templates/cli/utility/database/mongodb +4 -0
- data/templates/cli/utility/database/mysql +3 -0
- data/templates/cli/utility/database/postgresql +3 -0
- data/templates/cli/utility/database/redis +3 -0
- data/templates/cli/utility/database/riak +3 -0
- data/templates/cli/utility/storage/dropbox +4 -1
- data/templates/cli/utility/syncer/rsync_local +12 -0
- data/templates/cli/utility/syncer/{rsync → rsync_pull} +2 -2
- data/templates/cli/utility/syncer/rsync_push +17 -0
- data/templates/storage/dropbox/authorization_url.erb +1 -1
- metadata +42 -17
- data/lib/backup/configuration/syncer/rsync.rb +0 -45
- data/lib/backup/finder.rb +0 -87
- data/lib/backup/storage/object.rb +0 -47
- data/lib/backup/syncer/rsync.rb +0 -152
- data/spec/backup_spec.rb +0 -11
- data/spec/finder_spec.rb +0 -91
- data/spec/storage/object_spec.rb +0 -74
- data/spec/syncer/rsync_spec.rb +0 -195
data/spec/database/mysql_spec.rb
CHANGED
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
4
|
|
|
5
5
|
describe Backup::Database::MySQL do
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
Backup::Database::MySQL.any_instance.stubs(:load_defaults!)
|
|
9
|
-
end
|
|
10
|
-
|
|
6
|
+
let(:model) { Backup::Model.new('foo', 'foo') }
|
|
11
7
|
let(:db) do
|
|
12
|
-
Backup::Database::MySQL.new do |db|
|
|
8
|
+
Backup::Database::MySQL.new(model) do |db|
|
|
13
9
|
db.name = 'mydatabase'
|
|
14
10
|
db.username = 'someuser'
|
|
15
11
|
db.password = 'secret'
|
|
@@ -20,10 +16,11 @@ describe Backup::Database::MySQL do
|
|
|
20
16
|
db.skip_tables = ['logs', 'profiles']
|
|
21
17
|
db.only_tables = ['users', 'pirates']
|
|
22
18
|
db.additional_options = ['--single-transaction', '--quick']
|
|
19
|
+
db.mysqldump_utility = '/path/to/mysqldump'
|
|
23
20
|
end
|
|
24
21
|
end
|
|
25
22
|
|
|
26
|
-
describe '#
|
|
23
|
+
describe '#initialize' do
|
|
27
24
|
it 'should read the adapter details correctly' do
|
|
28
25
|
db.name.should == 'mydatabase'
|
|
29
26
|
db.username.should == 'someuser'
|
|
@@ -35,116 +32,194 @@ describe Backup::Database::MySQL do
|
|
|
35
32
|
db.skip_tables.should == ['logs', 'profiles']
|
|
36
33
|
db.only_tables.should == ['users', 'pirates']
|
|
37
34
|
db.additional_options.should == ['--single-transaction', '--quick']
|
|
35
|
+
db.mysqldump_utility.should == '/path/to/mysqldump'
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
db.password = 'secret'
|
|
38
|
+
context 'when options are not set' do
|
|
39
|
+
before do
|
|
40
|
+
Backup::Database::MySQL.any_instance.expects(:utility).
|
|
41
|
+
with(:mysqldump).returns('/real/mysqldump')
|
|
45
42
|
end
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
it 'should use default values' do
|
|
45
|
+
db = Backup::Database::MySQL.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.mysqldump_utility.should == '/real/mysqldump'
|
|
58
|
+
end
|
|
50
59
|
end
|
|
51
|
-
end
|
|
52
60
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
context 'when configuration defaults have been set' do
|
|
62
|
+
after { Backup::Configuration::Database::MySQL.clear_defaults! }
|
|
63
|
+
|
|
64
|
+
it 'should use configuration defaults' do
|
|
65
|
+
Backup::Configuration::Database::MySQL.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.mysqldump_utility = '/default/path/to/mysqldump'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
db = Backup::Database::MySQL.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.mysqldump_utility.should == '/default/path/to/mysqldump'
|
|
91
|
+
end
|
|
56
92
|
end
|
|
93
|
+
end # describe '#initialize'
|
|
57
94
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
95
|
+
describe '#perform!' do
|
|
96
|
+
let(:s) { sequence '' }
|
|
97
|
+
before do
|
|
98
|
+
# superclass actions
|
|
99
|
+
db.expects(:prepare!).in_sequence(s)
|
|
100
|
+
db.expects(:log!).in_sequence(s)
|
|
101
|
+
db.instance_variable_set(:@dump_path, '/dump/path')
|
|
102
|
+
|
|
103
|
+
db.stubs(:mysqldump).returns('mysqldump_command')
|
|
61
104
|
end
|
|
62
|
-
end
|
|
63
105
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
106
|
+
context 'when no compressor is configured' do
|
|
107
|
+
before do
|
|
108
|
+
model.expects(:compressor).in_sequence(s).returns(nil)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it 'should run mysqldump without compression' do
|
|
112
|
+
db.expects(:run).in_sequence(s).with(
|
|
113
|
+
"mysqldump_command > '/dump/path/mydatabase.sql'"
|
|
114
|
+
)
|
|
115
|
+
db.perform!
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context 'when a compressor is configured' do
|
|
120
|
+
before do
|
|
121
|
+
compressor = mock
|
|
122
|
+
model.expects(:compressor).twice.in_sequence(s).returns(compressor)
|
|
123
|
+
compressor.expects(:compress_with).in_sequence(s).yields('gzip', '.gz')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'should run mysqldump with compression' do
|
|
127
|
+
db.expects(:run).in_sequence(s).with(
|
|
128
|
+
"mysqldump_command | gzip > '/dump/path/mydatabase.sql.gz'"
|
|
129
|
+
)
|
|
130
|
+
db.perform!
|
|
131
|
+
end
|
|
67
132
|
end
|
|
68
133
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
134
|
+
end # describe '#perform!'
|
|
135
|
+
|
|
136
|
+
describe '#mysqldump' do
|
|
137
|
+
it 'should return the mysqldump command string' do
|
|
138
|
+
db.send(:mysqldump).should ==
|
|
139
|
+
"/path/to/mysqldump --user='someuser' --password='secret' " +
|
|
140
|
+
"--host='localhost' --port='123' --socket='/mysql.sock' " +
|
|
141
|
+
"--single-transaction --quick mydatabase users pirates " +
|
|
142
|
+
"--ignore-table='mydatabase.logs' --ignore-table='mydatabase.profiles'"
|
|
72
143
|
end
|
|
73
144
|
end
|
|
74
145
|
|
|
75
146
|
describe '#credential_options' do
|
|
76
|
-
|
|
77
|
-
|
|
147
|
+
context 'when a password is set' do
|
|
148
|
+
it 'should return the command string for the user credentials' do
|
|
149
|
+
db.send(:credential_options).should ==
|
|
150
|
+
"--user='someuser' --password='secret'"
|
|
151
|
+
end
|
|
78
152
|
end
|
|
79
153
|
|
|
80
|
-
|
|
81
|
-
db =
|
|
82
|
-
|
|
154
|
+
context 'when no password is set' do
|
|
155
|
+
before { db.password = nil }
|
|
156
|
+
it 'should return the command string for the user credentials' do
|
|
157
|
+
db.send(:credential_options).should ==
|
|
158
|
+
"--user='someuser'"
|
|
83
159
|
end
|
|
84
|
-
|
|
85
|
-
db.credential_options.should == "--user='someuser'"
|
|
86
160
|
end
|
|
87
161
|
end
|
|
88
162
|
|
|
89
163
|
describe '#connectivity_options' do
|
|
90
164
|
it 'should return the mysql syntax for the connectivity options' do
|
|
91
|
-
db.connectivity_options.should ==
|
|
165
|
+
db.send(:connectivity_options).should ==
|
|
166
|
+
"--host='localhost' --port='123' --socket='/mysql.sock'"
|
|
92
167
|
end
|
|
93
168
|
|
|
94
|
-
|
|
95
|
-
|
|
169
|
+
context 'when only the socket is set' do
|
|
170
|
+
it 'should return only the socket' do
|
|
96
171
|
db.host = ''
|
|
97
172
|
db.port = nil
|
|
98
|
-
db.socket
|
|
173
|
+
db.send(:connectivity_options).should == "--socket='/mysql.sock'"
|
|
99
174
|
end
|
|
175
|
+
end
|
|
100
176
|
|
|
101
|
-
|
|
177
|
+
context 'when only the host and port are set' do
|
|
178
|
+
it 'should return only the host and port' do
|
|
179
|
+
db.socket = nil
|
|
180
|
+
db.send(:connectivity_options).should ==
|
|
181
|
+
"--host='localhost' --port='123'"
|
|
182
|
+
end
|
|
102
183
|
end
|
|
103
184
|
end
|
|
104
185
|
|
|
105
|
-
describe '#
|
|
186
|
+
describe '#user_options' do
|
|
106
187
|
it 'should return a string of additional options specified by the user' do
|
|
107
|
-
db.
|
|
188
|
+
db.send(:user_options).should == '--single-transaction --quick'
|
|
108
189
|
end
|
|
109
190
|
|
|
110
|
-
|
|
111
|
-
db =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
describe '#mysqldump_string' do
|
|
117
|
-
it 'should return the full mysqldump string' do
|
|
118
|
-
db.expects(:utility).with(:mysqldump).returns('mysqldump')
|
|
119
|
-
db.mysqldump.should ==
|
|
120
|
-
"mysqldump --user='someuser' --password='secret' " +
|
|
121
|
-
"--host='localhost' --port='123' --socket='/mysql.sock' " +
|
|
122
|
-
"--single-transaction --quick mydatabase users pirates " +
|
|
123
|
-
"--ignore-table='mydatabase.logs' --ignore-table='mydatabase.profiles'"
|
|
191
|
+
context 'when #additional_options is not set' do
|
|
192
|
+
before { db.additional_options = [] }
|
|
193
|
+
it 'should return an empty string' do
|
|
194
|
+
db.send(:user_options).should == ''
|
|
195
|
+
end
|
|
124
196
|
end
|
|
125
197
|
end
|
|
126
198
|
|
|
127
|
-
describe '#
|
|
128
|
-
|
|
129
|
-
db.
|
|
130
|
-
db.stubs(:mkdir)
|
|
131
|
-
db.stubs(:run)
|
|
199
|
+
describe '#tables_to_dump' do
|
|
200
|
+
it 'should return a string for the mysqldump selected table to dump option' do
|
|
201
|
+
db.send(:tables_to_dump).should == 'users pirates'
|
|
132
202
|
end
|
|
133
203
|
|
|
134
|
-
|
|
135
|
-
db.
|
|
136
|
-
|
|
204
|
+
context 'when #only_tables is not set' do
|
|
205
|
+
before { db.only_tables = [] }
|
|
206
|
+
it 'should return an empty string' do
|
|
207
|
+
db.send(:tables_to_dump).should == ''
|
|
208
|
+
end
|
|
137
209
|
end
|
|
210
|
+
end
|
|
138
211
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
db.
|
|
212
|
+
describe '#tables_to_skip' do
|
|
213
|
+
it 'should return a string for the mysqldump --ignore-tables option' do
|
|
214
|
+
db.send(:tables_to_skip).should ==
|
|
215
|
+
"--ignore-table='mydatabase.logs' --ignore-table='mydatabase.profiles'"
|
|
142
216
|
end
|
|
143
217
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
218
|
+
context 'when #skip_tables is not set' do
|
|
219
|
+
before { db.skip_tables = [] }
|
|
220
|
+
it 'should return an empty string' do
|
|
221
|
+
db.send(:tables_to_skip).should == ''
|
|
222
|
+
end
|
|
148
223
|
end
|
|
149
224
|
end
|
|
150
225
|
end
|
|
@@ -3,183 +3,238 @@
|
|
|
3
3
|
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
4
|
|
|
5
5
|
describe Backup::Database::PostgreSQL do
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
Backup::Database::PostgreSQL.any_instance.stubs(:load_defaults!)
|
|
9
|
-
end
|
|
10
|
-
|
|
6
|
+
let(:model) { Backup::Model.new('foo', 'foo') }
|
|
11
7
|
let(:db) do
|
|
12
|
-
Backup::Database::PostgreSQL.new do |db|
|
|
8
|
+
Backup::Database::PostgreSQL.new(model) do |db|
|
|
13
9
|
db.name = 'mydatabase'
|
|
14
10
|
db.username = 'someuser'
|
|
15
11
|
db.password = 'secret'
|
|
16
12
|
db.host = 'localhost'
|
|
17
13
|
db.port = '123'
|
|
18
|
-
db.socket = '/
|
|
14
|
+
db.socket = '/pgsql.sock'
|
|
19
15
|
|
|
20
16
|
db.skip_tables = ['logs', 'profiles']
|
|
21
17
|
db.only_tables = ['users', 'pirates']
|
|
22
18
|
db.additional_options = ['--single-transaction', '--quick']
|
|
19
|
+
db.pg_dump_utility = '/path/to/pg_dump'
|
|
23
20
|
end
|
|
24
21
|
end
|
|
25
22
|
|
|
26
|
-
describe '#
|
|
23
|
+
describe '#initialize' do
|
|
27
24
|
it 'should read the adapter details correctly' do
|
|
28
25
|
db.name.should == 'mydatabase'
|
|
29
26
|
db.username.should == 'someuser'
|
|
30
27
|
db.password.should == 'secret'
|
|
31
28
|
db.host.should == 'localhost'
|
|
32
29
|
db.port.should == '123'
|
|
33
|
-
db.socket.should == '/
|
|
30
|
+
db.socket.should == '/pgsql.sock'
|
|
34
31
|
|
|
35
32
|
db.skip_tables.should == ['logs', 'profiles']
|
|
36
33
|
db.only_tables.should == ['users', 'pirates']
|
|
37
34
|
db.additional_options.should == ['--single-transaction', '--quick']
|
|
35
|
+
db.pg_dump_utility.should == '/path/to/pg_dump'
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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'
|
|
45
58
|
end
|
|
59
|
+
end
|
|
46
60
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
50
92
|
end
|
|
93
|
+
end # describe '#initialize'
|
|
51
94
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
describe '#perform!' do
|
|
96
|
+
let(:s) { sequence '' }
|
|
97
|
+
before do
|
|
98
|
+
# superclass actions
|
|
99
|
+
db.expects(:prepare!).in_sequence(s)
|
|
100
|
+
db.expects(:log!).in_sequence(s)
|
|
101
|
+
db.instance_variable_set(:@dump_path, '/dump/path')
|
|
55
102
|
|
|
56
|
-
db.
|
|
57
|
-
db.password_options.should == ''
|
|
103
|
+
db.stubs(:pgdump).returns('pgdump_command')
|
|
58
104
|
end
|
|
59
105
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
106
|
+
context 'when no compressor is configured' do
|
|
107
|
+
before do
|
|
108
|
+
model.expects(:compressor).in_sequence(s).returns(nil)
|
|
109
|
+
end
|
|
63
110
|
|
|
64
|
-
|
|
65
|
-
|
|
111
|
+
it 'should run pgdump without compression' do
|
|
112
|
+
db.expects(:run).in_sequence(s).with(
|
|
113
|
+
"pgdump_command > '/dump/path/mydatabase.sql'"
|
|
114
|
+
)
|
|
115
|
+
db.perform!
|
|
116
|
+
end
|
|
66
117
|
end
|
|
67
|
-
end
|
|
68
118
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
119
|
+
context 'when a compressor is configured' do
|
|
120
|
+
before do
|
|
121
|
+
compressor = mock
|
|
122
|
+
model.expects(:compressor).twice.in_sequence(s).returns(compressor)
|
|
123
|
+
compressor.expects(:compress_with).in_sequence(s).yields('gzip', '.gz')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'should run pgdump with compression' do
|
|
127
|
+
db.expects(:run).in_sequence(s).with(
|
|
128
|
+
"pgdump_command | gzip > '/dump/path/mydatabase.sql.gz'"
|
|
129
|
+
)
|
|
130
|
+
db.perform!
|
|
131
|
+
end
|
|
72
132
|
end
|
|
73
133
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
134
|
+
end # describe '#perform!'
|
|
135
|
+
|
|
136
|
+
describe '#pgdump' do
|
|
137
|
+
it 'should return the pgdump command string' do
|
|
138
|
+
db.send(:pgdump).should ==
|
|
139
|
+
"PGPASSWORD='secret' /path/to/pg_dump --username='someuser' " +
|
|
140
|
+
"--host='localhost' --port='123' --host='/pgsql.sock' " +
|
|
141
|
+
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
142
|
+
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context 'without a password' do
|
|
146
|
+
before { db.password = nil }
|
|
147
|
+
it 'should not leave a preceeding space' do
|
|
148
|
+
db.send(:pgdump).should ==
|
|
149
|
+
"/path/to/pg_dump --username='someuser' " +
|
|
150
|
+
"--host='localhost' --port='123' --host='/pgsql.sock' " +
|
|
151
|
+
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
152
|
+
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
153
|
+
end
|
|
77
154
|
end
|
|
78
155
|
end
|
|
79
156
|
|
|
80
|
-
describe '#
|
|
81
|
-
it '
|
|
82
|
-
db.
|
|
157
|
+
describe '#password_options' do
|
|
158
|
+
it 'returns the environment variable set for the password' do
|
|
159
|
+
db.send(:password_options).should == "PGPASSWORD='secret' "
|
|
83
160
|
end
|
|
84
161
|
|
|
85
|
-
|
|
86
|
-
db =
|
|
87
|
-
|
|
162
|
+
context 'when password is not set' do
|
|
163
|
+
before { db.password = nil }
|
|
164
|
+
it 'should return an empty string' do
|
|
165
|
+
db.send(:password_options).should == ''
|
|
166
|
+
end
|
|
88
167
|
end
|
|
89
168
|
end
|
|
90
169
|
|
|
91
170
|
describe '#username_options' do
|
|
92
171
|
it 'should return the postgresql syntax for the username options' do
|
|
93
|
-
db.username_options.should == "--username='someuser'"
|
|
172
|
+
db.send(:username_options).should == "--username='someuser'"
|
|
94
173
|
end
|
|
95
174
|
|
|
96
|
-
|
|
97
|
-
db =
|
|
98
|
-
|
|
175
|
+
context 'when username is not set' do
|
|
176
|
+
before { db.username = nil }
|
|
177
|
+
it 'should return an empty string' do
|
|
178
|
+
db.send(:username_options).should == ''
|
|
99
179
|
end
|
|
100
|
-
|
|
101
|
-
db.username_options.should == "--username='someuser'"
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
describe '#password_options' do
|
|
106
|
-
it 'returns the environment variable set for the password' do
|
|
107
|
-
db.password_options.should == "PGPASSWORD='secret'"
|
|
108
180
|
end
|
|
109
181
|
end
|
|
110
182
|
|
|
111
183
|
describe '#connectivity_options' do
|
|
112
184
|
it 'should return the postgresql syntax for the connectivity options' do
|
|
113
|
-
db.connectivity_options.should ==
|
|
185
|
+
db.send(:connectivity_options).should ==
|
|
186
|
+
"--host='localhost' --port='123' --host='/pgsql.sock'"
|
|
114
187
|
end
|
|
115
188
|
|
|
116
|
-
|
|
117
|
-
|
|
189
|
+
context 'when only the socket is set' do
|
|
190
|
+
before do
|
|
118
191
|
db.host = ''
|
|
119
192
|
db.port = nil
|
|
120
|
-
db.socket = '/pg.sock'
|
|
121
193
|
end
|
|
122
194
|
|
|
123
|
-
|
|
195
|
+
it 'should return only the socket' do
|
|
196
|
+
db.send(:connectivity_options).should == "--host='/pgsql.sock'"
|
|
197
|
+
end
|
|
124
198
|
end
|
|
125
199
|
end
|
|
126
200
|
|
|
127
|
-
describe '#
|
|
201
|
+
describe '#user_options' do
|
|
128
202
|
it 'should return a string of additional options specified by the user' do
|
|
129
|
-
db.
|
|
203
|
+
db.send(:user_options).should == '--single-transaction --quick'
|
|
130
204
|
end
|
|
131
205
|
|
|
132
|
-
|
|
133
|
-
db =
|
|
134
|
-
|
|
206
|
+
context 'when #additional_options is not set' do
|
|
207
|
+
before { db.additional_options = [] }
|
|
208
|
+
it 'should return an empty string' do
|
|
209
|
+
db.send(:user_options).should == ''
|
|
210
|
+
end
|
|
135
211
|
end
|
|
136
212
|
end
|
|
137
213
|
|
|
138
|
-
describe '#
|
|
139
|
-
|
|
140
|
-
db.
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it 'should return the full pg_dump string' do
|
|
144
|
-
db.pgdump.should ==
|
|
145
|
-
"PGPASSWORD='secret' pg_dump --username='someuser' " +
|
|
146
|
-
"--host='localhost' --port='123' --host='/pg.sock' " +
|
|
147
|
-
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
148
|
-
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
214
|
+
describe '#tables_to_dump' do
|
|
215
|
+
it 'should return a string for the pg_dump selected table to dump option' do
|
|
216
|
+
db.send(:tables_to_dump).should == "--table='users' --table='pirates'"
|
|
149
217
|
end
|
|
150
218
|
|
|
151
|
-
|
|
152
|
-
db.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
"--single-transaction --quick --table='users' --table='pirates' " +
|
|
157
|
-
"--exclude-table='logs' --exclude-table='profiles' mydatabase"
|
|
158
|
-
|
|
219
|
+
context 'when #only_tables is not set' do
|
|
220
|
+
before { db.only_tables = [] }
|
|
221
|
+
it 'should return an empty string' do
|
|
222
|
+
db.send(:tables_to_dump).should == ''
|
|
223
|
+
end
|
|
159
224
|
end
|
|
160
225
|
end
|
|
161
226
|
|
|
162
|
-
describe '#
|
|
163
|
-
|
|
164
|
-
db.
|
|
165
|
-
db.stubs(:mkdir)
|
|
166
|
-
db.stubs(:run)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
it 'should ensure the directory is available' do
|
|
170
|
-
db.expects(:mkdir).with(File.join(Backup::TMP_PATH, "myapp", "PostgreSQL"))
|
|
171
|
-
db.perform!
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
it 'should run the pg_dump command and dump it to the specified path' do
|
|
175
|
-
db.expects(:run).with("#{db.pgdump} > '#{Backup::TMP_PATH}/myapp/PostgreSQL/mydatabase.sql'")
|
|
176
|
-
db.perform!
|
|
227
|
+
describe '#tables_to_skip' do
|
|
228
|
+
it 'should return a string for the pg_dump --ignore-tables option' do
|
|
229
|
+
db.send(:tables_to_skip).should == "--exclude-table='logs' --exclude-table='profiles'"
|
|
177
230
|
end
|
|
178
231
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
232
|
+
context 'when #skip_tables is not set' do
|
|
233
|
+
before { db.skip_tables = [] }
|
|
234
|
+
it 'should return an empty string' do
|
|
235
|
+
db.send(:tables_to_skip).should == ''
|
|
236
|
+
end
|
|
183
237
|
end
|
|
184
238
|
end
|
|
239
|
+
|
|
185
240
|
end
|