backup-agoddard 3.0.27
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 +8 -0
- data/.travis.yml +10 -0
- data/Gemfile +28 -0
- data/Guardfile +23 -0
- data/LICENSE.md +24 -0
- data/README.md +478 -0
- data/backup.gemspec +32 -0
- data/bin/backup +11 -0
- data/lib/backup.rb +133 -0
- data/lib/backup/archive.rb +117 -0
- data/lib/backup/binder.rb +22 -0
- data/lib/backup/cleaner.rb +121 -0
- data/lib/backup/cli/helpers.rb +93 -0
- data/lib/backup/cli/utility.rb +255 -0
- data/lib/backup/compressor/base.rb +35 -0
- data/lib/backup/compressor/bzip2.rb +50 -0
- data/lib/backup/compressor/custom.rb +53 -0
- data/lib/backup/compressor/gzip.rb +50 -0
- data/lib/backup/compressor/lzma.rb +52 -0
- data/lib/backup/compressor/pbzip2.rb +59 -0
- data/lib/backup/config.rb +174 -0
- data/lib/backup/configuration.rb +33 -0
- data/lib/backup/configuration/helpers.rb +130 -0
- data/lib/backup/configuration/store.rb +24 -0
- data/lib/backup/database/base.rb +53 -0
- data/lib/backup/database/mongodb.rb +230 -0
- data/lib/backup/database/mysql.rb +160 -0
- data/lib/backup/database/postgresql.rb +144 -0
- data/lib/backup/database/redis.rb +136 -0
- data/lib/backup/database/riak.rb +67 -0
- data/lib/backup/dependency.rb +108 -0
- data/lib/backup/encryptor/base.rb +29 -0
- data/lib/backup/encryptor/gpg.rb +760 -0
- data/lib/backup/encryptor/open_ssl.rb +72 -0
- data/lib/backup/errors.rb +124 -0
- data/lib/backup/hooks.rb +68 -0
- data/lib/backup/logger.rb +152 -0
- data/lib/backup/model.rb +409 -0
- data/lib/backup/notifier/base.rb +81 -0
- data/lib/backup/notifier/campfire.rb +155 -0
- data/lib/backup/notifier/hipchat.rb +93 -0
- data/lib/backup/notifier/mail.rb +206 -0
- data/lib/backup/notifier/prowl.rb +65 -0
- data/lib/backup/notifier/pushover.rb +88 -0
- data/lib/backup/notifier/twitter.rb +70 -0
- data/lib/backup/package.rb +47 -0
- data/lib/backup/packager.rb +100 -0
- data/lib/backup/pipeline.rb +110 -0
- data/lib/backup/splitter.rb +75 -0
- data/lib/backup/storage/base.rb +99 -0
- data/lib/backup/storage/cloudfiles.rb +87 -0
- data/lib/backup/storage/cycler.rb +117 -0
- data/lib/backup/storage/dropbox.rb +178 -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 +46 -0
- data/lib/backup/syncer/cloud/base.rb +247 -0
- data/lib/backup/syncer/cloud/cloud_files.rb +78 -0
- data/lib/backup/syncer/cloud/s3.rb +68 -0
- data/lib/backup/syncer/rsync/base.rb +49 -0
- data/lib/backup/syncer/rsync/local.rb +55 -0
- data/lib/backup/syncer/rsync/pull.rb +36 -0
- data/lib/backup/syncer/rsync/push.rb +116 -0
- data/lib/backup/template.rb +46 -0
- data/lib/backup/version.rb +43 -0
- data/spec-live/.gitignore +6 -0
- data/spec-live/README +7 -0
- data/spec-live/backups/config.rb +83 -0
- data/spec-live/backups/config.yml.template +46 -0
- data/spec-live/backups/models.rb +184 -0
- data/spec-live/compressor/custom_spec.rb +30 -0
- data/spec-live/compressor/gzip_spec.rb +30 -0
- data/spec-live/encryptor/gpg_keys.rb +239 -0
- data/spec-live/encryptor/gpg_spec.rb +287 -0
- data/spec-live/notifier/mail_spec.rb +121 -0
- data/spec-live/spec_helper.rb +151 -0
- data/spec-live/storage/dropbox_spec.rb +151 -0
- data/spec-live/storage/local_spec.rb +83 -0
- data/spec-live/storage/scp_spec.rb +193 -0
- data/spec-live/syncer/cloud/s3_spec.rb +124 -0
- data/spec/archive_spec.rb +335 -0
- data/spec/cleaner_spec.rb +312 -0
- data/spec/cli/helpers_spec.rb +301 -0
- data/spec/cli/utility_spec.rb +411 -0
- data/spec/compressor/base_spec.rb +52 -0
- data/spec/compressor/bzip2_spec.rb +217 -0
- data/spec/compressor/custom_spec.rb +106 -0
- data/spec/compressor/gzip_spec.rb +217 -0
- data/spec/compressor/lzma_spec.rb +123 -0
- data/spec/compressor/pbzip2_spec.rb +165 -0
- data/spec/config_spec.rb +321 -0
- data/spec/configuration/helpers_spec.rb +247 -0
- data/spec/configuration/store_spec.rb +39 -0
- data/spec/configuration_spec.rb +62 -0
- data/spec/database/base_spec.rb +63 -0
- data/spec/database/mongodb_spec.rb +510 -0
- data/spec/database/mysql_spec.rb +411 -0
- data/spec/database/postgresql_spec.rb +353 -0
- data/spec/database/redis_spec.rb +334 -0
- data/spec/database/riak_spec.rb +176 -0
- data/spec/dependency_spec.rb +51 -0
- data/spec/encryptor/base_spec.rb +40 -0
- data/spec/encryptor/gpg_spec.rb +909 -0
- data/spec/encryptor/open_ssl_spec.rb +148 -0
- data/spec/errors_spec.rb +306 -0
- data/spec/hooks_spec.rb +35 -0
- data/spec/logger_spec.rb +367 -0
- data/spec/model_spec.rb +694 -0
- data/spec/notifier/base_spec.rb +104 -0
- data/spec/notifier/campfire_spec.rb +217 -0
- data/spec/notifier/hipchat_spec.rb +211 -0
- data/spec/notifier/mail_spec.rb +316 -0
- data/spec/notifier/prowl_spec.rb +138 -0
- data/spec/notifier/pushover_spec.rb +123 -0
- data/spec/notifier/twitter_spec.rb +153 -0
- data/spec/package_spec.rb +61 -0
- data/spec/packager_spec.rb +213 -0
- data/spec/pipeline_spec.rb +259 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/splitter_spec.rb +120 -0
- data/spec/storage/base_spec.rb +166 -0
- data/spec/storage/cloudfiles_spec.rb +254 -0
- data/spec/storage/cycler_spec.rb +247 -0
- data/spec/storage/dropbox_spec.rb +480 -0
- data/spec/storage/ftp_spec.rb +271 -0
- data/spec/storage/local_spec.rb +259 -0
- data/spec/storage/ninefold_spec.rb +343 -0
- data/spec/storage/rsync_spec.rb +362 -0
- data/spec/storage/s3_spec.rb +245 -0
- data/spec/storage/scp_spec.rb +233 -0
- data/spec/storage/sftp_spec.rb +244 -0
- data/spec/syncer/base_spec.rb +109 -0
- data/spec/syncer/cloud/base_spec.rb +515 -0
- data/spec/syncer/cloud/cloud_files_spec.rb +181 -0
- data/spec/syncer/cloud/s3_spec.rb +174 -0
- data/spec/syncer/rsync/base_spec.rb +98 -0
- data/spec/syncer/rsync/local_spec.rb +149 -0
- data/spec/syncer/rsync/pull_spec.rb +98 -0
- data/spec/syncer/rsync/push_spec.rb +333 -0
- data/spec/version_spec.rb +21 -0
- data/templates/cli/utility/archive +25 -0
- data/templates/cli/utility/compressor/bzip2 +4 -0
- data/templates/cli/utility/compressor/custom +11 -0
- data/templates/cli/utility/compressor/gzip +4 -0
- data/templates/cli/utility/compressor/lzma +10 -0
- data/templates/cli/utility/compressor/pbzip2 +10 -0
- data/templates/cli/utility/config +32 -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 +27 -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/prowl +11 -0
- data/templates/cli/utility/notifier/pushover +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 +46 -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 +43 -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 +277 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Configuration::Helpers' do
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
module Backup
|
|
9
|
+
class Foo
|
|
10
|
+
include Backup::Configuration::Helpers
|
|
11
|
+
attr_accessor :accessor, :accessor_two
|
|
12
|
+
attr_reader :reader
|
|
13
|
+
|
|
14
|
+
attr_deprecate :removed,
|
|
15
|
+
:version => '1.1'
|
|
16
|
+
|
|
17
|
+
attr_deprecate :removed_with_message,
|
|
18
|
+
:version => '1.2',
|
|
19
|
+
:message => 'This has no replacement.'
|
|
20
|
+
|
|
21
|
+
attr_deprecate :removed_with_action,
|
|
22
|
+
:version => '1.3',
|
|
23
|
+
:action => lambda {|klass, val|
|
|
24
|
+
klass.accessor = val ? '1' : '0'
|
|
25
|
+
klass.accessor_two = 'updated'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
attr_deprecate :removed_with_action_and_message,
|
|
29
|
+
:version => '1.4',
|
|
30
|
+
:message => "Updating accessors.",
|
|
31
|
+
:action => lambda {|klass, val|
|
|
32
|
+
klass.accessor = val ? '1' : '0'
|
|
33
|
+
klass.accessor_two = 'updated'
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
after do
|
|
40
|
+
Backup.send(:remove_const, 'Foo')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '.defaults' do
|
|
44
|
+
let(:configuration) { mock }
|
|
45
|
+
|
|
46
|
+
before do
|
|
47
|
+
Backup::Configuration::Store.expects(:new).once.returns(configuration)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should return the Configuration::Store for the class' do
|
|
51
|
+
Backup::Foo.defaults.should be(configuration)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should yield the Configuration::Store for the class' do
|
|
55
|
+
Backup::Foo.defaults do |config|
|
|
56
|
+
config.should be(configuration)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should cache the Configuration::Store for the class' do
|
|
61
|
+
Backup::Foo.instance_variable_get(:@configuration).should be_nil
|
|
62
|
+
Backup::Foo.defaults.should be(configuration)
|
|
63
|
+
Backup::Foo.instance_variable_get(
|
|
64
|
+
:@configuration).should be(configuration)
|
|
65
|
+
Backup::Foo.defaults.should be(configuration)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe '.clear_defaults!' do
|
|
70
|
+
it 'should clear all defaults set' do
|
|
71
|
+
Backup::Foo.defaults do |config|
|
|
72
|
+
config.accessor = 'foo'
|
|
73
|
+
end
|
|
74
|
+
Backup::Foo.defaults.accessor.should == 'foo'
|
|
75
|
+
|
|
76
|
+
Backup::Foo.clear_defaults!
|
|
77
|
+
Backup::Foo.defaults.accessor.should be_nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '.deprecations' do
|
|
82
|
+
it 'should return @deprecations' do
|
|
83
|
+
Backup::Foo.deprecations.should be_a(Hash)
|
|
84
|
+
Backup::Foo.deprecations.keys.count.should be(4)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should set @deprecations to an empty hash if not set' do
|
|
88
|
+
Backup::Foo.send(:remove_instance_variable, :@deprecations)
|
|
89
|
+
Backup::Foo.deprecations.should == {}
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe '.attr_deprecate' do
|
|
94
|
+
before do
|
|
95
|
+
Backup::Foo.send(:remove_instance_variable, :@deprecations)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'should add deprected attributes' do
|
|
99
|
+
Backup::Foo.send(:attr_deprecate, :attr1)
|
|
100
|
+
Backup::Foo.send(:attr_deprecate, :attr2,
|
|
101
|
+
:version => '2')
|
|
102
|
+
Backup::Foo.send(:attr_deprecate, :attr3,
|
|
103
|
+
:version => '3',
|
|
104
|
+
:message => 'attr3 message')
|
|
105
|
+
Backup::Foo.send(:attr_deprecate, :attr4,
|
|
106
|
+
:version => '4',
|
|
107
|
+
:message => 'attr4 message',
|
|
108
|
+
:action => 'attr4 action')
|
|
109
|
+
|
|
110
|
+
Backup::Foo.deprecations.should == {
|
|
111
|
+
:attr1 => { :version => nil,
|
|
112
|
+
:message => nil,
|
|
113
|
+
:action => nil },
|
|
114
|
+
:attr2 => { :version => '2',
|
|
115
|
+
:message => nil,
|
|
116
|
+
:action => nil },
|
|
117
|
+
:attr3 => { :version => '3',
|
|
118
|
+
:message => 'attr3 message',
|
|
119
|
+
:action => nil },
|
|
120
|
+
:attr4 => { :version => '4',
|
|
121
|
+
:message => 'attr4 message',
|
|
122
|
+
:action => 'attr4 action' }
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe '.log_deprecation_warning' do
|
|
128
|
+
context 'when no message given' do
|
|
129
|
+
it 'should log a warning that the attribute has been removed' do
|
|
130
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
131
|
+
err.message.should ==
|
|
132
|
+
"ConfigurationError: [DEPRECATION WARNING]\n" +
|
|
133
|
+
" Backup::Foo#removed has been deprecated as of backup v.1.1"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
deprecation = Backup::Foo.deprecations[:removed]
|
|
137
|
+
Backup::Foo.log_deprecation_warning(:removed, deprecation)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context 'when a message is given' do
|
|
142
|
+
it 'should log warning with the message' do
|
|
143
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
144
|
+
err.message.should ==
|
|
145
|
+
"ConfigurationError: [DEPRECATION WARNING]\n" +
|
|
146
|
+
" Backup::Foo#removed_with_message has been deprecated " +
|
|
147
|
+
"as of backup v.1.2\n" +
|
|
148
|
+
" This has no replacement."
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
deprecation = Backup::Foo.deprecations[:removed_with_message]
|
|
152
|
+
Backup::Foo.log_deprecation_warning(:removed_with_message, deprecation)
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end # describe '.log_deprecation_warning'
|
|
157
|
+
|
|
158
|
+
describe '#load_defaults!' do
|
|
159
|
+
let(:klass) { Backup::Foo.new }
|
|
160
|
+
|
|
161
|
+
it 'should load default values set for the class' do
|
|
162
|
+
Backup::Foo.defaults do |config|
|
|
163
|
+
config.accessor = 'foo'
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
klass.send(:load_defaults!)
|
|
167
|
+
klass.accessor.should == 'foo'
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'should raise an error if defaults are set for attribute readers' do
|
|
171
|
+
Backup::Foo.defaults do |config|
|
|
172
|
+
config.reader = 'foo'
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
expect do
|
|
176
|
+
klass.send(:load_defaults!)
|
|
177
|
+
end.to raise_error(NoMethodError, /Backup::Foo/)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'should raise an error if defaults were set for invalid accessors' do
|
|
181
|
+
Backup::Foo.defaults do |config|
|
|
182
|
+
config.foobar = 'foo'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
expect do
|
|
186
|
+
klass.send(:load_defaults!)
|
|
187
|
+
end.to raise_error(NoMethodError, /Backup::Foo/)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
describe '#method_missing' do
|
|
192
|
+
context 'when the method is a deprecated method' do
|
|
193
|
+
before do
|
|
194
|
+
Backup::Logger.expects(:warn).with(
|
|
195
|
+
instance_of(Backup::Errors::ConfigurationError)
|
|
196
|
+
)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context 'when an :action is specified' do
|
|
200
|
+
it 'should call the :action' do
|
|
201
|
+
value = [true, false].shuffle.first
|
|
202
|
+
expected_value = value ? '1' : '0'
|
|
203
|
+
|
|
204
|
+
klass = Backup::Foo.new
|
|
205
|
+
klass.removed_with_action = value
|
|
206
|
+
|
|
207
|
+
klass.accessor.should == expected_value
|
|
208
|
+
# lambda additionally sets :accessor_two
|
|
209
|
+
klass.accessor_two.should == 'updated'
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context 'when no :action is specified' do
|
|
214
|
+
it 'should only log the warning' do
|
|
215
|
+
Backup::Foo.any_instance.expects(:accessor=).never
|
|
216
|
+
|
|
217
|
+
klass = Backup::Foo.new
|
|
218
|
+
klass.removed = 'foo'
|
|
219
|
+
|
|
220
|
+
klass.accessor.should be_nil
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context 'when the method is not a deprecated method' do
|
|
226
|
+
it 'should raise a NoMethodError' do
|
|
227
|
+
Backup::Logger.expects(:warn).never
|
|
228
|
+
|
|
229
|
+
klass = Backup::Foo.new
|
|
230
|
+
expect do
|
|
231
|
+
klass.foobar = 'attr_value'
|
|
232
|
+
end.to raise_error(NoMethodError)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
context 'when the method is not a set operation' do
|
|
237
|
+
it 'should raise a NoMethodError' do
|
|
238
|
+
Backup::Logger.expects(:warn).never
|
|
239
|
+
|
|
240
|
+
klass = Backup::Foo.new
|
|
241
|
+
expect do
|
|
242
|
+
klass.removed
|
|
243
|
+
end.to raise_error(NoMethodError)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end # describe '#method_missing'
|
|
247
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Configuration::Store' do
|
|
6
|
+
let(:store) { Backup::Configuration::Store.new }
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
store.foo = 'one'
|
|
10
|
+
store.bar = 'two'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should be a subclass of OpenStruct' do
|
|
14
|
+
Backup::Configuration::Store.superclass.should == OpenStruct
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should return nil for unset attributes' do
|
|
18
|
+
store.foobar.should be_nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#_attribues' do
|
|
22
|
+
it 'should return an array of attribute names' do
|
|
23
|
+
store._attributes.should be_an Array
|
|
24
|
+
store._attributes.count.should be(2)
|
|
25
|
+
store._attributes.should include(:foo, :bar)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#reset!' do
|
|
30
|
+
it 'should clear all attributes set' do
|
|
31
|
+
store.reset!
|
|
32
|
+
store._attributes.should be_an Array
|
|
33
|
+
store._attributes.should be_empty
|
|
34
|
+
store.foo.should be_nil
|
|
35
|
+
store.bar.should be_nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe 'Backup::Configuration' do
|
|
6
|
+
|
|
7
|
+
after do
|
|
8
|
+
Backup::Configuration.send(:remove_const, 'Foo')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'should create modules for missing constants' do
|
|
12
|
+
Backup::Configuration::Foo.class.should == Module
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe 'a generated module' do
|
|
16
|
+
|
|
17
|
+
before do
|
|
18
|
+
module Backup
|
|
19
|
+
class Foo; end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
after do
|
|
24
|
+
Backup.send(:remove_const, 'Foo')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should create modules for missing constants' do
|
|
28
|
+
Backup::Configuration::Foo::A::B.class.should == Module
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should pass calls to .defaults to the proper class' do
|
|
32
|
+
Backup::Logger.expects(:warn)
|
|
33
|
+
Backup::Foo.expects(:defaults)
|
|
34
|
+
Backup::Configuration::Foo.defaults
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'should pass a given block to .defaults to the proper class' do
|
|
38
|
+
Backup::Logger.expects(:warn)
|
|
39
|
+
configuration = mock
|
|
40
|
+
Backup::Foo.expects(:defaults).yields(configuration)
|
|
41
|
+
configuration.expects(:foo=).with('bar')
|
|
42
|
+
|
|
43
|
+
Backup::Configuration::Foo.defaults do |config|
|
|
44
|
+
config.foo = 'bar'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should log a deprecation warning' do
|
|
49
|
+
Backup::Foo.stubs(:defaults)
|
|
50
|
+
Backup::Logger.expects(:warn).with do |err|
|
|
51
|
+
err.message.should ==
|
|
52
|
+
"ConfigurationError: [DEPRECATION WARNING]\n" +
|
|
53
|
+
" Backup::Configuration::Foo.defaults is being deprecated.\n" +
|
|
54
|
+
" To set pre-configured defaults for Backup::Foo, use:\n" +
|
|
55
|
+
" Backup::Foo.defaults"
|
|
56
|
+
end
|
|
57
|
+
Backup::Configuration::Foo.defaults
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Database::Base do
|
|
6
|
+
let(:model) { Backup::Model.new('foo', 'foo') }
|
|
7
|
+
let(:db) { Backup::Database::Base.new(model) }
|
|
8
|
+
|
|
9
|
+
it 'should include CLI::Helpers' do
|
|
10
|
+
Backup::Database::Base.
|
|
11
|
+
include?(Backup::CLI::Helpers).should be_true
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should include Configuration::Helpers' do
|
|
15
|
+
Backup::Database::Base.
|
|
16
|
+
include?(Backup::Configuration::Helpers).should be_true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe '#initialize' do
|
|
20
|
+
it 'should load pre-configured defaults' do
|
|
21
|
+
Backup::Database::Base.any_instance.expects(:load_defaults!)
|
|
22
|
+
db
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should set a reference to the model' do
|
|
26
|
+
db.instance_variable_get(:@model).should == model
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe '#perform!' do
|
|
31
|
+
it 'should invoke prepare! and log!' do
|
|
32
|
+
s = sequence ''
|
|
33
|
+
db.expects(:prepare!).in_sequence(s)
|
|
34
|
+
db.expects(:log!).in_sequence(s)
|
|
35
|
+
|
|
36
|
+
db.perform!
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe '#prepare!' do
|
|
41
|
+
it 'should set and create #dump_path' do
|
|
42
|
+
model = stub(:trigger => 'test_trigger')
|
|
43
|
+
db.instance_variable_set(:@model, model)
|
|
44
|
+
FileUtils.expects(:mkdir_p).with(
|
|
45
|
+
File.join(Backup::Config.tmp_path, 'test_trigger', 'databases', 'Base')
|
|
46
|
+
)
|
|
47
|
+
db.send(:prepare!)
|
|
48
|
+
db.instance_variable_get(:@dump_path).should ==
|
|
49
|
+
File.join(Backup::Config.tmp_path, 'test_trigger', 'databases', 'Base')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe '#log!' do
|
|
54
|
+
it 'should use #database_name' do
|
|
55
|
+
db.stubs(:name).returns('database_name')
|
|
56
|
+
Backup::Logger.expects(:message).with(
|
|
57
|
+
"Database::Base started dumping and archiving 'database_name'."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
db.send(:log!)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
4
|
+
|
|
5
|
+
describe Backup::Database::MongoDB do
|
|
6
|
+
let(:model) { Backup::Model.new(:test_trigger, 'test label') }
|
|
7
|
+
let(:db) do
|
|
8
|
+
Backup::Database::MongoDB.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
|
+
|
|
15
|
+
db.ipv6 = true
|
|
16
|
+
db.only_collections = ['users', 'pirates']
|
|
17
|
+
db.additional_options = ['--query', '--foo']
|
|
18
|
+
db.mongodump_utility = '/path/to/mongodump'
|
|
19
|
+
db.mongo_utility = '/path/to/mongo'
|
|
20
|
+
db.lock = true
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should be a subclass of Database::Base' do
|
|
25
|
+
Backup::Database::MongoDB.superclass.
|
|
26
|
+
should == Backup::Database::Base
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#initialize' do
|
|
30
|
+
|
|
31
|
+
it 'should load pre-configured defaults through Base' do
|
|
32
|
+
Backup::Database::MongoDB.any_instance.expects(:load_defaults!)
|
|
33
|
+
db
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should pass the model reference to Base' do
|
|
37
|
+
db.instance_variable_get(:@model).should == model
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'when no pre-configured defaults have been set' do
|
|
41
|
+
context 'when options are specified' do
|
|
42
|
+
it 'should use the given values' do
|
|
43
|
+
db.name.should == 'mydatabase'
|
|
44
|
+
db.username.should == 'someuser'
|
|
45
|
+
db.password.should == 'secret'
|
|
46
|
+
db.host.should == 'localhost'
|
|
47
|
+
db.port.should == 123
|
|
48
|
+
|
|
49
|
+
db.ipv6.should == true
|
|
50
|
+
db.only_collections.should == ['users', 'pirates']
|
|
51
|
+
db.additional_options.should == ['--query', '--foo']
|
|
52
|
+
db.mongodump_utility.should == '/path/to/mongodump'
|
|
53
|
+
db.mongo_utility.should == '/path/to/mongo'
|
|
54
|
+
db.lock.should == true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'when options are not specified' do
|
|
59
|
+
before do
|
|
60
|
+
Backup::Database::MongoDB.any_instance.expects(:utility).
|
|
61
|
+
with(:mongodump).returns('/real/mongodump')
|
|
62
|
+
Backup::Database::MongoDB.any_instance.expects(:utility).
|
|
63
|
+
with(:mongo).returns('/real/mongo')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should provide default values' do
|
|
67
|
+
db = Backup::Database::MongoDB.new(model)
|
|
68
|
+
|
|
69
|
+
db.name.should be_nil
|
|
70
|
+
db.username.should be_nil
|
|
71
|
+
db.password.should be_nil
|
|
72
|
+
db.host.should be_nil
|
|
73
|
+
db.port.should be_nil
|
|
74
|
+
|
|
75
|
+
db.ipv6.should be_false
|
|
76
|
+
db.only_collections.should == []
|
|
77
|
+
db.additional_options.should == []
|
|
78
|
+
db.mongodump_utility.should == '/real/mongodump'
|
|
79
|
+
db.mongo_utility.should == '/real/mongo'
|
|
80
|
+
db.lock.should be_false
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end # context 'when no pre-configured defaults have been set'
|
|
84
|
+
|
|
85
|
+
context 'when pre-configured defaults have been set' do
|
|
86
|
+
before do
|
|
87
|
+
Backup::Database::MongoDB.defaults do |db|
|
|
88
|
+
db.name = 'db_name'
|
|
89
|
+
db.username = 'db_username'
|
|
90
|
+
db.password = 'db_password'
|
|
91
|
+
db.host = 'db_host'
|
|
92
|
+
db.port = 789
|
|
93
|
+
|
|
94
|
+
db.ipv6 = 'default_ipv6'
|
|
95
|
+
db.only_collections = ['collection']
|
|
96
|
+
db.additional_options = ['--opt']
|
|
97
|
+
db.mongodump_utility = '/default/path/to/mongodump'
|
|
98
|
+
db.mongo_utility = '/default/path/to/mongo'
|
|
99
|
+
db.lock = 'default_lock'
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
after { Backup::Database::MongoDB.clear_defaults! }
|
|
104
|
+
|
|
105
|
+
context 'when options are specified' do
|
|
106
|
+
it 'should override the pre-configured defaults' do
|
|
107
|
+
db.name.should == 'mydatabase'
|
|
108
|
+
db.username.should == 'someuser'
|
|
109
|
+
db.password.should == 'secret'
|
|
110
|
+
db.host.should == 'localhost'
|
|
111
|
+
db.port.should == 123
|
|
112
|
+
|
|
113
|
+
db.ipv6.should == true
|
|
114
|
+
db.only_collections.should == ['users', 'pirates']
|
|
115
|
+
db.additional_options.should == ['--query', '--foo']
|
|
116
|
+
db.mongodump_utility.should == '/path/to/mongodump'
|
|
117
|
+
db.mongo_utility.should == '/path/to/mongo'
|
|
118
|
+
db.lock.should == true
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context 'when options are not specified' do
|
|
123
|
+
it 'should use the pre-configured defaults' do
|
|
124
|
+
db = Backup::Database::MongoDB.new(model)
|
|
125
|
+
|
|
126
|
+
db.name.should == 'db_name'
|
|
127
|
+
db.username.should == 'db_username'
|
|
128
|
+
db.password.should == 'db_password'
|
|
129
|
+
db.host.should == 'db_host'
|
|
130
|
+
db.port.should == 789
|
|
131
|
+
|
|
132
|
+
db.ipv6.should == 'default_ipv6'
|
|
133
|
+
db.only_collections.should == ['collection']
|
|
134
|
+
db.additional_options.should == ['--opt']
|
|
135
|
+
db.mongodump_utility.should == '/default/path/to/mongodump'
|
|
136
|
+
db.mongo_utility.should == '/default/path/to/mongo'
|
|
137
|
+
db.lock.should == 'default_lock'
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end # context 'when no pre-configured defaults have been set'
|
|
141
|
+
end # describe '#initialize'
|
|
142
|
+
|
|
143
|
+
describe '#perform!' do
|
|
144
|
+
let(:s) { sequence '' }
|
|
145
|
+
|
|
146
|
+
before do
|
|
147
|
+
# superclass actions
|
|
148
|
+
db.expects(:prepare!).in_sequence(s)
|
|
149
|
+
db.expects(:log!).in_sequence(s)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context 'when #lock is set to false' do
|
|
153
|
+
before { db.lock = false }
|
|
154
|
+
|
|
155
|
+
context 'when #only_collections has not been specified' do
|
|
156
|
+
before { db.only_collections = [] }
|
|
157
|
+
it 'should dump everything without locking' do
|
|
158
|
+
db.expects(:lock_database).never
|
|
159
|
+
db.expects(:unlock_database).never
|
|
160
|
+
db.expects(:specific_collection_dump!).never
|
|
161
|
+
|
|
162
|
+
db.expects(:dump!).in_sequence(s)
|
|
163
|
+
db.expects(:package!).in_sequence(s)
|
|
164
|
+
db.perform!
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
context 'when #only_collections has been specified' do
|
|
169
|
+
it 'should dump specific collections without locking' do
|
|
170
|
+
db.expects(:lock_database).never
|
|
171
|
+
db.expects(:unlock_database).never
|
|
172
|
+
db.expects(:dump!).never
|
|
173
|
+
|
|
174
|
+
db.expects(:specific_collection_dump!).in_sequence(s)
|
|
175
|
+
db.expects(:package!).in_sequence(s)
|
|
176
|
+
db.perform!
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end # context 'when #lock is set to false'
|
|
181
|
+
|
|
182
|
+
context 'when #lock is set to true' do
|
|
183
|
+
|
|
184
|
+
context 'when #only_collections has not been specified' do
|
|
185
|
+
before { db.only_collections = [] }
|
|
186
|
+
it 'should dump everything while locking the database' do
|
|
187
|
+
db.expects(:specific_collection_dump!).never
|
|
188
|
+
|
|
189
|
+
db.expects(:lock_database).in_sequence(s)
|
|
190
|
+
db.expects(:dump!).in_sequence(s)
|
|
191
|
+
db.expects(:unlock_database).in_sequence(s)
|
|
192
|
+
db.expects(:package!).in_sequence(s)
|
|
193
|
+
db.perform!
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context 'when #only_collections has been specified' do
|
|
198
|
+
it 'should dump specific collections without locking' do
|
|
199
|
+
db.expects(:lock_database).never
|
|
200
|
+
db.expects(:unlock_database).never
|
|
201
|
+
db.expects(:dump!).never
|
|
202
|
+
|
|
203
|
+
db.expects(:lock_database).in_sequence(s)
|
|
204
|
+
db.expects(:specific_collection_dump!).in_sequence(s)
|
|
205
|
+
db.expects(:unlock_database).in_sequence(s)
|
|
206
|
+
db.expects(:package!).in_sequence(s)
|
|
207
|
+
db.perform!
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end # context 'when #lock is set to true'
|
|
212
|
+
|
|
213
|
+
context 'when errors occur' do
|
|
214
|
+
it 'should re-raise error and skip package!' do
|
|
215
|
+
db.lock = false
|
|
216
|
+
|
|
217
|
+
db.expects(:specific_collection_dump!).in_sequence(s).
|
|
218
|
+
raises('Test Error Message')
|
|
219
|
+
db.expects(:package!).never
|
|
220
|
+
|
|
221
|
+
expect do
|
|
222
|
+
db.perform!
|
|
223
|
+
end.to raise_error(
|
|
224
|
+
Backup::Errors::Database::MongoDBError,
|
|
225
|
+
"Database::MongoDBError: Database Dump Failed!\n" +
|
|
226
|
+
" Reason: RuntimeError\n" +
|
|
227
|
+
" Test Error Message"
|
|
228
|
+
)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it 'should ensure database is unlocked' do
|
|
232
|
+
db.expects(:lock_database).in_sequence(s)
|
|
233
|
+
db.expects(:specific_collection_dump!).in_sequence(s).
|
|
234
|
+
raises('Test Error Message')
|
|
235
|
+
db.expects(:unlock_database).in_sequence(s)
|
|
236
|
+
db.expects(:package!).never
|
|
237
|
+
|
|
238
|
+
expect do
|
|
239
|
+
db.perform!
|
|
240
|
+
end.to raise_error(
|
|
241
|
+
Backup::Errors::Database::MongoDBError,
|
|
242
|
+
"Database::MongoDBError: Database Dump Failed!\n" +
|
|
243
|
+
" Reason: RuntimeError\n" +
|
|
244
|
+
" Test Error Message"
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
end # describe '#perform!'
|
|
250
|
+
|
|
251
|
+
describe '#dump!' do
|
|
252
|
+
it 'should run the mongodb dump command' do
|
|
253
|
+
db.expects(:mongodump).returns(:dump_command)
|
|
254
|
+
db.expects(:run).with(:dump_command)
|
|
255
|
+
db.send(:dump!)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe '#specific_collection_dump!' do
|
|
260
|
+
it 'should run the mongodb dump command for each collection' do
|
|
261
|
+
db.expects(:mongodump).twice.returns('dump_command')
|
|
262
|
+
db.expects(:run).with("dump_command --collection='users'")
|
|
263
|
+
db.expects(:run).with("dump_command --collection='pirates'")
|
|
264
|
+
db.send(:specific_collection_dump!)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
describe '#mongodump' do
|
|
269
|
+
before do
|
|
270
|
+
db.instance_variable_set(:@dump_path, '/path/to/dump/folder')
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'should return the mongodb dump command string' do
|
|
274
|
+
db.send(:mongodump).should == "/path/to/mongodump " +
|
|
275
|
+
"--db='mydatabase' --username='someuser' --password='secret' " +
|
|
276
|
+
"--host='localhost' --port='123' --ipv6 " +
|
|
277
|
+
"--query --foo --out='/path/to/dump/folder'"
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
describe '#package!' do
|
|
282
|
+
let(:compressor) { mock }
|
|
283
|
+
let(:pipeline) { mock }
|
|
284
|
+
let(:timestamp) { Time.now.to_i.to_s[-5, 5] }
|
|
285
|
+
let(:s) { sequence '' }
|
|
286
|
+
|
|
287
|
+
context 'when a compressor is configured' do
|
|
288
|
+
before do
|
|
289
|
+
Timecop.freeze(Time.now)
|
|
290
|
+
db.instance_variable_set(:@dump_path, '/path/to/dump/folder')
|
|
291
|
+
db.expects(:utility).with(:tar).returns('tar')
|
|
292
|
+
model.expects(:compressor).twice.returns(compressor)
|
|
293
|
+
compressor.expects(:compress_with).yields('compressor_command', '.gz')
|
|
294
|
+
Backup::Pipeline.expects(:new).returns(pipeline)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
context 'when pipeline command succeeds' do
|
|
298
|
+
it 'should package the dump directory, then remove it' do
|
|
299
|
+
|
|
300
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
301
|
+
"Database::MongoDB started compressing and packaging:\n" +
|
|
302
|
+
" '/path/to/dump/folder'"
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
306
|
+
"tar -cf - -C '/path/to/dump' 'folder'"
|
|
307
|
+
)
|
|
308
|
+
pipeline.expects(:<<).in_sequence(s).with('compressor_command')
|
|
309
|
+
pipeline.expects(:<<).in_sequence(s).with(
|
|
310
|
+
"cat > /path/to/dump/folder-#{ timestamp }.tar.gz"
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
pipeline.expects(:run).in_sequence(s)
|
|
314
|
+
pipeline.expects(:success?).in_sequence(s).returns(true)
|
|
315
|
+
Backup::Logger.expects(:message).in_sequence(s).with(
|
|
316
|
+
"Database::MongoDB completed compressing and packaging:\n" +
|
|
317
|
+
" '/path/to/dump/folder-#{ timestamp }.tar.gz'"
|
|
318
|
+
)
|
|
319
|
+
FileUtils.expects(:rm_rf).in_sequence(s).with('/path/to/dump/folder')
|
|
320
|
+
|
|
321
|
+
db.send(:package!)
|
|
322
|
+
end
|
|
323
|
+
end #context 'when pipeline command succeeds'
|
|
324
|
+
|
|
325
|
+
context 'when pipeline command fails' do
|
|
326
|
+
before do
|
|
327
|
+
pipeline.stubs(:<<)
|
|
328
|
+
pipeline.expects(:run)
|
|
329
|
+
pipeline.expects(:success?).returns(false)
|
|
330
|
+
pipeline.expects(:error_messages).returns('pipeline_errors')
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it 'should raise an error' do
|
|
334
|
+
Backup::Logger.expects(:message).with(
|
|
335
|
+
"Database::MongoDB started compressing and packaging:\n" +
|
|
336
|
+
" '/path/to/dump/folder'"
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
expect do
|
|
340
|
+
db.send(:package!)
|
|
341
|
+
end.to raise_error(
|
|
342
|
+
Backup::Errors::Database::PipelineError,
|
|
343
|
+
"Database::PipelineError: Database::MongoDB " +
|
|
344
|
+
"Failed to create compressed dump package:\n" +
|
|
345
|
+
" '/path/to/dump/folder-#{ timestamp }.tar.gz'\n" +
|
|
346
|
+
" pipeline_errors"
|
|
347
|
+
)
|
|
348
|
+
end
|
|
349
|
+
end # context 'when pipeline command fails'
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
context 'when a compressor is not configured' do
|
|
353
|
+
before do
|
|
354
|
+
model.expects(:compressor).returns(nil)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
it 'should return nil' do
|
|
358
|
+
Backup::Pipeline.expects(:new).never
|
|
359
|
+
db.send(:package!).should be_nil
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end # describe '#package!'
|
|
363
|
+
|
|
364
|
+
describe '#database' do
|
|
365
|
+
context 'when a database name is given' do
|
|
366
|
+
it 'should return the command string for the database' do
|
|
367
|
+
db.send(:database).should == "--db='mydatabase'"
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
context 'when no database name is given' do
|
|
372
|
+
it 'should return nil' do
|
|
373
|
+
db.name = nil
|
|
374
|
+
db.send(:database).should be_nil
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
describe '#credential_options' do
|
|
380
|
+
it 'should return the command string for the user credentials' do
|
|
381
|
+
db.send(:credential_options).should ==
|
|
382
|
+
"--username='someuser' --password='secret'"
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
describe '#connectivity_options' do
|
|
387
|
+
it 'should return the command string for the connectivity options' do
|
|
388
|
+
db.send(:connectivity_options).should == "--host='localhost' --port='123'"
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
describe '#ipv6_option' do
|
|
393
|
+
context 'when #ipv6 is set true' do
|
|
394
|
+
it 'should return the command string for the ipv6 option' do
|
|
395
|
+
db.send(:ipv6_option).should == '--ipv6'
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
context 'when #ipv6 is set false' do
|
|
400
|
+
it 'should return and empty string' do
|
|
401
|
+
db.ipv6 = false
|
|
402
|
+
db.send(:ipv6_option).should == ''
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
describe '#user_options' do
|
|
408
|
+
context 'when #additional_options are set' do
|
|
409
|
+
it 'should return the command string for the options' do
|
|
410
|
+
db.send(:user_options).should == '--query --foo'
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
context 'when #additional_options are not set' do
|
|
415
|
+
it 'should return an empty string' do
|
|
416
|
+
db.additional_options = []
|
|
417
|
+
db.send(:user_options).should == ''
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
describe '#dump_directory' do
|
|
423
|
+
it 'should return the command string for the dump path' do
|
|
424
|
+
db.instance_variable_set(:@dump_path, '/path/to/dump/folder')
|
|
425
|
+
db.send(:dump_directory).should == "--out='/path/to/dump/folder'"
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
describe '#lock_database' do
|
|
430
|
+
it 'should return the command to lock the database' do
|
|
431
|
+
db.stubs(:mongo_uri).returns(:mongo_uri_output)
|
|
432
|
+
db.expects(:run).with(
|
|
433
|
+
" echo 'use admin\n" +
|
|
434
|
+
' db.runCommand({"fsync" : 1, "lock" : 1})\' | /path/to/mongo mongo_uri_output' +
|
|
435
|
+
"\n"
|
|
436
|
+
)
|
|
437
|
+
db.send(:lock_database)
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
describe '#unlock_database' do
|
|
442
|
+
it 'should return the command to unlock the database' do
|
|
443
|
+
db.stubs(:mongo_uri).returns(:mongo_uri_output)
|
|
444
|
+
db.expects(:run).with(
|
|
445
|
+
" echo 'use admin\n" +
|
|
446
|
+
' db.$cmd.sys.unlock.findOne()\' | /path/to/mongo mongo_uri_output' +
|
|
447
|
+
"\n"
|
|
448
|
+
)
|
|
449
|
+
db.send(:unlock_database)
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
describe '#mongo_uri' do
|
|
454
|
+
before do
|
|
455
|
+
db.stubs(:credential_options).returns(:credential_options_output)
|
|
456
|
+
db.stubs(:ipv6_option).returns(:ipv6_option_output)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
context 'when a database name is given' do
|
|
460
|
+
it 'should return the URI specifying the database' do
|
|
461
|
+
db.send(:mongo_uri).should ==
|
|
462
|
+
"localhost:123/mydatabase credential_options_output ipv6_option_output"
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
context 'when no database name is given' do
|
|
467
|
+
it 'should return the URI without specifying the database' do
|
|
468
|
+
db.name = nil
|
|
469
|
+
db.send(:mongo_uri).should ==
|
|
470
|
+
"localhost:123 credential_options_output ipv6_option_output"
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
describe 'deprecations' do
|
|
476
|
+
describe '#utility_path' do
|
|
477
|
+
before do
|
|
478
|
+
Backup::Database::MongoDB.any_instance.stubs(:utility)
|
|
479
|
+
Backup::Logger.expects(:warn).with {|err|
|
|
480
|
+
err.should be_an_instance_of Backup::Errors::ConfigurationError
|
|
481
|
+
err.message.should match(
|
|
482
|
+
/Use MongoDB#mongodump_utility instead/
|
|
483
|
+
)
|
|
484
|
+
}
|
|
485
|
+
end
|
|
486
|
+
after do
|
|
487
|
+
Backup::Database::MongoDB.clear_defaults!
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
context 'when set directly' do
|
|
491
|
+
it 'should issue a deprecation warning and set the replacement value' do
|
|
492
|
+
mongodb = Backup::Database::MongoDB.new(model) do |db|
|
|
493
|
+
db.utility_path = 'foo'
|
|
494
|
+
end
|
|
495
|
+
mongodb.mongodump_utility.should == 'foo'
|
|
496
|
+
end
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
context 'when set as a default' do
|
|
500
|
+
it 'should issue a deprecation warning and set the replacement value' do
|
|
501
|
+
mongodb = Backup::Database::MongoDB.defaults do |db|
|
|
502
|
+
db.utility_path = 'foo'
|
|
503
|
+
end
|
|
504
|
+
mongodb = Backup::Database::MongoDB.new(model)
|
|
505
|
+
mongodb.mongodump_utility.should == 'foo'
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
end # describe '#utility_path'
|
|
509
|
+
end
|
|
510
|
+
end
|