interu-backup 3.0.16

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 (151) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +31 -0
  3. data/Gemfile.lock +117 -0
  4. data/Guardfile +17 -0
  5. data/LICENSE.md +24 -0
  6. data/README.md +332 -0
  7. data/backup.gemspec +31 -0
  8. data/bin/backup +267 -0
  9. data/lib/backup.rb +181 -0
  10. data/lib/backup/archive.rb +73 -0
  11. data/lib/backup/cli.rb +82 -0
  12. data/lib/backup/compressor/base.rb +17 -0
  13. data/lib/backup/compressor/bzip2.rb +64 -0
  14. data/lib/backup/compressor/gzip.rb +61 -0
  15. data/lib/backup/configuration/base.rb +15 -0
  16. data/lib/backup/configuration/compressor/base.rb +10 -0
  17. data/lib/backup/configuration/compressor/bzip2.rb +23 -0
  18. data/lib/backup/configuration/compressor/gzip.rb +23 -0
  19. data/lib/backup/configuration/database/base.rb +18 -0
  20. data/lib/backup/configuration/database/mongodb.rb +41 -0
  21. data/lib/backup/configuration/database/mysql.rb +37 -0
  22. data/lib/backup/configuration/database/postgresql.rb +37 -0
  23. data/lib/backup/configuration/database/redis.rb +35 -0
  24. data/lib/backup/configuration/encryptor/base.rb +10 -0
  25. data/lib/backup/configuration/encryptor/gpg.rb +17 -0
  26. data/lib/backup/configuration/encryptor/open_ssl.rb +26 -0
  27. data/lib/backup/configuration/helpers.rb +54 -0
  28. data/lib/backup/configuration/notifier/base.rb +39 -0
  29. data/lib/backup/configuration/notifier/campfire.rb +25 -0
  30. data/lib/backup/configuration/notifier/mail.rb +52 -0
  31. data/lib/backup/configuration/notifier/presently.rb +25 -0
  32. data/lib/backup/configuration/notifier/twitter.rb +21 -0
  33. data/lib/backup/configuration/storage/base.rb +18 -0
  34. data/lib/backup/configuration/storage/cloudfiles.rb +21 -0
  35. data/lib/backup/configuration/storage/dropbox.rb +29 -0
  36. data/lib/backup/configuration/storage/ftp.rb +25 -0
  37. data/lib/backup/configuration/storage/rsync.rb +25 -0
  38. data/lib/backup/configuration/storage/s3.rb +25 -0
  39. data/lib/backup/configuration/storage/scp.rb +25 -0
  40. data/lib/backup/configuration/storage/sftp.rb +25 -0
  41. data/lib/backup/configuration/syncer/rsync.rb +45 -0
  42. data/lib/backup/configuration/syncer/s3.rb +33 -0
  43. data/lib/backup/database/base.rb +33 -0
  44. data/lib/backup/database/mongodb.rb +179 -0
  45. data/lib/backup/database/mysql.rb +104 -0
  46. data/lib/backup/database/postgresql.rb +111 -0
  47. data/lib/backup/database/redis.rb +105 -0
  48. data/lib/backup/dependency.rb +96 -0
  49. data/lib/backup/encryptor/base.rb +17 -0
  50. data/lib/backup/encryptor/gpg.rb +78 -0
  51. data/lib/backup/encryptor/open_ssl.rb +67 -0
  52. data/lib/backup/exception/command_not_found.rb +8 -0
  53. data/lib/backup/finder.rb +39 -0
  54. data/lib/backup/logger.rb +102 -0
  55. data/lib/backup/model.rb +272 -0
  56. data/lib/backup/notifier/base.rb +29 -0
  57. data/lib/backup/notifier/binder.rb +32 -0
  58. data/lib/backup/notifier/campfire.rb +194 -0
  59. data/lib/backup/notifier/mail.rb +141 -0
  60. data/lib/backup/notifier/presently.rb +105 -0
  61. data/lib/backup/notifier/templates/notify_failure.erb +33 -0
  62. data/lib/backup/notifier/templates/notify_success.erb +16 -0
  63. data/lib/backup/notifier/twitter.rb +87 -0
  64. data/lib/backup/storage/base.rb +67 -0
  65. data/lib/backup/storage/cloudfiles.rb +95 -0
  66. data/lib/backup/storage/dropbox.rb +91 -0
  67. data/lib/backup/storage/ftp.rb +114 -0
  68. data/lib/backup/storage/object.rb +45 -0
  69. data/lib/backup/storage/rsync.rb +129 -0
  70. data/lib/backup/storage/s3.rb +180 -0
  71. data/lib/backup/storage/scp.rb +106 -0
  72. data/lib/backup/storage/sftp.rb +106 -0
  73. data/lib/backup/syncer/base.rb +10 -0
  74. data/lib/backup/syncer/rsync.rb +152 -0
  75. data/lib/backup/syncer/s3.rb +118 -0
  76. data/lib/backup/version.rb +43 -0
  77. data/lib/templates/archive +7 -0
  78. data/lib/templates/compressor/bzip2 +7 -0
  79. data/lib/templates/compressor/gzip +7 -0
  80. data/lib/templates/database/mongodb +14 -0
  81. data/lib/templates/database/mysql +14 -0
  82. data/lib/templates/database/postgresql +14 -0
  83. data/lib/templates/database/redis +13 -0
  84. data/lib/templates/encryptor/gpg +12 -0
  85. data/lib/templates/encryptor/openssl +8 -0
  86. data/lib/templates/notifier/campfire +11 -0
  87. data/lib/templates/notifier/mail +17 -0
  88. data/lib/templates/notifier/presently +12 -0
  89. data/lib/templates/notifier/twitter +12 -0
  90. data/lib/templates/readme +15 -0
  91. data/lib/templates/storage/cloudfiles +10 -0
  92. data/lib/templates/storage/dropbox +12 -0
  93. data/lib/templates/storage/ftp +11 -0
  94. data/lib/templates/storage/rsync +10 -0
  95. data/lib/templates/storage/s3 +21 -0
  96. data/lib/templates/storage/scp +11 -0
  97. data/lib/templates/storage/sftp +11 -0
  98. data/lib/templates/syncer/rsync +17 -0
  99. data/lib/templates/syncer/s3 +15 -0
  100. data/spec/archive_spec.rb +90 -0
  101. data/spec/backup_spec.rb +11 -0
  102. data/spec/compressor/bzip2_spec.rb +59 -0
  103. data/spec/compressor/gzip_spec.rb +59 -0
  104. data/spec/configuration/base_spec.rb +35 -0
  105. data/spec/configuration/compressor/gzip_spec.rb +28 -0
  106. data/spec/configuration/database/base_spec.rb +16 -0
  107. data/spec/configuration/database/mongodb_spec.rb +30 -0
  108. data/spec/configuration/database/mysql_spec.rb +32 -0
  109. data/spec/configuration/database/postgresql_spec.rb +32 -0
  110. data/spec/configuration/database/redis_spec.rb +30 -0
  111. data/spec/configuration/encryptor/gpg_spec.rb +25 -0
  112. data/spec/configuration/encryptor/open_ssl_spec.rb +31 -0
  113. data/spec/configuration/notifier/campfire_spec.rb +20 -0
  114. data/spec/configuration/notifier/mail_spec.rb +32 -0
  115. data/spec/configuration/notifier/twitter_spec.rb +22 -0
  116. data/spec/configuration/storage/cloudfiles_spec.rb +34 -0
  117. data/spec/configuration/storage/dropbox_spec.rb +43 -0
  118. data/spec/configuration/storage/ftp_spec.rb +40 -0
  119. data/spec/configuration/storage/rsync_spec.rb +37 -0
  120. data/spec/configuration/storage/s3_spec.rb +37 -0
  121. data/spec/configuration/storage/scp_spec.rb +40 -0
  122. data/spec/configuration/storage/sftp_spec.rb +40 -0
  123. data/spec/configuration/syncer/rsync_spec.rb +46 -0
  124. data/spec/configuration/syncer/s3_spec.rb +43 -0
  125. data/spec/database/base_spec.rb +30 -0
  126. data/spec/database/mongodb_spec.rb +181 -0
  127. data/spec/database/mysql_spec.rb +150 -0
  128. data/spec/database/postgresql_spec.rb +164 -0
  129. data/spec/database/redis_spec.rb +122 -0
  130. data/spec/encryptor/gpg_spec.rb +57 -0
  131. data/spec/encryptor/open_ssl_spec.rb +102 -0
  132. data/spec/logger_spec.rb +58 -0
  133. data/spec/model_spec.rb +236 -0
  134. data/spec/notifier/campfire_spec.rb +96 -0
  135. data/spec/notifier/mail_spec.rb +97 -0
  136. data/spec/notifier/presently_spec.rb +99 -0
  137. data/spec/notifier/twitter_spec.rb +86 -0
  138. data/spec/spec_helper.rb +25 -0
  139. data/spec/storage/base_spec.rb +33 -0
  140. data/spec/storage/cloudfiles_spec.rb +102 -0
  141. data/spec/storage/dropbox_spec.rb +105 -0
  142. data/spec/storage/ftp_spec.rb +133 -0
  143. data/spec/storage/object_spec.rb +74 -0
  144. data/spec/storage/rsync_spec.rb +131 -0
  145. data/spec/storage/s3_spec.rb +110 -0
  146. data/spec/storage/scp_spec.rb +129 -0
  147. data/spec/storage/sftp_spec.rb +125 -0
  148. data/spec/syncer/rsync_spec.rb +195 -0
  149. data/spec/syncer/s3_spec.rb +139 -0
  150. data/spec/version_spec.rb +21 -0
  151. metadata +231 -0
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Backup::Storage::Dropbox do
6
+
7
+ let(:db) do
8
+ Backup::Storage::Dropbox.new do |db|
9
+ db.email = 'my@email.com'
10
+ db.password = 'my_password'
11
+ db.api_key = 'my_api_key'
12
+ db.api_secret = 'my_secret'
13
+ db.keep = 20
14
+ db.timeout = 500
15
+ end
16
+ end
17
+
18
+ let(:connection) do
19
+ c = mock("Dropbox::Session")
20
+ db.stubs(:connection).returns(c); c
21
+ end
22
+
23
+ before do
24
+ Backup::Configuration::Storage::Dropbox.clear_defaults!
25
+ end
26
+
27
+ it 'should have defined the configuration properly' do
28
+ db.email.should == 'my@email.com'
29
+ db.password.should == 'my_password'
30
+ db.api_key.should == 'my_api_key'
31
+ db.api_secret.should == 'my_secret'
32
+ db.path.should == 'backups'
33
+ db.keep.should == 20
34
+ db.timeout.should == 500
35
+ end
36
+
37
+ it 'should overwrite the default timeout' do
38
+ db = Backup::Storage::Dropbox.new do |db|
39
+ db.timeout = 500
40
+ end
41
+
42
+ db.timeout.should == 500
43
+ end
44
+
45
+ it 'should provide a default timeout' do
46
+ db = Backup::Storage::Dropbox.new
47
+
48
+ db.timeout.should == 300
49
+ end
50
+
51
+ it 'should overwrite the default path' do
52
+ db = Backup::Storage::Dropbox.new do |db|
53
+ db.path = 'my/backups'
54
+ end
55
+
56
+ db.path.should == 'my/backups'
57
+ end
58
+
59
+ describe '#connection' do
60
+ it do
61
+ session = mock("Dropbox::Session")
62
+ Dropbox::Session.expects(:new).with('my_api_key', 'my_secret').returns(session)
63
+ session.expects(:mode=).with(:dropbox)
64
+ session.expects(:authorizing_user=).with('my@email.com')
65
+ session.expects(:authorizing_password=).with('my_password')
66
+ session.expects(:authorize!)
67
+
68
+ db.send(:connection)
69
+ end
70
+ end
71
+
72
+ describe '#transfer!' do
73
+ before do
74
+ Backup::Logger.stubs(:message)
75
+ connection.stubs(:upload)
76
+ connection.stubs(:delete)
77
+ end
78
+
79
+ it do
80
+ Backup::Logger.expects(:message).with("Backup::Storage::Dropbox started transferring \"#{ Backup::TIME }.#{ Backup::TRIGGER }.tar\".")
81
+ db.send(:transfer!)
82
+ end
83
+
84
+ it do
85
+ connection.expects(:upload).with(
86
+ File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar"),
87
+ File.join('backups', Backup::TRIGGER),
88
+ :timeout => db.timeout
89
+ )
90
+
91
+ db.send(:transfer!)
92
+ end
93
+ end
94
+
95
+ describe '#remove!' do
96
+ it do
97
+ connection.expects(:delete).with(
98
+ File.join('backups', Backup::TRIGGER, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
99
+ )
100
+
101
+ db.send(:remove!)
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Backup::Storage::FTP do
6
+
7
+ let(:ftp) do
8
+ Backup::Storage::FTP.new do |ftp|
9
+ ftp.username = 'my_username'
10
+ ftp.password = 'my_password'
11
+ ftp.ip = '123.45.678.90'
12
+ ftp.port = 21
13
+ ftp.path = '~/backups/'
14
+ ftp.keep = 20
15
+ end
16
+ end
17
+
18
+ before do
19
+ Backup::Configuration::Storage::FTP.clear_defaults!
20
+ end
21
+
22
+ it 'should have defined the configuration properly' do
23
+ ftp.username.should == 'my_username'
24
+ ftp.password.should == 'my_password'
25
+ ftp.ip.should == '123.45.678.90'
26
+ ftp.port.should == 21
27
+ ftp.path.should == 'backups/'
28
+ ftp.keep.should == 20
29
+ end
30
+
31
+ it 'should use the defaults if a particular attribute has not been defined' do
32
+ Backup::Configuration::Storage::FTP.defaults do |ftp|
33
+ ftp.username = 'my_default_username'
34
+ ftp.password = 'my_default_password'
35
+ ftp.path = '~/backups'
36
+ end
37
+
38
+ ftp = Backup::Storage::FTP.new do |ftp|
39
+ ftp.password = 'my_password'
40
+ ftp.ip = '123.45.678.90'
41
+ end
42
+
43
+ ftp.username.should == 'my_default_username'
44
+ ftp.password.should == 'my_password'
45
+ ftp.ip.should == '123.45.678.90'
46
+ ftp.port.should == 21
47
+ end
48
+
49
+ it 'should have its own defaults' do
50
+ ftp = Backup::Storage::FTP.new
51
+ ftp.port.should == 21
52
+ ftp.path.should == 'backups'
53
+ end
54
+
55
+ describe '#connection' do
56
+ it 'should establish a connection to the remote server using the provided ip address and credentials' do
57
+ Net::FTP.expects(:new).with('123.45.678.90', 'my_username', 'my_password')
58
+ ftp.send(:connection)
59
+ end
60
+
61
+ it 'should re-define the Net::FTP port' do
62
+ Net::FTP.stubs(:new)
63
+ ftp.port = 40
64
+ ftp.send(:connection)
65
+ Net::FTP::FTP_PORT.should == 40
66
+ end
67
+ end
68
+
69
+ describe '#transfer!' do
70
+ let(:connection) { mock('Fog::Storage') }
71
+
72
+ before do
73
+ Net::FTP.stubs(:new).returns(connection)
74
+ ftp.stubs(:create_remote_directories!)
75
+ Backup::Logger.stubs(:message)
76
+ end
77
+
78
+ it 'should transfer the provided file to the path' do
79
+ Backup::Model.new('blah', 'blah') {}
80
+ file = mock("Backup::Storage::FTP::File")
81
+
82
+ ftp.expects(:create_remote_directories!)
83
+ connection.expects(:put).with(
84
+ File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar"),
85
+ File.join('backups/myapp', "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
86
+ )
87
+
88
+ ftp.send(:transfer!)
89
+ end
90
+ end
91
+
92
+ describe '#remove!' do
93
+ let(:connection) { mock('Net::FTP') }
94
+
95
+ before do
96
+ Net::FTP.stubs(:new).returns(connection)
97
+ end
98
+
99
+ it 'should remove the file from the remote server path' do
100
+ connection.expects(:delete).with("backups/myapp/#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
101
+ ftp.send(:remove!)
102
+ end
103
+ end
104
+
105
+ describe '#create_remote_directories!' do
106
+ let(:connection) { mock('Net::FTP') }
107
+
108
+ before do
109
+ Net::FTP.stubs(:new).returns(connection)
110
+ end
111
+
112
+ it 'should properly create remote directories one by one' do
113
+ ftp.path = '~/backups/some_other_folder/another_folder'
114
+
115
+ connection.expects(:mkdir).with('~')
116
+ connection.expects(:mkdir).with('~/backups')
117
+ connection.expects(:mkdir).with('~/backups/some_other_folder')
118
+ connection.expects(:mkdir).with('~/backups/some_other_folder/another_folder')
119
+ connection.expects(:mkdir).with('~/backups/some_other_folder/another_folder/myapp')
120
+
121
+ ftp.send(:create_remote_directories!)
122
+ end
123
+ end
124
+
125
+ describe '#perform' do
126
+ it 'should invoke transfer! and cycle!' do
127
+ ftp.expects(:transfer!)
128
+ ftp.expects(:cycle!)
129
+ ftp.perform!
130
+ end
131
+ end
132
+
133
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Backup::Storage::Object do
6
+ let(:object) { Backup::Storage::Object.new(:s3) }
7
+
8
+ it do
9
+ object.storage_file.should == File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
10
+ end
11
+
12
+ describe '#load' do
13
+ it 'should return an array with objects' do
14
+ File.expects(:exist?).returns(true)
15
+ YAML.expects(:load_file).with(
16
+ File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
17
+ ).returns(YAML.load([Backup::Storage::S3.new, Backup::Storage::S3.new].to_yaml))
18
+
19
+ objects = object.load
20
+ objects.should be_an(Array)
21
+ objects.first.should be_an_instance_of(Backup::Storage::S3)
22
+ end
23
+
24
+ describe 'loading them sorted by time descending (newest backup is first in the array)' do
25
+ it do
26
+ obj_1 = Backup::Storage::S3.new; obj_1.time = '2007.00.00.00.00.00'
27
+ obj_2 = Backup::Storage::S3.new; obj_2.time = '2009.00.00.00.00.00'
28
+ obj_3 = Backup::Storage::S3.new; obj_3.time = '2011.00.00.00.00.00'
29
+
30
+ File.expects(:exist?).returns(true)
31
+ YAML.expects(:load_file).with(
32
+ File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
33
+ ).returns(YAML.load([obj_1, obj_2, obj_3].to_yaml))
34
+
35
+ objects = object.load
36
+ objects[0].time.should == '2011.00.00.00.00.00'
37
+ objects[1].time.should == '2009.00.00.00.00.00'
38
+ objects[2].time.should == '2007.00.00.00.00.00'
39
+ end
40
+
41
+ it do
42
+ obj_3 = Backup::Storage::S3.new; obj_3.time = '2007.00.00.00.00.00'
43
+ obj_2 = Backup::Storage::S3.new; obj_2.time = '2009.00.00.00.00.00'
44
+ obj_1 = Backup::Storage::S3.new; obj_1.time = '2011.00.00.00.00.00'
45
+
46
+ File.expects(:exist?).returns(true)
47
+ YAML.expects(:load_file).with(
48
+ File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
49
+ ).returns(YAML.load([obj_1, obj_2, obj_3].to_yaml))
50
+
51
+ objects = object.load
52
+ objects[0].time.should == '2011.00.00.00.00.00'
53
+ objects[1].time.should == '2009.00.00.00.00.00'
54
+ objects[2].time.should == '2007.00.00.00.00.00'
55
+ end
56
+
57
+ it do
58
+ obj_3 = Backup::Storage::S3.new; obj_3.time = '2007.00.00.00.00.00'
59
+ obj_1 = Backup::Storage::S3.new; obj_1.time = '2009.00.00.00.00.00'
60
+ obj_2 = Backup::Storage::S3.new; obj_2.time = '2011.00.00.00.00.00'
61
+
62
+ File.expects(:exist?).returns(true)
63
+ YAML.expects(:load_file).with(
64
+ File.join(Backup::DATA_PATH, Backup::TRIGGER, 's3.yml')
65
+ ).returns(YAML.load([obj_1, obj_2, obj_3].to_yaml))
66
+
67
+ objects = object.load
68
+ objects[0].time.should == '2011.00.00.00.00.00'
69
+ objects[1].time.should == '2009.00.00.00.00.00'
70
+ objects[2].time.should == '2007.00.00.00.00.00'
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,131 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
4
+
5
+ describe Backup::Storage::RSync do
6
+
7
+ let(:rsync) do
8
+ Backup::Storage::RSync.new do |rsync|
9
+ rsync.username = 'my_username'
10
+ rsync.password = 'my_password'
11
+ rsync.ip = '123.45.678.90'
12
+ rsync.port = 22
13
+ rsync.path = '~/backups/'
14
+ end
15
+ end
16
+
17
+ before do
18
+ Backup::Configuration::Storage::RSync.clear_defaults!
19
+ end
20
+
21
+ it 'should have defined the configuration properly' do
22
+ rsync.username.should == 'my_username'
23
+ rsync.send(:password).should =~ /backup-rsync-password/
24
+ rsync.ip.should == '123.45.678.90'
25
+ rsync.port.should == 22
26
+ rsync.path.should == 'backups/'
27
+
28
+ File.read(rsync.instance_variable_get('@password_file').path).should == 'my_password'
29
+ end
30
+
31
+ it 'should use the defaults if a particular attribute has not been defined' do
32
+ Backup::Configuration::Storage::RSync.defaults do |rsync|
33
+ rsync.username = 'my_default_username'
34
+ rsync.password = 'my_default_password'
35
+ rsync.path = '~/backups'
36
+ end
37
+
38
+ rsync = Backup::Storage::RSync.new do |rsync|
39
+ rsync.password = 'my_password'
40
+ rsync.ip = '123.45.678.90'
41
+ end
42
+
43
+ rsync.username.should == 'my_default_username'
44
+ rsync.send(:password).should =~ /backup-rsync-password/
45
+ rsync.ip.should == '123.45.678.90'
46
+ rsync.port.should == 22
47
+
48
+ File.read(rsync.instance_variable_get('@password_file').path).should == 'my_password'
49
+ end
50
+
51
+ it 'should have its own defaults' do
52
+ rsync = Backup::Storage::RSync.new
53
+ rsync.port.should == 22
54
+ rsync.path.should == 'backups'
55
+ end
56
+
57
+ describe '#connection' do
58
+ it 'should establish a connection to the remote server using the provided ip address and credentials' do
59
+ Net::SSH.expects(:start).with('123.45.678.90', 'my_username', :password => 'my_password', :port => 22)
60
+ rsync.send(:connection)
61
+ end
62
+ end
63
+
64
+ describe '#transfer!' do
65
+ let(:connection) { mock('Net::SCP') }
66
+
67
+ before do
68
+ Net::SSH.stubs(:start).returns(connection)
69
+ rsync.stubs(:create_remote_directories!)
70
+ Backup::Logger.stubs(:message)
71
+ end
72
+
73
+ it 'should transfer the provided file to the path' do
74
+ Backup::Model.new('blah', 'blah') {}
75
+ file = mock("Backup::Storage::RSync::File")
76
+
77
+ rsync.expects(:create_remote_directories!)
78
+ rsync.expects(:utility).returns('rsync')
79
+ rsync.expects(:run).with("rsync -z --port='22' --password-file='#{rsync.instance_variable_get('@password_file').path}' '#{ File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar") }' 'my_username@123.45.678.90:backups/#{ Backup::TRIGGER }/#{ Backup::TRIGGER }.tar'")
80
+
81
+ rsync.send(:transfer!)
82
+ end
83
+
84
+ it 'should not provide the --password-file option' do
85
+ Backup::Model.new('blah', 'blah') {}
86
+ file = mock("Backup::Storage::RSync::File")
87
+
88
+ rsync.password = nil
89
+ rsync.expects(:create_remote_directories!)
90
+ rsync.expects(:utility).returns('rsync')
91
+ rsync.expects(:run).with("rsync -z --port='22' '#{ File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER }.tar") }' 'my_username@123.45.678.90:backups/#{ Backup::TRIGGER }/#{ Backup::TRIGGER }.tar'")
92
+
93
+ rsync.send(:transfer!)
94
+ end
95
+ end
96
+
97
+ describe '#remove!' do
98
+ let(:connection) { mock('Net::SCP') }
99
+
100
+ before do
101
+ Net::SSH.stubs(:start).returns(connection)
102
+ end
103
+
104
+ it 'should remove the file from the remote server path' do
105
+ connection.expects(:exec!).with("rm backups/myapp/#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
106
+ rsync.send(:remove!)
107
+ end
108
+ end
109
+
110
+ describe '#create_remote_directories!' do
111
+ let(:connection) { mock('Net::SSH') }
112
+
113
+ before do
114
+ Net::SSH.stubs(:start).returns(connection)
115
+ end
116
+
117
+ it 'should properly create remote directories one by one' do
118
+ rsync.path = 'backups/some_other_folder/another_folder'
119
+ connection.expects(:exec!).with("mkdir -p 'backups/some_other_folder/another_folder/myapp'")
120
+ rsync.send(:create_remote_directories!)
121
+ end
122
+ end
123
+
124
+ describe '#perform' do
125
+ it 'should invoke transfer!' do
126
+ rsync.expects(:transfer!)
127
+ rsync.perform!
128
+ end
129
+ end
130
+
131
+ end
@@ -0,0 +1,110 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/../spec_helper'
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
+
10
+ let(:s3) do
11
+ Backup::Storage::S3.new do |s3|
12
+ s3.access_key_id = 'my_access_key_id'
13
+ s3.secret_access_key = 'my_secret_access_key'
14
+ s3.region = 'us-east-1'
15
+ s3.bucket = 'my-bucket'
16
+ s3.path = 'backups'
17
+ s3.keep = 20
18
+ end
19
+ end
20
+
21
+ before do
22
+ Backup::Configuration::Storage::S3.clear_defaults!
23
+ end
24
+
25
+ it 'should have defined the configuration properly' do
26
+ s3.access_key_id.should == 'my_access_key_id'
27
+ s3.secret_access_key.should == 'my_secret_access_key'
28
+ s3.region.should == 'us-east-1'
29
+ s3.bucket.should == 'my-bucket'
30
+ s3.keep.should == 20
31
+ end
32
+
33
+ it 'should use the defaults if a particular attribute has not been defined' do
34
+ Backup::Configuration::Storage::S3.defaults do |s3|
35
+ s3.access_key_id = 'my_access_key_id'
36
+ s3.region = 'us-east-1'
37
+ end
38
+
39
+ s3 = Backup::Storage::S3.new do |s3|
40
+ s3.region = 'us-west-1'
41
+ s3.path = 'my/backups'
42
+ end
43
+
44
+ s3.access_key_id.should == 'my_access_key_id' # not defined, uses default
45
+ s3.secret_access_key.should == nil # not defined, no default
46
+ s3.region.should == 'us-west-1' # defined, overwrites default
47
+ s3.bucket.should == nil # not defined, no default
48
+ s3.path.should == 'my/backups' # overwritten from Backup::Storage::S3
49
+ end
50
+
51
+ describe '#connection' do
52
+ it 'should establish a connection to Amazon S3 using the provided credentials' do
53
+ Fog::Storage.expects(:new).with({
54
+ :provider => 'AWS',
55
+ :aws_access_key_id => 'my_access_key_id',
56
+ :aws_secret_access_key => 'my_secret_access_key',
57
+ :region => 'us-east-1'
58
+ })
59
+
60
+ s3.send(:connection)
61
+ end
62
+ end
63
+
64
+ describe '#provider' do
65
+ it 'should be AWS' do
66
+ s3.provider == 'AWS'
67
+ end
68
+ end
69
+
70
+ describe '#transfer!' do
71
+ let(:connection) { mock('Fog::Storage') }
72
+ before do
73
+ Fog::Storage.stubs(:new).returns(connection)
74
+ Backup::Logger.stubs(:message)
75
+ end
76
+
77
+ it 'should transfer the provided file to the bucket' do
78
+ Backup::Model.new('blah', 'blah') {}
79
+ file = mock("Backup::Storage::S3::File")
80
+ File.expects(:open).with("#{File.join(Backup::TMP_PATH, "#{ Backup::TIME }.#{ Backup::TRIGGER}")}.tar").returns(file)
81
+ s3.expects(:remote_file).returns("#{ Backup::TIME }.#{ Backup::TRIGGER }.tar").twice
82
+ connection.expects(:sync_clock)
83
+ connection.expects(:put_object).with('my-bucket', "backups/myapp/#{ Backup::TIME }.#{ Backup::TRIGGER }.tar", file)
84
+ s3.send(:transfer!)
85
+ end
86
+ end
87
+
88
+ describe '#remove!' do
89
+ let(:connection) { mock('Fog::Storage') }
90
+ before do
91
+ Fog::Storage.stubs(:new).returns(connection)
92
+ end
93
+
94
+ it 'should remove the file from the bucket' do
95
+ s3.expects(:remote_file).returns("#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
96
+ connection.expects(:sync_clock)
97
+ connection.expects(:delete_object).with('my-bucket', "backups/myapp/#{ Backup::TIME }.#{ Backup::TRIGGER }.tar")
98
+ s3.send(:remove!)
99
+ end
100
+ end
101
+
102
+ describe '#perform' do
103
+ it 'should invoke transfer! and cycle!' do
104
+ s3.expects(:transfer!)
105
+ s3.expects(:cycle!)
106
+ s3.perform!
107
+ end
108
+ end
109
+
110
+ end