Skip to content

Commit

Permalink
Extract ProvidesMap and tests to their own files
Browse files Browse the repository at this point in the history
Also eliminates redundant tests in other classes that primarily test
ProvidesMap behavior. Higher-level tests have been left in place to
verify the interaction of the components.
  • Loading branch information
danielsdeleo committed Dec 4, 2013
1 parent d36dc76 commit 93967ce
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 211 deletions.
105 changes: 105 additions & 0 deletions lib/ohai/provides_map.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#
# Author:: Adam Jacob (<adam@opscode.com>)
# Author:: Daniel DeLeo (<dan@opscode.com>)
# Copyright:: Copyright (c) 2008, 2013 Opscode, Inc.
# 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 'ohai/mash'
require 'ohai/exception'
require 'ohai/mixin/os'
require 'ohai/dsl/plugin'

module Ohai
class ProvidesMap

attr_reader :map

def initialize
@map = Mash.new
end

def set_providers_for(plugin, provided_attributes)
unless plugin.kind_of?(Ohai::DSL::Plugin)
raise ArgumentError, "set_providers_for only accepts Ohai Plugin classes (got: #{plugin})"
end
provided_attributes.each do |attr|
parts = attr.split('/')
a = map
unless parts.length == 0
parts.shift if parts[0].length == 0
parts.each do |part|
a[part] ||= Mash.new
a = a[part]
end
end

a[:_plugins] ||= []
a[:_plugins] << plugin
end
end

def find_providers_for(attributes)
plugins = []
attributes.each do |attribute|
attrs = map
parts = attribute.split('/')
parts.each do |part|
next if part == Ohai::Mixin::OS.collect_os
raise Ohai::Exceptions::AttributeNotFound, "Cannot find plugin providing attribute \'#{attribute}\'" unless attrs[part]
attrs = attrs[part]
end
plugins << attrs[:_plugins]
plugins.flatten!
end
plugins.uniq
end


def all_plugins
collected = []
collect_plugins_in(map, collected).uniq
end

# TODO: change this to has_provider? or something domain specific.
def has_key?(key)
@map.has_key?(key)
end

# TODO: refactor out direct access to the map (mostly only occurs in test code)
def [](key)
@map[key]
end

# TODO: refactor out direct access to the map (mostly only occurs in test code)
def []=(key, value)
@map[key] = value
end

private

def collect_plugins_in(provides_map, collected)
provides_map.keys.each do |plugin|
if plugin.eql?("_plugins")
collected.concat(provides_map[plugin])
else
collect_plugins_in(provides_map[plugin], collected)
end
end
collected
end
end
end

1 change: 1 addition & 0 deletions lib/ohai/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

module Ohai
class Runner

# safe_run: set to true if this runner will run plugins in
# safe-mode. default false.
def initialize(controller, safe_run = false)
Expand Down
80 changes: 1 addition & 79 deletions lib/ohai/system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,91 +25,13 @@
require 'ohai/mixin/command'
require 'ohai/mixin/os'
require 'ohai/mixin/string'
require 'ohai/provides_map'
require 'mixlib/shellout'

require 'yajl'

module Ohai

class ProvidesMap

attr_reader :map

def initialize
@map = Mash.new
end

def set_providers_for(plugin, provided_attributes)
unless plugin.kind_of?(Ohai::DSL::Plugin)
raise ArgumentError, "set_providers_for only accepts Ohai Plugin classes (got: #{plugin})"
end
provided_attributes.each do |attr|
parts = attr.split('/')
a = map
unless parts.length == 0
parts.shift if parts[0].length == 0
parts.each do |part|
a[part] ||= Mash.new
a = a[part]
end
end

a[:_plugins] ||= []
a[:_plugins] << plugin
end
end

def find_providers_for(attributes)
plugins = []
attributes.each do |attribute|
attrs = map
parts = attribute.split('/')
parts.each do |part|
next if part == Ohai::Mixin::OS.collect_os
raise Ohai::Exceptions::AttributeNotFound, "Cannot find plugin providing attribute \'#{attribute}\'" unless attrs[part]
attrs = attrs[part]
end
plugins << attrs[:_plugins]
plugins.flatten!
end
plugins.uniq
end


def all_plugins
collected = []
collect_plugins_in(map, collected).uniq
end

# TODO: change this to has_provider? or something domain specific.
def has_key?(key)
@map.has_key?(key)
end

# TODO: refactor out direct access to the map (mostly only occurs in test code)
def [](key)
@map[key]
end

# TODO: refactor out direct access to the map (mostly only occurs in test code)
def []=(key, value)
@map[key] = value
end

private

def collect_plugins_in(provides_map, collected)
provides_map.keys.each do |plugin|
if plugin.eql?("_plugins")
collected.concat(provides_map[plugin])
else
collect_plugins_in(provides_map[plugin], collected)
end
end
collected
end
end

class System
attr_accessor :data
attr_reader :attributes
Expand Down
110 changes: 110 additions & 0 deletions spec/unit/provides_map_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#
# Author:: Daniel DeLeo (<dan@opscode.com>)
# Copyright:: Copyright (c) 2013 Opscode, Inc.
# 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 expressed or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License
#

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')

describe Ohai::ProvidesMap do

let(:ohai_system) { Ohai::System.new }
let(:provides_map) { Ohai::ProvidesMap.new }
let(:plugin_1) { Ohai::DSL::Plugin.new(ohai_system, "") }
let(:plugin_2) { Ohai::DSL::Plugin.new(ohai_system, "") }
let(:plugin_3) { Ohai::DSL::Plugin.new(ohai_system, "") }
let(:plugin_4) { Ohai::DSL::Plugin.new(ohai_system, "") }

describe "when looking up providing plugins for a single attribute" do
describe "when only one plugin provides the attribute" do
before do
provides_map.set_providers_for(plugin_1, ["single"])
end

it "should return the provider" do
expect(provides_map.find_providers_for(["single"])).to eq([plugin_1])
end
end

describe "when multiple plugins provide the attribute" do
before do
provides_map.set_providers_for(plugin_1, ["single"])
provides_map.set_providers_for(plugin_2, ["single"])
end

it "should return all providers" do
expect(provides_map.find_providers_for(["single"])).to eq([plugin_1, plugin_2])
end
end
end

describe "when looking up providing plugins for multiple attributes" do
describe "when a different plugin provides each attribute" do

before do
provides_map.set_providers_for(plugin_1, ["one"])
provides_map.set_providers_for(plugin_2, ["two"])
end

it "should return each provider" do
expect(provides_map.find_providers_for(["one", "two"])).to eq([plugin_1, plugin_2])
end
end

describe "when one plugin provides both requested attributes" do

before do
provides_map.set_providers_for(plugin_1, ["one"])
provides_map.set_providers_for(plugin_1, ["one_again"])
end

it "should return unique providers" do
expect(provides_map.find_providers_for(["one", "one_again"])).to eq([plugin_1])
end
end
end

describe "when looking up providers for multi-level attributes" do
before do
provides_map.set_providers_for(plugin_1, ["top/middle/bottom"])
end

it "should collect the provider" do
expect(provides_map.find_providers_for(["top/middle/bottom"])).to eq([plugin_1])
end
end

describe "when listing all plugins" do
before(:each) do
provides_map.set_providers_for(plugin_1, ["one"])
provides_map.set_providers_for(plugin_2, ["two"])
provides_map.set_providers_for(plugin_3, ["stub/three"])
provides_map.set_providers_for(plugin_4, ["foo/bar/four", "also/this/four"])
end

it "should find all the plugins providing attributes" do

all_plugins = provides_map.all_plugins
expect(all_plugins).to have(4).plugins
expect(all_plugins).to include(plugin_1)
expect(all_plugins).to include(plugin_2)
expect(all_plugins).to include(plugin_3)
expect(all_plugins).to include(plugin_4)
end
end

end

Loading

0 comments on commit 93967ce

Please sign in to comment.