require 'spec_helper' describe Astrails::Safe::S3 do def def_config { :s3 => { :bucket => "_bucket", :key => "_key", :secret => "_secret", }, :keep => { :s3 => 2 } } end def def_backup(extra = {}) { :kind => "_kind", :filename => "/backup/somewhere/_kind-_id.NOW.bar", :extension => ".bar", :id => "_id", :timestamp => "NOW" }.merge(extra) end def s3(config = def_config, backup = def_backup) Astrails::Safe::S3.new( Astrails::Safe::Config::Node.new.merge(config), Astrails::Safe::Backup.new(backup) ) end describe :cleanup do before(:each) do @s3 = s3 @files = [4,1,3,2].map { |i| stub(o = {}).key {"aaaaa#{i}"}; o } stub(AWS::S3::Bucket).objects("_bucket", :prefix => "_kind/_id/_kind-_id.", :max_keys => 4) {@files} stub(AWS::S3::Bucket).objects("_bucket", :prefix => anything).stub![0].stub!.delete end it "should check [:keep, :s3]" do @s3.config[:keep].data["s3"] = nil dont_allow(@s3.backup).filename @s3.send :cleanup end it "should delete extra files" do mock(AWS::S3::Bucket).objects("_bucket", :prefix => "aaaaa1").mock![0].mock!.delete mock(AWS::S3::Bucket).objects("_bucket", :prefix => "aaaaa2").mock![0].mock!.delete @s3.send :cleanup end end describe :active do before(:each) do @s3 = s3 end it "should be true when all params are set" do @s3.should be_active end it "should be false if bucket is missing" do @s3.config[:s3].data["bucket"] = nil @s3.should_not be_active end it "should be false if key is missing" do @s3.config[:s3].data["key"] = nil @s3.should_not be_active end it "should be false if secret is missing" do @s3.config[:s3].data["secret"] = nil @s3.should_not be_active end end describe :path do before(:each) do @s3 = s3 end it "should use s3/path 1st" do @s3.config[:s3].data["path"] = "s3_path" @s3.config[:local] = {:path => "local_path"} @s3.send(:path).should == "s3_path" end it "should use local/path 2nd" do @s3.config.merge local: {path: "local_path"} @s3.send(:path).should == "local_path" end it "should use constant 3rd" do @s3.send(:path).should == "_kind/_id" end end describe :save do def add_stubs(*stubs) stubs.each do |s| case s when :connection stub(AWS::S3::Base).establish_connection!(:access_key_id => "_key", :secret_access_key => "_secret", :use_ssl => true) when :stat stub(File).stat("foo").stub!.size {123} when :create_bucket stub(AWS::S3::Bucket).find('_bucket') { raise_error AWS::S3::NoSuchBucket } stub(AWS::S3::Bucket).create when :file_open stub(File).open("foo") {|f, block| block.call(:opened_file)} when :s3_store stub(AWS::S3::S3Object).store(@full_path, :opened_file, "_bucket") end end end before(:each) do @s3 = s3(def_config, def_backup(:path => "foo")) @full_path = "_kind/_id/backup/somewhere/_kind-_id.NOW.bar.bar" end it "should fail if no backup.file is set" do @s3.backup.path = nil proc {@s3.send(:save)}.should raise_error(RuntimeError) end it "should establish s3 connection" do mock(AWS::S3::Base).establish_connection!(:access_key_id => "_key", :secret_access_key => "_secret", :use_ssl => true) add_stubs(:stat, :create_bucket, :file_open, :s3_store) @s3.send(:save) end it "should open local file" do add_stubs(:connection, :stat, :create_bucket) mock(File).open("foo") @s3.send(:save) end it "should upload file" do add_stubs(:connection, :stat, :create_bucket, :file_open) mock(AWS::S3::S3Object).store(@full_path, :opened_file, "_bucket") @s3.send(:save) end it "should fail on files bigger then 5G" do add_stubs(:connection) mock(File).stat("foo").stub!.size {5*1024*1024*1024+1} mock(STDERR).puts(anything) dont_allow(Benchmark).realtime @s3.send(:save) end it 'should not create a bucket that already exists' do add_stubs(:connection, :stat, :file_open, :s3_store) stub(AWS::S3::Bucket).find('_bucket') { true } dont_allow(AWS::S3::Bucket).create @s3.send(:save) end end end