Skip to content

Commit

Permalink
Move the ruby_block[apply config] logic to a library, including tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zuazo committed Sep 17, 2015
1 parent a6657a0 commit e20824b
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 25 deletions.
62 changes: 62 additions & 0 deletions libraries/cookbook_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# `owncloud` cookbook internal classes.
module OwncloudCookbook
# Some helpers to use from `owncloud` cookbook recipes or resources.
module CookbookHelpers
def owncloud_config_file
::File.join(node['owncloud']['dir'], 'config', 'config.php')
end

def owncloud_config
@owncloud_config ||= OwncloudCookbook::Config.new(owncloud_config_file)
end

def owncloud_cookbook_config
@owncloud_cookbook_config ||= node['owncloud']['config'].to_hash
end

def owncloud_trusted_domains
[
node['owncloud']['server_name'], node['owncloud']['server_aliases']
].flatten
end

# Add server name and server aliases to trusted_domains config option.
def calculate_trusted_domains
unless owncloud_cookbook_config.key?('trusted_domains')
owncloud_cookbook_config['trusted_domains'] = []
end
owncloud_trusted_domains.each do |domain|
next if owncloud_cookbook_config['trusted_domains'].include?(domain)
owncloud_cookbook_config['trusted_domains'] << domain
end
end

def calculate_dbhost
owncloud_cookbook_config['dbhost'] =
[
owncloud_cookbook_config['dbhost'], owncloud_cookbook_config['dbport']
].join(':')
end

def owncloud_config_update
owncloud_config.merge(owncloud_cookbook_config)
owncloud_config.write
owncloud_config
end

# Store important options that where generated automatically by the setup.
def save_owncloud_node_configuration
return if Chef::Config[:solo]
%w(passwordsalt instanceid).each do |value|
node.set_unless['owncloud']['config'][value] = owncloud_config[value]
end
end

def apply_owncloud_configuration
calculate_trusted_domains
calculate_dbhost
owncloud_config_update
save_owncloud_node_configuration
end
end
end
27 changes: 2 additions & 25 deletions recipes/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -388,31 +388,8 @@
# Apply the configuration on attributes to config.php
ruby_block 'apply config' do
block do
config_file = ::File.join(node['owncloud']['dir'], 'config', 'config.php')
config = OwncloudCookbook::Config.new(config_file)
cookbook_config = node['owncloud']['config'].to_hash
# Add server name and server aliases to trusted_domains config option
unless cookbook_config.key?('trusted_domains')
cookbook_config['trusted_domains'] = []
end
[
node['owncloud']['server_name'], node['owncloud']['server_aliases']
].flatten.each do |domain|
next if cookbook_config['trusted_domains'].include?(domain)
cookbook_config['trusted_domains'] << domain
end
cookbook_config['dbhost'] =
"#{cookbook_config['dbhost']}:#{cookbook_config['dbport']}"
config.merge(cookbook_config)
config.write
unless Chef::Config[:solo]
# store important options that where generated automatically by the setup
node.set_unless['owncloud']['config']['passwordsalt'] =
config['passwordsalt']
node.set_unless['owncloud']['config']['instanceid'] =
config['instanceid']
node.save
end
self.class.send(:include, OwncloudCookbook::CookbookHelpers)
apply_owncloud_configuration
end
only_if do
::File.exist?(::File.join(node['owncloud']['dir'], 'config', 'config.php'))
Expand Down
208 changes: 208 additions & 0 deletions test/unit/libraries/cookbook_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
# encoding: UTF-8
#
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
# 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_relative '../spec_helper'
require_relative '../support/fake_recipe'
require 'cookbook_helpers'
require 'config'

describe OwncloudCookbook::CookbookHelpers, order: :random do
subject { FakeRecipe.new }
let(:node) { subject.node }
let(:config_file) { '/var/www/owncloud/config/config.php' }
before do
node.set['owncloud']['dir'] = '/var/www/owncloud'
allow(::File).to receive(:exist?).and_call_original
allow(::File).to receive(:exist?).with(config_file).and_return(false)
end

context '#owncloud_config_file' do
it 'returns ownCloud configuration file' do
expect(subject.owncloud_config_file).to eq(config_file)
end
end

context '#owncloud_config' do
it 'returns an OwncloudCookbook::Config instance' do
expect(::File).to receive(:exist?).with(config_file).and_return(false)
expect(subject.owncloud_config).to be_a(OwncloudCookbook::Config)
end

it 'passes the file path to OwncloudCookbook::Config' do
expect(OwncloudCookbook::Config)
.to receive(:new).once.and_return(config_file)
subject.owncloud_config
end
end

context '#owncloud_cookbook_config' do
it 'returns a hash' do
expect(subject.owncloud_cookbook_config).to be_instance_of(Hash)
end

it 'does not return a mash' do
expect(subject.owncloud_cookbook_config).to_not be_instance_of(Mash)
end

it 'has the same value as node["owncloud"]["config"]' do
expect(subject.owncloud_cookbook_config).to eq(node['owncloud']['config'])
end

it 'is not the same hash as node["owncloud"]["config"]' do
expect(subject.owncloud_cookbook_config)
.to_not equal(node['owncloud']['config'])
end
end # context #owncloud_cookbook_config

context '#owncloud_trusted_domains' do
let(:server_name) { 'servername1' }
let(:server_aliases) { %w(serveralias1 serveralias2) }
before do
node.set['owncloud']['server_name'] = server_name
node.set['owncloud']['server_aliases'] = server_aliases
end

it 'returns server name and server aliases' do
expect(subject.owncloud_trusted_domains)
.to eq(%w(servername1 serveralias1 serveralias2))
end
end

context '#calculate_trusted_domains' do
let(:server_name) { 'servername1' }
let(:server_aliases) { %w(serveralias1 serveralias2) }
before do
node.set['owncloud']['server_name'] = server_name
node.set['owncloud']['server_aliases'] = server_aliases
end

it 'sets owncloud trusted_domains configuration' do
subject.calculate_trusted_domains
expect(subject.owncloud_cookbook_config['trusted_domains'].sort)
.to eq(%w(servername1 serveralias1 serveralias2).sort)
end

it 'does not duplicate domains' do
node.set['owncloud']['config']['trusted_domains'] = [server_aliases[0]]
subject.calculate_trusted_domains
expect(subject.owncloud_cookbook_config['trusted_domains'].sort)
.to eq(%w(servername1 serveralias1 serveralias2).sort)
end
end # context #calculate_trusted_domains

context '#calculate_dbhost' do
let(:dbhost) { 'mydbhost' }
let(:dbport) { 'mydbport' }
before do
node.set['owncloud']['config']['dbhost'] = dbhost
node.set['owncloud']['config']['dbport'] = dbport
end

it 'returns database address' do
expect(subject.calculate_dbhost).to eq("#{dbhost}:#{dbport}")
end
end

context '#owncloud_config_update' do
let(:owncloud_config) { instance_double('OwncloudCookbook::Config') }
before do
allow(OwncloudCookbook::Config)
.to receive(:new).and_return(owncloud_config)
allow(owncloud_config).to receive(:merge)
allow(owncloud_config).to receive(:write)
end

it 'merges the configuration' do
expect(owncloud_config)
.to receive(:merge).with(subject.owncloud_cookbook_config).once
subject.owncloud_config_update
end

it 'writes the configuration' do
expect(owncloud_config).to receive(:write).with(no_args).once
subject.owncloud_config_update
end

it 'returns the owncloud configuration' do
expect(subject.owncloud_config_update).to equal(owncloud_config)
end
end # context #owncloud_config_update

context '#save_owncloud_node_configuration' do
let(:salt) { 'salt1' }
let(:id) { 'id1' }
let(:owncloud_config) { instance_double('OwncloudCookbook::Config') }
before do
allow(OwncloudCookbook::Config)
.to receive(:new).and_return(owncloud_config)
allow(owncloud_config)
.to receive(:[]).with('passwordsalt').and_return(salt)
allow(owncloud_config).to receive(:[]).with('instanceid').and_return(id)
end

context 'in Chef Solo' do
before { Chef::Config[:solo] = true }

it 'does not save the password salt' do
subject.save_owncloud_node_configuration
expect(node['owncloud']['config']['passwordsalt']).to_not eq(salt)
end

it 'does not save the instance id' do
subject.save_owncloud_node_configuration
expect(node['owncloud']['config']['instanceid']).to_not eq(id)
end
end

context 'in Chef Server' do
before { Chef::Config[:solo] = false }

it 'saves the password salt' do
subject.save_owncloud_node_configuration
expect(node['owncloud']['config']['passwordsalt']).to eq(salt)
end

it 'does not save the instance id' do
subject.save_owncloud_node_configuration
expect(node['owncloud']['config']['instanceid']).to eq(id)
end
end
end # context #save_owncloud_node_configuration

context '#apply_owncloud_configuration' do
methods = %w(
calculate_trusted_domains
calculate_dbhost
owncloud_config_update
save_owncloud_node_configuration
)
before do
methods.each do |meth|
allow(subject).to receive(meth).with(no_args)
end
end
after { subject.apply_owncloud_configuration }

methods.each do |meth|
it "calls ##{meth} method" do
expect(subject).to receive(meth).with(no_args).once
end
end
end
end
35 changes: 35 additions & 0 deletions test/unit/support/fake_recipe.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# encoding: UTF-8
#
# Author:: Xabier de Zuazo (<xabier@zuazo.org>)
# Copyright:: Copyright (c) 2015 Xabier de Zuazo
# 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 'chef/node'
require 'cookbook_helpers'

# Class to emulate the current recipe with some helpers.
class FakeRecipe < ::Chef::Node
include ::OwncloudCookbook::CookbookHelpers

def initialize
super
name('node001')
node = self
Dir.glob("#{::File.dirname(__FILE__)}/../../../attributes/*.rb") do |f|
node.from_file(f)
end
end
end

0 comments on commit e20824b

Please sign in to comment.