backup 3.0.27 → 3.1.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 (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