Project

General

Profile

« Previous | Next » 

Revision e86db516

Added by Dmitri Dolguikh almost 9 years ago

Fixes #11229: changes in puppet modules are now being detected when listing available puppet classes

View differences:

config/settings.d/puppet.yml.example
# Cache options
#:use_cache: true
# default location of cache is relative to the installation dir
#:cache_location: '/var/lib/smart-proxy/cache'
modules/puppet_proxy/class_scanner.rb
module Proxy::Puppet
class ClassScanner < ClassScannerBase
class << self
# scans a given directory and its sub directory for puppet classes
# returns an array of PuppetClass objects.
def scan_directory directory, environment
super directory, environment
end
def scan_manifest manifest, filename = ''
Proxy::Puppet::Initializer.load
parser = Puppet::Parser::Parser.new Puppet::Node::Environment.new
klasses = []
modules/puppet_proxy/class_scanner_base.rb
require 'puppet_proxy/puppet_cache'
module Proxy::Puppet
class ClassScannerBase
class << self
# scans a given directory and its sub directory for puppet classes using the parser passed to it
# returns an array of PuppetClass objects.
def scan_directory directory, environment
if Proxy::Puppet::Plugin.settings.use_cache
PuppetCache.scan_directory_with_cache(directory, environment, self)
else
Dir.glob("#{directory}/*/manifests/**/*.pp").map do |filename|
scan_manifest File.read(filename), filename
end.compact.flatten
end
Dir.glob("#{directory}/*/manifests/**/*.pp").map do |filename|
scan_manifest File.read(filename), filename
end.compact.flatten
end
end
end
modules/puppet_proxy/class_scanner_eparser.rb
require 'puppet'
require 'puppet_proxy/class_scanner_base'
# this is needed to support tests in environments with puppet version < 3.2
module Proxy::Puppet
class ClassScannerEParser < ClassScannerBase; end
end
if Puppet::PUPPETVERSION.to_f >= 3.2
require 'puppet/pops'
module Proxy::Puppet
class ClassScannerEParser < ClassScannerBase
class << self
# scans a given directory and its sub directory for puppet classes
# returns an array of PuppetClass objects.
def scan_directory directory, environment
super directory, environment
end
def scan_manifest manifest, filename = ''
Proxy::Puppet::Initializer.load
klasses = []
already_seen = Set.new
modules/puppet_proxy/class_scanner_factory.rb
require 'puppet_proxy/class_scanner'
require 'puppet_proxy/class_scanner_eparser'
require 'puppet_proxy/puppet_cache'
module Proxy::Puppet
class ClassScannerFactory
def initialize(use_eparser)
@use_eparser = use_eparser
end
def scanner
parser = @use_eparser ? ::Proxy::Puppet::ClassScannerEParser : ::Proxy::Puppet::ClassScanner
if Proxy::Puppet::Plugin.settings.use_cache
@@cached ||= PuppetCache.new(parser, MemoryStore.new, MemoryStore.new)
else
parser
end
end
end
end
modules/puppet_proxy/environment.rb
require 'puppet_proxy/config_reader'
require 'puppet_proxy/puppet_class'
require 'puppet_proxy/api_request'
require 'puppet_proxy/class_scanner_factory'
require 'proxy/util'
class Proxy::Puppet::Environment
......
::Proxy::Puppet::Initializer.load
conf = ::Proxy::Puppet::ConfigReader.new(::Proxy::Puppet::Initializer.config).get
eparser = (conf[:main] && conf[:main][:parser] == 'future') || (conf[:master] && conf[:master][:parser] == 'future')
scanner = ::Proxy::Puppet::ClassScannerFactory.new(eparser).scanner
paths.map {|path| ::Proxy::Puppet::PuppetClass.scan_directory path, name, eparser}.flatten
paths.map {|path| scanner.scan_directory(path, name) }.flatten
end
end
end
modules/puppet_proxy/memory_store.rb
module Proxy::Puppet
class MemoryStore
def initialize
@root = {}
end
def [](*path)
get(@root, path)
end
def []=(*args)
value = args.pop
put(@root, args, value)
end
def values(*path)
get_all_values(get(@root, path))
end
private
def get(store, path)
ret_val = store[path.first]
return ret_val if path.size == 1
ret_val ? get(ret_val, path.slice(1, path.size - 1)) : nil
end
def put(store, path, value)
return store[path.first] = value if path.size == 1
store[path.first] = {} unless store.key?(path.first)
put(store[path.first], path.slice(1, path.size - 1), value)
end
def get_all_values(store)
store.inject([]) do |acc, current|
acc + (current.last.is_a?(Hash) ? get_all_values(current.last) : [current.last])
end.flatten
end
end
end
modules/puppet_proxy/puppet_cache.rb
require 'json'
require 'puppet_proxy/memory_store'
require 'thread'
module Proxy::Puppet
class PuppetCache
extend Proxy::Log
class << self
def scan_directory_with_cache directory, environment, scanner
logger.info("Running scan_directory on #{environment}: #{directory}")
include Proxy::Log
cache = read_from_cache(environment)
attr_reader :class_scanner
if cache.has_key?(directory)
lcache = cache[directory]
else
lcache = {}
end
seenmodules=[]
changed = false
manifest = Dir.glob("#{directory}/*").map do |path|
puppetmodule = File.basename(path)
mtime = File.mtime(path).to_i
seenmodules.push(puppetmodule)
lcache[puppetmodule] = {} unless lcache.has_key?(puppetmodule)
if lcache[puppetmodule].has_key?('timestamp') && lcache[puppetmodule]['timestamp'] >= mtime
logger.debug("Using cached class #{puppetmodule}")
modulemanifest = lcache[puppetmodule]['manifest']
else
changed = true
logger.info("Scanning class #{puppetmodule}")
modulemanifest = Dir.glob("#{path}/manifests/**/*.pp").map do |filename|
scanner.scan_manifest File.read(filename), filename
end
lcache[puppetmodule]['timestamp']= Time.new.to_i
lcache[puppetmodule]['manifest'] = modulemanifest
end
modulemanifest
end.compact.flatten
if changed
logger.info("Cache file need to be updated for #{environment}: #{directory}")
# Clean obsolete cache modules
oldlength = lcache.length
lcache.delete_if { |key, value| !seenmodules.include?(key) }
logger.info("Cleaning #{oldlength - lcache.length } modules from cache") if oldlength - lcache.length > 0
cache[directory] = lcache
write_to_cache(cache, environment)
logger.info("Cache file updated for #{environment}: #{directory}")
end
manifest
end
def read_from_cache environment
cachefile = File.expand_path("cache_#{environment}.json", Proxy::Puppet::Plugin.settings.cache_location)
def initialize(class_scanner, classes_store, timestamps_store)
@classes_cache = classes_store
@timestamps = timestamps_store
@class_scanner = class_scanner
@mutex = Mutex.new
end
if File.exist?(cachefile)
as_hash = JSON.load(File.new(cachefile))
def scan_directory directory, environment
logger.debug("Running scan_directory on #{environment}: #{directory}")
if as_hash.delete('version') != ::Proxy::Puppet::Plugin.version
logger.info("Mismatching puppet cache version, discarding.")
return {}
end
@mutex.synchronize do
tmp_classes = MemoryStore.new
tmp_timestamps = MemoryStore.new
# ran into issues with deserialisation in older versions of json gem (ruby 1.8.7 + json 1.5.5),
# and opted for the deserialisation approach below.
# TODO: switch back to json library based deserialisation by implementing PuppetClass.json_create
# when support for Ruby 1.8.7 has been dropped.
as_hash.values.each do |dir|
dir.values.each do |puppet_module|
puppet_module['manifest'] =
puppet_module['manifest'].flatten.map { |klass| [Proxy::Puppet::PuppetClass.from_hash(klass)] }
Dir.glob("#{directory}/*").map do |path|
puppetmodule = File.basename(path)
Dir.glob("#{path}/manifests/**/*.pp").map do |filename|
if @timestamps[directory, filename] && (File.mtime(filename).to_i <= @timestamps[directory, filename])
logger.debug("Using #{puppetmodule} cached classes from #{filename}")
tmp_classes[directory, filename] = @classes_cache[directory, filename]
tmp_timestamps[directory, filename] = @timestamps[directory, filename]
else
logger.debug("Scanning #{puppetmodule} classes in #{filename}")
tmp_classes[directory, filename] = class_scanner.scan_manifest File.read(filename), filename
tmp_timestamps[directory, filename] = File.mtime(filename).to_i
end
end
as_hash
else
{}
end
end
def write_to_cache cache, environment
cache_dir = Proxy::Puppet::Plugin.settings.cache_location
FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
@classes_cache[directory] = tmp_classes[directory]
@timestamps[directory] = tmp_timestamps[directory]
cachefile = File.expand_path("cache_#{environment}.json", cache_dir)
lock = Proxy::FileLock.try_locking(cachefile)
unless lock.nil?
tmpfile = cachefile + '.tmp'
to_serialise = cache.merge('version' => ::Proxy::Puppet::Plugin.version)
File.open(tmpfile, 'w') { |file| file.write(to_serialise.to_json) }
File.rename(tmpfile, cachefile)
Proxy::FileLock.unlock(lock)
end
@classes_cache[directory] ? @classes_cache.values(directory).compact : []
end
end
end
modules/puppet_proxy/puppet_class.rb
require 'puppet_proxy/class_scanner_eparser'
class Proxy::Puppet::PuppetClass
class << self
# scans a given directory and its sub directory for puppet classes
# returns an array of PuppetClass objects.
def scan_directory directory, environment, eparser = false
# Get a Puppet Parser to parse the manifest source
Proxy::Puppet::Initializer.load
if eparser
Proxy::Puppet::ClassScannerEParser.scan_directory directory, environment
else
Proxy::Puppet::ClassScanner.scan_directory directory, environment
end
end
end
def initialize name, params = {}
@klass = name || raise("Must provide puppet class name")
@params = params
modules/puppet_proxy/puppet_plugin.rb
https_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
default_settings :puppet_provider => 'puppetrun', :puppetdir => '/etc/puppet', :use_cache => true,
:cache_location => File.expand_path("cache", File.expand_path("../../../", __FILE__)),
:salt_puppetrun_cmd => 'puppet.run'
plugin :puppet, ::Proxy::VERSION
end
test/fixtures/modules_include/testinclude/manifests/sub/foo.pp
class testinclude::sub::foo {
class testinclude::sub::foo(
$param1 = "first_parameter",
$param2 = "second_parameter"
) {
}
test/puppet/class_scanner_eparser_test.rb
assert klasses.any? {|k| k.name == "testinclude" }
end
def test_should_handle_import_in_a_manifest_with_cache
return unless Puppet::PUPPETVERSION.to_f >= 3.2
Proxy::Puppet::Plugin.load_test_settings(:use_cache => true)
Proxy::Puppet::PuppetCache.stubs(:read_from_cache).returns(
'./test/fixtures/modules_include' => { 'testinclude' => { 'timestamp' => Time.now.to_i,
'manifest' => [[Proxy::Puppet::PuppetClass.new('testinclude')],
[Proxy::Puppet::PuppetClass.new('testinclude::check::cache')]] }})
Proxy::Puppet::PuppetCache.stubs(:write_to_cache)
klasses = Proxy::Puppet::ClassScannerEParser.scan_directory('./test/fixtures/modules_include', "example_env")
assert_equal 2, klasses.size
klass = klasses.find {|k| k.name == "check::cache" }
assert klass
assert_equal "testinclude", klass.module
assert klasses.any? {|k| k.name == "testinclude" }
end
#TODO add scans to a real puppet directory with modules
end
test/puppet/class_scanner_factory_test.rb
require 'test_helper'
require 'puppet_proxy/puppet_plugin'
require 'puppet/testing_class_scanner_factory'
class ClassScannerFactoryTest < Test::Unit::TestCase
def setup
::Proxy::Puppet::ClassScannerFactory.new(false).reset_cache
end
def test_should_return_regular_parser
Proxy::Puppet::Plugin.load_test_settings(:use_cache => false)
assert_equal ::Proxy::Puppet::ClassScanner, ::Proxy::Puppet::ClassScannerFactory.new(false).scanner
end
def test_should_return_future_parser
Proxy::Puppet::Plugin.load_test_settings(:use_cache => false)
assert_equal ::Proxy::Puppet::ClassScannerEParser, ::Proxy::Puppet::ClassScannerFactory.new(true).scanner
end
def test_should_return_caching_parser
Proxy::Puppet::Plugin.load_test_settings(:use_cache => true)
scanner = ::Proxy::Puppet::ClassScannerFactory.new(false).scanner
assert_instance_of ::Proxy::Puppet::PuppetCache, scanner
assert_equal ::Proxy::Puppet::ClassScanner, scanner.class_scanner
end
def test_should_return_caching_future_parser
Proxy::Puppet::Plugin.load_test_settings(:use_cache => true)
scanner = ::Proxy::Puppet::ClassScannerFactory.new(true).scanner
assert scanner.is_a?(::Proxy::Puppet::PuppetCache)
assert_equal ::Proxy::Puppet::ClassScannerEParser, scanner.class_scanner
end
def test_should_use_shared_cache_by_default
Proxy::Puppet::Plugin.load_test_settings(:use_cache => true)
scanner1 = ::Proxy::Puppet::ClassScannerFactory.new(true).scanner
scanner2 = ::Proxy::Puppet::ClassScannerFactory.new(true).scanner
assert_equal scanner1, scanner2
end
end
test/puppet/class_scanner_test.rb
assert klasses.empty?
end
def test_should_scan_a_dir_with_cache
Proxy::Puppet::Plugin.load_test_settings(:use_cache => true)
Proxy::Puppet::PuppetCache.stubs(:read_from_cache).returns('./test/fixtures/modules_include' =>
{ 'testinclude' =>
{'timestamp' => Time.now.to_i,
'manifest' => [[Proxy::Puppet::PuppetClass.new('test')],
[Proxy::Puppet::PuppetClass.new('test::check::cache')]] }})
Proxy::Puppet::PuppetCache.stubs(:write_to_cache)
klasses = Proxy::Puppet::ClassScanner.scan_directory('./test/fixtures/modules_include', "example_env")
assert klasses.any? {|k| k.name == "check::cache" }
end
def test_should_extract_parameters__no_param_parenthesis
manifest = <<-EOF
class foreman::install {
test/puppet/memory_store_test.rb
require 'test_helper'
require 'puppet_proxy/memory_store'
require 'set'
class MemoryStoreTest < Test::Unit::TestCase
def setup
@store = Proxy::Puppet::MemoryStore.new
end
def test_should_return_nil_when_key_does_not_exist
assert_equal nil, @store["key"]
end
def test_should_store
@store["key"] = "value"
assert_equal "value", @store["key"]
end
def test_should_return_nil_when_hierarchical_key_does_not_exist
assert_equal nil, @store["a", "b", "c"]
end
def test_should_store_a_hierarchical_key
@store["a", "b", "c"] = "value"
assert_equal "value", @store["a", "b", "c"]
end
def test_should_return_all_values_of_arrays
@store["a", "b", "c"] = [1, 2]
@store["a", "b", "d"] = [3, 4]
@store["a", "e", "f"] = [5, 6]
assert_equal [1, 2, 3, 4, 5, 6].to_set, @store.values("a").to_set
end
def test_should_return_all_values
@store["a", "b", "c"] = 1
@store["a", "b", "d"] = 3
@store["a", "e", "f"] = 5
assert_equal [1, 3, 5].to_set, @store.values("a").to_set
end
end
test/puppet/puppet_cache_test.rb
require 'test_helper'
require 'puppet_proxy/puppet_plugin'
require 'puppet_proxy/puppet_class'
require 'puppet_proxy/class_scanner_base'
require 'puppet_proxy/puppet_cache'
require 'tmpdir'
class PuppetCacheTest < Test::Unit::TestCase
def setup
@scanner = Proxy::Puppet::ClassScannerBase.new
@scanner.stubs(:scan_manifest).returns([Proxy::Puppet::PuppetClass.new('testinclude')]).then.
returns([Proxy::Puppet::PuppetClass.new('testinclude::sub::foo')])
@classes_cache = ::Proxy::Puppet::MemoryStore.new
@timestamps = ::Proxy::Puppet::MemoryStore.new
@scanner = ::Proxy::Puppet::PuppetCache.new(::Proxy::Puppet::ClassScanner, @classes_cache, @timestamps)
end
def test_should_refresh_cache_when_dir_is_not_in_cache
timestamp = Time.new
Proxy::Puppet::PuppetCache.expects(:read_from_cache).returns({})
Proxy::Puppet::PuppetCache.expects(:write_to_cache).with(
{"./test/fixtures/modules_include" => {
"testinclude" => {
'timestamp' => timestamp.to_i,
'manifest' => [
[::Proxy::Puppet::PuppetClass.new('testinclude')],
[::Proxy::Puppet::PuppetClass.new('testinclude::sub::foo')]]}
}}, "example_env")
Time.expects(:new).returns(timestamp)
cache = Proxy::Puppet::PuppetCache.scan_directory_with_cache('./test/fixtures/modules_include', 'example_env', @scanner)
def test_should_refresh_classes_cache_when_dir_is_not_in_cache
@scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
assert_kind_of Array, cache
assert_equal 2, cache.size
assert_equal Proxy::Puppet::PuppetClass.new('testinclude'),
@classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'].first
assert_equal Proxy::Puppet::PuppetClass.new('testinclude::sub::foo', 'param1' => 'first_parameter', 'param2' => 'second_parameter'),
@classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/sub/foo.pp'].first
assert_equal 2, @classes_cache.values('./test/fixtures/modules_include').size
end
klass = cache.find { |k| k.name == "sub::foo" }
assert cache
assert_equal "testinclude", klass.module
def test_should_refresh_timestamps_when_dir_is_not_in_cache
@scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
klass = cache.find { |k| k.name == "testinclude" }
assert klass
assert @timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/sub/foo.pp']
assert @timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp']
assert_equal 2, @timestamps.values('./test/fixtures/modules_include').size
end
def test_should_refresh_cache_when_dir_is_changed
mtime = File.mtime(Dir.glob('./test/fixtures/modules_include/*')[0]).to_i
timestamp = Time.new
Proxy::Puppet::PuppetCache.stubs(:read_from_cache).returns('./test/fixtures/modules_include' =>
{ 'testinclude' => { 'timestamp' => (mtime - 1000),
'manifest' => [[Proxy::Puppet::PuppetClass.new('test')],
[Proxy::Puppet::PuppetClass.new('test::sub::foo')]] }})
Proxy::Puppet::PuppetCache.expects(:write_to_cache).with(
{"./test/fixtures/modules_include" => {
"testinclude" => {
'timestamp' => timestamp.to_i,
'manifest' => [
[::Proxy::Puppet::PuppetClass.new('testinclude')],
[::Proxy::Puppet::PuppetClass.new('testinclude::sub::foo')]]}
}}, "example_env")
Time.expects(:new).returns(timestamp)
cache = Proxy::Puppet::PuppetCache.scan_directory_with_cache('./test/fixtures/modules_include', 'example_env', @scanner)
def test_scan_directory_response
cache = @scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
assert_kind_of Array, cache
assert_equal 2, cache.size
klass = cache.find { |k| k.name == "sub::foo" }
assert cache
assert_equal "testinclude", klass.module
klass = cache.find { |k| k.name == "testinclude" }
assert klass
end
def test_cache_file_should_contain_version
Dir.mktmpdir do |cache_dir|
Proxy::Puppet::Plugin.load_test_settings(:cache_location => cache_dir)
Proxy::Puppet::PuppetCache.write_to_cache({'./test/fixtures/modules_include' => {}}, 'production')
assert File.read(File.expand_path("cache_production.json", cache_dir)).include?("\"version\":\"#{Proxy::Puppet::Plugin.version}\"")
end
assert_equal "sub::foo", klass.name
assert_equal({'param1' => 'first_parameter', 'param2' => 'second_parameter'}, klass.params)
assert cache.find { |k| k.name == "testinclude" }
end
def test_should_return_empty_hash_when_cache_version_is_mismatched
Dir.mktmpdir do |cache_dir|
Proxy::Puppet::Plugin.load_test_settings(:cache_location => cache_dir)
Proxy::Puppet::PuppetCache.write_to_cache({'./test/fixtures/modules_include' =>
{ 'testinclude' => { 'timestamp' => Time.now.to_i,
'manifest' => [[Proxy::Puppet::PuppetClass.new('test')]] }}}, 'production')
Proxy::Puppet::Plugin.expects(:version).returns("0.0.0.0.1")
assert_equal({}, Proxy::Puppet::PuppetCache.read_from_cache('production'))
end
def test_should_refresh_cache_when_dir_is_changed
@classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] =
[Proxy::Puppet::PuppetClass.new('testinclude'),
Proxy::Puppet::PuppetClass.new('another_testinclude'),
Proxy::Puppet::PuppetClass.new('yet_another_testinclude')]
@timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] =
1000
assert_equal 3, @classes_cache.values('./test/fixtures/modules_include').size
@scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
assert_equal 2, @classes_cache.values('./test/fixtures/modules_include').size
assert_equal 2, @timestamps.values('./test/fixtures/modules_include').size
assert @timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] != 1000
end
def test_should_not_refresh_cache_when_cache_is_more_recent
Proxy::Puppet::PuppetCache.stubs(:read_from_cache).returns('./test/fixtures/modules_include' =>
{ 'testinclude' => { 'timestamp' => Time.now.to_i,
'manifest' => [[Proxy::Puppet::PuppetClass.new('test')],
[Proxy::Puppet::PuppetClass.new('test::sub::foo')]] }})
Proxy::Puppet::PuppetCache.expects(:write_to_cache).never
cache = Proxy::Puppet::PuppetCache.scan_directory_with_cache('./test/fixtures/modules_include', 'example_env', @scanner)
def test_should_detect_module_removals
@classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/removed_testinclude/manifests/init.pp'] =
[Proxy::Puppet::PuppetClass.new('testinclude')]
@timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/removed_testinclude/manifests/init.pp'] =
Time.now.to_i + 10_000
assert @classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/removed_testinclude/manifests/init.pp']
assert_kind_of Array, cache
# reading from the cache returns two puppet classes
assert_equal 2, cache.size
@scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
klass = cache.find { |k| k.name == "sub::foo" }
assert cache
assert_equal "test", klass.module
assert_nil @classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/removed_testinclude/manifests/init.pp']
assert_nil @timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/removed_testinclude/manifests/init.pp']
assert @classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp']
assert @classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/sub/foo.pp']
end
klass = cache.find { |k| k.name == "test" }
assert klass
def test_should_not_refresh_cache_when_cache_is_more_recent
@classes_cache['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] =
[Proxy::Puppet::PuppetClass.new('testinclude'),
Proxy::Puppet::PuppetClass.new('another_testinclude'),
Proxy::Puppet::PuppetClass.new('yet_another_testinclude')]
@timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] =
(current_time = Time.now.to_i + 10_000)
assert_equal 3, @classes_cache.values('./test/fixtures/modules_include').size
@scanner.scan_directory('./test/fixtures/modules_include', 'example_env')
assert_equal 4, @classes_cache.values('./test/fixtures/modules_include').size
assert_equal 2, @timestamps.values('./test/fixtures/modules_include').size
assert @timestamps['./test/fixtures/modules_include', './test/fixtures/modules_include/testinclude/manifests/init.pp'] == current_time
end
def test_read_write_cache_idempotency
Dir.mktmpdir do |cache_dir|
Proxy::Puppet::Plugin.load_test_settings(:cache_location => cache_dir)
expected = {'./test/fixtures/modules_include' =>
{'testinclude' => { 'timestamp' => Time.now.to_i,
'manifest' => [[Proxy::Puppet::PuppetClass.new('test')],
[Proxy::Puppet::PuppetClass.new('test::sub::foo')]] }}}
Proxy::Puppet::PuppetCache.write_to_cache(expected, 'production')
assert_equal expected, Proxy::Puppet::PuppetCache.read_from_cache('production')
end
def test_should_return_no_puppet_classes_when_environment_has_no_modules
Dir.expects(:glob).with('empty_environment/*').returns([])
result = @scanner.scan_directory('empty_environment', 'example_env')
assert result.empty?
end
end
test/puppet/puppet_class_test.rb
assert_equal "klass::nested", klass.name
end
def test_scan_directory_loads_scanner
Proxy::Puppet::Initializer.expects(:load)
Proxy::Puppet::ClassScanner.expects(:scan_directory).with('/foo', 'development')
Proxy::Puppet::PuppetClass.scan_directory('/foo', 'development', nil)
end
def test_scan_directory_loads_eparser_scanner
return unless Puppet::PUPPETVERSION.to_f >= 3.2
Proxy::Puppet::Initializer.expects(:load)
Proxy::Puppet::ClassScannerEParser.expects(:scan_directory).with('/foo', 'development')
Proxy::Puppet::PuppetClass.scan_directory('/foo', 'development', true)
end
def test_json_serialization
clazz = Proxy::Puppet::PuppetClass.new(
"foreman_proxy::install", "namedconf_path"=>"${::dns::params::namedconf_path}", "dnsdir"=>"${::dns::params::dnsdir}")
test/puppet/puppet_environment_test.rb
def test_classes_calls_scan_directory
Proxy::Puppet::ConfigReader.any_instance.stubs(:get).returns({})
env = Proxy::Puppet::Environment.new(:name => 'production', :paths => ['/etc/puppet/modules', '/etc/puppet/production'])
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/modules', 'production', nil)
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/production', 'production', nil)
::Proxy::Puppet::ClassScanner.expects(:scan_directory).with('/etc/puppet/modules', 'production')
::Proxy::Puppet::ClassScanner.expects(:scan_directory).with('/etc/puppet/production', 'production')
env.classes
end
def test_classes_calls_scan_directory_with_eparser_master
Proxy::Puppet::ConfigReader.any_instance.stubs(:get).returns(:master => {:parser => 'future'})
env = Proxy::Puppet::Environment.new(:name => 'production', :paths => ['/etc/puppet/modules', '/etc/puppet/production'])
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/modules', 'production', true)
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/production', 'production', true)
Proxy::Puppet::ClassScannerEParser.expects(:scan_directory).with('/etc/puppet/modules', 'production')
Proxy::Puppet::ClassScannerEParser.expects(:scan_directory).with('/etc/puppet/production', 'production')
env.classes
end
def test_classes_calls_scan_directory_with_eparser_main
Proxy::Puppet::ConfigReader.any_instance.stubs(:get).returns(:main => {:parser => 'future'})
env = Proxy::Puppet::Environment.new(:name => 'production', :paths => ['/etc/puppet/modules', '/etc/puppet/production'])
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/modules', 'production', true)
Proxy::Puppet::PuppetClass.expects(:scan_directory).with('/etc/puppet/production', 'production', true)
Proxy::Puppet::ClassScannerEParser.expects(:scan_directory).with('/etc/puppet/modules', 'production')
Proxy::Puppet::ClassScannerEParser.expects(:scan_directory).with('/etc/puppet/production', 'production')
env.classes
end
test/puppet/testing_class_scanner_factory.rb
require 'puppet_proxy/class_scanner_factory'
class ::Proxy::Puppet::ClassScannerFactory
def reset_cache; @@cached = nil; end
end

Also available in: Unified diff