# # Original knife-windows author:: Steven Murawski () # Copyright:: Copyright (c) 2015-2016 Chef Software, Inc. # 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' describe Chef::Knife::WsmanTest do let(:http_client_mock) { HTTPClient.new } let(:ssl_policy) { double('DefaultSSLPolicy', :set_custom_certs => nil) } before(:all) do Chef::Config.reset end before(:each) do response_body = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsdMicrosoft CorporationOS: 0.0.0 SP: 0.0 Stack: 2.0' http_response_mock = HTTP::Message.new_response(response_body) allow(http_client_mock).to receive(:post).and_return(http_response_mock) allow(HTTPClient).to receive(:new).and_return(http_client_mock) subject.config[:verbosity] = 0 allow(subject.ui).to receive(:ask).and_return('prompted_password') allow(Chef::HTTP::DefaultSSLPolicy).to receive(:new) .with(http_client_mock.ssl_config) .and_return(ssl_policy) end subject { Chef::Knife::WsmanTest.new(['-m', 'localhost']) } it 'sets the ssl policy' do expect(ssl_policy).to receive(:set_custom_certs).twice subject.run end context 'when testing the WSMAN endpoint' do context 'and the service responds' do context 'successfully' do it 'writes a message about a successful connection' do expect(subject.ui).to receive(:msg) subject.run end end context 'with an invalid body' do it 'warns for a failed connection and exit with a status of 1' do response_body = 'I am invalid' http_response_mock = HTTP::Message.new_response(response_body) allow(http_client_mock).to receive(:post).and_return(http_response_mock) expect(subject.ui).to receive(:warn) expect(subject.ui).to receive(:error) expect(subject).to receive(:exit).with(1) subject.run end end context 'with a non-200 code' do it 'warns for a failed connection and exits with a status of 1' do http_response_mock = HTTP::Message.new_response('') http_response_mock.status = 404 allow(http_client_mock).to receive(:post).and_return(http_response_mock) expect(subject.ui).to receive(:warn) expect(subject.ui).to receive(:error) expect(subject).to receive(:exit).with(1) subject.run end end end context 'and the service does not respond' do error_message = 'A connection attempt failed because the connected party did not properly respond after a period of time.' before(:each) do allow(http_client_mock).to receive(:post).and_raise(Exception.new(error_message)) end it 'exits with a status code of 1' do expect(subject).to receive(:exit).with(1) subject.run end it 'writes a warning message for each node it fails to connect to' do expect(subject.ui).to receive(:warn) expect(subject).to receive(:exit).with(1) subject.run end it 'writes an error message if it fails to connect to any nodes' do expect(subject.ui).to receive(:error) expect(subject).to receive(:exit).with(1) subject.run end end end context 'when not validating ssl cert' do before(:each) do expect(subject.ui).to receive(:msg) subject.config[:winrm_ssl_verify_mode] = :verify_none subject.config[:winrm_transport] = :ssl end it 'sets verify_mode to verify_none' do subject.run expect(http_client_mock.ssl_config.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE) end end context 'when testing the WSMAN endpoint with verbose output' do before(:each) do subject.config[:verbosity] = 1 end context 'and the service does not respond' do it 'returns an object with an error message' do error_message = 'A connection attempt failed because the connected party did not properly respond after a period of time.' allow(http_client_mock).to receive(:post).and_raise(Exception.new(error_message)) expect(subject).to receive(:exit).with(1) expect(subject).to receive(:output) do |output| expect(output.error_message).to match(/#{error_message}/) end subject.run end end context 'with an invalid body' do it 'includes invalid body in error message' do response_body = 'I am invalid' http_response_mock = HTTP::Message.new_response(response_body) allow(http_client_mock).to receive(:post).and_return(http_response_mock) expect(subject).to receive(:exit).with(1) expect(subject).to receive(:output) do |output| expect(output.error_message).to match(/#{response_body}/) end subject.run end end context 'and the target node is Windows Server 2008 R2' do before(:each) do ws2008r2_response_body = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsdMicrosoft CorporationOS: 0.0.0 SP: 0.0 Stack: 2.0' http_response_mock = HTTP::Message.new_response(ws2008r2_response_body) allow(http_client_mock).to receive(:post).and_return(http_response_mock) end it 'identifies the stack of the product version as 2.0 ' do expect(subject).to receive(:output) do |output| expect(output.product_version).to eq 'OS: 0.0.0 SP: 0.0 Stack: 2.0' end subject.run end it 'identifies the protocol version as the current DMTF standard' do expect(subject).to receive(:output) do |output| expect(output.protocol_version).to eq 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd' end subject.run end it 'identifies the vendor as the Microsoft Corporation' do expect(subject).to receive(:output) do |output| expect(output.product_vendor).to eq 'Microsoft Corporation' end subject.run end end context 'and the target node is Windows Server 2012 R2' do before(:each) do ws2012_response_body = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsdMicrosoft CorporationOS: 0.0.0 SP: 0.0 Stack: 3.0' http_response_mock = HTTP::Message.new_response(ws2012_response_body) allow(http_client_mock).to receive(:post).and_return(http_response_mock) end it 'identifies the stack of the product version as 3.0 ' do expect(subject).to receive(:output) do |output| expect(output.product_version).to eq 'OS: 0.0.0 SP: 0.0 Stack: 3.0' end subject.run end it 'identifies the protocol version as the current DMTF standard' do expect(subject).to receive(:output) do |output| expect(output.protocol_version).to eq 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd' end subject.run end it 'identifies the vendor as the Microsoft Corporation' do expect(subject).to receive(:output) do |output| expect(output.product_vendor).to eq 'Microsoft Corporation' end subject.run end end end end