webtranslateit-safe 0.4.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.
- checksums.yaml +7 -0
- data/.autotest +3 -0
- data/.document +5 -0
- data/.github/dependabot.yml +26 -0
- data/.github/release-drafter.yml +36 -0
- data/.github/workflows/ci.yml +51 -0
- data/.github/workflows/release-drafter.yml +29 -0
- data/.gitignore +18 -0
- data/.rspec +3 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +552 -0
- data/CHANGELOG +42 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +89 -0
- data/LICENSE.txt +22 -0
- data/README.markdown +237 -0
- data/Rakefile +8 -0
- data/TODO +31 -0
- data/bin/webtranslateit-safe +64 -0
- data/lib/extensions/mktmpdir.rb +45 -0
- data/lib/webtranslateit/safe/archive.rb +29 -0
- data/lib/webtranslateit/safe/backup.rb +27 -0
- data/lib/webtranslateit/safe/cloudfiles.rb +77 -0
- data/lib/webtranslateit/safe/config/builder.rb +100 -0
- data/lib/webtranslateit/safe/config/node.rb +79 -0
- data/lib/webtranslateit/safe/ftp.rb +85 -0
- data/lib/webtranslateit/safe/gpg.rb +52 -0
- data/lib/webtranslateit/safe/gzip.rb +29 -0
- data/lib/webtranslateit/safe/local.rb +55 -0
- data/lib/webtranslateit/safe/mongodump.rb +30 -0
- data/lib/webtranslateit/safe/mysqldump.rb +36 -0
- data/lib/webtranslateit/safe/pgdump.rb +36 -0
- data/lib/webtranslateit/safe/pipe.rb +23 -0
- data/lib/webtranslateit/safe/s3.rb +80 -0
- data/lib/webtranslateit/safe/sftp.rb +96 -0
- data/lib/webtranslateit/safe/sink.rb +40 -0
- data/lib/webtranslateit/safe/source.rb +51 -0
- data/lib/webtranslateit/safe/stream.rb +40 -0
- data/lib/webtranslateit/safe/svndump.rb +17 -0
- data/lib/webtranslateit/safe/tmp_file.rb +53 -0
- data/lib/webtranslateit/safe/version.rb +9 -0
- data/lib/webtranslateit/safe.rb +70 -0
- data/spec/integration/archive_integration_spec.rb +89 -0
- data/spec/integration/cleanup_spec.rb +62 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/webtranslateit/safe/archive_spec.rb +67 -0
- data/spec/webtranslateit/safe/cloudfiles_spec.rb +175 -0
- data/spec/webtranslateit/safe/config_spec.rb +307 -0
- data/spec/webtranslateit/safe/gpg_spec.rb +148 -0
- data/spec/webtranslateit/safe/gzip_spec.rb +64 -0
- data/spec/webtranslateit/safe/local_spec.rb +109 -0
- data/spec/webtranslateit/safe/mongodump_spec.rb +54 -0
- data/spec/webtranslateit/safe/mysqldump_spec.rb +83 -0
- data/spec/webtranslateit/safe/pgdump_spec.rb +45 -0
- data/spec/webtranslateit/safe/s3_spec.rb +168 -0
- data/spec/webtranslateit/safe/svndump_spec.rb +39 -0
- data/templates/script.rb +183 -0
- data/webtranslateit-safe.gemspec +32 -0
- metadata +149 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module WebTranslateIt
|
2
|
+
|
3
|
+
module Safe
|
4
|
+
|
5
|
+
class Stream
|
6
|
+
|
7
|
+
attr_accessor :config, :backup
|
8
|
+
|
9
|
+
def initialize(config, backup)
|
10
|
+
@config = config
|
11
|
+
@backup = backup
|
12
|
+
end
|
13
|
+
|
14
|
+
# FIXME: move to Backup
|
15
|
+
def expand(path)
|
16
|
+
path
|
17
|
+
.gsub(/:kind\b/, @backup.kind.to_s)
|
18
|
+
.gsub(/:id\b/, @backup.id.to_s)
|
19
|
+
.gsub(/:timestamp\b/, @backup.timestamp)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def verbose?
|
25
|
+
config[:verbose]
|
26
|
+
end
|
27
|
+
|
28
|
+
def local_only?
|
29
|
+
config[:local_only]
|
30
|
+
end
|
31
|
+
|
32
|
+
def dry_run?
|
33
|
+
config[:dry_run]
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
module WebTranslateIt
|
3
|
+
|
4
|
+
module Safe
|
5
|
+
|
6
|
+
module TmpFile
|
7
|
+
|
8
|
+
@keep_files = []
|
9
|
+
|
10
|
+
def self.tmproot
|
11
|
+
@tmproot ||= Dir.mktmpdir
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.cleanup
|
15
|
+
begin
|
16
|
+
FileUtils.remove_entry_secure tmproot
|
17
|
+
rescue ArgumentError => e
|
18
|
+
raise unless e.message =~ /parent directory is world writable/
|
19
|
+
|
20
|
+
puts <<~ERR
|
21
|
+
|
22
|
+
|
23
|
+
********************************************************************************
|
24
|
+
It looks like you have wrong permissions on your TEMP directory. The usual
|
25
|
+
case is when you have world writable TEMP directory withOUT the sticky bit.
|
26
|
+
|
27
|
+
Try "chmod +t" on it.
|
28
|
+
|
29
|
+
********************************************************************************
|
30
|
+
|
31
|
+
ERR
|
32
|
+
raise
|
33
|
+
end
|
34
|
+
@tmproot = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.create(name)
|
38
|
+
# create temp directory
|
39
|
+
|
40
|
+
file = Tempfile.new(name, tmproot)
|
41
|
+
|
42
|
+
yield file
|
43
|
+
|
44
|
+
file.close
|
45
|
+
@keep_files << file # so that it will not get gcollected and removed from filesystem until the end
|
46
|
+
file.path
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'webtranslateit/safe/version'
|
2
|
+
|
3
|
+
require 'aws/s3'
|
4
|
+
require 'cloudfiles'
|
5
|
+
require 'net/sftp'
|
6
|
+
# require 'net/ftp'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'benchmark'
|
9
|
+
|
10
|
+
require 'tempfile'
|
11
|
+
require 'extensions/mktmpdir'
|
12
|
+
|
13
|
+
require 'webtranslateit/safe/tmp_file'
|
14
|
+
|
15
|
+
require 'webtranslateit/safe/config/node'
|
16
|
+
require 'webtranslateit/safe/config/builder'
|
17
|
+
|
18
|
+
require 'webtranslateit/safe/stream'
|
19
|
+
|
20
|
+
require 'webtranslateit/safe/backup'
|
21
|
+
|
22
|
+
require 'webtranslateit/safe/source'
|
23
|
+
require 'webtranslateit/safe/mysqldump'
|
24
|
+
require 'webtranslateit/safe/pgdump'
|
25
|
+
require 'webtranslateit/safe/archive'
|
26
|
+
require 'webtranslateit/safe/svndump'
|
27
|
+
require 'webtranslateit/safe/mongodump'
|
28
|
+
|
29
|
+
require 'webtranslateit/safe/pipe'
|
30
|
+
require 'webtranslateit/safe/gpg'
|
31
|
+
require 'webtranslateit/safe/gzip'
|
32
|
+
|
33
|
+
require 'webtranslateit/safe/sink'
|
34
|
+
require 'webtranslateit/safe/local'
|
35
|
+
require 'webtranslateit/safe/s3'
|
36
|
+
require 'webtranslateit/safe/cloudfiles'
|
37
|
+
require 'webtranslateit/safe/sftp'
|
38
|
+
require 'webtranslateit/safe/ftp'
|
39
|
+
|
40
|
+
module WebTranslateIt
|
41
|
+
|
42
|
+
module Safe
|
43
|
+
|
44
|
+
ROOT = File.join(File.dirname(__FILE__), '..', '..')
|
45
|
+
|
46
|
+
def safe(&)
|
47
|
+
Config::Node.new(&)
|
48
|
+
end
|
49
|
+
|
50
|
+
def process(config)
|
51
|
+
[[Mysqldump, [:mysqldump, :databases]],
|
52
|
+
[Pgdump, [:pgdump, :databases]],
|
53
|
+
[Mongodump, [:mongodump, :databases]],
|
54
|
+
[Archive, [:tar, :archives]],
|
55
|
+
[Svndump, [:svndump, :repos]]].each do |klass, path|
|
56
|
+
next unless (collection = config[*path])
|
57
|
+
|
58
|
+
collection.each do |name, c|
|
59
|
+
klass.new(name, c).backup.run(c, :gpg, :gzip, :local, :s3, :cloudfiles, :sftp, :ftp)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
WebTranslateIt::Safe::TmpFile.cleanup
|
64
|
+
end
|
65
|
+
module_function :safe
|
66
|
+
module_function :process
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils
|
5
|
+
|
6
|
+
describe 'tar backup' do
|
7
|
+
before(:all) do
|
8
|
+
# need both local and instance vars
|
9
|
+
# instance variables are used in tests
|
10
|
+
# local variables are used in the backup definition (instance vars can't be seen)
|
11
|
+
@root = root = 'tmp/archive_backup_example'
|
12
|
+
|
13
|
+
# clean state
|
14
|
+
rm_rf @root
|
15
|
+
mkdir_p @root
|
16
|
+
|
17
|
+
# create source tree
|
18
|
+
@src = src = "#{@root}/src"
|
19
|
+
mkdir_p "#{@src}/q/w/e"
|
20
|
+
mkdir_p "#{@src}/a/s/d"
|
21
|
+
|
22
|
+
File.open("#{@src}/qwe1", 'w') {|f| f.write('qwe') }
|
23
|
+
File.open("#{@src}/q/qwe2", 'w') {|f| f.write('qwe'*2) }
|
24
|
+
File.open("#{@src}/q/w/qwe3", 'w') {|f| f.write('qwe'*3) }
|
25
|
+
File.open("#{@src}/q/w/e/qwe4", 'w') {|f| f.write('qwe'*4) }
|
26
|
+
|
27
|
+
File.open("#{@src}/asd1", 'w') {|f| f.write('asd') }
|
28
|
+
File.open("#{@src}/a/asd2", 'w') {|f| f.write('asd' * 2) }
|
29
|
+
File.open("#{@src}/a/s/asd3", 'w') {|f| f.write('asd' * 3) }
|
30
|
+
|
31
|
+
@dst = dst = "#{@root}/backup"
|
32
|
+
mkdir_p @dst
|
33
|
+
|
34
|
+
@now = Time.now
|
35
|
+
@timestamp = @now.strftime('%y%m%d-%H%M')
|
36
|
+
|
37
|
+
stub(Time).now {@now} # Freeze
|
38
|
+
|
39
|
+
config = WebTranslateIt::Safe.safe do
|
40
|
+
local :path => "#{dst}/:kind"
|
41
|
+
tar do
|
42
|
+
archive :test1 do
|
43
|
+
files src
|
44
|
+
exclude "#{src}/q/w"
|
45
|
+
exclude "#{src}/q/w/e"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
WebTranslateIt::Safe.process config
|
50
|
+
|
51
|
+
@backup = "#{dst}/archive/archive-test1.#{@timestamp}.tar.gz"
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should create backup file' do
|
55
|
+
File.exist?(@backup).should be true
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'after extracting' do
|
59
|
+
before(:all) do
|
60
|
+
# prepare target dir
|
61
|
+
@target = "#{@root}/test"
|
62
|
+
mkdir_p @target
|
63
|
+
system "tar -zxvf #{@backup} -C #{@target}"
|
64
|
+
|
65
|
+
@test = "#{@target}/#{@root}/src"
|
66
|
+
puts @test
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should include asd1/2/3' do
|
70
|
+
File.exist?("#{@test}/asd1").should be true
|
71
|
+
File.exist?("#{@test}/a/asd2").should be true
|
72
|
+
File.exist?("#{@test}/a/s/asd3").should be true
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should only include qwe 1 and 2 (no 3)' do
|
76
|
+
File.exist?("#{@test}/qwe1").should be true
|
77
|
+
File.exist?("#{@test}/q/qwe2").should be true
|
78
|
+
File.exist?("#{@test}/q/w/qwe3").should be false
|
79
|
+
File.exist?("#{@test}/q/w/e/qwe4").should be false
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should preserve file content' do
|
83
|
+
File.read("#{@test}/qwe1").should == 'qwe'
|
84
|
+
File.read("#{@test}/q/qwe2").should == 'qweqwe'
|
85
|
+
File.read("#{@test}/a/s/asd3").should == 'asdasdasd'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
include FileUtils
|
5
|
+
|
6
|
+
describe 'tar backup' do
|
7
|
+
before(:all) do
|
8
|
+
# need both local and instance vars
|
9
|
+
# instance variables are used in tests
|
10
|
+
# local variables are used in the backup definition (instance vars can't be seen)
|
11
|
+
@root = root = 'tmp/cleanup_example'
|
12
|
+
|
13
|
+
# clean state
|
14
|
+
rm_rf @root
|
15
|
+
mkdir_p @root
|
16
|
+
|
17
|
+
# create source tree
|
18
|
+
@src = src = "#{@root}/src"
|
19
|
+
mkdir_p src
|
20
|
+
|
21
|
+
File.open(qwe = "#{@src}/qwe", 'w') {|f| f.write('qwe') }
|
22
|
+
|
23
|
+
@dst = dst = "#{@root}/backup"
|
24
|
+
mkdir_p "#{@dst}/archive"
|
25
|
+
|
26
|
+
@now = Time.now
|
27
|
+
@timestamp = @now.strftime('%y%m%d-%H%M')
|
28
|
+
|
29
|
+
stub(Time).now {@now} # Freeze
|
30
|
+
|
31
|
+
cp qwe, "#{dst}/archive/archive-foo.000001.tar.gz"
|
32
|
+
cp qwe, "#{dst}/archive/archive-foo.000002.tar.gz"
|
33
|
+
cp qwe, "#{dst}/archive/archive-foobar.000001.tar.gz"
|
34
|
+
cp qwe, "#{dst}/archive/archive-foobar.000002.tar.gz"
|
35
|
+
|
36
|
+
config = WebTranslateIt::Safe.safe do
|
37
|
+
local :path => "#{dst}/:kind"
|
38
|
+
tar do
|
39
|
+
keep :local => 1 # only leave the latest
|
40
|
+
archive :foo do
|
41
|
+
files src
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
WebTranslateIt::Safe.process config
|
46
|
+
|
47
|
+
@backup = "#{dst}/archive/archive-foo.#{@timestamp}.tar.gz"
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should create backup file' do
|
51
|
+
File.exist?(@backup).should be true
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should remove old backups' do
|
55
|
+
Dir["#{@dst}/archive/archive-foo.*"].should == [@backup]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should NOT remove backups with base having same prefix' do
|
59
|
+
Dir["#{@dst}/archive/archive-foobar.*"].sort.should == ["#{@dst}/archive/archive-foobar.000001.tar.gz", "#{@dst}/archive/archive-foobar.000002.tar.gz"]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WebTranslateIt::Safe::Archive do
|
4
|
+
|
5
|
+
def def_config
|
6
|
+
{
|
7
|
+
options: 'OPTS',
|
8
|
+
files: 'apples',
|
9
|
+
exclude: 'oranges'
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def archive(id = :foo, config = def_config)
|
14
|
+
WebTranslateIt::Safe::Archive.new(id, WebTranslateIt::Safe::Config::Node.new(nil, config))
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:each) { WebTranslateIt::Safe::TmpFile.cleanup }
|
18
|
+
|
19
|
+
describe :backup do
|
20
|
+
before(:each) do
|
21
|
+
@archive = archive
|
22
|
+
stub(@archive).timestamp { 'NOW' }
|
23
|
+
end
|
24
|
+
|
25
|
+
{
|
26
|
+
id: 'foo',
|
27
|
+
kind: 'archive',
|
28
|
+
extension: '.tar',
|
29
|
+
filename: 'archive-foo.NOW',
|
30
|
+
command: 'tar -cf - OPTS --exclude=oranges apples'
|
31
|
+
}.each do |k, v|
|
32
|
+
it "sets #{k} to #{v}" do
|
33
|
+
@archive.backup.send(k).should == v
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe :tar_exclude_files do
|
39
|
+
it "returns '' when no excludes" do
|
40
|
+
archive(:foo, {}).send(:tar_exclude_files).should == ''
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'accepts single exclude as string' do
|
44
|
+
archive(:foo, {exclude: 'bar'}).send(:tar_exclude_files).should == '--exclude=bar'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'accepts multiple exclude as array' do
|
48
|
+
archive(:foo, {exclude: ['foo', 'bar']}).send(:tar_exclude_files).should == '--exclude=foo --exclude=bar'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe :tar_files do
|
53
|
+
it 'raises RuntimeError when no files' do
|
54
|
+
lambda {
|
55
|
+
archive(:foo, {}).send(:tar_files)
|
56
|
+
}.should raise_error(RuntimeError, 'missing files for tar')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'accepts single file as string' do
|
60
|
+
archive(:foo, {files: 'foo'}).send(:tar_files).should == 'foo'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'accepts multiple files as array' do
|
64
|
+
archive(:foo, {files: ['foo', 'bar']}).send(:tar_files).should == 'foo bar'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WebTranslateIt::Safe::Cloudfiles do
|
4
|
+
|
5
|
+
def def_config
|
6
|
+
{
|
7
|
+
cloudfiles: {
|
8
|
+
container: '_container',
|
9
|
+
user: '_user',
|
10
|
+
api_key: '_api_key',
|
11
|
+
},
|
12
|
+
keep: { cloudfiles: 2 }
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def def_backup(extra = {})
|
17
|
+
{
|
18
|
+
kind: '_kind',
|
19
|
+
filename: '/backup/somewhere/_kind-_id.NOW.bar',
|
20
|
+
extension: '.bar',
|
21
|
+
id: '_id',
|
22
|
+
timestamp: 'NOW'
|
23
|
+
}.merge(extra)
|
24
|
+
end
|
25
|
+
|
26
|
+
def cloudfiles(config = def_config, backup = def_backup)
|
27
|
+
WebTranslateIt::Safe::Cloudfiles.new(
|
28
|
+
WebTranslateIt::Safe::Config::Node.new.merge(config),
|
29
|
+
WebTranslateIt::Safe::Backup.new(backup)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe :cleanup do
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
@cloudfiles = cloudfiles
|
37
|
+
|
38
|
+
@files = [4,1,3,2].map { |i| "aaaaa#{i}" }
|
39
|
+
|
40
|
+
@container = 'container'
|
41
|
+
|
42
|
+
stub(@container).objects(prefix: '_kind/_id/_kind-_id.') { @files }
|
43
|
+
stub(@container).delete_object(anything)
|
44
|
+
|
45
|
+
stub(CloudFiles::Connection).
|
46
|
+
new('_user', '_api_key', true, false).stub!.
|
47
|
+
container('_container') {@container}
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should check [:keep, :cloudfiles]' do
|
51
|
+
@cloudfiles.config[:keep].data['cloudfiles'] = nil
|
52
|
+
dont_allow(@cloudfiles.backup).filename
|
53
|
+
@cloudfiles.send :cleanup
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should delete extra files' do
|
57
|
+
mock(@container).delete_object('aaaaa1')
|
58
|
+
mock(@container).delete_object('aaaaa2')
|
59
|
+
@cloudfiles.send :cleanup
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
describe :active do
|
65
|
+
before(:each) do
|
66
|
+
@cloudfiles = cloudfiles
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be true when all params are set' do
|
70
|
+
expect(@cloudfiles.active?).to be_truthy
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should be false if container is missing' do
|
74
|
+
@cloudfiles.config[:cloudfiles].data['container'] = nil
|
75
|
+
expect(@cloudfiles.active?).to be_falsy
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should be false if user is missing' do
|
79
|
+
@cloudfiles.config[:cloudfiles].data['user'] = nil
|
80
|
+
expect(@cloudfiles.active?).to be_falsy
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should be false if api_key is missing' do
|
84
|
+
@cloudfiles.config[:cloudfiles].data['api_key'] = nil
|
85
|
+
expect(@cloudfiles.active?).to be_falsy
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe :path do
|
90
|
+
before(:each) do
|
91
|
+
@cloudfiles = cloudfiles
|
92
|
+
end
|
93
|
+
it 'should use cloudfiles/path 1st' do
|
94
|
+
@cloudfiles.config[:cloudfiles].data['path'] = 'cloudfiles_path'
|
95
|
+
@cloudfiles.config[:local] = {path: 'local_path'}
|
96
|
+
@cloudfiles.send(:path).should == 'cloudfiles_path'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should use local/path 2nd' do
|
100
|
+
@cloudfiles.config.merge local: {path: 'local_path'}
|
101
|
+
@cloudfiles.send(:path).should == 'local_path'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should use constant 3rd' do
|
105
|
+
@cloudfiles.send(:path).should == '_kind/_id'
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe :save do
|
111
|
+
def add_stubs(*stubs)
|
112
|
+
stubs.each do |s|
|
113
|
+
case s
|
114
|
+
when :connection
|
115
|
+
@connection = 'connection'
|
116
|
+
stub(CloudFiles::Authentication).new
|
117
|
+
stub(CloudFiles::Connection).
|
118
|
+
new('_user', '_api_key', true, false) {@connection}
|
119
|
+
when :file_size
|
120
|
+
stub(@cloudfiles).get_file_size('foo') {123}
|
121
|
+
when :create_container
|
122
|
+
@container = 'container'
|
123
|
+
stub(@container).create_object('_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar', true) {@object}
|
124
|
+
stub(@connection).create_container {@container}
|
125
|
+
when :file_open
|
126
|
+
stub(File).open('foo')
|
127
|
+
when :cloudfiles_store
|
128
|
+
@object = 'object'
|
129
|
+
stub(@object).write(nil) {true}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
before(:each) do
|
135
|
+
@cloudfiles = cloudfiles(def_config, def_backup(path: 'foo'))
|
136
|
+
@full_path = '_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar'
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should fail if no backup.file is set' do
|
140
|
+
@cloudfiles.backup.path = nil
|
141
|
+
proc {@cloudfiles.send(:save)}.should raise_error(RuntimeError)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should establish Cloud Files connection' do
|
145
|
+
add_stubs(:connection, :file_size, :create_container, :file_open, :cloudfiles_store)
|
146
|
+
@cloudfiles.send(:save)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should open local file' do
|
150
|
+
add_stubs(:connection, :file_size, :create_container, :cloudfiles_store)
|
151
|
+
mock(File).open('foo')
|
152
|
+
@cloudfiles.send(:save)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should call write on the cloudfile object with files' descriptor" do
|
156
|
+
add_stubs(:connection, :file_size, :create_container, :cloudfiles_store)
|
157
|
+
stub(File).open('foo') {'qqq'}
|
158
|
+
mock(@object).write('qqq') {true}
|
159
|
+
@cloudfiles.send(:save)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should upload file' do
|
163
|
+
add_stubs(:connection, :file_size, :create_container, :file_open, :cloudfiles_store)
|
164
|
+
@cloudfiles.send(:save)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should fail on files bigger then 5G' do
|
168
|
+
add_stubs(:connection)
|
169
|
+
mock(File).stat('foo').stub!.size {5*1024*1024*1024+1}
|
170
|
+
mock(STDERR).puts(anything)
|
171
|
+
dont_allow(Benchmark).realtime
|
172
|
+
@cloudfiles.send(:save)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|