Skip to content
This repository has been archived by the owner on Feb 16, 2024. It is now read-only.

Commit

Permalink
Implementation, unit tests and documentation for the install_module a…
Browse files Browse the repository at this point in the history
…nd install_module_on methods, along with some supporting methods and accompanying tests
  • Loading branch information
Wilson McCoubrey committed Dec 5, 2016
1 parent 30fe0c3 commit e489736
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ AllCops:
RSpec/DescribeClass:
Enabled: false

RSpec/AnyInstance:
Enabled: false

Lint/AmbiguousRegexpLiteral:
Enabled: false

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ source 'https://rubygems.org'
gemspec

group :test do
gem 'beaker', '2.51.0' if RUBY_VERSION <= '2.1.6'
gem 'beaker', '2.52.0' if RUBY_VERSION <= '2.1.6'
gem 'beaker' if RUBY_VERSION > '2.1.6'
gem 'bundler', '~> 1.9'
gem 'rake', '~> 10.0'
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@

This gem is simply an abstraction for the various functions that are performed within the `spec/spec_helper_acceptance.rb` files across the modules to standardise how these are implemented.

### `install_module_on`
### `install_module`
This will call `install_module_on` on the hosts with role 'master'. If there are none, the module will be install on all hosts with the role 'agent', again, if there are none, the module will be installed on all hosts.

This will install the module under test on the specified host using the local source
### `install_module_on`
This will install the module under test on the specified host using the local source. The module name will be derived from the name property of the module's metadata.json file, assuming it is in format author-modulename.

### `install_module_dependencies_on`

This will install a list of dependencies on the specified host either from forge or github, depending on the specified dependencies

### Support

No support is supplied or implied. Use at your own risk.

### TODO
- Implement `install_module_on`
- Implement `install_module_dependencies_on`
64 changes: 61 additions & 3 deletions lib/beaker/module_install_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,74 @@
# Provides method for use in module test setup to install the module under
# test and it's dependencies on the specified hosts
module Beaker::ModuleInstallHelper
# This method will install the module under test on the specified host
def install_module_on(_host)
raise 'Not Implemented Yet'
include Beaker::DSL

# This method calls the install_module_on method for each host which is a
# master, or if no master is present, on all agent nodes.
def install_module
install_module_on hosts_to_install_module_on
end

# This method will install the module under test on the specified host(s) from
# the source on the local machine
def install_module_on(host)
copy_module_to(host,
source: @module_source_dir,
module_name: module_name_from_metadata)
end

# This method will install the module under tests dependencies on the
# specified host
def install_module_dependencies_on(_host, _dependencies)
raise 'Not Implemented Yet'
end

# This method will return array of all masters. If no masters exist, it will
# return all agent nodes. If no nodes tagged master or agent exist, all nodes
# will be returned
def hosts_to_install_module_on
masters = hosts_with_role(hosts, :master)
return masters unless masters.empty?

agents = hosts_with_role(hosts, :agent)
return agents unless agents.empty?

hosts
end

# This method will read the 'name' attribute from metadata.json file and
# remove the first segment. E.g. puppetlabs-vcsrepo -> vcsrepo
def module_name_from_metadata
res = get_module_name module_metadata['name']
raise 'Error getting module name' unless res
res[1]
end

# This method uses the module_source_directory path to read the metadata.json
# file into a json array
def module_metadata
metadata_path = "#{@module_source_dir}/metadata.json"
unless File.exist?(metadata_path)
raise "Error loading metadata.json file from #{@module_source_dir}"
end
JSON.parse(File.read(metadata_path))
end

# Use this property to store the module_source_dir, so we don't traverse
# the tree every time
def get_module_source_directory(search_in)
module_source_dir = nil
# here we go up the file tree and search the directories for a
# valid metadata.json
while module_source_dir.nil? && search_in.length > 1
# remove last segment (file or folder, doesn't matter)
search_in = search_in.split('/')[0...-1].join('/')
module_source_dir = search_in if File.exist?("#{search_in}/metadata.json")
end
module_source_dir
end
end

include Beaker::ModuleInstallHelper
# Use the caller (requirer) of this file to begin search for module source dir
@module_source_dir = get_module_source_directory caller[0][/[^:]+/]
83 changes: 79 additions & 4 deletions spec/unit/beaker/module_install_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,87 @@
require 'spec_helper'

describe 'ModuleInstallHelper' do
describe Beaker::ModuleInstallHelper do
context 'hosts_to_install_module_on with split master/agent setup' do
let(:hosts) do
[
{ 'roles' => %w(master database dashboard classifier) },
{ 'roles' => ['agent'] }
]
end

it 'returns a node with master role' do
expect(hosts_to_install_module_on.first['roles']).to include 'master'
end
end

context 'hosts_to_install_module_on with split master/agent setup' do
let(:hosts) { [{ 'roles' => ['agent'] }] }

it 'returns a node with master role' do
expect(hosts_to_install_module_on.first['roles']).to include 'agent'
end
end

context 'module_name_from_metadata' do
let(:module_metadata) { { 'name' => 'puppetlabs-vcsrepo' } }

it 'Removes author from name' do
res = module_name_from_metadata
expect(res).to eq('vcsrepo')
end
end

context 'module_metadata' do
before do
@module_source_dir = '/a/b/c/d'
allow(File).to receive(:exist?).and_return(true)
allow(File).to receive(:read).and_return('{"name": "puppetlabs-vcsrepo"}')
end

it 'Returns hash with correct data' do
expect(module_metadata['name']).to eq('puppetlabs-vcsrepo')
end
end

context 'get_module_source_directory' do
let(:search_in) { '/a/b/c/d/e/f/g/h.rb' }

before do
allow(File).to receive(:exist?).with(anything).and_return(false)
allow(File).to receive(:exist?).with('/a/metadata.json').and_return(true)
end

it 'traverses file tree until it finds a folder containing metadata.json' do
expect(get_module_source_directory(search_in)).to eq('/a')
end
end

context 'install_module_on' do
it 'raises not implemented error' do
expect { install_module_on(nil) }
.to raise_error /Not Implemented Yet/
let(:module_source_dir) { '/a/b/c/d' }

before do
@module_source_dir = '/a/b/c/d'
allow(File).to receive(:exist?).and_return(true)
allow(File).to receive(:read).and_return('{"name": "puppetlabs-vcsrepo"}')

allow_any_instance_of(Beaker::DSL::InstallUtils::ModuleUtils)
.to receive(:copy_module_to)
.with(anything)
.and_return(false)

allow_any_instance_of(Beaker::DSL::InstallUtils::ModuleUtils)
.to receive(:copy_module_to)
.with(host, source: module_source_dir, module_name: 'vcsrepo')
.and_return(true)
end

let(:host) { { 'roles' => %w(master database dashboard classifier) } }

it 'copy module to given host' do
expect(install_module_on(host)).to be true
end
end

context 'install_module_dependencies_on' do
it 'raises not implemented error' do
expect { install_module_dependencies_on(nil, nil) }
Expand Down

0 comments on commit e489736

Please sign in to comment.