Skip to content

Commit

Permalink
Merge pull request #161 from chef/bugfix-profile
Browse files Browse the repository at this point in the history
Merged change 5ce5796b-e97e-4826-a9de-9848865207af

From review branch bugfix-profile into master

Signed-off-by: chartmann <chartmann@chef.io>
  • Loading branch information
chef-delivery committed Oct 27, 2015
2 parents 44bc61d + 8daf8df commit 6ddc454
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 40 deletions.
24 changes: 12 additions & 12 deletions lib/inspec/metadata.rb
Expand Up @@ -27,38 +27,38 @@ def initialize(logger = nil)
description
version
}.each do |name|
define_method name do |arg|
params[name] = arg
define_method name.to_sym do |arg|
params[name.to_sym] = arg
end
end

def supports(sth, version = nil)
params['supports'] ||= []
params['supports'].push(
params[:supports] ||= []
params[:supports].push(
{
'os' => sth,
'version' => version,
os: sth,
version: version,
},
)
end

def valid?
is_valid = true
%w{ name title version summary }.each do |field|
next unless params[field].nil?
@log.error("Missing profile #{field} in metadata.rb")
next unless params[field.to_sym].nil?
@logger.error("Missing profile #{field} in metadata.rb")
is_valid = false
end
%w{ maintainer copyright }.each do |field|
next unless params[field].nil?
@log.warn("Missing profile #{field} in metadata.rb")
next unless params[field.to_sym].nil?
@logger.warn("Missing profile #{field} in metadata.rb")
is_valid = false
end
is_valid && @missing_methods.empty?
end

def method_missing(sth, *args)
@log.warn "metadata.rb doesn't support: #{sth} #{args}"
@logger.warn "metadata.rb doesn't support: #{sth} #{args}"
@missing_methods.push(sth)
end

Expand All @@ -72,7 +72,7 @@ def self.from_file(path, profile_id, logger = nil)

res = Metadata.new(logger)
res.instance_eval(File.read(path), path, 1)
res.dict['name'] = profile_id.to_s unless profile_id.to_s.empty?
res.params[:name] = profile_id.to_s unless profile_id.to_s.empty?
res
end
end
Expand Down
55 changes: 31 additions & 24 deletions lib/inspec/profile.rb
Expand Up @@ -8,7 +8,8 @@
module Inspec
class Profile
def self.from_path(path, options = nil)
opt = options.dup || {}
opt = {}
options.each { |k, v| opt[k.to_sym] = v } unless options.nil?
opt[:path] = path
Profile.new(opt)
end
Expand All @@ -18,9 +19,9 @@ def self.from_path(path, options = nil)

def initialize(options = nil)
@options = options || {}
@profile_id = options[:id] || nil
@params = {}
@logger = options.delete(:logger) || Logger.new(nil)
@profile_id = options.delete(:profile_id)
@logger = options[:logger] || Logger.new(nil)

@path = @options[:path]
fail 'Cannot read an empty path.' if @path.nil? || @path.empty?
Expand All @@ -29,14 +30,16 @@ def initialize(options = nil)
@metadata = read_metadata
@params = @metadata.params unless @metadata.nil?

@params['rules'] = rules = {}
@params[:rules] = rules = {}
@runner = Runner.new(
id: @profile_id,
backend: :mock,
)
@runner.add_tests([@path])
@runner.rules.each do |id, rule|
rules[id] = {
file = rule.instance_variable_get(:@__file)
rules[file] ||= {}
rules[file][id] = {
title: rule.title,
desc: rule.desc,
impact: rule.impact,
Expand All @@ -49,17 +52,21 @@ def initialize(options = nil)
def info
res = @params.dup
rules = {}
res['rules'].each do |id, rule|
next if id.to_s.empty?

data = rule.dup
data.delete(:checks)
data[:impact] ||= 0.5
data[:impact] = 1.0 if data[:impact] > 1.0
data[:impact] = 0.0 if data[:impact] < 0.0
rules[id] = data
res[:rules].each do |gid, group|
next if gid.to_s.empty?
path = gid.sub(File.join(@path, ''), '')
rules[path] = { title: '', rules: {} }
group.each do |id, rule|
next if id.to_s.empty?
data = rule.dup
data.delete(:checks)
data[:impact] ||= 0.5
data[:impact] = 1.0 if data[:impact] > 1.0
data[:impact] = 0.0 if data[:impact] < 0.0
rules[path][:rules][id] = data
end
end
res['rules'] = rules
res[:rules] = rules
res
end

Expand All @@ -81,26 +88,26 @@ def check # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metri

@logger.info "Checking profile in #{@path}"

if @params['name'].to_s.empty?
if @params[:name].to_s.empty?
error.call('No profile name defined')
elsif !(@params['name'].to_s =~ %r{^\S+\/\S+$})
elsif !(@params[:name].to_s =~ %r{^\S+\/\S+$})
error.call('Profile name must be defined as: OWNER/ID')
end

warn.call('No version defined') if @params['version'].to_s.empty?
warn.call('No title defined') if @params['title'].to_s.empty?
warn.call('No maintainer defined') if @params['maintainer'].to_s.empty?
warn.call('No supports defined') if @params['supports'].empty?
warn.call('No version defined') if @params[:name].to_s.empty?
warn.call('No title defined') if @params[:name].to_s.empty?
warn.call('No maintainer defined') if @params[:name].to_s.empty?
warn.call('No supports defined') if @params[:name].empty?
@logger.info 'Metadata OK.' if no_warnings

no_warnings = true
if @params['rules'].empty?
if @params[:name].empty?
warn.call('No rules were found.')
else
@logger.debug "Found #{@params['rules'].length} rules."
@logger.debug "Found #{@params[:name].length} rules."
end

@params['rules'].each do |id, rule|
@params[:name].each do |id, rule|
error.call('Avoid rules with empty IDs') if id.nil? or id.empty?
warn.call("Rule #{id} has no title") if rule[:title].to_s.empty?
warn.call("Rule #{id} has no description") if rule[:desc].to_s.empty?
Expand Down
2 changes: 2 additions & 0 deletions lib/inspec/profile_context.rb
Expand Up @@ -27,6 +27,7 @@ def initialize(profile_id, backend, profile_registry = {}, only_ifs = [])
end

def load(content, source = nil, line = nil)
@current_file = source
@profile_context.instance_eval(content, source || 'unknown', line || 1)
end

Expand All @@ -37,6 +38,7 @@ def unregister_rule(id)

def register_rule(r)
# get the full ID
r.instance_variable_set(:@__file, @current_file)
full_id = Inspec::Rule.full_id(@profile_id, r)
if full_id.nil?
# TODO: error
Expand Down
11 changes: 9 additions & 2 deletions lib/inspec/rule.rb
Expand Up @@ -26,8 +26,15 @@ def not_to(*args, &block)

def example_group
that = self
outer_clr = calls[0][3]
RSpec::Core::ExampleGroup.describe(that.value, caller: outer_clr) do

opts = { 'caller' => calls[0][3] }
if !calls[0][3].nil? && !calls[0][3].empty? &&
(m = calls[0][3][0].match(/^([^:]*):(\d+):/))
opts['file_path'] = m[0]
opts['line_number'] = m[1]
end

RSpec::Core::ExampleGroup.describe(that.value, opts) do
that.calls.each do |method, args, block, clr|
it(nil, caller: clr) do
x = expect(that.value, &that.block).method(method)
Expand Down
11 changes: 9 additions & 2 deletions lib/inspec/runner.rb
Expand Up @@ -83,17 +83,24 @@ def run_with(rspec_runner)
private

def get_check_example(method_name, arg, block)
opts = {}
if !block.nil? && block.respond_to?(:source_location)
file_path, line = block.source_location
opts['file_path'] = file_path
opts['line_number'] = line
end

if !arg.empty? &&
arg[0].respond_to?(:resource_skipped) &&
!arg[0].resource_skipped.nil?
return RSpec::Core::ExampleGroup.describe(*arg) do
return RSpec::Core::ExampleGroup.describe(*arg, opts) do
it arg[0].resource_skipped
end
else
# add the resource
case method_name
when 'describe'
return RSpec::Core::ExampleGroup.describe(*arg, &block)
return RSpec::Core::ExampleGroup.describe(*arg, opts, &block)
when 'expect'
return block.example_group
else
Expand Down
1 change: 1 addition & 0 deletions test/helper.rb
Expand Up @@ -15,6 +15,7 @@

require 'inspec/resource'
require 'inspec/backend'
require 'inspec/profile'

class MockLoader
# pass the os identifier to emulate a specific operating system
Expand Down
Empty file.
1 change: 1 addition & 0 deletions test/unit/mock/profiles/metadata/metadata.rb
@@ -0,0 +1 @@
name 'metadata profile'
49 changes: 49 additions & 0 deletions test/unit/profile_test.rb
@@ -0,0 +1,49 @@
# encoding: utf-8
# author: Christoph Hartmann
# author: Dominik Richter

require 'helper'

def load_profile(name)
pwd = File.dirname(__FILE__)
Inspec::Profile.from_path("#{pwd}/mock/profiles/#{name}")
end

describe Inspec::Profile do
before {
# mock up the profile runner
# TODO: try to take the real profile runner here;
# currently it's stopped at test runner conflicts
class Inspec::Profile::Runner
def initialize(opts) end
def add_tests(tests) end
def rules
{}
end
end
}

describe 'with empty profile' do
let(:profile) { load_profile('empty') }

it 'has no metadata' do
profile.params[:name].must_be_nil
end

it 'has no rules' do
profile.params[:rules].must_equal({})
end
end

describe 'with normal metadata in profile' do
let(:profile) { load_profile('metadata') }

it 'has metadata' do
profile.params[:name].must_equal 'metadata profile'
end

it 'has no rules' do
profile.params[:rules].must_equal({})
end
end
end

0 comments on commit 6ddc454

Please sign in to comment.