Skip to content

Commit

Permalink
Tests, tests, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-sidorenko committed Nov 10, 2016
1 parent 4248eb7 commit b4bef9a
Showing 1 changed file with 235 additions and 0 deletions.
235 changes: 235 additions & 0 deletions spec/libraries/devsec_ssh_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# encoding: utf-8
#
# Copyright 2016, Artem Sidorenko
#
# 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_relative '../../libraries/devsec_ssh.rb'

# Simple mock for Chef::Log
class Chef
class Log
def self.info(*); end

def self.debug(*); end
end
end

describe DevSec::Ssh do
subject { DevSec::Ssh }
let(:family) { 'debian' }
let(:platform) { 'ubuntu' }
let(:version) { '16.04' }
let(:package_installed) { true }
let(:package_version) { '1:7.2p2-4ubuntu2.1' }
let(:package_name) { 'openssh-server' }
let(:node) do
node = {
'platform_family' => family,
'platform' => platform,
'platform_version' => version,
'sshclient' => {
'package' => package_name
},
'sshserver' => {
'package' => package_name
}
}
node['packages'] = { package_name => { 'version' => package_version } } if package_installed

node
end

describe 'guess_ssh_version' do
context 'when running on Ubuntu 16.04' do
let(:family) { 'debian' }
let(:platform) { 'ubuntu' }
let(:version) { '16.04' }

it 'should return ssh version 6.6' do
expect(subject.send(:guess_ssh_version, node)).to eq 6.6
end
end

context 'when running on RHEL 7' do
let(:family) { 'rhel' }
let(:platform) { 'centos' }
let(:version) { '7.2.1511' }

it 'should return ssh version 6.6' do
expect(subject.send(:guess_ssh_version, node)).to eq 6.6
end
end

context 'when running on RHEL 6' do
let(:family) { 'rhel' }
let(:platform) { 'centos' }
let(:version) { '6.8' }

it 'should return ssh version 5.3' do
expect(subject.send(:guess_ssh_version, node)).to eq 5.3
end
end

context 'when running on unknown platform' do
let(:family) { 'unknown' }
let(:platform) { 'unknown' }
let(:version) { 'unknown' }

it 'should return the fallback ssh version' do
expect(subject.send(:guess_ssh_version, node)).to eq subject::FALLBACK_SSH_VERSION
end
end
end

describe 'get_ssh_version' do
context 'when ssh server package is installed' do
let(:package_installed) { true }
let(:package_name) { 'openssh-server' }

context 'with version 6.6 on rhel system' do
let(:package_version) { '6.6.1p1' }
let(:family) { 'rhel' }

it 'should return the ssh version 6.6' do
expect(subject.send(:get_ssh_version, node, package_name)).to eq 6.6
end
end

context 'with version 1:7.2p2-4ubuntu2.1 on debian system' do
let(:package_version) { '1:7.2p2-4ubuntu2.1' }
let(:family) { 'debian' }

it 'should return the ssh version 7.2' do
expect(subject.send(:get_ssh_version, node, package_name)).to eq 7.2
end
end
end

context 'when ssh package is not installed' do
let(:package_installed) { false }

it 'should guess the ssh version' do
expect(subject).to receive(:guess_ssh_version)
subject.send(:get_ssh_version, node, package_name)
end
end
end

describe 'get_ssh_server_version' do
it 'should call get_ssh_version with server package attribute' do
expect(subject).to receive(:get_ssh_version).with(node, package_name)
subject.send(:get_ssh_server_version, node)
end
end

describe 'get_ssh_client_version' do
it 'should call get_ssh_version with client package attribute' do
expect(subject).to receive(:get_ssh_version).with(node, package_name)
subject.send(:get_ssh_client_version, node)
end
end

# Here we test the meta functions:
# get_[client|server]_[kexs|macs|ciphers]
# In order to cover all possible combinations, we need a complex nested loops:-\
# We start with client|server combination
%w(client server).each do |type|
# Go over different types of crypto parameters, e.g. kexs, macs, ciphers
DevSec::Ssh::CRYPTO.each do |crypto_type, crypto_value| # we can not use subject here, as its not in the block
function = "get_#{type}_#{crypto_type}"

# here we start to describe a specfic function like get_client_kexs
describe function do
# Go over different ssh versions
crypto_value.each do |openssh_version, crypto_params|
next unless openssh_version.is_a?(Float) # skip :weak

context "when openssh is >= #{openssh_version}" do
before :each do
# mock get_ssh_[client|server]_version. We test it somewhere else
expect(subject).to receive("get_ssh_#{type}_version") { openssh_version }
end

if crypto_params.empty?
it 'get nil' do
expect(subject.send(function, node)).to eq nil
end
else
# Check the different combinatios of weak_parameter to the function
[true, false].each do |weak_option|
context "and when weak option is #{weak_option}" do
let(:ret) { subject.send(function, node, weak_option).split(',') }

it "get crypto parameters #{weak_option ? 'with' : 'without'} weak options" do
exp = weak_option ? (crypto_params | crypto_value[:weak]) : crypto_params
expect(ret).to eq exp
end
end
end
end
end
end

context 'when openssh has a totaly unsupported version, e.g. 3.0' do
it 'should raise an exception' do
expect(subject).to receive("get_ssh_#{type}_version".to_sym) { 3.0 }
expect { subject.send(function, node) }.to raise_exception(/Unsupported ssh version/)
end
end
end
end
end

describe 'Exceptions for undefined calls' do
context 'when function name is totally undefined' do
it 'should raise an exception' do
expect { subject.someundefined_function(nil) }.to raise_exception(NoMethodError)
end
end

context 'when ssh type is unknown' do
it 'should raise an exception' do
expect { subject.get_unknown_kexs(nil) }.to raise_exception(NoMethodError)
end
end

context 'when crypto type is unknown' do
it 'should raise an exception' do
expect { subject.get_client_unknown(nil) }.to raise_exception(NoMethodError)
end
end
end
end

# Test the connector to the library
describe Chef::Recipe::DevSec do
subject { Chef::Recipe::DevSec }
# test the existing methods
context 'when the called function exists' do
it 'should be passed to DevSec:Ssh' do
expect(DevSec::Ssh).to receive(:get_server_kexs)
subject.get_server_kexs(nil)
end
end

# test some missing method
context 'when the called function does not exist' do
it 'should raise an exception' do
expect { subject.some_unimplemented_thing }.to raise_exception(NoMethodError)
end
end
end

0 comments on commit b4bef9a

Please sign in to comment.