cookbooks/fb_chef_hints/spec/default_spec.rb (265 lines of code) (raw):
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
#
# Copyright (c) 2020-present, Facebook, Inc.
# All rights reserved.
#
# 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 '../libraries/chef_hints_helpers.rb'
require_relative '../../fb_helpers/libraries/fb_helpers.rb'
require 'chef/node'
describe FB::ChefHints do
context 'valid_hints?' do
it 'returns false if source is missing' do
hint = {
'hint' => {
'foo' => 1,
},
}
expect(FB::ChefHints.valid_hints?(hint)).to eq(false)
end
it 'returns false if hint is missing' do
expect(FB::ChefHints.valid_hints?({ 'source' => 'foo' })).
to eq(false)
end
it 'returns false if source is not allowed' do
hint = {
'source' => 'foo',
'hint' => {
'foo' => 1,
},
}
expect(FB::ChefHints.valid_hints?(hint)).to eq(false)
end
it 'returns true if source is allowed' do
hint = {
'source' => 'foo',
'hint' => {
'foo' => 1,
},
}
expect(FB::ChefHints.valid_hints?(hint, ['foo'])).
to eq(true)
end
end
context 'apply_hints' do
it 'skips a hint if source is not allowed' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = [].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => 0,
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = 1
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(1)
end
it 'skips a hint if hint is not allowed' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = [].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => 0,
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = 1
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(1)
end
it 'sets an allowed leaf Integer attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => 0,
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = 1
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(0)
end
it 'sets an allowed leaf String attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => 'pie',
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = 'cake'
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq('pie')
end
it 'sets an allowed leaf Array attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => ['pie'],
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = ['cake']
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(['pie'])
end
it 'sets an allowed leaf Hash attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => { 'pie' => 1 },
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = { 'cake' => 1 }
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq({ 'pie' => 1 })
end
it 'clears an allowed leaf Array attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => [],
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = ['cake']
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq([])
end
it 'clears an allowed leaf Hash attribute hint' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => {},
},
},
}
node = Chef::Node.new
node.default['foo']['bar'] = { 'cake' => 1 }
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq({})
end
it 'leaves attributes unchanged if filter does not match' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo/bar/cake'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => {
'pie' => {
'baz' => 1,
},
},
},
},
}
node = Chef::Node.new
node.default['foo']['bar']['pie']['baz'] = 1
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']['pie']['baz']).to eq(1)
end
it 'does not clobber other attributes in the hash when setting a int' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo/bar'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => 1,
},
},
}
node = Chef::Node.new
node.default['foo']['cake'] = 2
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(hint['hint']['foo']['bar'])
expect(node['foo']['cake']).to eq(2)
end
it 'does not clobber other attributes in the hash when setting an array' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo/bar'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => [1, 2, 3],
},
},
}
node = Chef::Node.new
node.default['foo']['cake'] = 2
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(hint['hint']['foo']['bar'])
expect(node['foo']['cake']).to eq(2)
end
it 'does not clobber other attributes in the hash when setting a hash' do
FB::ChefHintsSiteData::ALLOWED_SOURCES = ['chefspec'].freeze
FB::ChefHintsSiteData::ALLOWED_HINTS = ['foo/bar'].freeze
hint = {
'source' => 'chefspec',
'hint' => {
'foo' => {
'bar' => {
'baz' => 1,
},
},
},
}
node = Chef::Node.new
node.default['foo']['cake'] = 2
allow(FB::Helpers).to receive(:parse_json_file).
with('hint.json', Hash, true).and_return(hint)
FB::ChefHints.apply_hint(node, 'hint.json')
expect(node['foo']['bar']).to eq(hint['hint']['foo']['bar'])
expect(node['foo']['cake']).to eq(2)
end
end
end