backup 3.0.16 → 3.0.18

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 (81) hide show
  1. data/.travis.yml +10 -0
  2. data/Gemfile.lock +50 -47
  3. data/Guardfile +3 -3
  4. data/README.md +136 -81
  5. data/backup.gemspec +3 -2
  6. data/bin/backup +36 -15
  7. data/lib/backup.rb +30 -20
  8. data/lib/backup/cli.rb +30 -2
  9. data/lib/backup/compressor/lzma.rb +63 -0
  10. data/lib/backup/configuration/compressor/lzma.rb +23 -0
  11. data/lib/backup/configuration/helpers.rb +10 -4
  12. data/lib/backup/configuration/notifier/mail.rb +5 -0
  13. data/lib/backup/configuration/storage/dropbox.rb +19 -4
  14. data/lib/backup/configuration/storage/ftp.rb +4 -0
  15. data/lib/backup/configuration/storage/local.rb +17 -0
  16. data/lib/backup/configuration/storage/ninefold.rb +20 -0
  17. data/lib/backup/configuration/storage/rsync.rb +4 -0
  18. data/lib/backup/database/postgresql.rb +12 -3
  19. data/lib/backup/database/redis.rb +5 -1
  20. data/lib/backup/dependency.rb +11 -12
  21. data/lib/backup/encryptor/gpg.rb +2 -0
  22. data/lib/backup/exception/command_failed.rb +8 -0
  23. data/lib/backup/finder.rb +49 -9
  24. data/lib/backup/notifier/mail.rb +7 -1
  25. data/lib/backup/notifier/twitter.rb +1 -1
  26. data/lib/backup/storage/dropbox.rb +93 -16
  27. data/lib/backup/storage/ftp.rb +10 -3
  28. data/lib/backup/storage/local.rb +78 -0
  29. data/lib/backup/storage/ninefold.rb +96 -0
  30. data/lib/backup/storage/rsync.rb +37 -20
  31. data/lib/backup/storage/s3.rb +1 -1
  32. data/lib/backup/storage/scp.rb +1 -1
  33. data/lib/backup/syncer/rsync.rb +1 -1
  34. data/lib/backup/version.rb +1 -1
  35. data/lib/templates/compressor/lzma +7 -0
  36. data/lib/templates/storage/dropbox +2 -2
  37. data/lib/templates/storage/ftp +8 -7
  38. data/lib/templates/storage/local +7 -0
  39. data/lib/templates/storage/ninefold +9 -0
  40. data/lib/templates/storage/rsync +1 -0
  41. data/spec/archive_spec.rb +0 -1
  42. data/spec/compressor/bzip2_spec.rb +0 -1
  43. data/spec/compressor/gzip_spec.rb +0 -1
  44. data/spec/compressor/lzma_spec.rb +58 -0
  45. data/spec/configuration/compressor/bzip2_spec.rb +28 -0
  46. data/spec/configuration/compressor/lzma_spec.rb +28 -0
  47. data/spec/configuration/database/mongodb_spec.rb +16 -0
  48. data/spec/configuration/database/mysql_spec.rb +17 -0
  49. data/spec/configuration/database/postgresql_spec.rb +17 -0
  50. data/spec/configuration/database/redis_spec.rb +16 -0
  51. data/spec/configuration/notifier/campfire_spec.rb +11 -0
  52. data/spec/configuration/notifier/mail_spec.rb +20 -0
  53. data/spec/configuration/notifier/presently_spec.rb +34 -0
  54. data/spec/configuration/notifier/twitter_spec.rb +12 -0
  55. data/spec/configuration/storage/dropbox_spec.rb +0 -6
  56. data/spec/configuration/storage/ftp_spec.rb +15 -12
  57. data/spec/configuration/storage/local_spec.rb +28 -0
  58. data/spec/configuration/storage/ninefold_spec.rb +31 -0
  59. data/spec/configuration/storage/rsync_spec.rb +2 -0
  60. data/spec/database/mongodb_spec.rb +0 -1
  61. data/spec/database/mysql_spec.rb +0 -1
  62. data/spec/database/postgresql_spec.rb +31 -11
  63. data/spec/database/redis_spec.rb +9 -4
  64. data/spec/encryptor/gpg_spec.rb +1 -1
  65. data/spec/encryptor/open_ssl_spec.rb +0 -1
  66. data/spec/logger_spec.rb +32 -24
  67. data/spec/model_spec.rb +15 -15
  68. data/spec/spec_helper.rb +8 -4
  69. data/spec/storage/base_spec.rb +0 -4
  70. data/spec/storage/cloudfiles_spec.rb +0 -1
  71. data/spec/storage/dropbox_spec.rb +44 -14
  72. data/spec/storage/ftp_spec.rb +26 -15
  73. data/spec/storage/local_spec.rb +83 -0
  74. data/spec/storage/ninefold_spec.rb +142 -0
  75. data/spec/storage/object_spec.rb +1 -1
  76. data/spec/storage/rsync_spec.rb +17 -7
  77. data/spec/storage/s3_spec.rb +4 -3
  78. data/spec/storage/scp_spec.rb +0 -1
  79. data/spec/storage/sftp_spec.rb +0 -1
  80. data/spec/syncer/rsync_spec.rb +8 -8
  81. metadata +62 -36
@@ -6,7 +6,6 @@ describe Backup::Database::Redis do
6
6
 
7
7
  before do
8
8
  Backup::Database::Redis.any_instance.stubs(:load_defaults!)
9
- Backup::Logger.stubs(:error)
10
9
  end
11
10
 
12
11
  let(:db) do
@@ -51,7 +50,7 @@ describe Backup::Database::Redis do
51
50
  end
52
51
 
53
52
  describe '#credential_options' do
54
- it 'should return the mongo syntax for the credential options' do
53
+ it 'should return the redis-cli syntax for the credential options' do
55
54
  db.credential_options.should == "-a 'secret'"
56
55
  end
57
56
  end
@@ -72,7 +71,7 @@ describe Backup::Database::Redis do
72
71
  end
73
72
 
74
73
  describe '#invoke_save!' do
75
- it 'should return the full mongodump string' do
74
+ it 'should return the full redis-cli string' do
76
75
  db.expects(:utility).with('redis-cli').returns('redis-cli')
77
76
  db.expects(:run).with("redis-cli -a 'secret' -h 'localhost' -p '123' -s '/redis.sock' --query SAVE")
78
77
  db.invoke_save!
@@ -86,11 +85,17 @@ describe Backup::Database::Redis do
86
85
  db.expects(:run).with("cp '#{ File.join('/var/lib/redis/db/mydatabase.rdb') }' '#{ File.join(Backup::TMP_PATH, Backup::TRIGGER, 'Redis', 'mydatabase.rdb') }'")
87
86
  db.copy!
88
87
  end
88
+
89
+ it 'should find the cp utility when utility_path is set' do
90
+ File.expects(:exist?).returns(true)
91
+ db.utility_path = '/usr/local/bin/redis-cli'
92
+ db.expects(:run).with { |v| v =~ %r{^/bin/cp .+} }
93
+ db.copy!
94
+ end
89
95
  end
90
96
 
91
97
  describe '#perform!' do
92
98
  before do
93
- Backup::Logger.stubs(:message)
94
99
  File.stubs(:exist?).returns(true)
95
100
  db.stubs(:utility).returns('redis-cli')
96
101
  db.stubs(:mkdir)
@@ -45,7 +45,7 @@ WNa3g2n0nokA7Zr5FA4GXoEaYivfbvGiyNpd6P4okH+//G2p+3FIryu5xz+89D1b
45
45
 
46
46
  describe '#write_tmp_file!' do
47
47
  it do
48
- tmp_file = mock('TmpFile')
48
+ tmp_file = Tempfile.new("foo")
49
49
  Tempfile.expects(:new).returns(tmp_file)
50
50
  tmp_file.expects(:write).with('secret')
51
51
  tmp_file.expects(:close)
@@ -54,7 +54,6 @@ describe Backup::Encryptor::OpenSSL do
54
54
  let(:encryptor) { Backup::Encryptor::OpenSSL.new }
55
55
  before do
56
56
  Backup::Model.extension = 'tar'
57
- Backup::Logger.stubs(:message)
58
57
  [:utility, :run, :rm].each { |method| encryptor.stubs(method) }
59
58
  end
60
59
 
@@ -5,49 +5,57 @@ require 'timecop'
5
5
 
6
6
  describe Backup::Logger do
7
7
  before do
8
- Timecop.freeze( Time.now )
8
+ Timecop.freeze(Time.now)
9
+
10
+ [:message, :error, :warn, :normal, :silent].each do |message_type|
11
+ Backup::Logger.unstub(message_type)
12
+ end
9
13
  end
10
14
 
11
- context 'when logging regular messages' do
12
- it do
13
- Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[32mmessage\e[0m] This has been logged.")
15
+ describe 'logging messages to STDOUT and a log file' do
16
+ before do
14
17
  File.expects(:open).with(File.join(Backup::LOG_PATH, 'backup.log'), 'a')
18
+ end
15
19
 
16
- Backup::Logger.message "This has been logged."
20
+ context 'when logging regular messages' do
21
+ it do
22
+ Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[32mmessage\e[0m] This has been logged.")
23
+
24
+ Backup::Logger.message "This has been logged."
25
+ end
17
26
  end
18
- end
19
27
 
20
- context 'when logging error messages' do
21
- it do
22
- Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[31merror\e[0m] This has been logged.")
23
- File.expects(:open).with(File.join(Backup::LOG_PATH, 'backup.log'), 'a')
28
+ context 'when logging error messages' do
29
+ it do
30
+ Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[31merror\e[0m] This has been logged.")
24
31
 
25
- Backup::Logger.error "This has been logged."
32
+ Backup::Logger.error "This has been logged."
33
+ end
26
34
  end
27
- end
28
35
 
29
- context 'when logging warn messages' do
30
- it do
31
- Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[33mwarning\e[0m] This has been logged.")
32
- File.expects(:open).with(File.join(Backup::LOG_PATH, 'backup.log'), 'a')
36
+ context 'when logging warn messages' do
37
+ it do
38
+ Backup::Logger.expects(:puts).with("[#{ Time.now.strftime("%Y/%m/%d %H:%M:%S") }][\e[33mwarning\e[0m] This has been logged.")
33
39
 
34
- Backup::Logger.warn "This has been logged."
40
+ Backup::Logger.warn "This has been logged."
41
+ end
35
42
  end
36
- end
37
43
 
38
- context 'when logging silent messages' do
39
- it do
40
- Backup::Logger.expects(:puts).never
41
- File.expects(:open).with(File.join(Backup::LOG_PATH, 'backup.log'), 'a')
44
+ context 'when logging silent messages' do
45
+ it do
46
+ Backup::Logger.expects(:puts).never
42
47
 
43
- Backup::Logger.silent "This has been logged."
48
+ Backup::Logger.silent "This has been logged."
49
+ end
44
50
  end
45
51
  end
46
52
 
47
- context 'when quieted' do
53
+ describe 'logging messages to log file and not STDOUT' do
48
54
  it do
49
55
  Backup::Logger.send(:const_set, :QUIET, true)
56
+
50
57
  Backup::Logger.expects(:puts).never
58
+ File.expects(:open).times(4).with(File.join(Backup::LOG_PATH, 'backup.log'), 'a')
51
59
 
52
60
  Backup::Logger.message "This has been logged."
53
61
  Backup::Logger.error "This has been logged."
@@ -5,30 +5,32 @@ require File.dirname(__FILE__) + '/spec_helper'
5
5
  describe Backup::Model do
6
6
 
7
7
  before do
8
+ # stub out the creation of an archive, for this spec's purpose
9
+ Backup::Archive.stubs(:new).returns(true)
10
+
11
+ # create mockup classes for testing the behavior of Backup::Model
8
12
  class Backup::Database::TestDatabase
9
13
  def initialize(&block); end
10
14
  end
11
15
  class Backup::Storage::TestStorage
12
16
  def initialize(&block); end
13
17
  end
14
- class Backup::Archive
15
- def initialize(name, &block); end
16
- end
17
- class Backup::Compressor::Gzip
18
+ class Backup::Compressor::TestGzip
18
19
  def initialize(&block); end
19
20
  end
20
- class Backup::Compressor::SevenZip
21
+ class Backup::Compressor::TestSevenZip
21
22
  def initialize(&block); end
22
23
  end
23
- class Backup::Encryptor::OpenSSL
24
+ class Backup::Encryptor::TestOpenSSL
24
25
  def initialize(&block); end
25
26
  end
26
- class Backup::Encryptor::GPG
27
+ class Backup::Encryptor::TestGPG
27
28
  def initialize(&block); end
28
29
  end
29
30
  class Backup::Notifier::TestMail
30
31
  def initialize(&block); end
31
32
  end
33
+
32
34
  end
33
35
 
34
36
  let(:model) { Backup::Model.new('mysql-s3', 'MySQL S3 Backup for MyApp') {} }
@@ -143,7 +145,7 @@ describe Backup::Model do
143
145
  describe '#compress_with' do
144
146
  it 'should add a compressor to the array of compressors to use' do
145
147
  model = Backup::Model.new('mysql-s3', 'MySQL S3 Backup for MyApp') do
146
- compress_with('Gzip')
148
+ compress_with('TestGzip')
147
149
  end
148
150
 
149
151
  model.compressors.count.should == 1
@@ -151,8 +153,8 @@ describe Backup::Model do
151
153
 
152
154
  it 'should add a compressor to the array of compressors to use' do
153
155
  model = Backup::Model.new('mysql-s3', 'MySQL S3 Backup for MyApp') do
154
- compress_with('Gzip')
155
- compress_with('SevenZip')
156
+ compress_with('TestGzip')
157
+ compress_with('TestSevenZip')
156
158
  end
157
159
 
158
160
  model.compressors.count.should == 2
@@ -162,7 +164,7 @@ describe Backup::Model do
162
164
  describe '#encrypt_with' do
163
165
  it 'should add a encryptor to the array of encryptors to use' do
164
166
  model = Backup::Model.new('mysql-s3', 'MySQL S3 Backup for MyApp') do
165
- encrypt_with('OpenSSL')
167
+ encrypt_with('TestOpenSSL')
166
168
  end
167
169
 
168
170
  model.encryptors.count.should == 1
@@ -170,8 +172,8 @@ describe Backup::Model do
170
172
 
171
173
  it 'should add a encryptor to the array of encryptors to use' do
172
174
  model = Backup::Model.new('mysql-s3', 'MySQL S3 Backup for MyApp') do
173
- encrypt_with('OpenSSL')
174
- encrypt_with('GPG')
175
+ encrypt_with('TestOpenSSL')
176
+ encrypt_with('TestGPG')
175
177
  end
176
178
 
177
179
  model.encryptors.count.should == 2
@@ -200,7 +202,6 @@ describe Backup::Model do
200
202
  describe '#package!' do
201
203
  before do
202
204
  [:utility, :run].each { |method| model.stubs(method) }
203
- Backup::Logger.stubs(:message)
204
205
  end
205
206
 
206
207
  it 'should package the folder' do
@@ -218,7 +219,6 @@ describe Backup::Model do
218
219
  describe '#clean!' do
219
220
  before do
220
221
  [:utility, :run, :rm].each { |method| model.stubs(method) }
221
- Backup::Logger.stubs(:message)
222
222
  end
223
223
 
224
224
  it 'should remove the temporary files and folders that were created' do
@@ -8,10 +8,14 @@ require File.expand_path( '../../lib/backup', __FILE__ )
8
8
  # Use Mocha to mock with RSpec
9
9
  RSpec.configure do |config|
10
10
  config.mock_with :mocha
11
+ config.before(:each) do
12
+ FileUtils.stubs(:mkdir_p)
13
+ [:message, :error, :warn, :normal, :silent].each do |message_type|
14
+ Backup::Logger.stubs(message_type)
15
+ end
16
+ end
11
17
  end
12
18
 
13
- # FIXTURES_PATH = File.join( File.dirname(__FILE__), 'fixtures' )
14
-
15
19
  Backup.send(:remove_const, :TRIGGER) if defined? Backup::TRIGGER
16
20
  Backup.send(:remove_const, :TIME) if defined? Backup::TIME
17
21
 
@@ -20,6 +24,6 @@ module Backup
20
24
  TIME = Time.now.strftime("%Y.%m.%d.%H.%M.%S")
21
25
  end
22
26
 
23
- unless @put_ruby_version
24
- puts @put_ruby_version = "\n\nRuby version: #{ENV['rvm_ruby_string']}\n\n"
27
+ unless @_put_ruby_version
28
+ puts @_put_ruby_version = "\n\nRuby version: #{ENV['rvm_ruby_string']}\n\n"
25
29
  end
@@ -5,10 +5,6 @@ require File.dirname(__FILE__) + '/../spec_helper'
5
5
  describe Backup::Storage::Base do
6
6
  let(:base) { Backup::Storage::Base.new }
7
7
 
8
- before do
9
- Backup::Logger.stubs(:message)
10
- end
11
-
12
8
  it do
13
9
  storage_object = mock
14
10
  Backup::Storage::Object.expects(:new).with('Base').returns(storage_object)
@@ -65,7 +65,6 @@ describe Backup::Storage::CloudFiles do
65
65
  let(:connection) { mock('Fog::Storage') }
66
66
  before do
67
67
  Fog::Storage.stubs(:new).returns(connection)
68
- Backup::Logger.stubs(:message)
69
68
  end
70
69
 
71
70
  it 'should transfer the provided file to the container' do
@@ -6,8 +6,6 @@ describe Backup::Storage::Dropbox do
6
6
 
7
7
  let(:db) do
8
8
  Backup::Storage::Dropbox.new do |db|
9
- db.email = 'my@email.com'
10
- db.password = 'my_password'
11
9
  db.api_key = 'my_api_key'
12
10
  db.api_secret = 'my_secret'
13
11
  db.keep = 20
@@ -22,11 +20,10 @@ describe Backup::Storage::Dropbox do
22
20
 
23
21
  before do
24
22
  Backup::Configuration::Storage::Dropbox.clear_defaults!
23
+ STDIN.stubs(:gets)
25
24
  end
26
25
 
27
26
  it 'should have defined the configuration properly' do
28
- db.email.should == 'my@email.com'
29
- db.password.should == 'my_password'
30
27
  db.api_key.should == 'my_api_key'
31
28
  db.api_secret.should == 'my_secret'
32
29
  db.path.should == 'backups'
@@ -57,21 +54,54 @@ describe Backup::Storage::Dropbox do
57
54
  end
58
55
 
59
56
  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)
57
+ context "when the session cache has not yet been written" do
58
+ before do
59
+ db.stubs(:gets)
60
+ end
61
+
62
+ it do
63
+ session = mock("Dropbox::Session")
64
+ Dropbox::Session.expects(:new).with('my_api_key', 'my_secret').returns(session)
65
+ session.expects(:mode=).with(:dropbox)
66
+ session.expects(:authorize)
67
+ session.expects(:authorize_url)
68
+ db.expects(:cache_exists?).returns(false)
69
+ db.expects(:write_cache!).with(session)
70
+ db.send(:connection)
71
+ end
72
+ end
73
+
74
+ context "when the session cache has already been written" do
75
+ before do
76
+ db.stubs(:gets)
77
+ end
78
+
79
+ it "should load the session from cache, instead of creating a new one" do
80
+ db.expects(:cache_exists?).returns(true)
81
+ File.expects(:read).with("#{ENV['HOME']}/Backup/.cache/my_api_keymy_secret").returns("foo")
82
+ session = mock("Dropbox::Session")
83
+ session.expects(:authorized?).returns(true)
84
+ Dropbox::Session.expects(:deserialize).with("foo").returns(session)
85
+
86
+ db.expects(:create_write_and_return_new_session!).never
87
+ db.send(:connection)
88
+ end
89
+
90
+ it "should load it from cache, but if it's invalid/corrupt, the create a session anyway" do
91
+ db.expects(:cache_exists?).returns(true)
92
+ File.expects(:read).with("#{ENV['HOME']}/Backup/.cache/my_api_keymy_secret").returns("foo")
93
+ session = mock("Dropbox::Session")
94
+ session.expects(:authorized?).returns(false)
95
+ Dropbox::Session.expects(:deserialize).with("foo").returns(session)
96
+
97
+ db.expects(:create_write_and_return_new_session!)
98
+ db.send(:connection)
99
+ end
69
100
  end
70
101
  end
71
102
 
72
103
  describe '#transfer!' do
73
104
  before do
74
- Backup::Logger.stubs(:message)
75
105
  connection.stubs(:upload)
76
106
  connection.stubs(:delete)
77
107
  end
@@ -6,12 +6,13 @@ describe Backup::Storage::FTP do
6
6
 
7
7
  let(:ftp) do
8
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
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
+ ftp.passive_mode = false
15
16
  end
16
17
  end
17
18
 
@@ -20,12 +21,13 @@ describe Backup::Storage::FTP do
20
21
  end
21
22
 
22
23
  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
24
+ ftp.username.should == 'my_username'
25
+ ftp.password.should == 'my_password'
26
+ ftp.ip.should == '123.45.678.90'
27
+ ftp.port.should == 21
28
+ ftp.path.should == 'backups/'
29
+ ftp.keep.should == 20
30
+ ftp.passive_mode.should == false
29
31
  end
30
32
 
31
33
  it 'should use the defaults if a particular attribute has not been defined' do
@@ -48,11 +50,14 @@ describe Backup::Storage::FTP do
48
50
 
49
51
  it 'should have its own defaults' do
50
52
  ftp = Backup::Storage::FTP.new
51
- ftp.port.should == 21
52
- ftp.path.should == 'backups'
53
+ ftp.port.should == 21
54
+ ftp.path.should == 'backups'
55
+ ftp.passive_mode.should == false
53
56
  end
54
57
 
55
58
  describe '#connection' do
59
+ let(:connection) { mock('Fog::Storage') }
60
+
56
61
  it 'should establish a connection to the remote server using the provided ip address and credentials' do
57
62
  Net::FTP.expects(:new).with('123.45.678.90', 'my_username', 'my_password')
58
63
  ftp.send(:connection)
@@ -64,6 +69,13 @@ describe Backup::Storage::FTP do
64
69
  ftp.send(:connection)
65
70
  Net::FTP::FTP_PORT.should == 40
66
71
  end
72
+
73
+ it 'configures net/ftp to use passive mode if passive_mode set to true' do
74
+ ftp.passive_mode = true
75
+ Net::FTP.stubs(:new).returns(connection)
76
+ connection.expects(:passive=).with(true)
77
+ ftp.send(:connection)
78
+ end
67
79
  end
68
80
 
69
81
  describe '#transfer!' do
@@ -72,7 +84,6 @@ describe Backup::Storage::FTP do
72
84
  before do
73
85
  Net::FTP.stubs(:new).returns(connection)
74
86
  ftp.stubs(:create_remote_directories!)
75
- Backup::Logger.stubs(:message)
76
87
  end
77
88
 
78
89
  it 'should transfer the provided file to the path' do