spec/unit/policyfile/uploader_spec.rb in chef-dk-0.4.0 vs spec/unit/policyfile/uploader_spec.rb in chef-dk-0.5.0.rc.1

- old
+ new

@@ -84,273 +84,327 @@ it "has an HTTP client" do expect(uploader.http_client).to eq(http_client) end - describe "uploading documents in compat mode" do + describe "uploading policies and cookbooks" do let(:cookbook_locks) { {} } let(:cookbook_versions) { {} } - let(:existing_cookbook_on_remote) do - {"apt"=> - {"url"=>"http://localhost:8889/cookbooks/apt", - "versions"=> - [{"url"=> - "http://localhost:8889/cookbooks/apt/46097674477573307.43471642740453733.243606720748315", - "version"=>"46097674477573307.43471642740453733.243606720748315"}]}, - "build-essential"=> - {"url"=>"http://localhost:8889/cookbooks/build-essential", - "versions"=> - [{"url"=> - "http://localhost:8889/cookbooks/build-essential/67369247788170534.26353953100055918.55660493423796", - "version"=>"67369247788170534.26353953100055918.55660493423796"}]}, - "java"=> - {"url"=>"http://localhost:8889/cookbooks/java", - "versions"=> - [{"url"=> - "http://localhost:8889/cookbooks/java/5664982062912610.52588194571203830.6215746262253", - "version"=>"5664982062912610.52588194571203830.6215746262253"}]}, - "jenkins"=> - {"url"=>"http://localhost:8889/cookbooks/jenkins", - "versions"=> - [{"url"=> - "http://localhost:8889/cookbooks/jenkins/69194928762630300.30177357398946006.269829039948647", - "version"=>"69194928762630300.30177357398946006.269829039948647"}]} - } - end - before do allow(policyfile_lock).to receive(:cookbook_locks).and_return(cookbook_locks) end - def lock_double(name, dotted_decimal_id) + def lock_double(name, identifier, dotted_decimal_id) cache_path = "/home/user/cache_path/#{name}" lock = instance_double("ChefDK::Policyfile::CookbookLock", name: name, version: "1.0.0", - identifier: "64b3e64306cff223206348e46af545b19032b170", + identifier: identifier, dotted_decimal_identifier: dotted_decimal_id, cookbook_path: cache_path) cookbook_version = instance_double("Chef::CookbookVersion", name: name, + identifier: lock.identifier, version: dotted_decimal_id) + allow(cookbook_version).to receive(:identifier=).with(lock.identifier) + allow(ChefDK::Policyfile::ReadCookbookForCompatModeUpload). to receive(:load). with(name, dotted_decimal_id, cache_path). and_return(cookbook_version) + allow(ChefDK::Policyfile::CookbookLoaderWithChefignore). + to receive(:load). + with(name, cache_path). + and_return(cookbook_version) + cookbook_versions[name] = cookbook_version cookbook_locks[name] = lock lock end - context "when configured for policy document compat mode" do + shared_examples_for "uploading cookbooks" do - let(:policyfiles_data_bag) { {"name" => "policyfiles" } } + describe "uploading cookbooks" do - it "ensures a data bag named 'policyfiles' exists" do - expect(http_client).to receive(:post).with('data', policyfiles_data_bag) - uploader.data_bag_create - end + it "enumerates the cookbooks already on the server" do + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) + expect(uploader.existing_cookbook_on_remote).to eq(existing_cookbook_on_remote) + end - it "does not error when the 'policyfiles' data bag exists" do - response = double("Net::HTTP response", code: "409") - error = Net::HTTPServerException.new("conflict", response) - expect(http_client).to receive(:post).with('data', {"name" => "policyfiles"}).and_raise(error) - expect { uploader.data_bag_create }.to_not raise_error - end + context "with an empty policyfile lock" do - it "uploads the policyfile as a data bag item" do - response = double("Net::HTTP response", code: "404") - error = Net::HTTPServerException.new("Not Found", response) - expect(http_client).to receive(:put). - with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item). - and_raise(error) - expect(http_client).to receive(:post). - with('data/policyfiles', policyfile_as_data_bag_item) + it "has an empty list of cookbooks for possible upload" do + expect(policyfile_lock).to receive(:validate_cookbooks!) - uploader.data_bag_item_create - end + expect(uploader.cookbook_versions_for_policy).to eq([]) + end - it "replaces an existing policyfile on the server if it exists" do - expect(http_client).to receive(:put). - with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item) - uploader.data_bag_item_create - end + it "has an empty list of cookbooks that need to be uploaded" do + expect(policyfile_lock).to receive(:validate_cookbooks!) - it "creates the data bag and item to upload the policy" do - expect(http_client).to receive(:post).with('data', policyfiles_data_bag) - expect(http_client).to receive(:put). - with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item) - uploader.upload_policy - end + expect(uploader.cookbook_versions_to_upload).to eq([]) + end - end + end - context "when configured for policy document native mode" do + context "with a set of cookbooks that don't exist on the server" do - let(:policy_document_native_api) { true } + before do + lock_double("my_apache2", "1111111111111111111111111111111111111111", "123.456.789") + lock_double("my_jenkins", "2222222222222222222222222222222222222222", "321.654.987") + end - it "enables native document mode for policyfiles" do - expect(uploader.using_policy_document_native_api?).to be(true) - end + it "lists the cookbooks in the lock as possibly needing to be uploaded" do + expect(policyfile_lock).to receive(:validate_cookbooks!) - it "uploads the policyfile to the native API" do - expect(http_client).to receive(:put). - with('/policies/unit-test/example', policyfile_lock_data) + expected_versions_for_policy = cookbook_versions.keys.map do |cb_name| + cb = cookbook_versions[cb_name] + lock = cookbook_locks[cb_name] + ChefDK::Policyfile::Uploader::LockedCookbookForUpload.new(cb, lock) + end - uploader.upload_policy - end + expect(uploader.cookbook_versions_for_policy).to eq(expected_versions_for_policy) + end - end + it "lists all cookbooks in the lock as needing to be uploaded" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) - it "enumerates the cookbooks already on the server" do - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) - expect(uploader.existing_cookbook_on_remote).to eq(existing_cookbook_on_remote) - end + expect(uploader.cookbook_versions_to_upload).to eq(cookbook_versions.values) + end - context "with an empty policyfile lock" do + it "uploads the cookbooks and then the policy" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) - it "has an empty list of cookbooks for possible upload" do - expect(policyfile_lock).to receive(:validate_cookbooks!) + cookbook_uploader = instance_double("Chef::CookbookUploader") + expect(Chef::CookbookUploader).to receive(:new). + with(cookbook_versions.values, rest: http_client, policy_mode: policy_document_native_api). + and_return(cookbook_uploader) + expect(cookbook_uploader).to receive(:upload_cookbooks) - expect(uploader.cookbook_versions_for_policy).to eq([]) - end + expect_policyfile_upload - it "has an empty list of cookbooks that need to be uploaded" do - expect(policyfile_lock).to receive(:validate_cookbooks!) + uploader.upload + end - expect(uploader.cookbook_versions_to_upload).to eq([]) - end + end - end + context "with a set of cookbooks where some already exist on the server" do - context "with a set of cookbooks that don't exist on the server" do + before do + # These are new: + lock_double("my_apache2", "1111111111111111111111111111111111111111", "123.456.789") + lock_double("my_jenkins", "2222222222222222222222222222222222222222", "321.654.987") - before do - lock_double("my_apache2", "123.456.789") - lock_double("my_jenkins", "321.654.987") - end + # Have this one: + lock_double("build-essential", "571d8ebd02b296fe90b2e4d68754af7e8e185f28", "67369247788170534.26353953100055918.55660493423796") + end - it "lists the cookbooks in the lock as possibly needing to be uploaded" do - expect(policyfile_lock).to receive(:validate_cookbooks!) + let(:expected_cookbooks_for_upload) do + [ + cookbook_versions["my_apache2"], + cookbook_versions["my_jenkins"] + ] + end - expected_versions_for_policy = cookbook_versions.keys.map do |cb_name| - cb = cookbook_versions[cb_name] - lock = cookbook_locks[cb_name] - ChefDK::Policyfile::Uploader::LockedCookbookForUpload.new(cb, lock) - end + it "lists only cookbooks not on the server as needing to be uploaded" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) - expect(uploader.cookbook_versions_for_policy).to eq(expected_versions_for_policy) - end - it "lists all cookbooks in the lock as needing to be uploaded" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) + expect(uploader.cookbook_versions_to_upload).to eq(expected_cookbooks_for_upload) + end - expect(uploader.cookbook_versions_to_upload).to eq(cookbook_versions.values) - end + it "uploads the cookbooks and then the policy" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) - it "uploads the cookbooks and then the policy" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) + cookbook_uploader = instance_double("Chef::CookbookUploader") + expect(Chef::CookbookUploader).to receive(:new). + with(expected_cookbooks_for_upload, rest: http_client, policy_mode: policy_document_native_api). + and_return(cookbook_uploader) + expect(cookbook_uploader).to receive(:upload_cookbooks) - cookbook_uploader = instance_double("Chef::CookbookUploader") - expect(Chef::CookbookUploader).to receive(:new). - with(cookbook_versions.values, :rest => http_client). - and_return(cookbook_uploader) - expect(cookbook_uploader).to receive(:upload_cookbooks) + expect_policyfile_upload - # behavior for these tested above - expect(uploader).to receive(:data_bag_create) - expect(uploader).to receive(:data_bag_item_create) + uploader.upload + end - uploader.upload - end + end - end + context "with a set of cookbooks that all exist on the server" do - context "with a set of cookbooks where some already exist on the server" do + before do + # Have this one: + lock_double("build-essential", "571d8ebd02b296fe90b2e4d68754af7e8e185f28", "67369247788170534.26353953100055918.55660493423796") + end - before do - # These are new: - lock_double("my_apache2", "123.456.789") - lock_double("my_jenkins", "321.654.987") + let(:expected_cookbooks_for_upload) do + [] + end - # Have this one: - lock_double("build-essential", "67369247788170534.26353953100055918.55660493423796") - end + it "lists no cookbooks as needing to be uploaded" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) - let(:expected_cookbooks_for_upload) do - [ - cookbook_versions["my_apache2"], - cookbook_versions["my_jenkins"] - ] - end + expect(uploader.cookbook_versions_to_upload).to eq(expected_cookbooks_for_upload) + end - it "lists only cookbooks not on the server as needing to be uploaded" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) + it "skips cookbooks uploads, then uploads the policy" do + expect(policyfile_lock).to receive(:validate_cookbooks!) + expect(http_client).to receive(:get).with(list_cookbooks_url).and_return(existing_cookbook_on_remote) + expect(uploader.uploader).to_not receive(:upload_cookbooks) - expect(uploader.cookbook_versions_to_upload).to eq(expected_cookbooks_for_upload) + expect_policyfile_upload + + uploader.upload + end + end end + end # uploading cookbooks shared examples - it "uploads the cookbooks and then the policy" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) + context "when configured for policy document compat mode" do - cookbook_uploader = instance_double("Chef::CookbookUploader") - expect(Chef::CookbookUploader).to receive(:new). - with(expected_cookbooks_for_upload, :rest => http_client). - and_return(cookbook_uploader) - expect(cookbook_uploader).to receive(:upload_cookbooks) + let(:policyfiles_data_bag) { {"name" => "policyfiles" } } - # behavior for these tested above + let(:list_cookbooks_url) { 'cookbooks?num_versions=all' } + + let(:existing_cookbook_on_remote) do + {"apt"=> + {"url"=>"http://localhost:8889/cookbooks/apt", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbooks/apt/46097674477573307.43471642740453733.243606720748315", + "version"=>"46097674477573307.43471642740453733.243606720748315"}]}, + "build-essential"=> + {"url"=>"http://localhost:8889/cookbooks/build-essential", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbooks/build-essential/67369247788170534.26353953100055918.55660493423796", + "version"=>"67369247788170534.26353953100055918.55660493423796"}]}, + "java"=> + {"url"=>"http://localhost:8889/cookbooks/java", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbooks/java/5664982062912610.52588194571203830.6215746262253", + "version"=>"5664982062912610.52588194571203830.6215746262253"}]}, + "jenkins"=> + {"url"=>"http://localhost:8889/cookbooks/jenkins", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbooks/jenkins/69194928762630300.30177357398946006.269829039948647", + "version"=>"69194928762630300.30177357398946006.269829039948647"}]} + } + end + + def expect_policyfile_upload expect(uploader).to receive(:data_bag_create) expect(uploader).to receive(:data_bag_item_create) + end - uploader.upload + it "ensures a data bag named 'policyfiles' exists" do + expect(http_client).to receive(:post).with('data', policyfiles_data_bag) + uploader.data_bag_create end - end + it "does not error when the 'policyfiles' data bag exists" do + response = double("Net::HTTP response", code: "409") + error = Net::HTTPServerException.new("conflict", response) + expect(http_client).to receive(:post).with('data', {"name" => "policyfiles"}).and_raise(error) + expect { uploader.data_bag_create }.to_not raise_error + end - context "with a set of cookbooks that all exist on the server" do + it "uploads the policyfile as a data bag item" do + response = double("Net::HTTP response", code: "404") + error = Net::HTTPServerException.new("Not Found", response) + expect(http_client).to receive(:put). + with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item). + and_raise(error) + expect(http_client).to receive(:post). + with('data/policyfiles', policyfile_as_data_bag_item) - before do - # Have this one: - lock_double("build-essential", "67369247788170534.26353953100055918.55660493423796") + uploader.data_bag_item_create end - let(:expected_cookbooks_for_upload) do - [] + it "replaces an existing policyfile on the server if it exists" do + expect(http_client).to receive(:put). + with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item) + uploader.data_bag_item_create end - it "lists no cookbooks as needing to be uploaded" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) - - expect(uploader.cookbook_versions_to_upload).to eq(expected_cookbooks_for_upload) + it "creates the data bag and item to upload the policy" do + expect(http_client).to receive(:post).with('data', policyfiles_data_bag) + expect(http_client).to receive(:put). + with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item) + uploader.upload_policy end - it "skips cookbooks uploads, then uploads the policy" do - expect(policyfile_lock).to receive(:validate_cookbooks!) - expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote) + include_examples "uploading cookbooks" - expect(uploader.uploader).to_not receive(:upload_cookbooks) + end - # behavior for these tested above - expect(uploader).to receive(:data_bag_create) - expect(uploader).to receive(:data_bag_item_create) + context "when configured for policy document native mode" do - uploader.upload + let(:policy_document_native_api) { true } + + let(:list_cookbooks_url) { 'cookbook_artifacts?num_versions=all' } + + let(:existing_cookbook_on_remote) do + {"apt"=> + {"url"=>"http://localhost:8889/cookbook_artifacts/apt", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbook_artifacts/apt/5f7045a8aeaf6ccda3b3594258df9ee982b3a023", + "identifier"=>"5f7045a8aeaf6ccda3b3594258df9ee982b3a023"}]}, + "build-essential"=> + {"url"=>"http://localhost:8889/cookbook_artifacts/build-essential", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbook_artifacts/build-essential/571d8ebd02b296fe90b2e4d68754af7e8e185f28", + "identifier"=>"571d8ebd02b296fe90b2e4d68754af7e8e185f28"}]}, + "java"=> + {"url"=>"http://localhost:8889/cookbook_artifacts/java", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbook_artifacts/java/9178a38ad3e3baa55b49c1b8d9f4bf6a43dbc358", + "identifier"=>"9178a38ad3e3baa55b49c1b8d9f4bf6a43dbc358"}]}, + "jenkins"=> + {"url"=>"http://localhost:8889/cookbook_artifacts/jenkins", + "versions"=> + [{"url"=> + "http://localhost:8889/cookbook_artifacts/jenkins/0be380429add00d189b4431059ac967a60052323", + "identifier"=>"0be380429add00d189b4431059ac967a60052323"}]} + } end + def expect_policyfile_upload + expect(http_client).to receive(:put). + with('/policy_groups/unit-test/policies/example', policyfile_lock_data) + end + + it "enables native document mode for policyfiles" do + expect(uploader.using_policy_document_native_api?).to be(true) + end + + it "uploads the policyfile to the native API" do + expect(http_client).to receive(:put). + with('/policy_groups/unit-test/policies/example', policyfile_lock_data) + + uploader.upload_policy + end + + include_examples "uploading cookbooks" + end + end end