diff options
Diffstat (limited to 'spec/unit/knife')
-rw-r--r-- | spec/unit/knife/client_delete_spec.rb | 16 | ||||
-rw-r--r-- | spec/unit/knife/configure_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/knife/cookbook_metadata_spec.rb | 229 | ||||
-rw-r--r-- | spec/unit/knife/core/bootstrap_context_spec.rb | 60 | ||||
-rw-r--r-- | spec/unit/knife/node_delete_spec.rb | 29 | ||||
-rw-r--r-- | spec/unit/knife/ssh_spec.rb | 70 |
6 files changed, 241 insertions, 165 deletions
diff --git a/spec/unit/knife/client_delete_spec.rb b/spec/unit/knife/client_delete_spec.rb index 82ef902e09..f20b25f5e6 100644 --- a/spec/unit/knife/client_delete_spec.rb +++ b/spec/unit/knife/client_delete_spec.rb @@ -34,6 +34,22 @@ describe Chef::Knife::ClientDelete do @knife.run end + context "receives multiple clients" do + let(:clients) { %w{ "adam", "ben", "charlie" } } + + before(:each) do + @knife.name_args = clients + end + + it "deletes all clients" do + clients.each do |client| + expect(@knife).to receive(:delete_object).with(Chef::ApiClientV1, client, "client") + end + + @knife.run + end + end + it "should print usage and exit when a client name is not provided" do @knife.name_args = [] expect(@knife).to receive(:show_usage) diff --git a/spec/unit/knife/configure_spec.rb b/spec/unit/knife/configure_spec.rb index e96115c056..b7802d3890 100644 --- a/spec/unit/knife/configure_spec.rb +++ b/spec/unit/knife/configure_spec.rb @@ -38,7 +38,7 @@ describe Chef::Knife::Configure do let(:default_validator_key) { "/etc/chef-server/chef-validator.pem" } let(:default_validator_key_win32) { File.expand_path(default_validator_key) } - let(:default_server_url) { "https://#{fqdn}:443" } + let(:default_server_url) { "https://#{fqdn}/organizations/myorg" } it "asks the user for the URL of the chef server" do @knife.ask_user_for_config diff --git a/spec/unit/knife/cookbook_metadata_spec.rb b/spec/unit/knife/cookbook_metadata_spec.rb index 4b405d0842..c19fc5ae2d 100644 --- a/spec/unit/knife/cookbook_metadata_spec.rb +++ b/spec/unit/knife/cookbook_metadata_spec.rb @@ -19,63 +19,96 @@ require "spec_helper" describe Chef::Knife::CookbookMetadata do + let(:knife) do + knife = Chef::Knife::CookbookMetadata.new + knife.name_args = ["foobar"] + knife + end + + let(:cookbook_dir) { Dir.mktmpdir } + + let(:stdout) { StringIO.new } + + let(:stderr) { StringIO.new } + before(:each) do - @knife = Chef::Knife::CookbookMetadata.new - @knife.name_args = ["foobar"] - @cookbook_dir = Dir.mktmpdir - @json_data = '{ "version": "1.0.0" }' - @stdout = StringIO.new - @stderr = StringIO.new - allow(@knife.ui).to receive(:stdout).and_return(@stdout) - allow(@knife.ui).to receive(:stderr).and_return(@stderr) + allow(knife.ui).to receive(:stdout).and_return(stdout) + allow(knife.ui).to receive(:stderr).and_return(stderr) + end + + def create_metadata_rb(**kwargs) + name = kwargs[:name] + Dir.mkdir("#{cookbook_dir}/#{name}") + File.open("#{cookbook_dir}/#{name}/metadata.rb", "w+") do |f| + kwargs.each do |key, value| + if value.is_a?(Array) + f.puts "#{key} #{value.map { |v| "\"#{v}\"" }.join(", ")}" + else + f.puts "#{key} \"#{value}\"" + end + end + end + end + + def create_metadata_json(**kwargs) + name = kwargs[:name] + Dir.mkdir("#{cookbook_dir}/#{name}") + File.open("#{cookbook_dir}/#{name}/metadata.json", "w+") do |f| + f.write(FFI_Yajl::Encoder.encode(kwargs)) + end + end + + def create_invalid_json + Dir.mkdir("#{cookbook_dir}/foobar") + File.open("#{cookbook_dir}/foobar/metadata.json", "w+") do |f| + f.write <<-EOH + { "version": "1.0.0", {ImInvalid}} + EOH + end end describe "run" do it "should print an error and exit if a cookbook name was not provided" do - @knife.name_args = [] - expect(@knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i) - expect { @knife.run }.to raise_error(SystemExit) + knife.name_args = [] + expect(knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i) + expect { knife.run }.to raise_error(SystemExit) end it "should print an error and exit if an empty cookbook name was provided" do - @knife.name_args = [""] - expect(@knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i) - expect { @knife.run }.to raise_error(SystemExit) + knife.name_args = [""] + expect(knife.ui).to receive(:error).with(/you must specify the cookbook.+use the --all/i) + expect { knife.run }.to raise_error(SystemExit) end it "should generate the metadata for the cookbook" do - expect(@knife).to receive(:generate_metadata).with("foobar") - @knife.run + expect(knife).to receive(:generate_metadata).with("foobar") + knife.run end describe "with -a or --all" do before(:each) do - @knife.config[:all] = true - @foo = Chef::CookbookVersion.new("foo", "/tmp/blah") - @foo.version = "1.0.0" - @bar = Chef::CookbookVersion.new("bar", "/tmp/blah") - @bar.version = "2.0.0" - @cookbook_loader = { - "foo" => @foo, - "bar" => @bar, - } - expect(@cookbook_loader).to receive(:load_cookbooks).and_return(@cookbook_loader) - expect(@knife).to receive(:generate_metadata).with("foo") - expect(@knife).to receive(:generate_metadata).with("bar") + Chef::Config[:cookbook_path] = cookbook_dir + knife.config[:all] = true + create_metadata_rb(name: "foo", version: "1.0.0") + create_metadata_rb(name: "bar", version: "2.0.0") + expect(knife).to receive(:generate_metadata).with("foo").and_call_original + expect(knife).to receive(:generate_metadata).with("bar").and_call_original end it "should generate the metadata for each cookbook" do - Chef::Config[:cookbook_path] = @cookbook_dir - expect(Chef::CookbookLoader).to receive(:new).with(@cookbook_dir).and_return(@cookbook_loader) - @knife.run + expect(Chef::CookbookLoader).to receive(:new).with(cookbook_dir).and_call_original + knife.run + expect(stderr.string).to match /generating metadata for foo from #{cookbook_dir}\/foo\/metadata\.rb/im + expect(stderr.string).to match /generating metadata for bar from #{cookbook_dir}\/bar\/metadata\.rb/im end - describe "and with -o or --cookbook-path" do - it "should look in the provided path and generate cookbook metadata" do - @knife.config[:cookbook_path] = "/opt/chef/cookbooks" - expect(Chef::CookbookLoader).to receive(:new).with("/opt/chef/cookbooks").and_return(@cookbook_loader) - @knife.run - end + it "with -o or --cookbook_path should look in the provided path and generate cookbook metadata" do + Chef::Config[:cookbook_path] = "/dev/null" + knife.config[:cookbook_path] = cookbook_dir + expect(Chef::CookbookLoader).to receive(:new).with(cookbook_dir).and_call_original + knife.run + expect(stderr.string).to match /generating metadata for foo from #{cookbook_dir}\/foo\/metadata\.rb/im + expect(stderr.string).to match /generating metadata for bar from #{cookbook_dir}\/bar\/metadata\.rb/im end end @@ -83,97 +116,67 @@ describe Chef::Knife::CookbookMetadata do describe "generate_metadata" do before(:each) do - @knife.config[:cookbook_path] = @cookbook_dir - allow(File).to receive(:expand_path).with("#{@cookbook_dir}/foobar/metadata.rb"). - and_return("#{@cookbook_dir}/foobar/metadata.rb") + Chef::Config[:cookbook_path] = cookbook_dir end it "should generate the metadata from metadata.rb if it exists" do - expect(File).to receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb"). - and_return(true) - expect(@knife).to receive(:generate_metadata_from_file).with("foobar", "#{@cookbook_dir}/foobar/metadata.rb") - @knife.run + create_metadata_rb(name: "foobar", version: "1.0.0") + expect(knife).to receive(:generate_metadata_from_file).with("foobar", "#{cookbook_dir}/foobar/metadata.rb").and_call_original + knife.run + expect(File.exist?("#{cookbook_dir}/foobar/metadata.json")).to be true + json = FFI_Yajl::Parser.parse(IO.read("#{cookbook_dir}/foobar/metadata.json")) + expect(json["name"]).to eql("foobar") + expect(json["version"]).to eql("1.0.0") end it "should validate the metadata json if metadata.rb does not exist" do - expect(File).to receive(:exists?).with("#{@cookbook_dir}/foobar/metadata.rb"). - and_return(false) - expect(@knife).to receive(:validate_metadata_json).with(@cookbook_dir, "foobar") - @knife.run + create_metadata_json(name: "foobar", version: "1.0.0") + expect(knife).to receive(:validate_metadata_json).with(cookbook_dir, "foobar").and_call_original + knife.run end end - describe "generate_metadata_from_file" do + describe "validation errors" do before(:each) do - @metadata_mock = double("metadata") - @json_file_mock = double("json_file") - end - - it "should generate the metatdata json from metatdata.rb" do - allow(Chef::Cookbook::Metadata).to receive(:new).and_return(@metadata_mock) - expect(@metadata_mock).to receive(:name).with("foobar") - expect(@metadata_mock).to receive(:from_file).with("#{@cookbook_dir}/foobar/metadata.rb") - expect(File).to receive(:open).with("#{@cookbook_dir}/foobar/metadata.json", "w"). - and_yield(@json_file_mock) - expect(@json_file_mock).to receive(:write).with(@json_data) - expect(Chef::JSONCompat).to receive(:to_json_pretty).with(@metadata_mock). - and_return(@json_data) - @knife.generate_metadata_from_file("foobar", "#{@cookbook_dir}/foobar/metadata.rb") - expect(@stderr.string).to match /generating metadata for foobar from #{@cookbook_dir}\/foobar\/metadata\.rb/im - end - - { Chef::Exceptions::ObsoleteDependencySyntax => "obsolote dependency", - Chef::Exceptions::InvalidVersionConstraint => "invalid version constraint", - }.each_pair do |klass, description| - it "should print an error and exit when an #{description} syntax exception is encountered" do - exception = klass.new("#{description} blah") - allow(Chef::Cookbook::Metadata).to receive(:new).and_raise(exception) - expect do - @knife.generate_metadata_from_file("foobar", "#{@cookbook_dir}/foobar/metadata.rb") - end.to raise_error(SystemExit) - expect(@stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im - expect(@stderr.string).to match /in #{@cookbook_dir}\/foobar\/metadata\.rb/im - expect(@stderr.string).to match /#{description} blah/im - end + Chef::Config[:cookbook_path] = cookbook_dir end - end - describe "validate_metadata_json" do - it "should validate the metadata json" do - expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json"). - and_return(true) - expect(IO).to receive(:read).with("#{@cookbook_dir}/foobar/metadata.json"). - and_return(@json_data) - expect(Chef::Cookbook::Metadata).to receive(:validate_json).with(@json_data) - @knife.validate_metadata_json(@cookbook_dir, "foobar") + it "should fail for obsolete operators in metadata.rb" do + create_metadata_rb(name: "foobar", version: "1.0.0", depends: [ "foo:bar", ">> 0.2" ]) + expect(Chef::Cookbook::Metadata).not_to receive(:validate_json) + expect { knife.run }.to raise_error(SystemExit) + expect(stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im end - it "should not try to validate the metadata json if the file does not exist" do - expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json"). - and_return(false) - expect(IO).not_to receive(:read) + it "should fail for obsolete format in metadata.rb (sadly)" do + create_metadata_rb(name: "foobar", version: "1.0.0", depends: [ "foo:bar", "> 0.2", "< 1.0" ]) expect(Chef::Cookbook::Metadata).not_to receive(:validate_json) - @knife.validate_metadata_json(@cookbook_dir, "foobar") - end - - { Chef::Exceptions::ObsoleteDependencySyntax => "obsolote dependency", - Chef::Exceptions::InvalidVersionConstraint => "invalid version constraint", - }.each_pair do |klass, description| - it "should print an error and exit when an #{description} syntax exception is encountered" do - expect(File).to receive(:exist?).with("#{@cookbook_dir}/foobar/metadata.json"). - and_return(true) - expect(IO).to receive(:read).with("#{@cookbook_dir}/foobar/metadata.json"). - and_return(@json_data) - exception = klass.new("#{description} blah") - allow(Chef::Cookbook::Metadata).to receive(:validate_json).and_raise(exception) - expect do - @knife.validate_metadata_json(@cookbook_dir, "foobar") - end.to raise_error(SystemExit) - expect(@stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im - expect(@stderr.string).to match /in #{@cookbook_dir}\/foobar\/metadata\.json/im - expect(@stderr.string).to match /#{description} blah/im - end + expect { knife.run }.to raise_error(SystemExit) + expect(stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im + end + + it "should fail for obsolete operators in metadata.json" do + create_metadata_json(name: "foobar", version: "1.0.0", dependencies: { "foo:bar" => ">> 0.2" }) + expect { knife.run }.to raise_error(SystemExit) + expect(stderr.string).to match /error: the cookbook 'foobar' contains invalid or obsolete metadata syntax/im end - end + it "should not fail for unknown field in metadata.rb" do + create_metadata_rb(name: "sounders", version: "2.0.0", beats: "toronto") + expect(Chef::Cookbook::Metadata).not_to receive(:validate_json) + expect { knife.run }.not_to raise_error + expect(stderr.string).to eql("") + end + + it "should not fail for unknown field in metadata.json" do + create_metadata_json(name: "sounders", version: "2.0.0", beats: "toronto") + expect { knife.run }.not_to raise_error + expect(stderr.string).to eql("") + end + + it "should fail on unparsable json" do + create_invalid_json + expect { knife.run }.to raise_error(Chef::Exceptions::JSON::ParseError) + end + end end diff --git a/spec/unit/knife/core/bootstrap_context_spec.rb b/spec/unit/knife/core/bootstrap_context_spec.rb index 6465e18ac9..515381cf6e 100644 --- a/spec/unit/knife/core/bootstrap_context_spec.rb +++ b/spec/unit/knife/core/bootstrap_context_spec.rb @@ -30,6 +30,8 @@ describe Chef::Knife::Core::BootstrapContext do let(:run_list) { Chef::RunList.new("recipe[tmux]", "role[base]") } let(:chef_config) do { + :config_log_level => "info", + :config_log_location => "/tmp/log", :validation_key => File.join(CHEF_SPEC_DATA, "ssl", "private_key.pem"), :chef_server_url => "http://chef.example.com:4444", :validation_client_name => "chef-validator-testing", @@ -68,18 +70,15 @@ describe Chef::Knife::Core::BootstrapContext do it "generates the config file data" do expected = <<-EXPECTED -log_location STDOUT chef_server_url "http://chef.example.com:4444" validation_client_name "chef-validator-testing" +log_level :info +log_location "/tmp/log" # Using default node name (fqdn) EXPECTED expect(bootstrap_context.config_content).to eq expected end - it "does not set a default log_level" do - expect(bootstrap_context.config_content).not_to match(/log_level/) - end - describe "alternate chef-client path" do let(:chef_config) { { :chef_client_path => "/usr/local/bin/chef-client" } } it "runs chef-client from another path when specified" do @@ -254,4 +253,55 @@ EXPECTED end end + describe "#config_log_location" do + context "when config_log_location is nil" do + let(:chef_config) { { :config_log_location => nil } } + it "sets the default config_log_location in the client.rb" do + expect(bootstrap_context.get_log_location).to eq "STDOUT" + end + end + + context "when config_log_location is empty" do + let(:chef_config) { { :config_log_location => "" } } + it "sets the default config_log_location in the client.rb" do + expect(bootstrap_context.get_log_location).to eq "STDOUT" + end + end + + context "when config_log_location is :win_evt" do + let(:chef_config) { { :config_log_location => :win_evt } } + it "raise error when config_log_location is :win_evt " do + expect { bootstrap_context.get_log_location }.to raise_error("The value :win_evt is not supported for config_log_location on Linux Platforms \n") + end + end + + context "when config_log_location is :syslog" do + let(:chef_config) { { :config_log_location => :syslog } } + it "sets the config_log_location value as :syslog in the client.rb" do + expect(bootstrap_context.get_log_location).to eq ":syslog" + end + end + + context "When config_log_location is STDOUT" do + let(:chef_config) { { :config_log_location => STDOUT } } + it "Sets the config_log_location value as STDOUT in the client.rb" do + expect(bootstrap_context.get_log_location).to eq "STDOUT" + end + end + + context "when config_log_location is STDERR" do + let(:chef_config) { { :config_log_location => STDERR } } + it "sets the config_log_location value as STDERR in the client.rb" do + expect(bootstrap_context.get_log_location).to eq "STDERR" + end + end + + context "when config_log_location is a path" do + let(:chef_config) { { :config_log_location => "/tmp/ChefLogFile" } } + it "sets the config_log_location path in the client.rb" do + expect(bootstrap_context.get_log_location).to eq "\"/tmp/ChefLogFile\"" + end + end + + end end diff --git a/spec/unit/knife/node_delete_spec.rb b/spec/unit/knife/node_delete_spec.rb index d4ef32bccf..1a6b277dbb 100644 --- a/spec/unit/knife/node_delete_spec.rb +++ b/spec/unit/knife/node_delete_spec.rb @@ -25,12 +25,17 @@ describe Chef::Knife::NodeDelete do @knife.config = { :print_after => nil, } - @knife.name_args = [ "adam" ] + @knife.name_args = %w{ adam ben } allow(@knife).to receive(:output).and_return(true) allow(@knife).to receive(:confirm).and_return(true) - @node = Chef::Node.new() - allow(@node).to receive(:destroy).and_return(true) - allow(Chef::Node).to receive(:load).and_return(@node) + + @adam_node = Chef::Node.new() + @ben_node = Chef::Node.new() + allow(@ben_node).to receive(:destroy).and_return(true) + allow(@adam_node).to receive(:destroy).and_return(true) + allow(Chef::Node).to receive(:load).with("adam").and_return(@adam_node) + allow(Chef::Node).to receive(:load).with("ben").and_return(@ben_node) + @stdout = StringIO.new allow(@knife.ui).to receive(:stdout).and_return(@stdout) end @@ -41,13 +46,15 @@ describe Chef::Knife::NodeDelete do @knife.run end - it "should load the node" do - expect(Chef::Node).to receive(:load).with("adam").and_return(@node) + it "should load the nodes" do + expect(Chef::Node).to receive(:load).with("adam").and_return(@adam_node) + expect(Chef::Node).to receive(:load).with("ben").and_return(@ben_node) @knife.run end - it "should delete the node" do - expect(@node).to receive(:destroy).and_return(@node) + it "should delete the nodes" do + expect(@adam_node).to receive(:destroy).and_return(@adam_node) + expect(@ben_node).to receive(:destroy).and_return(@ben_node) @knife.run end @@ -59,8 +66,10 @@ describe Chef::Knife::NodeDelete do describe "with -p or --print-after" do it "should pretty print the node, formatted for display" do @knife.config[:print_after] = true - expect(@knife).to receive(:format_for_display).with(@node).and_return("poop") - expect(@knife).to receive(:output).with("poop") + expect(@knife).to receive(:format_for_display).with(@adam_node).and_return("adam") + expect(@knife).to receive(:format_for_display).with(@ben_node).and_return("ben") + expect(@knife).to receive(:output).with("adam") + expect(@knife).to receive(:output).with("ben") @knife.run end end diff --git a/spec/unit/knife/ssh_spec.rb b/spec/unit/knife/ssh_spec.rb index 44a133d858..6141a8a6df 100644 --- a/spec/unit/knife/ssh_spec.rb +++ b/spec/unit/knife/ssh_spec.rb @@ -21,54 +21,53 @@ require "net/ssh" require "net/ssh/multi" describe Chef::Knife::Ssh do - before(:each) do - Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem" - end + let(:query_result) { double("chef search results") } before do + Chef::Config[:client_key] = CHEF_SPEC_DATA + "/ssl/private_key.pem" @knife = Chef::Knife::Ssh.new @knife.merge_configs - @node_foo = Chef::Node.new - @node_foo.automatic_attrs[:fqdn] = "foo.example.org" - @node_foo.automatic_attrs[:ipaddress] = "10.0.0.1" + @node_foo = {} + @node_foo["fqdn"] = "foo.example.org" + @node_foo["ipaddress"] = "10.0.0.1" + @node_foo["cloud"] = {} + + @node_bar = {} + @node_bar["fqdn"] = "bar.example.org" + @node_bar["ipaddress"] = "10.0.0.2" + @node_bar["cloud"] = {} - @node_bar = Chef::Node.new - @node_bar.automatic_attrs[:fqdn] = "bar.example.org" - @node_bar.automatic_attrs[:ipaddress] = "10.0.0.2" end describe "#configure_session" do context "manual is set to false (default)" do before do @knife.config[:manual] = false - @query = Chef::Search::Query.new - end - - def configure_query(node_array) - allow(@query).to receive(:search).and_return([node_array]) - allow(Chef::Search::Query).to receive(:new).and_return(@query) + allow(query_result).to receive(:search).with(any_args).and_yield(@node_foo).and_yield(@node_bar) + allow(Chef::Search::Query).to receive(:new).and_return(query_result) end def self.should_return_specified_attributes it "returns an array of the attributes specified on the command line OR config file, if only one is set" do + @node_bar["config"] = "10.0.0.2" + @node_foo["config"] = "10.0.0.1" @knife.config[:attribute] = "ipaddress" Chef::Config[:knife][:ssh_attribute] = "ipaddress" # this value will be in the config file - configure_query([@node_foo, @node_bar]) expect(@knife).to receive(:session_from_list).with([["10.0.0.1", nil], ["10.0.0.2", nil]]) @knife.configure_session end it "returns an array of the attributes specified on the command line even when a config value is set" do + @node_bar["config"] = "10.0.0.2" + @node_foo["config"] = "10.0.0.1" Chef::Config[:knife][:ssh_attribute] = "config_file" # this value will be in the config file @knife.config[:attribute] = "ipaddress" # this is the value of the command line via #configure_attribute - configure_query([@node_foo, @node_bar]) expect(@knife).to receive(:session_from_list).with([["10.0.0.1", nil], ["10.0.0.2", nil]]) @knife.configure_session end end it "searchs for and returns an array of fqdns" do - configure_query([@node_foo, @node_bar]) expect(@knife).to receive(:session_from_list).with([ ["foo.example.org", nil], ["bar.example.org", nil], @@ -80,11 +79,10 @@ describe Chef::Knife::Ssh do context "when cloud hostnames are available" do before do - @node_foo.automatic_attrs[:cloud][:public_hostname] = "ec2-10-0-0-1.compute-1.amazonaws.com" - @node_bar.automatic_attrs[:cloud][:public_hostname] = "ec2-10-0-0-2.compute-1.amazonaws.com" + @node_foo["cloud"]["public_hostname"] = "ec2-10-0-0-1.compute-1.amazonaws.com" + @node_bar["cloud"]["public_hostname"] = "ec2-10-0-0-2.compute-1.amazonaws.com" end it "returns an array of cloud public hostnames" do - configure_query([@node_foo, @node_bar]) expect(@knife).to receive(:session_from_list).with([ ["ec2-10-0-0-1.compute-1.amazonaws.com", nil], ["ec2-10-0-0-2.compute-1.amazonaws.com", nil], @@ -97,12 +95,11 @@ describe Chef::Knife::Ssh do context "when cloud hostnames are available but empty" do before do - @node_foo.automatic_attrs[:cloud][:public_hostname] = "" - @node_bar.automatic_attrs[:cloud][:public_hostname] = "" + @node_foo["cloud"]["public_hostname"] = "" + @node_bar["cloud"]["public_hostname"] = "" end it "returns an array of fqdns" do - configure_query([@node_foo, @node_bar]) expect(@knife).to receive(:session_from_list).with([ ["foo.example.org", nil], ["bar.example.org", nil], @@ -114,7 +111,7 @@ describe Chef::Knife::Ssh do end it "should raise an error if no host are found" do - configure_query([ ]) + allow(query_result).to receive(:search).with(any_args) expect(@knife.ui).to receive(:fatal) expect(@knife).to receive(:exit).with(10) @knife.configure_session @@ -122,10 +119,8 @@ describe Chef::Knife::Ssh do context "when there are some hosts found but they do not have an attribute to connect with" do before do - allow(@query).to receive(:search).and_return([[@node_foo, @node_bar]]) - @node_foo.automatic_attrs[:fqdn] = nil - @node_bar.automatic_attrs[:fqdn] = nil - allow(Chef::Search::Query).to receive(:new).and_return(@query) + @node_foo["fqdn"] = nil + @node_bar["fqdn"] = nil end it "should raise a specific error (CHEF-3402)" do @@ -158,31 +153,34 @@ describe Chef::Knife::Ssh do before do Chef::Config[:knife][:ssh_attribute] = nil @knife.config[:attribute] = nil - @node_foo.automatic_attrs[:cloud][:public_hostname] = "ec2-10-0-0-1.compute-1.amazonaws.com" - @node_bar.automatic_attrs[:cloud][:public_hostname] = "" + @node_foo["cloud"]["public_hostname"] = "ec2-10-0-0-1.compute-1.amazonaws.com" + @node_bar["cloud"]["public_hostname"] = "" end it "should return fqdn by default" do - expect(@knife.get_ssh_attribute(Chef::Node.new)).to eq("fqdn") + expect(@knife.get_ssh_attribute({ "fqdn" => "fqdn" })).to eq("fqdn") end it "should return cloud.public_hostname attribute if available" do - expect(@knife.get_ssh_attribute(@node_foo)).to eq("cloud.public_hostname") + expect(@knife.get_ssh_attribute(@node_foo)).to eq("ec2-10-0-0-1.compute-1.amazonaws.com") end it "should favor to attribute_from_cli over config file and cloud" do @knife.config[:attribute] = "command_line" Chef::Config[:knife][:ssh_attribute] = "config_file" + @node_foo["config"] = "command_line" + @node_foo["knife_config"] = "config_file" expect( @knife.get_ssh_attribute(@node_foo)).to eq("command_line") end it "should favor config file over cloud and default" do Chef::Config[:knife][:ssh_attribute] = "config_file" + @node_foo["knife_config"] = "config_file" expect( @knife.get_ssh_attribute(@node_foo)).to eq("config_file") end it "should return fqdn if cloud.hostname is empty" do - expect( @knife.get_ssh_attribute(@node_bar)).to eq("fqdn") + expect( @knife.get_ssh_attribute(@node_bar)).to eq("bar.example.org") end end @@ -190,7 +188,7 @@ describe Chef::Knife::Ssh do before :each do @knife.instance_variable_set(:@longest, 0) ssh_config = { :timeout => 50, :user => "locutus", :port => 23 } - allow(Net::SSH).to receive(:configuration_for).with("the.b.org").and_return(ssh_config) + allow(Net::SSH).to receive(:configuration_for).with("the.b.org", true).and_return(ssh_config) end it "uses the port from an ssh config file" do @@ -294,7 +292,7 @@ describe Chef::Knife::Ssh do describe "#run" do before do @query = Chef::Search::Query.new - expect(@query).to receive(:search).and_return([[@node_foo]]) + expect(@query).to receive(:search).and_yield(@node_foo) allow(Chef::Search::Query).to receive(:new).and_return(@query) allow(@knife).to receive(:ssh_command).and_return(exit_code) @knife.name_args = ["*:*", "false"] |