backup_checksum 3.0.23

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 (244) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +28 -0
  4. data/Gemfile.lock +130 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.md +24 -0
  7. data/README.md +476 -0
  8. data/backup_checksum.gemspec +32 -0
  9. data/bin/backup +11 -0
  10. data/lib/backup.rb +217 -0
  11. data/lib/backup/archive.rb +117 -0
  12. data/lib/backup/binder.rb +22 -0
  13. data/lib/backup/checksum/base.rb +44 -0
  14. data/lib/backup/checksum/shasum.rb +16 -0
  15. data/lib/backup/cleaner.rb +121 -0
  16. data/lib/backup/cli/helpers.rb +88 -0
  17. data/lib/backup/cli/utility.rb +247 -0
  18. data/lib/backup/compressor/base.rb +29 -0
  19. data/lib/backup/compressor/bzip2.rb +50 -0
  20. data/lib/backup/compressor/gzip.rb +47 -0
  21. data/lib/backup/compressor/lzma.rb +50 -0
  22. data/lib/backup/compressor/pbzip2.rb +56 -0
  23. data/lib/backup/config.rb +173 -0
  24. data/lib/backup/configuration/base.rb +15 -0
  25. data/lib/backup/configuration/checksum/base.rb +9 -0
  26. data/lib/backup/configuration/checksum/shasum.rb +9 -0
  27. data/lib/backup/configuration/compressor/base.rb +9 -0
  28. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  29. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  30. data/lib/backup/configuration/compressor/lzma.rb +23 -0
  31. data/lib/backup/configuration/compressor/pbzip2.rb +28 -0
  32. data/lib/backup/configuration/database/base.rb +19 -0
  33. data/lib/backup/configuration/database/mongodb.rb +49 -0
  34. data/lib/backup/configuration/database/mysql.rb +42 -0
  35. data/lib/backup/configuration/database/postgresql.rb +41 -0
  36. data/lib/backup/configuration/database/redis.rb +39 -0
  37. data/lib/backup/configuration/database/riak.rb +29 -0
  38. data/lib/backup/configuration/encryptor/base.rb +9 -0
  39. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  40. data/lib/backup/configuration/encryptor/open_ssl.rb +32 -0
  41. data/lib/backup/configuration/helpers.rb +52 -0
  42. data/lib/backup/configuration/notifier/base.rb +28 -0
  43. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  44. data/lib/backup/configuration/notifier/hipchat.rb +41 -0
  45. data/lib/backup/configuration/notifier/mail.rb +112 -0
  46. data/lib/backup/configuration/notifier/presently.rb +25 -0
  47. data/lib/backup/configuration/notifier/prowl.rb +23 -0
  48. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  49. data/lib/backup/configuration/storage/base.rb +18 -0
  50. data/lib/backup/configuration/storage/cloudfiles.rb +25 -0
  51. data/lib/backup/configuration/storage/dropbox.rb +58 -0
  52. data/lib/backup/configuration/storage/ftp.rb +29 -0
  53. data/lib/backup/configuration/storage/local.rb +17 -0
  54. data/lib/backup/configuration/storage/ninefold.rb +20 -0
  55. data/lib/backup/configuration/storage/rsync.rb +29 -0
  56. data/lib/backup/configuration/storage/s3.rb +25 -0
  57. data/lib/backup/configuration/storage/scp.rb +25 -0
  58. data/lib/backup/configuration/storage/sftp.rb +25 -0
  59. data/lib/backup/configuration/syncer/base.rb +10 -0
  60. data/lib/backup/configuration/syncer/cloud.rb +23 -0
  61. data/lib/backup/configuration/syncer/cloud_files.rb +30 -0
  62. data/lib/backup/configuration/syncer/rsync/base.rb +28 -0
  63. data/lib/backup/configuration/syncer/rsync/local.rb +11 -0
  64. data/lib/backup/configuration/syncer/rsync/pull.rb +11 -0
  65. data/lib/backup/configuration/syncer/rsync/push.rb +31 -0
  66. data/lib/backup/configuration/syncer/s3.rb +23 -0
  67. data/lib/backup/database/base.rb +59 -0
  68. data/lib/backup/database/mongodb.rb +232 -0
  69. data/lib/backup/database/mysql.rb +163 -0
  70. data/lib/backup/database/postgresql.rb +146 -0
  71. data/lib/backup/database/redis.rb +139 -0
  72. data/lib/backup/database/riak.rb +69 -0
  73. data/lib/backup/dependency.rb +114 -0
  74. data/lib/backup/encryptor/base.rb +29 -0
  75. data/lib/backup/encryptor/gpg.rb +80 -0
  76. data/lib/backup/encryptor/open_ssl.rb +72 -0
  77. data/lib/backup/errors.rb +124 -0
  78. data/lib/backup/logger.rb +152 -0
  79. data/lib/backup/model.rb +386 -0
  80. data/lib/backup/notifier/base.rb +81 -0
  81. data/lib/backup/notifier/campfire.rb +168 -0
  82. data/lib/backup/notifier/hipchat.rb +99 -0
  83. data/lib/backup/notifier/mail.rb +206 -0
  84. data/lib/backup/notifier/presently.rb +88 -0
  85. data/lib/backup/notifier/prowl.rb +65 -0
  86. data/lib/backup/notifier/twitter.rb +70 -0
  87. data/lib/backup/package.rb +51 -0
  88. data/lib/backup/packager.rb +108 -0
  89. data/lib/backup/pipeline.rb +107 -0
  90. data/lib/backup/splitter.rb +75 -0
  91. data/lib/backup/storage/base.rb +119 -0
  92. data/lib/backup/storage/cloudfiles.rb +87 -0
  93. data/lib/backup/storage/cycler.rb +117 -0
  94. data/lib/backup/storage/dropbox.rb +181 -0
  95. data/lib/backup/storage/ftp.rb +119 -0
  96. data/lib/backup/storage/local.rb +82 -0
  97. data/lib/backup/storage/ninefold.rb +116 -0
  98. data/lib/backup/storage/rsync.rb +149 -0
  99. data/lib/backup/storage/s3.rb +94 -0
  100. data/lib/backup/storage/scp.rb +99 -0
  101. data/lib/backup/storage/sftp.rb +108 -0
  102. data/lib/backup/syncer/base.rb +42 -0
  103. data/lib/backup/syncer/cloud.rb +190 -0
  104. data/lib/backup/syncer/cloud_files.rb +56 -0
  105. data/lib/backup/syncer/rsync/base.rb +52 -0
  106. data/lib/backup/syncer/rsync/local.rb +53 -0
  107. data/lib/backup/syncer/rsync/pull.rb +38 -0
  108. data/lib/backup/syncer/rsync/push.rb +113 -0
  109. data/lib/backup/syncer/s3.rb +47 -0
  110. data/lib/backup/template.rb +46 -0
  111. data/lib/backup/version.rb +43 -0
  112. data/spec/archive_spec.rb +335 -0
  113. data/spec/cleaner_spec.rb +304 -0
  114. data/spec/cli/helpers_spec.rb +176 -0
  115. data/spec/cli/utility_spec.rb +363 -0
  116. data/spec/compressor/base_spec.rb +31 -0
  117. data/spec/compressor/bzip2_spec.rb +83 -0
  118. data/spec/compressor/gzip_spec.rb +83 -0
  119. data/spec/compressor/lzma_spec.rb +83 -0
  120. data/spec/compressor/pbzip2_spec.rb +124 -0
  121. data/spec/config_spec.rb +321 -0
  122. data/spec/configuration/base_spec.rb +35 -0
  123. data/spec/configuration/compressor/bzip2_spec.rb +29 -0
  124. data/spec/configuration/compressor/gzip_spec.rb +29 -0
  125. data/spec/configuration/compressor/lzma_spec.rb +29 -0
  126. data/spec/configuration/compressor/pbzip2_spec.rb +32 -0
  127. data/spec/configuration/database/base_spec.rb +17 -0
  128. data/spec/configuration/database/mongodb_spec.rb +56 -0
  129. data/spec/configuration/database/mysql_spec.rb +53 -0
  130. data/spec/configuration/database/postgresql_spec.rb +53 -0
  131. data/spec/configuration/database/redis_spec.rb +50 -0
  132. data/spec/configuration/database/riak_spec.rb +35 -0
  133. data/spec/configuration/encryptor/gpg_spec.rb +26 -0
  134. data/spec/configuration/encryptor/open_ssl_spec.rb +35 -0
  135. data/spec/configuration/notifier/base_spec.rb +32 -0
  136. data/spec/configuration/notifier/campfire_spec.rb +32 -0
  137. data/spec/configuration/notifier/hipchat_spec.rb +44 -0
  138. data/spec/configuration/notifier/mail_spec.rb +71 -0
  139. data/spec/configuration/notifier/presently_spec.rb +35 -0
  140. data/spec/configuration/notifier/prowl_spec.rb +29 -0
  141. data/spec/configuration/notifier/twitter_spec.rb +35 -0
  142. data/spec/configuration/storage/cloudfiles_spec.rb +41 -0
  143. data/spec/configuration/storage/dropbox_spec.rb +38 -0
  144. data/spec/configuration/storage/ftp_spec.rb +44 -0
  145. data/spec/configuration/storage/local_spec.rb +29 -0
  146. data/spec/configuration/storage/ninefold_spec.rb +32 -0
  147. data/spec/configuration/storage/rsync_spec.rb +41 -0
  148. data/spec/configuration/storage/s3_spec.rb +38 -0
  149. data/spec/configuration/storage/scp_spec.rb +41 -0
  150. data/spec/configuration/storage/sftp_spec.rb +41 -0
  151. data/spec/configuration/syncer/cloud_files_spec.rb +44 -0
  152. data/spec/configuration/syncer/rsync/base_spec.rb +33 -0
  153. data/spec/configuration/syncer/rsync/local_spec.rb +10 -0
  154. data/spec/configuration/syncer/rsync/pull_spec.rb +10 -0
  155. data/spec/configuration/syncer/rsync/push_spec.rb +43 -0
  156. data/spec/configuration/syncer/s3_spec.rb +38 -0
  157. data/spec/database/base_spec.rb +54 -0
  158. data/spec/database/mongodb_spec.rb +428 -0
  159. data/spec/database/mysql_spec.rb +335 -0
  160. data/spec/database/postgresql_spec.rb +278 -0
  161. data/spec/database/redis_spec.rb +260 -0
  162. data/spec/database/riak_spec.rb +108 -0
  163. data/spec/dependency_spec.rb +49 -0
  164. data/spec/encryptor/base_spec.rb +30 -0
  165. data/spec/encryptor/gpg_spec.rb +134 -0
  166. data/spec/encryptor/open_ssl_spec.rb +129 -0
  167. data/spec/errors_spec.rb +306 -0
  168. data/spec/logger_spec.rb +363 -0
  169. data/spec/model_spec.rb +649 -0
  170. data/spec/notifier/base_spec.rb +89 -0
  171. data/spec/notifier/campfire_spec.rb +199 -0
  172. data/spec/notifier/hipchat_spec.rb +188 -0
  173. data/spec/notifier/mail_spec.rb +280 -0
  174. data/spec/notifier/presently_spec.rb +181 -0
  175. data/spec/notifier/prowl_spec.rb +117 -0
  176. data/spec/notifier/twitter_spec.rb +132 -0
  177. data/spec/package_spec.rb +61 -0
  178. data/spec/packager_spec.rb +225 -0
  179. data/spec/pipeline_spec.rb +257 -0
  180. data/spec/spec_helper.rb +59 -0
  181. data/spec/splitter_spec.rb +120 -0
  182. data/spec/storage/base_spec.rb +160 -0
  183. data/spec/storage/cloudfiles_spec.rb +230 -0
  184. data/spec/storage/cycler_spec.rb +239 -0
  185. data/spec/storage/dropbox_spec.rb +370 -0
  186. data/spec/storage/ftp_spec.rb +247 -0
  187. data/spec/storage/local_spec.rb +235 -0
  188. data/spec/storage/ninefold_spec.rb +319 -0
  189. data/spec/storage/rsync_spec.rb +345 -0
  190. data/spec/storage/s3_spec.rb +221 -0
  191. data/spec/storage/scp_spec.rb +209 -0
  192. data/spec/storage/sftp_spec.rb +220 -0
  193. data/spec/syncer/base_spec.rb +22 -0
  194. data/spec/syncer/cloud_files_spec.rb +192 -0
  195. data/spec/syncer/rsync/base_spec.rb +118 -0
  196. data/spec/syncer/rsync/local_spec.rb +121 -0
  197. data/spec/syncer/rsync/pull_spec.rb +90 -0
  198. data/spec/syncer/rsync/push_spec.rb +327 -0
  199. data/spec/syncer/s3_spec.rb +192 -0
  200. data/spec/version_spec.rb +21 -0
  201. data/templates/cli/utility/archive +25 -0
  202. data/templates/cli/utility/compressor/bzip2 +7 -0
  203. data/templates/cli/utility/compressor/gzip +7 -0
  204. data/templates/cli/utility/compressor/lzma +7 -0
  205. data/templates/cli/utility/compressor/pbzip2 +7 -0
  206. data/templates/cli/utility/config +31 -0
  207. data/templates/cli/utility/database/mongodb +18 -0
  208. data/templates/cli/utility/database/mysql +21 -0
  209. data/templates/cli/utility/database/postgresql +17 -0
  210. data/templates/cli/utility/database/redis +16 -0
  211. data/templates/cli/utility/database/riak +11 -0
  212. data/templates/cli/utility/encryptor/gpg +12 -0
  213. data/templates/cli/utility/encryptor/openssl +9 -0
  214. data/templates/cli/utility/model.erb +23 -0
  215. data/templates/cli/utility/notifier/campfire +12 -0
  216. data/templates/cli/utility/notifier/hipchat +15 -0
  217. data/templates/cli/utility/notifier/mail +22 -0
  218. data/templates/cli/utility/notifier/presently +13 -0
  219. data/templates/cli/utility/notifier/prowl +11 -0
  220. data/templates/cli/utility/notifier/twitter +13 -0
  221. data/templates/cli/utility/splitter +7 -0
  222. data/templates/cli/utility/storage/cloud_files +22 -0
  223. data/templates/cli/utility/storage/dropbox +20 -0
  224. data/templates/cli/utility/storage/ftp +12 -0
  225. data/templates/cli/utility/storage/local +7 -0
  226. data/templates/cli/utility/storage/ninefold +9 -0
  227. data/templates/cli/utility/storage/rsync +11 -0
  228. data/templates/cli/utility/storage/s3 +19 -0
  229. data/templates/cli/utility/storage/scp +11 -0
  230. data/templates/cli/utility/storage/sftp +11 -0
  231. data/templates/cli/utility/syncer/cloud_files +48 -0
  232. data/templates/cli/utility/syncer/rsync_local +12 -0
  233. data/templates/cli/utility/syncer/rsync_pull +17 -0
  234. data/templates/cli/utility/syncer/rsync_push +17 -0
  235. data/templates/cli/utility/syncer/s3 +45 -0
  236. data/templates/general/links +11 -0
  237. data/templates/general/version.erb +2 -0
  238. data/templates/notifier/mail/failure.erb +9 -0
  239. data/templates/notifier/mail/success.erb +7 -0
  240. data/templates/notifier/mail/warning.erb +9 -0
  241. data/templates/storage/dropbox/authorization_url.erb +6 -0
  242. data/templates/storage/dropbox/authorized.erb +4 -0
  243. data/templates/storage/dropbox/cache_file_written.erb +10 -0
  244. metadata +311 -0
@@ -0,0 +1,345 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper.rb', __FILE__)
4
+
5
+ describe Backup::Storage::RSync do
6
+ let(:model) { Backup::Model.new(:test_trigger, 'test label') }
7
+ let(:storage) do
8
+ Backup::Storage::RSync.new(model) do |rsync|
9
+ rsync.username = 'my_username'
10
+ rsync.password = 'my_password'
11
+ rsync.ip = '123.45.678.90'
12
+ rsync.keep = 5
13
+ end
14
+ end
15
+
16
+ describe '#initialize' do
17
+ it 'should set the correct values' do
18
+ storage.username.should == 'my_username'
19
+ storage.password.should == 'my_password'
20
+ storage.ip.should == '123.45.678.90'
21
+ storage.port.should == 22
22
+ storage.path.should == 'backups'
23
+ storage.local.should == false
24
+
25
+ storage.storage_id.should be_nil
26
+ storage.keep.should == 5
27
+ end
28
+
29
+ it 'should set a storage_id if given' do
30
+ rsync = Backup::Storage::RSync.new(model, 'my storage_id')
31
+ rsync.storage_id.should == 'my storage_id'
32
+ end
33
+
34
+ it 'should remove any preceeding tilde and slash from the path' do
35
+ storage = Backup::Storage::RSync.new(model) do |rsync|
36
+ rsync.path = '~/my_backups/path'
37
+ end
38
+ storage.path.should == 'my_backups/path'
39
+ end
40
+
41
+ context 'when setting configuration defaults' do
42
+ after { Backup::Configuration::Storage::RSync.clear_defaults! }
43
+
44
+ it 'should use the configured defaults' do
45
+ Backup::Configuration::Storage::RSync.defaults do |rsync|
46
+ rsync.username = 'some_username'
47
+ rsync.password = 'some_password'
48
+ rsync.ip = 'some_ip'
49
+ rsync.port = 'some_port'
50
+ rsync.path = 'some_path'
51
+ rsync.local = 'some_local'
52
+ rsync.keep = 'some_keep'
53
+ end
54
+ storage = Backup::Storage::RSync.new(model)
55
+ storage.username.should == 'some_username'
56
+ storage.password.should == 'some_password'
57
+ storage.ip.should == 'some_ip'
58
+ storage.port.should == 'some_port'
59
+ storage.path.should == 'some_path'
60
+ storage.local.should == 'some_local'
61
+
62
+ storage.storage_id.should be_nil
63
+ storage.keep.should == 'some_keep'
64
+ end
65
+
66
+ it 'should override the configured defaults' do
67
+ Backup::Configuration::Storage::RSync.defaults do |rsync|
68
+ rsync.username = 'old_username'
69
+ rsync.password = 'old_password'
70
+ rsync.ip = 'old_ip'
71
+ rsync.port = 'old_port'
72
+ rsync.path = 'old_path'
73
+ rsync.local = 'old_local'
74
+ rsync.keep = 'old_keep'
75
+ end
76
+ storage = Backup::Storage::RSync.new(model) do |rsync|
77
+ rsync.username = 'new_username'
78
+ rsync.password = 'new_password'
79
+ rsync.ip = 'new_ip'
80
+ rsync.port = 'new_port'
81
+ rsync.path = 'new_path'
82
+ rsync.local = 'new_local'
83
+ rsync.keep = 'new_keep'
84
+ end
85
+
86
+ storage.username.should == 'new_username'
87
+ storage.password.should == 'new_password'
88
+ storage.ip.should == 'new_ip'
89
+ storage.port.should == 'new_port'
90
+ storage.path.should == 'new_path'
91
+ storage.local.should == 'new_local'
92
+
93
+ storage.storage_id.should be_nil
94
+ storage.keep.should == 'new_keep'
95
+ end
96
+ end # context 'when setting configuration defaults'
97
+
98
+ end # describe '#initialize'
99
+
100
+ describe '#remote_path_for' do
101
+ let(:package) { mock }
102
+ before do
103
+ storage.instance_variable_set(:@package, package)
104
+ package.expects(:trigger).returns(model.trigger)
105
+ end
106
+
107
+ it 'should override superclass so the time folder is not used' do
108
+ storage.send(:remote_path_for, package).should ==
109
+ File.join('backups', 'test_trigger')
110
+ end
111
+ end
112
+
113
+ describe '#connection' do
114
+ let(:connection) { mock }
115
+ it 'should yield a Net::SSH connection' do
116
+ Net::SSH.expects(:start).with(
117
+ '123.45.678.90', 'my_username', :password => 'my_password', :port => 22
118
+ ).yields(connection)
119
+
120
+ storage.send(:connection) do |ssh|
121
+ ssh.should be(connection)
122
+ end
123
+ end
124
+ end
125
+
126
+ describe '#transfer!' do
127
+ let(:package) { mock }
128
+ let(:s) { sequence '' }
129
+
130
+ before do
131
+ storage.instance_variable_set(:@package, package)
132
+ storage.stubs(:storage_name).returns('Storage::RSync')
133
+ storage.stubs(:local_path).returns('/local/path')
134
+ storage.stubs(:rsync_options).returns(:rsync_options)
135
+ storage.stubs(:rsync_port).returns(:rsync_port)
136
+ storage.stubs(:rsync_password_file).returns(:rsync_password_file)
137
+ storage.expects(:utility).with(:rsync).times(0..2).returns('rsync')
138
+ end
139
+
140
+ context 'when @local is set to false' do
141
+ it 'should transfer the package files to the remote' do
142
+ storage.expects(:write_password_file!).in_sequence(s)
143
+
144
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
145
+ returns('remote/path')
146
+
147
+ storage.expects(:create_remote_path!).in_sequence(s).with('remote/path')
148
+
149
+ storage.expects(:files_to_transfer_for).in_sequence(s).with(package).
150
+ multiple_yields(
151
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
152
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
153
+ )
154
+ # first yield
155
+ Backup::Logger.expects(:message).in_sequence(s).with(
156
+ "Storage::RSync started transferring " +
157
+ "'2011.12.31.11.00.02.backup.tar.enc-aa' to '123.45.678.90'."
158
+ )
159
+ storage.expects(:run).in_sequence(s).with(
160
+ "rsync rsync_options rsync_port rsync_password_file " +
161
+ "'#{ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-aa') }' " +
162
+ "'my_username@123.45.678.90:#{ File.join('remote/path', 'backup.tar.enc-aa') }'"
163
+ )
164
+ # second yield
165
+ Backup::Logger.expects(:message).in_sequence(s).with(
166
+ "Storage::RSync started transferring " +
167
+ "'2011.12.31.11.00.02.backup.tar.enc-ab' to '123.45.678.90'."
168
+ )
169
+ storage.expects(:run).in_sequence(s).with(
170
+ "rsync rsync_options rsync_port rsync_password_file " +
171
+ "'#{ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-ab') }' " +
172
+ "'my_username@123.45.678.90:#{ File.join('remote/path', 'backup.tar.enc-ab') }'"
173
+ )
174
+
175
+ storage.expects(:remove_password_file!).in_sequence(s)
176
+
177
+ storage.send(:transfer!)
178
+ end
179
+
180
+ it 'should ensure password file removal' do
181
+ storage.expects(:write_password_file!).raises('error message')
182
+ storage.expects(:remove_password_file!)
183
+
184
+ expect do
185
+ storage.send(:transfer!)
186
+ end.to raise_error(RuntimeError, 'error message')
187
+ end
188
+ end # context 'when @local is set to false'
189
+
190
+ context 'when @local is set to true' do
191
+ before { storage.local = true }
192
+
193
+ it 'should transfer the package files locally' do
194
+ storage.expects(:write_password_file!).never
195
+
196
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
197
+ returns('remote/path')
198
+
199
+ storage.expects(:create_remote_path!).in_sequence(s).with('remote/path')
200
+
201
+ storage.expects(:files_to_transfer_for).in_sequence(s).with(package).
202
+ multiple_yields(
203
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
204
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
205
+ )
206
+ # first yield
207
+ Backup::Logger.expects(:message).in_sequence(s).with(
208
+ "Storage::RSync started transferring " +
209
+ "'2011.12.31.11.00.02.backup.tar.enc-aa' to 'remote/path'."
210
+ )
211
+ storage.expects(:run).in_sequence(s).with(
212
+ "rsync " +
213
+ "'#{ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-aa') }' " +
214
+ "'#{ File.join('remote/path', 'backup.tar.enc-aa') }'"
215
+ )
216
+ # second yield
217
+ Backup::Logger.expects(:message).in_sequence(s).with(
218
+ "Storage::RSync started transferring " +
219
+ "'2011.12.31.11.00.02.backup.tar.enc-ab' to 'remote/path'."
220
+ )
221
+ storage.expects(:run).in_sequence(s).with(
222
+ "rsync " +
223
+ "'#{ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-ab') }' " +
224
+ "'#{ File.join('remote/path', 'backup.tar.enc-ab') }'"
225
+ )
226
+
227
+ storage.expects(:remove_password_file!).never
228
+
229
+ storage.send(:transfer!)
230
+ end
231
+
232
+ end # context 'when @local is set to true'
233
+
234
+ end # describe '#transfer!'
235
+
236
+ ##
237
+ # Note: Storage::RSync doesn't cycle
238
+ describe '#remove!' do
239
+ it 'should never even be called' do
240
+ storage.send(:remove!).should be_nil
241
+ end
242
+ end
243
+
244
+ describe '#create_remote_path!' do
245
+ let(:connection) { mock }
246
+
247
+ context 'when @local is set to false' do
248
+ it 'should create the remote_path on the remote' do
249
+ FileUtils.expects(:mkdir_p).never
250
+
251
+ storage.expects(:connection).yields(connection)
252
+ connection.expects(:exec!).with("mkdir -p 'remote/path'")
253
+
254
+ storage.send(:create_remote_path!, 'remote/path')
255
+ end
256
+ end
257
+
258
+ context 'when @local is set to true' do
259
+ before { storage.local = true }
260
+ it 'should create the remote_path locally' do
261
+ storage.expects(:connection).never
262
+
263
+ FileUtils.expects(:mkdir_p).with('remote/path')
264
+
265
+ storage.send(:create_remote_path!, 'remote/path')
266
+ end
267
+ end
268
+ end
269
+
270
+ describe '#write_password_file!' do
271
+ let(:file) { mock }
272
+
273
+ context 'when a @password is set' do
274
+ it 'should write the password to file and set @password_file' do
275
+ Tempfile.expects(:new).with('backup-rsync-password').returns(file)
276
+ file.expects(:write).with('my_password')
277
+ file.expects(:close)
278
+
279
+ storage.send(:write_password_file!)
280
+ storage.instance_variable_get(:@password_file).should be(file)
281
+ end
282
+ end
283
+
284
+ context 'when a @password is not set' do
285
+ before { storage.password = nil }
286
+ it 'should do nothing' do
287
+ Tempfile.expects(:new).never
288
+
289
+ storage.send(:write_password_file!)
290
+ storage.instance_variable_get(:@password_file).should be_nil
291
+ end
292
+ end
293
+ end
294
+
295
+ describe '#remove_password_file!' do
296
+ let(:file) { mock }
297
+
298
+ context 'when @password_file is set' do
299
+ before { storage.instance_variable_set(:@password_file, file) }
300
+ it 'should delete the file and clear @password_file' do
301
+ file.expects(:delete)
302
+ storage.send(:remove_password_file!)
303
+ storage.instance_variable_get(:@password_file).should be_nil
304
+ end
305
+ end
306
+
307
+ context 'when @password_file is not set' do
308
+ it 'should do nothing' do
309
+ file.expects(:delete).never
310
+ storage.send(:remove_password_file!)
311
+ end
312
+ end
313
+ end
314
+
315
+ describe '#rsync_password_file' do
316
+ let(:file) { mock }
317
+
318
+ context 'when @password_file is set' do
319
+ before { storage.instance_variable_set(:@password_file, file) }
320
+ it 'should return the syntax for rsync to use the password file' do
321
+ file.expects(:path).returns('/path/to/file')
322
+ storage.send(:rsync_password_file).should == "--password-file='/path/to/file'"
323
+ end
324
+ end
325
+
326
+ context 'when @password_file is not set' do
327
+ it 'should return nil' do
328
+ storage.send(:rsync_password_file).should be_nil
329
+ end
330
+ end
331
+ end
332
+
333
+ describe '#rsync_port' do
334
+ it 'should return the syntax for rsync to set the port' do
335
+ storage.send(:rsync_port).should == "-e 'ssh -p 22'"
336
+ end
337
+ end
338
+
339
+ describe '#rsync_options' do
340
+ it 'should return the syntax for rsync to set other options' do
341
+ storage.send(:rsync_options).should == '-z'
342
+ end
343
+ end
344
+
345
+ end
@@ -0,0 +1,221 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper.rb', __FILE__)
4
+
5
+ ##
6
+ # available S3 regions:
7
+ # eu-west-1, us-east-1, ap-southeast-1, us-west-1
8
+ describe Backup::Storage::S3 do
9
+ let(:model) { Backup::Model.new(:test_trigger, 'test label') }
10
+ let(:storage) do
11
+ Backup::Storage::S3.new(model) do |s3|
12
+ s3.access_key_id = 'my_access_key_id'
13
+ s3.secret_access_key = 'my_secret_access_key'
14
+ s3.bucket = 'my-bucket'
15
+ s3.region = 'us-east-1'
16
+ s3.keep = 5
17
+ end
18
+ end
19
+
20
+ describe '#initialize' do
21
+ it 'should set the correct values' do
22
+ storage.access_key_id.should == 'my_access_key_id'
23
+ storage.secret_access_key.should == 'my_secret_access_key'
24
+ storage.bucket.should == 'my-bucket'
25
+ storage.path.should == 'backups'
26
+ storage.region.should == 'us-east-1'
27
+
28
+ storage.storage_id.should be_nil
29
+ storage.keep.should == 5
30
+ end
31
+
32
+ it 'should set a storage_id if given' do
33
+ s3 = Backup::Storage::S3.new(model, 'my storage_id')
34
+ s3.storage_id.should == 'my storage_id'
35
+ end
36
+
37
+ context 'when setting configuration defaults' do
38
+ after { Backup::Configuration::Storage::S3.clear_defaults! }
39
+
40
+ it 'should use the configured defaults' do
41
+ Backup::Configuration::Storage::S3.defaults do |s3|
42
+ s3.access_key_id = 'some_access_key_id'
43
+ s3.secret_access_key = 'some_secret_access_key'
44
+ s3.bucket = 'some-bucket'
45
+ s3.path = 'some_path'
46
+ s3.region = 'some_region'
47
+ s3.keep = 15
48
+ end
49
+ storage = Backup::Storage::S3.new(model)
50
+ storage.access_key_id.should == 'some_access_key_id'
51
+ storage.secret_access_key.should == 'some_secret_access_key'
52
+ storage.bucket.should == 'some-bucket'
53
+ storage.path.should == 'some_path'
54
+ storage.region.should == 'some_region'
55
+
56
+ storage.storage_id.should be_nil
57
+ storage.keep.should == 15
58
+ end
59
+
60
+ it 'should override the configured defaults' do
61
+ Backup::Configuration::Storage::S3.defaults do |s3|
62
+ s3.access_key_id = 'old_access_key_id'
63
+ s3.secret_access_key = 'old_secret_access_key'
64
+ s3.bucket = 'old-bucket'
65
+ s3.path = 'old_path'
66
+ s3.region = 'old_region'
67
+ s3.keep = 15
68
+ end
69
+ storage = Backup::Storage::S3.new(model) do |s3|
70
+ s3.access_key_id = 'new_access_key_id'
71
+ s3.secret_access_key = 'new_secret_access_key'
72
+ s3.bucket = 'new-bucket'
73
+ s3.path = 'new_path'
74
+ s3.region = 'new_region'
75
+ s3.keep = 10
76
+ end
77
+
78
+ storage.access_key_id.should == 'new_access_key_id'
79
+ storage.secret_access_key.should == 'new_secret_access_key'
80
+ storage.bucket.should == 'new-bucket'
81
+ storage.path.should == 'new_path'
82
+ storage.region.should == 'new_region'
83
+
84
+ storage.storage_id.should be_nil
85
+ storage.keep.should == 10
86
+ end
87
+ end # context 'when setting configuration defaults'
88
+
89
+ end # describe '#initialize'
90
+
91
+ describe '#provider' do
92
+ it 'should set the Fog provider' do
93
+ storage.send(:provider).should == 'AWS'
94
+ end
95
+ end
96
+
97
+ describe '#connection' do
98
+ let(:connection) { mock }
99
+
100
+ it 'should create a new connection' do
101
+ Fog::Storage.expects(:new).once.with(
102
+ :provider => 'AWS',
103
+ :aws_access_key_id => 'my_access_key_id',
104
+ :aws_secret_access_key => 'my_secret_access_key',
105
+ :region => 'us-east-1'
106
+ ).returns(connection)
107
+ storage.send(:connection).should == connection
108
+ end
109
+
110
+ it 'should return an existing connection' do
111
+ Fog::Storage.expects(:new).once.returns(connection)
112
+ storage.send(:connection).should == connection
113
+ storage.send(:connection).should == connection
114
+ end
115
+ end # describe '#connection'
116
+
117
+ describe '#remote_path_for' do
118
+ let(:package) { mock }
119
+
120
+ before do
121
+ # for superclass method
122
+ package.expects(:trigger).returns('trigger')
123
+ package.expects(:time).returns('time')
124
+ end
125
+
126
+ it 'should remove any preceeding slash from the remote path' do
127
+ storage.path = '/backups'
128
+ storage.send(:remote_path_for, package).should == 'backups/trigger/time'
129
+ end
130
+ end
131
+
132
+ describe '#transfer!' do
133
+ let(:connection) { mock }
134
+ let(:package) { mock }
135
+ let(:file) { mock }
136
+ let(:s) { sequence '' }
137
+
138
+ before do
139
+ storage.instance_variable_set(:@package, package)
140
+ storage.stubs(:storage_name).returns('Storage::S3')
141
+ storage.stubs(:local_path).returns('/local/path')
142
+ storage.stubs(:connection).returns(connection)
143
+ end
144
+
145
+ it 'should transfer the package files' do
146
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
147
+ returns('remote/path')
148
+ connection.expects(:sync_clock).in_sequence(s)
149
+ storage.expects(:files_to_transfer_for).in_sequence(s).with(package).
150
+ multiple_yields(
151
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
152
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
153
+ )
154
+ # first yield
155
+ Backup::Logger.expects(:message).in_sequence(s).with(
156
+ "Storage::S3 started transferring " +
157
+ "'2011.12.31.11.00.02.backup.tar.enc-aa' to bucket 'my-bucket'."
158
+ )
159
+ File.expects(:open).in_sequence(s).with(
160
+ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-aa'), 'r'
161
+ ).yields(file)
162
+ connection.expects(:put_object).in_sequence(s).with(
163
+ 'my-bucket', File.join('remote/path', 'backup.tar.enc-aa'), file
164
+ )
165
+ # second yield
166
+ Backup::Logger.expects(:message).in_sequence(s).with(
167
+ "Storage::S3 started transferring " +
168
+ "'2011.12.31.11.00.02.backup.tar.enc-ab' to bucket 'my-bucket'."
169
+ )
170
+ File.expects(:open).in_sequence(s).with(
171
+ File.join('/local/path', '2011.12.31.11.00.02.backup.tar.enc-ab'), 'r'
172
+ ).yields(file)
173
+ connection.expects(:put_object).in_sequence(s).with(
174
+ 'my-bucket', File.join('remote/path', 'backup.tar.enc-ab'), file
175
+ )
176
+
177
+ storage.send(:transfer!)
178
+ end
179
+ end # describe '#transfer!'
180
+
181
+ describe '#remove!' do
182
+ let(:package) { mock }
183
+ let(:connection) { mock }
184
+ let(:s) { sequence '' }
185
+
186
+ before do
187
+ storage.stubs(:storage_name).returns('Storage::S3')
188
+ storage.stubs(:connection).returns(connection)
189
+ end
190
+
191
+ it 'should remove the package files' do
192
+ storage.expects(:remote_path_for).in_sequence(s).with(package).
193
+ returns('remote/path')
194
+ connection.expects(:sync_clock).in_sequence(s)
195
+ storage.expects(:transferred_files_for).in_sequence(s).with(package).
196
+ multiple_yields(
197
+ ['2011.12.31.11.00.02.backup.tar.enc-aa', 'backup.tar.enc-aa'],
198
+ ['2011.12.31.11.00.02.backup.tar.enc-ab', 'backup.tar.enc-ab']
199
+ )
200
+ # first yield
201
+ Backup::Logger.expects(:message).in_sequence(s).with(
202
+ "Storage::S3 started removing " +
203
+ "'2011.12.31.11.00.02.backup.tar.enc-aa' from bucket 'my-bucket'."
204
+ )
205
+ connection.expects(:delete_object).in_sequence(s).with(
206
+ 'my-bucket', File.join('remote/path', 'backup.tar.enc-aa')
207
+ )
208
+ # second yield
209
+ Backup::Logger.expects(:message).in_sequence(s).with(
210
+ "Storage::S3 started removing " +
211
+ "'2011.12.31.11.00.02.backup.tar.enc-ab' from bucket 'my-bucket'."
212
+ )
213
+ connection.expects(:delete_object).in_sequence(s).with(
214
+ 'my-bucket', File.join('remote/path', 'backup.tar.enc-ab')
215
+ )
216
+
217
+ storage.send(:remove!, package)
218
+ end
219
+ end # describe '#remove!'
220
+
221
+ end