# # Author:: Xabier de Zuazo (xabier@onddo.com) # Copyright:: Copyright 2013-2016, Onddo Labs, SL. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require "spec_helper" require "chef/cookbook_site_streaming_uploader" class FakeTempfile def initialize(basename) @basename = basename end def close end def path "#{@basename}.ZZZ" end end describe Chef::CookbookSiteStreamingUploader do describe "create_build_dir" do before(:each) do @cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) @loader = Chef::CookbookLoader.new(@cookbook_repo) @loader.load_cookbooks allow(File).to receive(:unlink) end it "should create the cookbook tmp dir" do cookbook = @loader[:openldap] files_count = Dir.glob(File.join(@cookbook_repo, cookbook.name.to_s, "**", "*"), File::FNM_DOTMATCH).count { |file| File.file?(file) } # The fixture cookbook contains a spec/spec_helper.rb file, which is not # a part of any cookbook segment, so it is not uploaded. files_count -= 1 expect(Tempfile).to receive(:new).with("chef-#{cookbook.name}-build").and_return(FakeTempfile.new("chef-#{cookbook.name}-build")) expect(FileUtils).to receive(:mkdir_p).exactly(files_count + 1).times expect(FileUtils).to receive(:cp).exactly(files_count).times Chef::CookbookSiteStreamingUploader.create_build_dir(cookbook) end end # create_build_dir describe "make_request" do before(:each) do @uri = "http://cookbooks.dummy.com/api/v1/cookbooks" @secret_filename = File.join(CHEF_SPEC_DATA, "ssl/private_key.pem") @rsa_key = File.read(@secret_filename) response = Net::HTTPResponse.new("1.0", "200", "OK") allow_any_instance_of(Net::HTTP).to receive(:request).and_return(response) end it "should send an http request" do expect_any_instance_of(Net::HTTP).to receive(:request) Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, "bill", @secret_filename) end it "should read the private key file" do expect(File).to receive(:read).with(@secret_filename).and_return(@rsa_key) Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, "bill", @secret_filename) end it "should add the authentication signed header" do expect_any_instance_of(Mixlib::Authentication::SigningObject).to receive(:sign).and_return({}) Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, "bill", @secret_filename) end it "should be able to send post requests" do post = Net::HTTP::Post.new(@uri, {}) expect(Net::HTTP::Post).to receive(:new).once.and_return(post) expect(Net::HTTP::Put).not_to receive(:new) expect(Net::HTTP::Get).not_to receive(:new) Chef::CookbookSiteStreamingUploader.make_request(:post, @uri, "bill", @secret_filename) end it "should be able to send put requests" do put = Net::HTTP::Put.new(@uri, {}) expect(Net::HTTP::Post).not_to receive(:new) expect(Net::HTTP::Put).to receive(:new).once.and_return(put) expect(Net::HTTP::Get).not_to receive(:new) Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, "bill", @secret_filename) end it "should be able to receive files to attach as argument" do Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, "bill", @secret_filename, { :myfile => File.new(File.join(CHEF_SPEC_DATA, "config.rb")), # a dummy file }) end it "should be able to receive strings to attach as argument" do Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, "bill", @secret_filename, { :mystring => "Lorem ipsum", }) end it "should be able to receive strings and files as argument at the same time" do Chef::CookbookSiteStreamingUploader.make_request(:put, @uri, "bill", @secret_filename, { :myfile1 => File.new(File.join(CHEF_SPEC_DATA, "config.rb")), :mystring1 => "Lorem ipsum", :myfile2 => File.new(File.join(CHEF_SPEC_DATA, "config.rb")), :mystring2 => "Dummy text", }) end end # make_request describe "StreamPart" do before(:each) do @file = File.new(File.join(CHEF_SPEC_DATA, "config.rb")) @stream_part = Chef::CookbookSiteStreamingUploader::StreamPart.new(@file, File.size(@file)) end it "should create a StreamPart" do expect(@stream_part).to be_instance_of(Chef::CookbookSiteStreamingUploader::StreamPart) end it "should expose its size" do expect(@stream_part.size).to eql(File.size(@file)) end it "should read with offset and how_much" do content = @file.read(4) @file.rewind expect(@stream_part.read(0, 4)).to eql(content) end end # StreamPart describe "StringPart" do before(:each) do @str = "What a boring string" @string_part = Chef::CookbookSiteStreamingUploader::StringPart.new(@str) end it "should create a StringPart" do expect(@string_part).to be_instance_of(Chef::CookbookSiteStreamingUploader::StringPart) end it "should expose its size" do expect(@string_part.size).to eql(@str.size) end it "should read with offset and how_much" do expect(@string_part.read(2, 4)).to eql(@str[2, 4]) end end # StringPart describe "MultipartStream" do before(:each) do @string1 = "stream1" @string2 = "stream2" @stream1 = Chef::CookbookSiteStreamingUploader::StringPart.new(@string1) @stream2 = Chef::CookbookSiteStreamingUploader::StringPart.new(@string2) @parts = [ @stream1, @stream2 ] @multipart_stream = Chef::CookbookSiteStreamingUploader::MultipartStream.new(@parts) end it "should create a MultipartStream" do expect(@multipart_stream).to be_instance_of(Chef::CookbookSiteStreamingUploader::MultipartStream) end it "should expose its size" do expect(@multipart_stream.size).to eql(@stream1.size + @stream2.size) end it "should read with how_much" do expect(@multipart_stream.read(10)).to eql("#{@string1}#{@string2}"[0, 10]) end it "should read receiving destination buffer as second argument (CHEF-4456: Ruby 2 compat)" do dst_buf = "" @multipart_stream.read(10, dst_buf) expect(dst_buf).to eql("#{@string1}#{@string2}"[0, 10]) end end # MultipartStream end