webtranslateit-safe 0.4.0

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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +3 -0
  3. data/.document +5 -0
  4. data/.github/dependabot.yml +26 -0
  5. data/.github/release-drafter.yml +36 -0
  6. data/.github/workflows/ci.yml +51 -0
  7. data/.github/workflows/release-drafter.yml +29 -0
  8. data/.gitignore +18 -0
  9. data/.rspec +3 -0
  10. data/.rubocop.yml +8 -0
  11. data/.rubocop_todo.yml +552 -0
  12. data/CHANGELOG +42 -0
  13. data/Gemfile +11 -0
  14. data/Gemfile.lock +89 -0
  15. data/LICENSE.txt +22 -0
  16. data/README.markdown +237 -0
  17. data/Rakefile +8 -0
  18. data/TODO +31 -0
  19. data/bin/webtranslateit-safe +64 -0
  20. data/lib/extensions/mktmpdir.rb +45 -0
  21. data/lib/webtranslateit/safe/archive.rb +29 -0
  22. data/lib/webtranslateit/safe/backup.rb +27 -0
  23. data/lib/webtranslateit/safe/cloudfiles.rb +77 -0
  24. data/lib/webtranslateit/safe/config/builder.rb +100 -0
  25. data/lib/webtranslateit/safe/config/node.rb +79 -0
  26. data/lib/webtranslateit/safe/ftp.rb +85 -0
  27. data/lib/webtranslateit/safe/gpg.rb +52 -0
  28. data/lib/webtranslateit/safe/gzip.rb +29 -0
  29. data/lib/webtranslateit/safe/local.rb +55 -0
  30. data/lib/webtranslateit/safe/mongodump.rb +30 -0
  31. data/lib/webtranslateit/safe/mysqldump.rb +36 -0
  32. data/lib/webtranslateit/safe/pgdump.rb +36 -0
  33. data/lib/webtranslateit/safe/pipe.rb +23 -0
  34. data/lib/webtranslateit/safe/s3.rb +80 -0
  35. data/lib/webtranslateit/safe/sftp.rb +96 -0
  36. data/lib/webtranslateit/safe/sink.rb +40 -0
  37. data/lib/webtranslateit/safe/source.rb +51 -0
  38. data/lib/webtranslateit/safe/stream.rb +40 -0
  39. data/lib/webtranslateit/safe/svndump.rb +17 -0
  40. data/lib/webtranslateit/safe/tmp_file.rb +53 -0
  41. data/lib/webtranslateit/safe/version.rb +9 -0
  42. data/lib/webtranslateit/safe.rb +70 -0
  43. data/spec/integration/archive_integration_spec.rb +89 -0
  44. data/spec/integration/cleanup_spec.rb +62 -0
  45. data/spec/spec_helper.rb +7 -0
  46. data/spec/webtranslateit/safe/archive_spec.rb +67 -0
  47. data/spec/webtranslateit/safe/cloudfiles_spec.rb +175 -0
  48. data/spec/webtranslateit/safe/config_spec.rb +307 -0
  49. data/spec/webtranslateit/safe/gpg_spec.rb +148 -0
  50. data/spec/webtranslateit/safe/gzip_spec.rb +64 -0
  51. data/spec/webtranslateit/safe/local_spec.rb +109 -0
  52. data/spec/webtranslateit/safe/mongodump_spec.rb +54 -0
  53. data/spec/webtranslateit/safe/mysqldump_spec.rb +83 -0
  54. data/spec/webtranslateit/safe/pgdump_spec.rb +45 -0
  55. data/spec/webtranslateit/safe/s3_spec.rb +168 -0
  56. data/spec/webtranslateit/safe/svndump_spec.rb +39 -0
  57. data/templates/script.rb +183 -0
  58. data/webtranslateit-safe.gemspec +32 -0
  59. metadata +149 -0
@@ -0,0 +1,307 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebTranslateIt::Safe::Config do
4
+ it 'parses example config' do
5
+ config = WebTranslateIt::Safe::Config::Node.new do
6
+
7
+ dry_run false
8
+ local_only true
9
+ verbose true
10
+
11
+ local do
12
+ path 'path'
13
+ end
14
+
15
+ s3 do
16
+ key 's3 key'
17
+ secret 'secret'
18
+ bucket 'bucket'
19
+ path 'path1'
20
+ end
21
+
22
+ sftp do
23
+ user 'sftp user'
24
+ password 'sftp password'
25
+ host 'sftp host'
26
+ end
27
+
28
+ gpg do
29
+ password 'astrails'
30
+ key 'gpg-key'
31
+ end
32
+
33
+ keep do
34
+ s3 20
35
+ local 4
36
+ end
37
+
38
+ mysqldump do
39
+ options '-ceKq --single-transaction --create-options'
40
+
41
+ user 'astrails'
42
+ password ''
43
+ host 'localhost'
44
+ port 3306
45
+ socket '/var/run/mysqld/mysqld.sock'
46
+
47
+ database :blog
48
+
49
+ database :production do
50
+ keep local: 3
51
+
52
+ gpg do
53
+ password 'custom-production-pass'
54
+ end
55
+
56
+ skip_tables [:logger_exceptions, :request_logs]
57
+ end
58
+
59
+ end
60
+
61
+ pgdump do
62
+ options '-i -x -O'
63
+
64
+ user 'astrails'
65
+ password ''
66
+ host 'localhost'
67
+ port 5432
68
+
69
+ database :blog
70
+
71
+ database :production do
72
+ keep local: 3
73
+
74
+ skip_tables [:logger_exceptions, :request_logs]
75
+ end
76
+
77
+ end
78
+
79
+ svndump do
80
+ repo :my_repo do
81
+ repo_path '/home/svn/my_repo'
82
+ end
83
+ end
84
+
85
+ tar do
86
+ archive 'git-repositories' do
87
+ files '/home/git/repositories'
88
+ end
89
+
90
+ archive 'etc-files' do
91
+ files '/etc'
92
+ exclude '/etc/puppet/other'
93
+ end
94
+
95
+ archive 'dot-configs' do
96
+ files '/home/*/.[^.]*'
97
+ end
98
+
99
+ archive 'blog' do
100
+ files '/var/www/blog.astrails.com/'
101
+ exclude ['/var/www/blog.astrails.com/log', '/var/www/blog.astrails.com/tmp']
102
+ end
103
+
104
+ archive :misc do
105
+ files ['/backup/*.rb']
106
+ end
107
+ end
108
+
109
+ mongodump do
110
+ host 'host'
111
+ database 'database'
112
+ user 'user'
113
+ password 'password'
114
+ end
115
+ end
116
+
117
+ expected = {
118
+ 'dry_run' => false,
119
+ 'local_only' => true,
120
+ 'verbose' => true,
121
+
122
+ 'local' => {'path' => 'path'},
123
+
124
+ 's3' => {
125
+ 'key' => 's3 key',
126
+ 'secret' => 'secret',
127
+ 'bucket' => 'bucket',
128
+ 'path' => 'path1'
129
+ },
130
+
131
+ 'sftp' => {
132
+ 'user' => 'sftp user',
133
+ 'password' => 'sftp password',
134
+ 'host' => 'sftp host'
135
+ },
136
+
137
+ 'gpg' => {'password' => 'astrails', 'key' => 'gpg-key'},
138
+
139
+ 'keep' => {'s3' => 20, 'local' => 4},
140
+
141
+ 'mysqldump' => {
142
+ 'options' => '-ceKq --single-transaction --create-options',
143
+ 'user' => 'astrails',
144
+ 'password' => '',
145
+ 'host' => 'localhost',
146
+ 'port' => 3306,
147
+ 'socket' => '/var/run/mysqld/mysqld.sock',
148
+
149
+ 'databases' => {
150
+ 'blog' => {},
151
+ 'production' => {
152
+ 'keep' => {'local' => 3},
153
+ 'gpg' => {'password' => 'custom-production-pass'},
154
+ 'skip_tables' => ['logger_exceptions', 'request_logs']
155
+ }
156
+ }
157
+ },
158
+
159
+ 'pgdump' => {
160
+ 'options' => '-i -x -O',
161
+ 'user' => 'astrails',
162
+ 'password' => '',
163
+ 'host' => 'localhost',
164
+ 'port' => 5432,
165
+
166
+ 'databases' => {
167
+ 'blog' => {},
168
+ 'production' => {
169
+ 'keep' => {'local' => 3},
170
+ 'skip_tables' => ['logger_exceptions', 'request_logs']
171
+ }
172
+ }
173
+ },
174
+
175
+ 'svndump' => {
176
+ 'repos' => {
177
+ 'my_repo' => {
178
+ 'repo_path' => '/home/svn/my_repo'
179
+ }
180
+ }
181
+ },
182
+
183
+ 'tar' => {
184
+ 'archives' => {
185
+ 'git-repositories' => {'files' => ['/home/git/repositories']},
186
+ 'etc-files' => {'files' => ['/etc'], 'exclude' => ['/etc/puppet/other']},
187
+ 'dot-configs' => {'files' => ['/home/*/.[^.]*']},
188
+ 'blog' => {
189
+ 'files' => ['/var/www/blog.astrails.com/'],
190
+ 'exclude' => ['/var/www/blog.astrails.com/log', '/var/www/blog.astrails.com/tmp']
191
+ },
192
+ 'misc' => {'files' => ['/backup/*.rb']}
193
+ }
194
+ },
195
+
196
+ 'mongodump' => {
197
+ 'host' => 'host',
198
+ 'databases' => {
199
+ 'database' => {}
200
+ },
201
+ 'user' => 'user',
202
+ 'password' => 'password'
203
+ }
204
+ }
205
+
206
+ config.to_hash.should == expected
207
+ end
208
+
209
+ it 'makes an array from multivalues' do
210
+ config = WebTranslateIt::Safe::Config::Node.new do
211
+ skip_tables 'a'
212
+ skip_tables 'b'
213
+ files '/foo'
214
+ files '/bar'
215
+ exclude '/foo/bar'
216
+ exclude '/foo/bar/baz'
217
+ end
218
+
219
+ expected = {
220
+ 'skip_tables' => ['a', 'b'],
221
+ 'files' => ['/foo', '/bar'],
222
+ 'exclude' => ['/foo/bar', '/foo/bar/baz']
223
+ }
224
+
225
+ config.to_hash.should == expected
226
+ end
227
+
228
+ it 'raises error on key duplication' do
229
+ proc do
230
+ WebTranslateIt::Safe::Config::Node.new do
231
+ path 'foo'
232
+ path 'bar'
233
+ end
234
+ end.should raise_error(ArgumentError, "duplicate value for 'path'")
235
+ end
236
+
237
+ it 'accepts hash as data' do
238
+ WebTranslateIt::Safe::Config::Node.new do
239
+ tar do
240
+ archive 'blog', files: 'foo', exclude: ['aaa', 'bbb']
241
+ end
242
+ end.to_hash.should == {
243
+ 'tar' => {
244
+ 'archives' => {
245
+ 'blog' => {
246
+ 'files' => ['foo'],
247
+ 'exclude' => ['aaa', 'bbb']
248
+ }
249
+ }
250
+ }
251
+ }
252
+ end
253
+
254
+ it 'accepts hash as data and a block' do
255
+ WebTranslateIt::Safe::Config::Node.new do
256
+ tar do
257
+ archive 'blog', files: 'foo' do
258
+ exclude ['aaa', 'bbb']
259
+ end
260
+ end
261
+ end.to_hash.should == {
262
+ 'tar' => {
263
+ 'archives' => {
264
+ 'blog' => {
265
+ 'files' => ['foo'],
266
+ 'exclude' => ['aaa', 'bbb']
267
+ }
268
+ }
269
+ }
270
+ }
271
+ end
272
+
273
+ it 'accepts multiple levels of data hash' do
274
+ config = WebTranslateIt::Safe::Config::Node.new nil, tar: {
275
+ s3: {bucket: '_bucket', key: '_key', secret: '_secret'},
276
+ keep: {s3: 2}
277
+ }
278
+
279
+ config.to_hash.should == {
280
+ 'tar' => {
281
+ 's3' => {'bucket' => '_bucket', 'key' => '_key', 'secret' => '_secret'},
282
+ 'keep' => {'s3' => 2}
283
+ }
284
+ }
285
+ end
286
+
287
+ it 'sets multi value as array' do
288
+ config = WebTranslateIt::Safe::Config::Node.new do
289
+ tar do
290
+ archive 'foo' do
291
+ files 'bar'
292
+ end
293
+ end
294
+ end
295
+
296
+ config.to_hash.should == {
297
+ 'tar' => {
298
+ 'archives' => {
299
+ 'foo' => {
300
+ 'files' => ['bar']
301
+ }
302
+ }
303
+ }
304
+ }
305
+ end
306
+
307
+ end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebTranslateIt::Safe::Gpg do
4
+ def def_backup
5
+ {
6
+ compressed: false,
7
+ command: 'command',
8
+ extension: '.foo',
9
+ filename: 'qweqwe'
10
+ }
11
+ end
12
+
13
+ def gpg(config = {}, backup = def_backup)
14
+ WebTranslateIt::Safe::Gpg.new(
15
+ WebTranslateIt::Safe::Config::Node.new(nil, config),
16
+ WebTranslateIt::Safe::Backup.new(backup)
17
+ )
18
+ end
19
+
20
+ after(:each) { WebTranslateIt::Safe::TmpFile.cleanup }
21
+
22
+ describe :process do
23
+
24
+ before(:each) do
25
+ @gpg = gpg
26
+ stub(@gpg).gpg_password_file { 'pwd-file' }
27
+ stub(@gpg).pipe { '|gpg -BLAH' }
28
+ end
29
+
30
+ describe 'when active' do
31
+ before(:each) do
32
+ stub(@gpg).active? { true }
33
+ end
34
+
35
+ it 'adds .gpg extension' do
36
+ mock(@gpg.backup.extension) << '.gpg'
37
+ @gpg.process
38
+ end
39
+
40
+ it 'adds command pipe' do
41
+ mock(@gpg.backup.command) << (/\|gpg -BLAH/)
42
+ @gpg.process
43
+ end
44
+
45
+ it 'sets compressed' do
46
+ mock(@gpg.backup).compressed = true
47
+ @gpg.process
48
+ end
49
+ end
50
+
51
+ describe 'when inactive' do
52
+ before(:each) do
53
+ stub(@gpg).active? { false }
54
+ end
55
+
56
+ it 'does not touch extension' do
57
+ dont_allow(@gpg.backup.extension) << anything
58
+ @gpg.process
59
+ end
60
+
61
+ it 'does not touch command' do
62
+ dont_allow(@gpg.backup.command) << anything
63
+ @gpg.process
64
+ end
65
+
66
+ it 'does not touch compressed' do
67
+ dont_allow(@gpg.backup).compressed = anything
68
+ @gpg.process
69
+ end
70
+ end
71
+ end
72
+
73
+ describe :active? do
74
+
75
+ describe 'with key' do
76
+ it 'is true' do
77
+ expect(gpg(gpg: {key: :foo})).to be_active
78
+ end
79
+ end
80
+
81
+ describe 'with password' do
82
+ it 'is true' do
83
+ expect(gpg(gpg: {password: :foo})).to be_active
84
+ end
85
+ end
86
+
87
+ describe 'without key & password' do
88
+ it 'is false' do
89
+ expect(gpg).not_to be_active
90
+ end
91
+ end
92
+
93
+ describe 'with key & password' do
94
+ it 'raises RuntimeError' do
95
+ lambda {
96
+ gpg(gpg: {key: 'foo', password: 'bar'}).send :active?
97
+ }.should raise_error(RuntimeError, "can't use both gpg password and pubkey")
98
+ end
99
+ end
100
+ end
101
+
102
+ describe :pipe do
103
+
104
+ describe 'with key' do
105
+ def kgpg(extra = {})
106
+ gpg({gpg: {key: 'foo', options: 'GPG-OPT'}.merge(extra), options: 'OPT'})
107
+ end
108
+
109
+ it 'does not call gpg_password_file' do
110
+ g = kgpg
111
+ dont_allow(g).gpg_password_file(anything)
112
+ g.send(:pipe)
113
+ end
114
+
115
+ it "uses '-r' and :options" do
116
+ kgpg.send(:pipe).should == '|gpg GPG-OPT -e -r foo'
117
+ end
118
+
119
+ it "uses the 'command' options" do
120
+ kgpg(command: 'other-gpg').send(:pipe).should == '|other-gpg GPG-OPT -e -r foo'
121
+ end
122
+ end
123
+
124
+ describe 'with password' do
125
+ def pgpg(extra = {})
126
+ returning(gpg({gpg: {password: 'bar', options: 'GPG-OPT'}.merge(extra), options: 'OPT'})) do |g|
127
+ stub(g).gpg_password_file(anything) { 'pass-file' }
128
+ end
129
+ end
130
+
131
+ it "uses '--passphrase-file' and :options" do
132
+ pgpg.send(:pipe).should == '|gpg GPG-OPT -c --passphrase-file pass-file'
133
+ end
134
+
135
+ it "uses the 'command' options" do
136
+ pgpg(command: 'other-gpg').send(:pipe).should == '|other-gpg GPG-OPT -c --passphrase-file pass-file'
137
+ end
138
+ end
139
+ end
140
+
141
+ describe :gpg_password_file do
142
+ it 'creates password file' do
143
+ file = gpg.send(:gpg_password_file, 'foo')
144
+ expect(File.exist?(file)).to be true
145
+ File.read(file).should == 'foo'
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebTranslateIt::Safe::Gzip do
4
+
5
+ def def_backup
6
+ {
7
+ compressed: false,
8
+ command: 'command',
9
+ extension: '.foo',
10
+ filename: 'qweqwe'
11
+ }
12
+ end
13
+
14
+ after(:each) { WebTranslateIt::Safe::TmpFile.cleanup }
15
+
16
+ def gzip(config = {}, backup = def_backup)
17
+ WebTranslateIt::Safe::Gzip.new(
18
+ @config = WebTranslateIt::Safe::Config::Node.new(nil, config),
19
+ @backup = WebTranslateIt::Safe::Backup.new(backup)
20
+ )
21
+ end
22
+
23
+ describe :preocess do
24
+
25
+ describe 'when not yet compressed' do
26
+ before(:each) { @gzip = gzip }
27
+
28
+ it 'adds .gz extension' do
29
+ mock(@backup.extension) << '.gz'
30
+ @gzip.process
31
+ end
32
+
33
+ it 'adds |gzip pipe' do
34
+ mock(@backup.command) << '|gzip'
35
+ @gzip.process
36
+ end
37
+
38
+ it 'sets compressed' do
39
+ mock(@backup).compressed = true
40
+ @gzip.process
41
+ end
42
+ end
43
+
44
+ describe 'when already compressed' do
45
+
46
+ before(:each) { @gzip = gzip({}, extension: '.foo', command: 'foobar', compressed: true) }
47
+
48
+ it 'does not touch extension' do
49
+ @gzip.process
50
+ @backup.extension.should == '.foo'
51
+ end
52
+
53
+ it 'does not touch command' do
54
+ @gzip.process
55
+ @backup.command.should == 'foobar'
56
+ end
57
+
58
+ it 'does not touch compressed' do
59
+ @gzip.process
60
+ @backup.compressed.should == true
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebTranslateIt::Safe::Local do
4
+ def def_config
5
+ {
6
+ local: {
7
+ path: '/:kind~:id~:timestamp'
8
+ },
9
+ keep: {
10
+ local: 2
11
+ }
12
+ }
13
+ end
14
+
15
+ def def_backup
16
+ {
17
+ kind: 'mysqldump',
18
+ id: 'blog',
19
+ timestamp: 'NoW',
20
+ compressed: true,
21
+ command: 'command',
22
+ extension: '.foo.gz',
23
+ filename: 'qweqwe'
24
+ }
25
+ end
26
+
27
+ def local(config = def_config, backup = def_backup)
28
+ WebTranslateIt::Safe::Local.new(
29
+ @config = WebTranslateIt::Safe::Config::Node.new(nil, config),
30
+ @backup = WebTranslateIt::Safe::Backup.new(backup)
31
+ )
32
+ end
33
+
34
+ describe :active? do
35
+ it 'is true' do
36
+ expect(local).to be_active
37
+ end
38
+ end
39
+
40
+ describe :path do
41
+ it 'raises RuntimeError when no path' do
42
+ lambda {
43
+ local({}).send :path
44
+ }.should raise_error(RuntimeError, 'missing :local/:path')
45
+ end
46
+
47
+ it 'uses local/path' do
48
+ local.send(:path).should == '/mysqldump~blog~NoW'
49
+ end
50
+ end
51
+
52
+ describe :save do
53
+ before(:each) do
54
+ @local = local
55
+ stub(@local).system
56
+ stub(@local).full_path { 'file-path' }
57
+ stub(FileUtils).mkdir_p
58
+ end
59
+
60
+ it 'calls system to save the file' do
61
+ mock(@local).system('command>file-path')
62
+ @local.send(:save)
63
+ end
64
+
65
+ it 'creates directory' do
66
+ mock(FileUtils).mkdir_p('/mysqldump~blog~NoW')
67
+ @local.send(:save)
68
+ end
69
+
70
+ it 'sets backup.path' do
71
+ mock(@backup).path = 'file-path'
72
+ @local.send(:save)
73
+ end
74
+
75
+ describe 'dry run' do
76
+ before(:each) { @local.config[:dry_run] = true }
77
+
78
+ it 'should not create directory'
79
+ it 'should not call system'
80
+ it 'sets backup.path' do
81
+ mock(@backup).path = 'file-path'
82
+ @local.send(:save)
83
+ end
84
+ end
85
+ end
86
+
87
+ describe :cleanup do
88
+ before(:each) do
89
+ @files = [4, 1, 3, 2].map { |i| "/mysqldump~blog~NoW/qweqwe.#{i}" }
90
+ stub(File).file?(anything) { true }
91
+ stub(File).size(anything) { 1 }
92
+ stub(File).unlink
93
+ end
94
+
95
+ it 'checks [:keep, :local]' do
96
+ @local = local(def_config.merge(keep: {}))
97
+ dont_allow(Dir).[]
98
+ @local.send :cleanup
99
+ end
100
+
101
+ it 'deletes extra files' do
102
+ @local = local
103
+ mock(Dir).[]('/mysqldump~blog~NoW/qweqwe.*') { @files }
104
+ mock(File).unlink('/mysqldump~blog~NoW/qweqwe.1')
105
+ mock(File).unlink('/mysqldump~blog~NoW/qweqwe.2')
106
+ @local.send :cleanup
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe WebTranslateIt::Safe::Mongodump do
4
+ def def_config
5
+ {
6
+ host: 'prod.example.com',
7
+ user: 'testuser',
8
+ password: 'p4ssw0rd'
9
+ }
10
+ end
11
+
12
+ def mongodump(id = :foo, config = def_config)
13
+ WebTranslateIt::Safe::Mongodump.new(id, WebTranslateIt::Safe::Config::Node.new(nil, config))
14
+ end
15
+
16
+ before(:each) do
17
+ stub(Time).now.stub!.strftime { 'NOW' }
18
+ @output_folder = File.join(WebTranslateIt::Safe::TmpFile.tmproot, 'mongodump')
19
+ end
20
+
21
+ after(:each) { WebTranslateIt::Safe::TmpFile.cleanup }
22
+
23
+ describe :backup do
24
+ before(:each) do
25
+ @mongo = mongodump
26
+ end
27
+
28
+ {
29
+ id: 'foo',
30
+ kind: 'mongodump',
31
+ extension: '.tar',
32
+ filename: 'mongodump-foo.NOW'
33
+ }.each do |k, v|
34
+ it "sets #{k} to #{v}" do
35
+ @mongo.backup.send(k).should == v
36
+ end
37
+ end
38
+
39
+ it 'sets the command' do
40
+ @mongo.backup.send(:command).should == "mongodump -q \"{xxxx : { \\$ne : 0 } }\" --db foo --host prod.example.com -u testuser -p p4ssw0rd --out #{@output_folder} && cd #{@output_folder} && tar cf - ."
41
+ end
42
+
43
+ {
44
+ host: '--host ',
45
+ user: '-u ',
46
+ password: '-p '
47
+ }.each do |key, v|
48
+ it "does not add #{key} to command if it is not present" do
49
+ @mongo = mongodump(:foo, def_config.reject! { |k, _v| k == key })
50
+ @mongo.backup.send(:command).should_not =~ /#{v}/
51
+ end
52
+ end
53
+ end
54
+ end