Add a new custom matcher render_config_file to test ini file content
After this, you can use below way to test ini file content: render_config_file(file).with_section_content(section, content) Change-Id: Iaed80a3fc61db02324fb2c8166b7032fd1823f60
This commit is contained in:
parent
47ba1660b9
commit
d99aacda7c
|
@ -11,6 +11,7 @@ This file is used to list changes made in each version of cookbook-openstack-com
|
|||
* Add OS_VOLUME_API_VERSION for openrc
|
||||
* Removed the hardcoded PPA reference to "Precise"
|
||||
* Added an optional automatic apt-get update for Debian based repos
|
||||
* Add a new custom matcher render_config_file to test ini file content
|
||||
|
||||
## 10.1.0
|
||||
* Adding identity admin bind host endpoint to allow flexibility and consistency
|
||||
|
|
|
@ -121,6 +121,7 @@ This cookbook exposes a set of default library routines:
|
|||
* `db_create_with_user` -- Creates a database and database user for a named OpenStack database
|
||||
* `secret` -- Returns the value of an encrypted data bag for a named OpenStack secret key and key-section
|
||||
* `get_password` -- Ease-of-use helper that returns the decrypted password for a named database, service or keystone user.
|
||||
* `matchers` -- A custom matcher(render_config_file) for testing ini format file section content by with_section_content.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
# encoding: UTF-8
|
||||
|
||||
if defined?(ChefSpec)
|
||||
|
||||
#
|
||||
# Test method for ini format file
|
||||
#
|
||||
# Example file content:
|
||||
#
|
||||
# [section1]
|
||||
# option1 = value1
|
||||
# option2 = value2
|
||||
# [section2]
|
||||
# option1 = value2
|
||||
#
|
||||
# Example custom matcher that can be called in other
|
||||
# dependends cookbooks.
|
||||
#
|
||||
# render_config_file(path).with_section_content(
|
||||
# 'section1', 'option1 = value1')
|
||||
# render_config_file(path).with_section_content(
|
||||
# 'section1', /^option2 = value2$/)
|
||||
#
|
||||
def render_config_file(path)
|
||||
RenderConfigFileMatcher.new(path)
|
||||
end
|
||||
|
||||
#
|
||||
# Extend the RenderFileMatcher as RenderConfigFileMatcher,
|
||||
# add a new method with_section_content for ini format file.
|
||||
#
|
||||
class RenderConfigFileMatcher < ChefSpec::Matchers::RenderFileMatcher
|
||||
def with_section_content(section, expected_content)
|
||||
@section = section
|
||||
@expected_content = expected_content
|
||||
self
|
||||
end
|
||||
|
||||
# rubocop:disable MethodLength, CyclomaticComplexity
|
||||
def matches_content?
|
||||
def section?(line, section = '.*')
|
||||
if line =~ /^[ \t]*\[#{section}\]/
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def get_section_content(content, section)
|
||||
match = false
|
||||
section_content = ''
|
||||
content.split("\n").each do |line|
|
||||
if section?(line, section)
|
||||
match = true
|
||||
next
|
||||
end
|
||||
|
||||
section_content << "#{line}\n" if match == true && !section?(line)
|
||||
|
||||
break if match == true && section?(line)
|
||||
end
|
||||
section_content
|
||||
end
|
||||
|
||||
return true if @expected_content.nil?
|
||||
|
||||
@actual_content = ChefSpec::Renderer.new(@runner, resource).content
|
||||
|
||||
unless @actual_content.nil?
|
||||
unless @section.nil?
|
||||
@actual_content = get_section_content(@actual_content, @section)
|
||||
end
|
||||
end
|
||||
|
||||
return false if @actual_content.nil?
|
||||
|
||||
if @expected_content.is_a?(Regexp)
|
||||
@actual_content =~ @expected_content
|
||||
elsif RSpec::Matchers.is_a_matcher?(@expected_content)
|
||||
@expected_content.matches?(@actual_content)
|
||||
else
|
||||
@actual_content.include?(@expected_content)
|
||||
end
|
||||
end
|
||||
# rubocop:enable MethodLength, CyclomaticComplexity
|
||||
end
|
||||
end
|
|
@ -18,5 +18,6 @@ end
|
|||
|
||||
depends 'apt', '>= 2.3.8'
|
||||
depends 'database', '>= 2.0.0'
|
||||
depends 'mysql', '< 6.0.0'
|
||||
depends 'yum', '>= 3.1.4'
|
||||
depends 'yum-epel', '>= 0.3.4'
|
||||
|
|
|
@ -46,155 +46,200 @@ describe 'openstack-common::logging' do
|
|||
'ignore.key.1' => 'ignore.value.1',
|
||||
'ignore.key.2' => 'ignore.value.2'
|
||||
}
|
||||
[
|
||||
/^\[loggers\]$/,
|
||||
/^keys=.*ignore_key_1,ignore_key_2$/
|
||||
].each do |content|
|
||||
expect(chef_run).to render_file(file.name).with_content(content)
|
||||
end
|
||||
expect(chef_run).to render_config_file(file.name)
|
||||
.with_section_content('loggers', /^keys=.*ignore_key_1,ignore_key_2$/)
|
||||
end
|
||||
|
||||
it 'adds specific logger ignore block' do
|
||||
node.set['openstack']['logging']['ignore'] = {
|
||||
'test.nova.api.openstack.wsgi' => 'WARNING'
|
||||
}
|
||||
content = [
|
||||
'[logger_test_nova_api_openstack_wsgi]',
|
||||
[
|
||||
'level = WARNING',
|
||||
'handlers = prod,debug',
|
||||
'qualname = test.nova.api.openstack.wsgi'
|
||||
]
|
||||
expect(chef_run).to render_file(file.name).with_content(build_section(content))
|
||||
].each do |line|
|
||||
expect(chef_run).to render_config_file(file.name)
|
||||
.with_section_content('logger_test_nova_api_openstack_wsgi', line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'loggers' do
|
||||
it 'adds default loggers' do
|
||||
[
|
||||
['[loggers]',
|
||||
'keys=root,ceilometer,cinder,glance,horizon,keystone,nova,'\
|
||||
'neutron,swift,trove,amqplib,sqlalchemy,boto,suds,eventletwsgi,'\
|
||||
'nova_api_openstack_wsgi,nova_osapi_compute_wsgi_server'],
|
||||
['[logger_root]',
|
||||
'level=NOTSET',
|
||||
'handlers=devel'],
|
||||
['[logger_ceilometer]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=ceilometer'],
|
||||
['[logger_cinder]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=cinder'],
|
||||
['[logger_glance]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=glance'],
|
||||
['[logger_horizon]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=horizon'],
|
||||
['[logger_keystone]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=keystone'],
|
||||
['[logger_nova]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova'],
|
||||
['[logger_neutron]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=neutron'],
|
||||
['[logger_swift]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=swift'],
|
||||
['[logger_trove]',
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=trove'],
|
||||
['[logger_amqplib]',
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=amqplib'],
|
||||
['[logger_sqlalchemy]',
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=sqlalchemy'],
|
||||
['[logger_boto]',
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=boto'],
|
||||
['[logger_suds]',
|
||||
'level=INFO',
|
||||
'handlers=stderr',
|
||||
'qualname=suds'],
|
||||
['[logger_eventletwsgi]',
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=eventlet.wsgi.server'],
|
||||
['[logger_nova_api_openstack_wsgi]',
|
||||
'level=WARNING',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova.api.openstack.wsgi'],
|
||||
['[logger_nova_osapi_compute_wsgi_server]',
|
||||
'level=WARNING',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova.osapi_compute.wsgi.server']
|
||||
].each do |content|
|
||||
expect(chef_run).to render_file(file.name).with_content(build_section(content))
|
||||
{
|
||||
'loggers' =>
|
||||
[
|
||||
'keys=root,ceilometer,cinder,glance,horizon,keystone,nova,'\
|
||||
'neutron,swift,trove,amqplib,sqlalchemy,boto,suds,eventletwsgi,'\
|
||||
'nova_api_openstack_wsgi,nova_osapi_compute_wsgi_server'
|
||||
],
|
||||
'logger_root' =>
|
||||
[
|
||||
'level=NOTSET',
|
||||
'handlers=devel'
|
||||
],
|
||||
'logger_ceilometer' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=ceilometer'
|
||||
],
|
||||
'logger_cinder' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=cinder'
|
||||
],
|
||||
'logger_glance' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=glance'
|
||||
],
|
||||
'logger_horizon' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=horizon'
|
||||
],
|
||||
'logger_keystone' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=keystone'
|
||||
],
|
||||
'logger_nova' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova'
|
||||
],
|
||||
'logger_neutron' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=neutron'
|
||||
],
|
||||
'logger_swift' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=swift'
|
||||
],
|
||||
'logger_trove' =>
|
||||
[
|
||||
'level=DEBUG',
|
||||
'handlers=prod,debug',
|
||||
'qualname=trove'
|
||||
],
|
||||
'logger_amqplib' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=amqplib'
|
||||
],
|
||||
'logger_sqlalchemy' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=sqlalchemy'
|
||||
],
|
||||
'logger_boto' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=boto'
|
||||
],
|
||||
'logger_suds' =>
|
||||
[
|
||||
'level=INFO',
|
||||
'handlers=stderr',
|
||||
'qualname=suds'
|
||||
],
|
||||
'logger_eventletwsgi' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=stderr',
|
||||
'qualname=eventlet.wsgi.server'
|
||||
],
|
||||
'logger_nova_api_openstack_wsgi' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova.api.openstack.wsgi'
|
||||
],
|
||||
'logger_nova_osapi_compute_wsgi_server' =>
|
||||
[
|
||||
'level=WARNING',
|
||||
'handlers=prod,debug',
|
||||
'qualname=nova.osapi_compute.wsgi.server'
|
||||
]
|
||||
}.each do |section, content|
|
||||
content.each do |line|
|
||||
expect(chef_run).to render_config_file(file.name).with_section_content(section, line)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'formatters' do
|
||||
it 'adds default formatters' do
|
||||
[
|
||||
['[formatters]',
|
||||
'keys=normal,normal_with_name,debug,syslog_with_name,syslog_debug'],
|
||||
['[formatter_normal]',
|
||||
'format=%(asctime)s %(levelname)s %(message)s'],
|
||||
['[formatter_normal_with_name]',
|
||||
'format=[%(name)s]: %(asctime)s %(levelname)s %(message)s'],
|
||||
['[formatter_debug]',
|
||||
'format=[%(name)s]: %(asctime)s %(levelname)s %(module)s.%(funcName)s %(message)s'],
|
||||
['[formatter_syslog_with_name]',
|
||||
'format=%(name)s: %(levelname)s %(message)s'],
|
||||
['[formatter_syslog_debug]',
|
||||
'format=%(name)s: %(levelname)s %(module)s.%(funcName)s %(message)s']
|
||||
].each do |content|
|
||||
expect(chef_run).to render_file(file.name).with_content(build_section(content))
|
||||
{
|
||||
'formatters' =>
|
||||
'keys=normal,normal_with_name,debug,syslog_with_name,syslog_debug',
|
||||
'formatter_normal' =>
|
||||
'format=%(asctime)s %(levelname)s %(message)s',
|
||||
'formatter_normal_with_name' =>
|
||||
'format=[%(name)s]: %(asctime)s %(levelname)s %(message)s',
|
||||
'formatter_debug' =>
|
||||
'format=[%(name)s]: %(asctime)s %(levelname)s %(module)s.%(funcName)s %(message)s',
|
||||
'formatter_syslog_with_name' =>
|
||||
'format=%(name)s: %(levelname)s %(message)s',
|
||||
'formatter_syslog_debug' =>
|
||||
'format=%(name)s: %(levelname)s %(module)s.%(funcName)s %(message)s'
|
||||
}.each do |section, content|
|
||||
expect(chef_run).to render_config_file(file.name).with_section_content(section, content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'handlers' do
|
||||
it 'adds default handlers' do
|
||||
[
|
||||
['[handlers]',
|
||||
'keys=stderr,devel,prod,debug'],
|
||||
['[handler_stderr]',
|
||||
'args=(sys.stderr,)',
|
||||
'class=StreamHandler',
|
||||
'formatter=debug'],
|
||||
['[handler_devel]',
|
||||
'args=(sys.stdout,)',
|
||||
'class=StreamHandler',
|
||||
'formatter=debug',
|
||||
'level=NOTSET'],
|
||||
['[handler_prod]',
|
||||
"args=(('/dev/log'), handlers.SysLogHandler.LOG_LOCAL0)",
|
||||
'class=handlers.SysLogHandler',
|
||||
'formatter=syslog_with_name',
|
||||
'level=INFO'],
|
||||
['[handler_debug]',
|
||||
"args=(('/dev/log'), handlers.SysLogHandler.LOG_LOCAL1)",
|
||||
'class=handlers.SysLogHandler',
|
||||
'formatter=syslog_debug',
|
||||
'level=DEBUG']
|
||||
].each do |content|
|
||||
expect(chef_run).to render_file(file.name).with_content(build_section(content))
|
||||
{
|
||||
'handlers' =>
|
||||
['keys=stderr,devel,prod,debug'],
|
||||
'handler_stderr' =>
|
||||
[
|
||||
'args=(sys.stderr,)',
|
||||
'class=StreamHandler',
|
||||
'formatter=debug'
|
||||
],
|
||||
'handler_devel' =>
|
||||
[
|
||||
'args=(sys.stdout,)',
|
||||
'class=StreamHandler',
|
||||
'formatter=debug',
|
||||
'level=NOTSET'
|
||||
],
|
||||
'handler_prod' =>
|
||||
[
|
||||
"args=(('/dev/log'), handlers.SysLogHandler.LOG_LOCAL0)",
|
||||
'class=handlers.SysLogHandler',
|
||||
'formatter=syslog_with_name',
|
||||
'level=INFO'
|
||||
],
|
||||
'handler_debug' =>
|
||||
[
|
||||
"args=(('/dev/log'), handlers.SysLogHandler.LOG_LOCAL1)",
|
||||
'class=handlers.SysLogHandler',
|
||||
'formatter=syslog_debug',
|
||||
'level=DEBUG'
|
||||
]
|
||||
}.each do |section, content|
|
||||
content.each do |line|
|
||||
expect(chef_run).to render_config_file(file.name).with_section_content(section, line)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,12 +23,6 @@ SUSE_OPTS = {
|
|||
# We set a default platform for non-platform specific test cases
|
||||
CHEFSPEC_OPTS = UBUNTU_OPTS
|
||||
|
||||
# Build a regex for a section of lines
|
||||
def build_section(lines)
|
||||
lines.map! { |line| Regexp.quote(line) }
|
||||
/^#{lines.join('\n')}/
|
||||
end
|
||||
|
||||
shared_context 'library-stubs' do
|
||||
before do
|
||||
allow(subject).to receive(:node).and_return(chef_run.node)
|
||||
|
|
Loading…
Reference in New Issue