backup 3.0.27 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/LICENSE.md +1 -1
  2. data/README.md +139 -386
  3. data/bin/backup +1 -7
  4. data/lib/backup.rb +3 -9
  5. data/lib/backup/archive.rb +26 -20
  6. data/lib/backup/cleaner.rb +2 -2
  7. data/lib/backup/cli.rb +366 -0
  8. data/lib/backup/compressor/base.rb +2 -2
  9. data/lib/backup/compressor/gzip.rb +35 -1
  10. data/lib/backup/config.rb +1 -2
  11. data/lib/backup/database/base.rb +2 -2
  12. data/lib/backup/database/mongodb.rb +3 -3
  13. data/lib/backup/database/mysql.rb +3 -2
  14. data/lib/backup/database/postgresql.rb +3 -2
  15. data/lib/backup/database/riak.rb +18 -5
  16. data/lib/backup/dependency.rb +144 -93
  17. data/lib/backup/encryptor/base.rb +2 -2
  18. data/lib/backup/logger.rb +108 -110
  19. data/lib/backup/logger/console.rb +51 -0
  20. data/lib/backup/logger/logfile.rb +113 -0
  21. data/lib/backup/logger/syslog.rb +116 -0
  22. data/lib/backup/model.rb +67 -65
  23. data/lib/backup/notifier/base.rb +1 -1
  24. data/lib/backup/notifier/hipchat.rb +1 -1
  25. data/lib/backup/notifier/mail.rb +1 -1
  26. data/lib/backup/notifier/pushover.rb +6 -3
  27. data/lib/backup/packager.rb +4 -4
  28. data/lib/backup/pipeline.rb +17 -3
  29. data/lib/backup/splitter.rb +2 -2
  30. data/lib/backup/storage/base.rb +2 -2
  31. data/lib/backup/storage/cloudfiles.rb +2 -2
  32. data/lib/backup/storage/dropbox.rb +4 -4
  33. data/lib/backup/storage/ftp.rb +2 -2
  34. data/lib/backup/storage/local.rb +2 -2
  35. data/lib/backup/storage/ninefold.rb +2 -2
  36. data/lib/backup/storage/rsync.rb +3 -3
  37. data/lib/backup/storage/s3.rb +2 -2
  38. data/lib/backup/storage/scp.rb +2 -6
  39. data/lib/backup/storage/sftp.rb +2 -5
  40. data/lib/backup/syncer/base.rb +1 -1
  41. data/lib/backup/syncer/cloud/base.rb +15 -8
  42. data/lib/backup/syncer/rsync/local.rb +1 -1
  43. data/lib/backup/syncer/rsync/pull.rb +1 -1
  44. data/lib/backup/syncer/rsync/push.rb +1 -1
  45. data/lib/backup/utilities.rb +211 -0
  46. data/lib/backup/version.rb +1 -1
  47. data/templates/cli/{utility/archive → archive} +4 -8
  48. data/templates/cli/{utility/compressor → compressor}/bzip2 +0 -0
  49. data/templates/cli/{utility/compressor → compressor}/custom +0 -0
  50. data/templates/cli/{utility/compressor → compressor}/gzip +0 -0
  51. data/templates/cli/{utility/compressor → compressor}/lzma +0 -0
  52. data/templates/cli/{utility/compressor → compressor}/pbzip2 +0 -0
  53. data/templates/cli/config +68 -0
  54. data/templates/cli/{utility/database → database}/mongodb +1 -1
  55. data/templates/cli/{utility/database → database}/mysql +1 -1
  56. data/templates/cli/{utility/database → database}/postgresql +1 -1
  57. data/templates/cli/{utility/database → database}/redis +0 -0
  58. data/templates/cli/database/riak +20 -0
  59. data/templates/cli/{utility/encryptor → encryptor}/gpg +0 -0
  60. data/templates/cli/{utility/encryptor → encryptor}/openssl +0 -0
  61. data/templates/cli/{utility/model.erb → model.erb} +4 -4
  62. data/templates/cli/{utility/notifier → notifier}/campfire +0 -0
  63. data/templates/cli/{utility/notifier → notifier}/hipchat +0 -0
  64. data/templates/cli/{utility/notifier → notifier}/mail +0 -0
  65. data/templates/cli/{utility/notifier → notifier}/prowl +0 -0
  66. data/templates/cli/{utility/notifier → notifier}/pushover +0 -0
  67. data/templates/cli/{utility/notifier → notifier}/twitter +0 -0
  68. data/templates/cli/{utility/splitter → splitter} +0 -0
  69. data/templates/cli/{utility/storage → storage}/cloud_files +0 -0
  70. data/templates/cli/{utility/storage → storage}/dropbox +0 -0
  71. data/templates/cli/{utility/storage → storage}/ftp +0 -0
  72. data/templates/cli/{utility/storage → storage}/local +0 -0
  73. data/templates/cli/{utility/storage → storage}/ninefold +0 -0
  74. data/templates/cli/{utility/storage → storage}/rsync +0 -0
  75. data/templates/cli/{utility/storage → storage}/s3 +0 -0
  76. data/templates/cli/{utility/storage → storage}/scp +0 -0
  77. data/templates/cli/{utility/storage → storage}/sftp +0 -0
  78. data/templates/cli/{utility/syncer → syncer}/cloud_files +0 -0
  79. data/templates/cli/{utility/syncer → syncer}/rsync_local +0 -0
  80. data/templates/cli/{utility/syncer → syncer}/rsync_pull +0 -0
  81. data/templates/cli/{utility/syncer → syncer}/rsync_push +0 -0
  82. data/templates/cli/{utility/syncer → syncer}/s3 +0 -0
  83. metadata +55 -131
  84. data/.gitignore +0 -8
  85. data/.travis.yml +0 -10
  86. data/Gemfile +0 -28
  87. data/Guardfile +0 -23
  88. data/backup.gemspec +0 -32
  89. data/lib/backup/cli/helpers.rb +0 -93
  90. data/lib/backup/cli/utility.rb +0 -255
  91. data/spec-live/.gitignore +0 -6
  92. data/spec-live/README +0 -7
  93. data/spec-live/backups/config.rb +0 -83
  94. data/spec-live/backups/config.yml.template +0 -46
  95. data/spec-live/backups/models.rb +0 -184
  96. data/spec-live/compressor/custom_spec.rb +0 -30
  97. data/spec-live/compressor/gzip_spec.rb +0 -30
  98. data/spec-live/encryptor/gpg_keys.rb +0 -239
  99. data/spec-live/encryptor/gpg_spec.rb +0 -287
  100. data/spec-live/notifier/mail_spec.rb +0 -121
  101. data/spec-live/spec_helper.rb +0 -151
  102. data/spec-live/storage/dropbox_spec.rb +0 -151
  103. data/spec-live/storage/local_spec.rb +0 -83
  104. data/spec-live/storage/scp_spec.rb +0 -193
  105. data/spec-live/syncer/cloud/s3_spec.rb +0 -124
  106. data/spec/archive_spec.rb +0 -335
  107. data/spec/cleaner_spec.rb +0 -312
  108. data/spec/cli/helpers_spec.rb +0 -301
  109. data/spec/cli/utility_spec.rb +0 -411
  110. data/spec/compressor/base_spec.rb +0 -52
  111. data/spec/compressor/bzip2_spec.rb +0 -217
  112. data/spec/compressor/custom_spec.rb +0 -106
  113. data/spec/compressor/gzip_spec.rb +0 -217
  114. data/spec/compressor/lzma_spec.rb +0 -123
  115. data/spec/compressor/pbzip2_spec.rb +0 -165
  116. data/spec/config_spec.rb +0 -321
  117. data/spec/configuration/helpers_spec.rb +0 -247
  118. data/spec/configuration/store_spec.rb +0 -39
  119. data/spec/configuration_spec.rb +0 -62
  120. data/spec/database/base_spec.rb +0 -63
  121. data/spec/database/mongodb_spec.rb +0 -510
  122. data/spec/database/mysql_spec.rb +0 -411
  123. data/spec/database/postgresql_spec.rb +0 -353
  124. data/spec/database/redis_spec.rb +0 -334
  125. data/spec/database/riak_spec.rb +0 -176
  126. data/spec/dependency_spec.rb +0 -51
  127. data/spec/encryptor/base_spec.rb +0 -40
  128. data/spec/encryptor/gpg_spec.rb +0 -909
  129. data/spec/encryptor/open_ssl_spec.rb +0 -148
  130. data/spec/errors_spec.rb +0 -306
  131. data/spec/logger_spec.rb +0 -367
  132. data/spec/model_spec.rb +0 -666
  133. data/spec/notifier/base_spec.rb +0 -104
  134. data/spec/notifier/campfire_spec.rb +0 -217
  135. data/spec/notifier/hipchat_spec.rb +0 -211
  136. data/spec/notifier/mail_spec.rb +0 -316
  137. data/spec/notifier/prowl_spec.rb +0 -138
  138. data/spec/notifier/pushover_spec.rb +0 -123
  139. data/spec/notifier/twitter_spec.rb +0 -153
  140. data/spec/package_spec.rb +0 -61
  141. data/spec/packager_spec.rb +0 -213
  142. data/spec/pipeline_spec.rb +0 -259
  143. data/spec/spec_helper.rb +0 -60
  144. data/spec/splitter_spec.rb +0 -120
  145. data/spec/storage/base_spec.rb +0 -166
  146. data/spec/storage/cloudfiles_spec.rb +0 -254
  147. data/spec/storage/cycler_spec.rb +0 -247
  148. data/spec/storage/dropbox_spec.rb +0 -480
  149. data/spec/storage/ftp_spec.rb +0 -271
  150. data/spec/storage/local_spec.rb +0 -259
  151. data/spec/storage/ninefold_spec.rb +0 -343
  152. data/spec/storage/rsync_spec.rb +0 -362
  153. data/spec/storage/s3_spec.rb +0 -245
  154. data/spec/storage/scp_spec.rb +0 -233
  155. data/spec/storage/sftp_spec.rb +0 -244
  156. data/spec/syncer/base_spec.rb +0 -109
  157. data/spec/syncer/cloud/base_spec.rb +0 -515
  158. data/spec/syncer/cloud/cloud_files_spec.rb +0 -181
  159. data/spec/syncer/cloud/s3_spec.rb +0 -174
  160. data/spec/syncer/rsync/base_spec.rb +0 -98
  161. data/spec/syncer/rsync/local_spec.rb +0 -149
  162. data/spec/syncer/rsync/pull_spec.rb +0 -98
  163. data/spec/syncer/rsync/push_spec.rb +0 -333
  164. data/spec/version_spec.rb +0 -21
  165. data/templates/cli/utility/config +0 -32
  166. data/templates/cli/utility/database/riak +0 -11
@@ -1,301 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.expand_path('../../spec_helper.rb', __FILE__)
4
-
5
- describe Backup::CLI::Helpers do
6
- let(:helpers) { Module.new.extend(Backup::CLI::Helpers) }
7
-
8
- describe '#run' do
9
- let(:stdout_io) { stub(:read => stdout_messages) }
10
- let(:stderr_io) { stub(:read => stderr_messages) }
11
- let(:stdin_io) { stub(:close) }
12
- let(:process_status) { stub(:success? => process_success) }
13
- let(:command) { '/path/to/cmd_name arg1 arg2' }
14
-
15
- context 'when the command is successful' do
16
- let(:process_success) { true }
17
-
18
- before do
19
- Backup::Logger.expects(:message).with(
20
- "Running system utility 'cmd_name'..."
21
- )
22
-
23
- Open4.expects(:popen4).with(command).yields(
24
- nil, stdin_io, stdout_io, stderr_io
25
- ).returns(process_status)
26
- end
27
-
28
- context 'and generates no messages' do
29
- let(:stdout_messages) { '' }
30
- let(:stderr_messages) { '' }
31
-
32
- it 'should return stdout and generate no additional log messages' do
33
- helpers.send(:run, command).should == ''
34
- end
35
- end
36
-
37
- context 'and generates only stdout messages' do
38
- let(:stdout_messages) { "out line1\nout line2\n" }
39
- let(:stderr_messages) { '' }
40
-
41
- it 'should return stdout and log the stdout messages' do
42
- Backup::Logger.expects(:message).with(
43
- "cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
44
- )
45
- helpers.send(:run, command).should == stdout_messages.strip
46
- end
47
- end
48
-
49
- context 'and generates only stderr messages' do
50
- let(:stdout_messages) { '' }
51
- let(:stderr_messages) { "err line1\nerr line2\n" }
52
-
53
- it 'should return stdout and log the stderr messages' do
54
- Backup::Logger.expects(:warn).with(
55
- "cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
56
- )
57
- helpers.send(:run, command).should == ''
58
- end
59
- end
60
-
61
- context 'and generates messages on both stdout and stderr' do
62
- let(:stdout_messages) { "out line1\nout line2\n" }
63
- let(:stderr_messages) { "err line1\nerr line2\n" }
64
-
65
- it 'should return stdout and log both stdout and stderr messages' do
66
- Backup::Logger.expects(:message).with(
67
- "cmd_name:STDOUT: out line1\ncmd_name:STDOUT: out line2"
68
- )
69
- Backup::Logger.expects(:warn).with(
70
- "cmd_name:STDERR: err line1\ncmd_name:STDERR: err line2"
71
- )
72
- helpers.send(:run, command).should == stdout_messages.strip
73
- end
74
- end
75
- end # context 'when the command is successful'
76
-
77
- context 'when the command is not successful' do
78
- let(:process_success) { false }
79
- let(:message_head) do
80
- "CLI::SystemCallError: 'cmd_name' Failed on #{ RUBY_PLATFORM }\n" +
81
- " The following information should help to determine the problem:\n" +
82
- " Command was: /path/to/cmd_name arg1 arg2\n" +
83
- " Exit Status: 1\n"
84
- end
85
-
86
- before do
87
- Backup::Logger.expects(:message).with(
88
- "Running system utility 'cmd_name'..."
89
- )
90
-
91
- Open4.expects(:popen4).with(command).yields(
92
- nil, stdin_io, stdout_io, stderr_io
93
- ).returns(process_status)
94
-
95
- process_status.stubs(:exitstatus).returns(1)
96
- end
97
-
98
- context 'and generates no messages' do
99
- let(:stdout_messages) { '' }
100
- let(:stderr_messages) { '' }
101
-
102
- it 'should raise an error reporting no messages' do
103
- expect do
104
- helpers.send(:run, command)
105
- end.to raise_error {|err|
106
- err.message.should == message_head +
107
- " STDOUT Messages: None\n" +
108
- " STDERR Messages: None"
109
- }
110
- end
111
- end
112
-
113
- context 'and generates only stdout messages' do
114
- let(:stdout_messages) { "out line1\nout line2\n" }
115
- let(:stderr_messages) { '' }
116
-
117
- it 'should raise an error and report the stdout messages' do
118
- expect do
119
- helpers.send(:run, command)
120
- end.to raise_error {|err|
121
- err.message.should == message_head +
122
- " STDOUT Messages: \n" +
123
- " out line1\n" +
124
- " out line2\n" +
125
- " STDERR Messages: None"
126
- }
127
- end
128
- end
129
-
130
- context 'and generates only stderr messages' do
131
- let(:stdout_messages) { '' }
132
- let(:stderr_messages) { "err line1\nerr line2\n" }
133
-
134
- it 'should raise an error and report the stderr messages' do
135
- expect do
136
- helpers.send(:run, command)
137
- end.to raise_error {|err|
138
- err.message.should == message_head +
139
- " STDOUT Messages: None\n" +
140
- " STDERR Messages: \n" +
141
- " err line1\n" +
142
- " err line2"
143
- }
144
- end
145
- end
146
-
147
- context 'and generates messages on both stdout and stderr' do
148
- let(:stdout_messages) { "out line1\nout line2\n" }
149
- let(:stderr_messages) { "err line1\nerr line2\n" }
150
-
151
- it 'should raise an error and report the stdout and stderr messages' do
152
- expect do
153
- helpers.send(:run, command)
154
- end.to raise_error {|err|
155
- err.message.should == message_head +
156
- " STDOUT Messages: \n" +
157
- " out line1\n" +
158
- " out line2\n" +
159
- " STDERR Messages: \n" +
160
- " err line1\n" +
161
- " err line2"
162
- }
163
- end
164
- end
165
- end # context 'when the command is not successful'
166
-
167
- context 'when the system fails to execute the command' do
168
- before do
169
- Backup::Logger.expects(:message).with(
170
- "Running system utility 'cmd_name'..."
171
- )
172
-
173
- Open4.expects(:popen4).raises("exec call failed")
174
- end
175
-
176
- it 'should raise an error wrapping the system error raised' do
177
- expect do
178
- helpers.send(:run, command)
179
- end.to raise_error {|err|
180
- err.message.should == "CLI::SystemCallError: " +
181
- "Failed to execute system command on #{ RUBY_PLATFORM }\n" +
182
- " Command was: /path/to/cmd_name arg1 arg2\n" +
183
- " Reason: RuntimeError\n" +
184
- " exec call failed"
185
- }
186
- end
187
- end # context 'when the system fails to execute the command'
188
- end # describe '#run'
189
-
190
- describe '#utility' do
191
- after { Backup::CLI::Helpers::UTILITY.clear }
192
-
193
- context 'when a system path for the utility is available' do
194
- it 'should return the system path with newline removed' do
195
- helpers.expects(:`).with('which foo 2>/dev/null').returns("system_path\n")
196
- helpers.send(:utility, :foo).should == 'system_path'
197
- end
198
-
199
- it 'should cache the returned path' do
200
- helpers.expects(:`).once.with('which cache_me 2>/dev/null').
201
- returns("cached_path\n")
202
-
203
- helpers.send(:utility, :cache_me).should == 'cached_path'
204
- helpers.send(:utility, :cache_me).should == 'cached_path'
205
- end
206
-
207
- it 'should cache the value for all extended objects' do
208
- helpers.expects(:`).once.with('which once_only 2>/dev/null').
209
- returns("cached_path\n")
210
-
211
- helpers.send(:utility, :once_only).should == 'cached_path'
212
- Class.new.extend(Backup::CLI::Helpers).send(
213
- :utility, :once_only).should == 'cached_path'
214
- end
215
- end
216
-
217
- context 'when a system path for the utility is not available' do
218
- it 'should raise an error' do
219
- helpers.expects(:`).with('which unknown 2>/dev/null').returns("\n")
220
-
221
- expect do
222
- helpers.send(:utility, :unknown)
223
- end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
224
- err.message.should match(/Could not locate 'unknown'/)
225
- }
226
- end
227
-
228
- it 'should not cache any value for the utility' do
229
- helpers.expects(:`).with('which not_cached 2>/dev/null').twice.returns("\n")
230
-
231
- expect do
232
- helpers.send(:utility, :not_cached)
233
- end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
234
- err.message.should match(/Could not locate 'not_cached'/)
235
- }
236
-
237
- expect do
238
- helpers.send(:utility, :not_cached)
239
- end.to raise_error(Backup::Errors::CLI::UtilityNotFoundError) {|err|
240
- err.message.should match(/Could not locate 'not_cached'/)
241
- }
242
- end
243
- end
244
-
245
- it 'should raise an error if name is nil' do
246
- expect do
247
- helpers.send(:utility, nil)
248
- end.to raise_error(
249
- Backup::Errors::CLI::UtilityNotFoundError,
250
- 'CLI::UtilityNotFoundError: Utility Name Empty'
251
- )
252
- end
253
-
254
- it 'should raise an error if name is empty' do
255
- expect do
256
- helpers.send(:utility, ' ')
257
- end.to raise_error(
258
- Backup::Errors::CLI::UtilityNotFoundError,
259
- 'CLI::UtilityNotFoundError: Utility Name Empty'
260
- )
261
- end
262
- end # describe '#utility'
263
-
264
- describe '#command_name' do
265
- context 'given a command line path with no arguments' do
266
- it 'should return the base command name' do
267
- cmd = '/path/to/a/command'
268
- helpers.send(:command_name, cmd).should == 'command'
269
- end
270
- end
271
-
272
- context 'given a command line path with a single argument' do
273
- it 'should return the base command name' do
274
- cmd = '/path/to/a/command with_args'
275
- helpers.send(:command_name, cmd).should == 'command'
276
- end
277
- end
278
-
279
- context 'given a command line path with multiple arguments' do
280
- it 'should return the base command name' do
281
- cmd = '/path/to/a/command with multiple args'
282
- helpers.send(:command_name, cmd).should == 'command'
283
- end
284
- end
285
-
286
- context 'given a command with no path and arguments' do
287
- it 'should return the base command name' do
288
- cmd = 'command args'
289
- helpers.send(:command_name, cmd).should == 'command'
290
- end
291
- end
292
-
293
- context 'given a command with no path and no arguments' do
294
- it 'should return the base command name' do
295
- cmd = 'command'
296
- helpers.send(:command_name, cmd).should == 'command'
297
- end
298
- end
299
- end # describe '#command_name'
300
-
301
- end
@@ -1,411 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.expand_path('../../spec_helper.rb', __FILE__)
4
-
5
- describe 'Backup::CLI::Utility' do
6
- let(:cli) { Backup::CLI::Utility }
7
- let(:utility) { Backup::CLI::Utility.new }
8
- let(:s) { sequence '' }
9
-
10
- before { @argv_save = ARGV }
11
- after { ARGV.replace(@argv_save) }
12
-
13
- describe '#perform' do
14
- let(:model_a) { Backup::Model.new(:test_trigger_a, 'test label a') }
15
- let(:model_b) { Backup::Model.new(:test_trigger_b, 'test label b') }
16
-
17
- after { Backup::Model.all.clear }
18
-
19
- it 'should perform the backup for the given trigger' do
20
- Backup::Logger.expects(:quiet=).in_sequence(s)
21
- Backup::Config.expects(:update).in_sequence(s)
22
-
23
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
24
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
25
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
26
-
27
- Backup::Config.expects(:load_config!).in_sequence(s)
28
-
29
- Backup::Logger.expects(:truncate!)
30
-
31
- model_a.expects(:prepare!).in_sequence(s)
32
- model_a.expects(:perform!).in_sequence(s)
33
- Backup::Logger.expects(:clear!).in_sequence(s)
34
-
35
- expect do
36
- ARGV.replace(['perform', '-t', 'test_trigger_a'])
37
- cli.start
38
- end.not_to raise_error
39
- end
40
-
41
- it 'should perform backups for the multiple triggers' do
42
- Backup::Logger.expects(:quiet=).in_sequence(s)
43
- Backup::Config.expects(:update).in_sequence(s)
44
-
45
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
46
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
47
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
48
-
49
- Backup::Config.expects(:load_config!).in_sequence(s)
50
-
51
- Backup::Logger.expects(:truncate!)
52
-
53
- model_a.expects(:prepare!).in_sequence(s)
54
- model_a.expects(:perform!).in_sequence(s)
55
- Backup::Logger.expects(:clear!).in_sequence(s)
56
-
57
- model_b.expects(:prepare!).in_sequence(s)
58
- model_b.expects(:perform!).in_sequence(s)
59
- Backup::Logger.expects(:clear!).in_sequence(s)
60
-
61
- expect do
62
- ARGV.replace(['perform', '-t', 'test_trigger_a,test_trigger_b'])
63
- cli.start
64
- end.not_to raise_error
65
- end
66
-
67
- it 'should perform backups for the multiple triggers when using wildcard' do
68
- Backup::Logger.expects(:quiet=).in_sequence(s)
69
- Backup::Config.expects(:update).in_sequence(s)
70
-
71
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.log_path)
72
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.cache_path)
73
- FileUtils.expects(:mkdir_p).in_sequence(s).with(Backup::Config.tmp_path)
74
-
75
- Backup::Config.expects(:load_config!).in_sequence(s)
76
-
77
- Backup::Logger.expects(:truncate!)
78
-
79
- model_a.expects(:prepare!).in_sequence(s)
80
- model_a.expects(:perform!).in_sequence(s)
81
- Backup::Logger.expects(:clear!).in_sequence(s)
82
-
83
- model_b.expects(:prepare!).in_sequence(s)
84
- model_b.expects(:perform!).in_sequence(s)
85
- Backup::Logger.expects(:clear!).in_sequence(s)
86
-
87
- expect do
88
- ARGV.replace(['perform', '-t', 'test_trigger_*'])
89
- cli.start
90
- end.not_to raise_error
91
- end
92
-
93
- context 'when errors occur' do
94
- it 'should log the error and exit' do
95
- Backup::Logger.stubs(:quiet=).raises(SystemCallError, 'yikes!')
96
- Backup::Logger.expects(:error).with do |err|
97
- err.message.should ==
98
- "CLIError: SystemCallError: unknown error - yikes!"
99
- end
100
-
101
- expect do
102
- ARGV.replace(['perform', '-t', 'foo'])
103
- cli.start
104
- end.to raise_error(SystemExit) {|exit| exit.status.should == 1 }
105
- end
106
- end # context 'when errors occur'
107
-
108
- end # describe '#perform'
109
-
110
- describe '#generate:model' do
111
- before do
112
- FileUtils.unstub(:mkdir_p)
113
- FileUtils.unstub(:touch)
114
- end
115
-
116
- after do
117
- Backup::Config.send(:reset!)
118
- end
119
-
120
- context 'when given a config_path' do
121
- context 'when no config file exists' do
122
- it 'should create both a config and a model under the given path' do
123
- Dir.mktmpdir do |path|
124
- model_file = File.join(path, 'custom', 'models', 'test_trigger.rb')
125
- config_file = File.join(path, 'custom', 'config.rb')
126
-
127
- out, err = capture_io do
128
- ARGV.replace(['generate:model',
129
- '--config-path', File.join(path, 'custom'),
130
- '--trigger', 'test_trigger'
131
- ])
132
- cli.start
133
- end
134
-
135
- out.should == "Generated model file: '#{ model_file }'.\n" +
136
- "Generated configuration file: '#{ config_file }'.\n"
137
- File.exist?(model_file).should be_true
138
- File.exist?(config_file).should be_true
139
- end
140
- end
141
- end
142
-
143
- context 'when a config file already exists' do
144
- it 'should only create a model under the given path' do
145
- Dir.mktmpdir do |path|
146
- model_file = File.join(path, 'custom', 'models', 'test_trigger.rb')
147
- config_file = File.join(path, 'custom', 'config.rb')
148
- FileUtils.mkdir_p(File.join(path, 'custom'))
149
- FileUtils.touch(config_file)
150
-
151
- out, err = capture_io do
152
- ARGV.replace(['generate:model',
153
- '--config-path', File.join(path, 'custom'),
154
- '--trigger', 'test_trigger'
155
- ])
156
- cli.start
157
- end
158
-
159
- out.should == "Generated model file: '#{ model_file }'.\n"
160
- File.exist?(model_file).should be_true
161
- end
162
- end
163
- end
164
-
165
- # These pass, but generate Thor warnings...
166
- #
167
- # context 'when a model file already exists' do
168
- # it 'should prompt to overwrite the model under the given path' do
169
- # Dir.mktmpdir do |path|
170
- # model_file = File.join(path, 'models', 'test_trigger.rb')
171
- # config_file = File.join(path, 'config.rb')
172
- #
173
- # cli.any_instance.expects(:overwrite?).with(model_file).returns(false)
174
- #
175
- # out, err = capture_io do
176
- # ARGV.replace(['generate:model',
177
- # '--config-path', path,
178
- # '--trigger', 'test_trigger'
179
- # ])
180
- # cli.start
181
- # end
182
- #
183
- # out.should == "Generated configuration file: '#{ config_file }'.\n"
184
- # File.exist?(config_file).should be_true
185
- # File.exist?(model_file).should be_false
186
- # end
187
- # end
188
- # end
189
-
190
- end # context 'when given a config_path'
191
-
192
- context 'when not given a config_path' do
193
- it 'should create both a config and a model under the root path' do
194
- Dir.mktmpdir do |path|
195
- Backup::Config.update(:root_path => path)
196
- model_file = File.join(path, 'models', 'test_trigger.rb')
197
- config_file = File.join(path, 'config.rb')
198
-
199
- out, err = capture_io do
200
- ARGV.replace(['generate:model', '--trigger', 'test_trigger'])
201
- cli.start
202
- end
203
-
204
- out.should == "Generated model file: '#{ model_file }'.\n" +
205
- "Generated configuration file: '#{ config_file }'.\n"
206
- File.exist?(model_file).should be_true
207
- File.exist?(config_file).should be_true
208
- end
209
- end
210
- end
211
-
212
- it 'should generate the proper help output' do
213
- ruby19_output = <<-EOS
214
- Usage:
215
- #{ File.basename($0) } generate:model --trigger=TRIGGER
216
-
217
- Options:
218
- --trigger=TRIGGER
219
- [--config-path=CONFIG_PATH] # Path to your Backup configuration directory
220
- [--databases=DATABASES] # (mongodb, mysql, postgresql, redis, riak)
221
- [--storages=STORAGES] # (cloud_files, dropbox, ftp, local, ninefold, rsync, s3, scp, sftp)
222
- [--syncers=SYNCERS] # (cloud_files, rsync_local, rsync_pull, rsync_push, s3)
223
- [--encryptors=ENCRYPTORS] # (gpg, openssl)
224
- [--compressors=COMPRESSORS] # (bzip2, custom, gzip, lzma, pbzip2)
225
- [--notifiers=NOTIFIERS] # (campfire, hipchat, mail, prowl, pushover, twitter)
226
- [--archives]
227
- [--splitter] # use `--no-splitter` to disable
228
- # Default: true
229
- Generates a Backup model file
230
-
231
- Note:
232
- '--config-path' is the path to the directory where 'config.rb' is located.
233
- The model file will be created as '<config_path>/models/<trigger>.rb'
234
- Default: #{ Backup::Config.root_path }
235
- EOS
236
-
237
- out, err = capture_io do
238
- ARGV.replace(['help', 'generate:model'])
239
- cli.start
240
- end
241
-
242
- expected_lines = ruby19_output.split("\n").map(&:strip).select {|e| !e.empty? }
243
- output_lines = out.split("\n").map(&:strip).select {|e| !e.empty? }
244
-
245
- output_lines.sort.should == expected_lines.sort
246
- end
247
- end # describe '#generate:model'
248
-
249
- describe '#generate:config' do
250
- before do
251
- FileUtils.unstub(:mkdir_p)
252
- FileUtils.unstub(:touch)
253
- end
254
-
255
- after do
256
- Backup::Config.send(:reset!)
257
- end
258
-
259
- context 'when given a config_path' do
260
- it 'should create a config file in the given path' do
261
- Dir.mktmpdir do |path|
262
- config_file = File.join(path, 'custom', 'config.rb')
263
-
264
- out, err = capture_io do
265
- ARGV.replace(['generate:config',
266
- '--config-path', File.join(path, 'custom'),
267
- ])
268
- cli.start
269
- end
270
-
271
- out.should == "Generated configuration file: '#{ config_file }'.\n"
272
- File.exist?(config_file).should be_true
273
- end
274
- end
275
- end
276
-
277
- context 'when not given a config_path' do
278
- it 'should create a config file in the root path' do
279
- Dir.mktmpdir do |path|
280
- Backup::Config.update(:root_path => path)
281
- config_file = File.join(path, 'config.rb')
282
-
283
- out, err = capture_io do
284
- ARGV.replace(['generate:config'])
285
- cli.start
286
- end
287
-
288
- out.should == "Generated configuration file: '#{ config_file }'.\n"
289
- File.exist?(config_file).should be_true
290
- end
291
- end
292
- end
293
-
294
- # These pass, but generate Thor warnings...
295
- #
296
- # context 'when a config file already exists' do
297
- # it 'should prompt to overwrite the config file' do
298
- # Dir.mktmpdir do |path|
299
- # Backup::Config.update(:root_path => path)
300
- # config_file = File.join(path, 'config.rb')
301
- #
302
- # cli.any_instance.expects(:overwrite?).with(config_file).returns(false)
303
- #
304
- # out, err = capture_io do
305
- # ARGV.replace(['generate:config'])
306
- # cli.start
307
- # end
308
- #
309
- # out.should be_empty
310
- # File.exist?(config_file).should be_false
311
- # end
312
- # end
313
- # end
314
-
315
- end # describe '#generate:config'
316
-
317
- describe '#decrypt' do
318
-
319
- # These pass, but generate Thor warnings...
320
- #
321
- # it 'should perform OpenSSL decryption' do
322
- # ARGV.replace(['decrypt', '--encryptor', 'openssl',
323
- # '--in', 'in_file',
324
- # '--out', 'out_file',
325
- # '--base64', '--salt',
326
- # '--password-file', 'pwd_file'])
327
- #
328
- # cli.any_instance.expects(:`).with(
329
- # "openssl aes-256-cbc -d -base64 -pass file:pwd_file -salt " +
330
- # "-in 'in_file' -out 'out_file'"
331
- # )
332
- # cli.start
333
- # end
334
- #
335
- # it 'should omit -pass option if no --password-file given' do
336
- # ARGV.replace(['decrypt', '--encryptor', 'openssl',
337
- # '--in', 'in_file',
338
- # '--out', 'out_file',
339
- # '--base64', '--salt'])
340
- #
341
- # cli.any_instance.expects(:`).with(
342
- # "openssl aes-256-cbc -d -base64 -salt " +
343
- # "-in 'in_file' -out 'out_file'"
344
- # )
345
- # cli.start
346
- # end
347
- #
348
- # it 'should perform GnuPG decryption' do
349
- # ARGV.replace(['decrypt', '--encryptor', 'gpg',
350
- # '--in', 'in_file',
351
- # '--out', 'out_file'])
352
- #
353
- # cli.any_instance.expects(:`).with(
354
- # "gpg -o 'out_file' -d 'in_file'"
355
- # )
356
- # cli.start
357
- # end
358
-
359
- it 'should show a message if given an invalid encryptor' do
360
- ARGV.replace(['decrypt', '--encryptor', 'foo',
361
- '--in', 'in_file',
362
- '--out', 'out_file'])
363
- out, err = capture_io do
364
- cli.start
365
- end
366
- err.should == ''
367
- out.should == "Unknown encryptor: foo\n" +
368
- "Use either 'openssl' or 'gpg'.\n"
369
- end
370
- end
371
-
372
- # would have the same Thor warnings issues...
373
- # describe '#dependencies' do
374
- # end
375
-
376
- describe '#version' do
377
- it 'should output the current version' do
378
- utility.expects(:puts).with("Backup #{ Backup::Version.current }")
379
- utility.version
380
- end
381
-
382
- it 'should output the current version for "-v"' do
383
- ARGV.replace ['-v']
384
- out, err = capture_io do
385
- cli.start
386
- end
387
- out.should == "Backup #{ Backup::Version.current }\n"
388
- end
389
- end
390
-
391
- describe '#overwrite?' do
392
- context 'when the path exists' do
393
- before { File.expects(:exist?).returns(true) }
394
-
395
- it 'should prompt user' do
396
- utility.expects(:yes?).with(
397
- "A file already exists at 'a/path'. Do you want to overwrite? [y/n]"
398
- ).returns(:response)
399
- utility.send(:overwrite?, 'a/path').should == :response
400
- end
401
- end
402
-
403
- context 'when the path does not exist' do
404
- before { File.expects(:exist?).returns(false) }
405
- it 'should return true' do
406
- utility.expects(:yes?).never
407
- utility.send(:overwrite?, 'a/path').should be_true
408
- end
409
- end
410
- end
411
- end