[DRE-commits] [ruby-hiera] 02/10: Imported Upstream version 1.2.1
Jonas Genannt
jonas at brachium-system.net
Fri Oct 18 18:25:16 UTC 2013
This is an automated email from the git hooks/post-receive script.
hggh-guest pushed a commit to branch master
in repository ruby-hiera.
commit 43a742ae3fcd8022a2a63bcadbb8a1ea8bafb8f2
Author: Jonas Genannt <jonas at brachium-system.net>
Date: Fri Oct 18 20:14:31 2013 +0200
Imported Upstream version 1.2.1
---
.gitignore | 3 -
README.md | 2 +
Rakefile | 48 -----
acceptance_tests/tests/yaml_backend/00-setup.rb | 26 ---
.../yaml_backend/01-lookup_data_without_a_key.rb | 9 -
.../yaml_backend/02-lookup_data_with_no_options.rb | 48 -----
.../yaml_backend/03-lookup_data_with_a_scope.rb | 62 -------
.../04-lookup_data_with_array_search.rb | 46 -----
.../05-lookup_data_with_hash_search.rb | 49 -----
docs/images/hiera_hierarchy_resolution.png | Bin 15495 -> 0 bytes
.../hiera_hierarchy_resolution_empty_scope.png | Bin 8172 -> 0 bytes
docs/tutorials/getting_started.md | 113 ------------
docs/tutorials/hierarchies_sources_and_scope.md | 123 -------------
ext/build_defaults.yaml | 23 ---
ext/debian/changelog.erb | 23 ---
ext/debian/compat | 1 -
ext/debian/control | 13 --
ext/debian/copyright | 1 -
ext/debian/rules | 35 ----
ext/debian/source/format | 1 -
ext/hiera.yaml | 15 --
ext/ips/hiera.p5m.erb | 10 --
ext/ips/rules | 17 --
ext/ips/transforms | 20 ---
ext/osx/file_mapping.yaml | 32 ----
ext/osx/preflight.erb | 30 ----
ext/osx/prototype.plist.erb | 38 ----
ext/project_data.yaml | 17 --
ext/redhat/hiera.spec.erb | 80 ---------
lib/hiera.rb | 26 +--
lib/hiera/backend.rb | 83 +++++----
lib/hiera/backend/json_backend.rb | 17 +-
lib/hiera/backend/yaml_backend.rb | 40 ++---
lib/hiera/config.rb | 18 +-
lib/hiera/fallback_logger.rb | 41 +++++
lib/hiera/filecache.rb | 74 ++++++++
lib/hiera/puppet_logger.rb | 4 +
lib/hiera/recursive_lookup.rb | 31 ++++
metadata.yml | 114 ++++++++++++
spec/unit/backend/json_backend_spec.rb | 32 ++--
spec/unit/backend/yaml_backend_spec.rb | 109 ++++--------
spec/unit/backend_spec.rb | 188 ++++++++++++++------
spec/unit/config_spec.rb | 7 +-
spec/unit/fallback_logger_spec.rb | 80 +++++++++
spec/unit/filecache_spec.rb | 63 +++++++
spec/unit/hiera_spec.rb | 41 +++--
spec/unit/puppet_logger_spec.rb | 31 ++++
47 files changed, 766 insertions(+), 1118 deletions(-)
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 55a711c..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-pkg
-test.rb
-ext/packaging
diff --git a/README.md b/README.md
index 0c18e9c..968290c 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Hiera
+[](https://travis-ci.org/puppetlabs/hiera)
+
A simple pluggable Hierarchical Database.
-
diff --git a/Rakefile b/Rakefile
deleted file mode 100644
index 41ef3a4..0000000
--- a/Rakefile
+++ /dev/null
@@ -1,48 +0,0 @@
-begin
- require 'rubygems'
- require 'rspec/core/rake_task'
-rescue LoadError
-end
-
-Dir['tasks/**/*.rake'].each { |t| load t }
-Dir['ext/packaging/tasks/**/*'].sort.each { |t| load t }
-
-build_defs_file = 'ext/build_defaults.yaml'
-if File.exist?(build_defs_file)
- begin
- require 'yaml'
- @build_defaults ||= YAML.load_file(build_defs_file)
- rescue Exception => e
- STDERR.puts "Unable to load yaml from #{build_defs_file}:"
- STDERR.puts e
- end
- @packaging_url = @build_defaults['packaging_url']
- @packaging_repo = @build_defaults['packaging_repo']
- raise "Could not find packaging url in #{build_defs_file}" if @packaging_url.nil?
- raise "Could not find packaging repo in #{build_defs_file}" if @packaging_repo.nil?
-
- namespace :package do
- desc "Bootstrap packaging automation, e.g. clone into packaging repo"
- task :bootstrap do
- if File.exist?("ext/#{@packaging_repo}")
- puts "It looks like you already have ext/#{@packaging_repo}. If you don't like it, blow it away with package:implode."
- else
- cd 'ext' do
- %x{git clone #{@packaging_url}}
- end
- end
- end
- desc "Remove all cloned packaging automation"
- task :implode do
- rm_rf "ext/#{@packaging_repo}"
- end
- end
-end
-
-if defined?(RSpec::Core::RakeTask)
- desc "Run all specs"
- RSpec::Core::RakeTask.new(:test) do |t|
- t.pattern = 'spec/**/*_spec.rb'
- end
-end
-
diff --git a/acceptance_tests/tests/yaml_backend/00-setup.rb b/acceptance_tests/tests/yaml_backend/00-setup.rb
deleted file mode 100644
index 100e7e1..0000000
--- a/acceptance_tests/tests/yaml_backend/00-setup.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-test_name "Hiera setup for YAML backend"
-
-apply_manifest_on master, <<-PP
-file { '/etc/hiera.yaml':
- ensure => present,
- content => '---
- :backends:
- - "yaml"
- :logger: "console"
- :hierarchy:
- - "%{fqdn}"
- - "%{environment}"
- - "global"
-
- :yaml:
- :datadir: "/etc/puppet/hieradata"
- '
-}
-
-file { '/etc/puppet/hieradata':
- ensure => directory,
- recurse => true,
- purge => true,
- force => true,
-}
-PP
diff --git a/acceptance_tests/tests/yaml_backend/01-lookup_data_without_a_key.rb b/acceptance_tests/tests/yaml_backend/01-lookup_data_without_a_key.rb
deleted file mode 100644
index 5a9c3e6..0000000
--- a/acceptance_tests/tests/yaml_backend/01-lookup_data_without_a_key.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-test_name "Lookup data without a key"
-
-step "Try to lookup data without specifying a key"
-
-on master, hiera(""), :acceptable_exit_codes => [1] do
- assert_output <<-OUTPUT
- STDERR> Please supply a data item to look up
- OUTPUT
-end
diff --git a/acceptance_tests/tests/yaml_backend/02-lookup_data_with_no_options.rb b/acceptance_tests/tests/yaml_backend/02-lookup_data_with_no_options.rb
deleted file mode 100644
index 6175d08..0000000
--- a/acceptance_tests/tests/yaml_backend/02-lookup_data_with_no_options.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-begin test_name "Lookup data using the default options"
-
-step 'Setup'
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata/global.yaml':
- ensure => present,
- content => "---
- http_port: 8080
- ntp_servers: ['0.ntp.puppetlabs.com', '1.ntp.puppetlabs.com']
- users:
- pete:
- uid: 2000
- tom:
- uid: 2001
- "
-}
-PP
-
-step "Try to lookup string data"
-on master, hiera("http_port"), :acceptable_exit_codes => [0] do
- assert_output <<-OUTPUT
- STDOUT> 8080
- OUTPUT
-end
-
-step "Try to lookup array data"
-on master, hiera("ntp_servers"), :acceptable_exit_codes => [0] do
- assert_output <<-OUTPUT
- STDOUT> ["0.ntp.puppetlabs.com", "1.ntp.puppetlabs.com"]
- OUTPUT
-end
-
-step "Try to lookup hash data"
-on master, hiera("users"), :acceptable_exit_codes => [0] do
- assert_match /tom[^}]+"uid"=>2001}/, result.output
- assert_match /pete[^}]+"uid"=>2000}/, result.output
-end
-
-ensure step "Teardown"
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata':
- ensure => directory,
- recurse => true,
- purge => true,
- force => true,
-}
-PP
-end
diff --git a/acceptance_tests/tests/yaml_backend/03-lookup_data_with_a_scope.rb b/acceptance_tests/tests/yaml_backend/03-lookup_data_with_a_scope.rb
deleted file mode 100644
index 377c065..0000000
--- a/acceptance_tests/tests/yaml_backend/03-lookup_data_with_a_scope.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-begin test_name "Lookup data with a scope"
-
-step 'Setup'
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata/global.yaml':
- ensure => present,
- content => "---
- http_port: 8080
- ntp_servers: ['0.ntp.puppetlabs.com', '1.ntp.puppetlabs.com']
- users:
- pete:
- uid: 2000
- gid: 2000
- shell: '/bin/bash'
- tom:
- uid: 2001
- gid: 2001
- shell: '/bin/bash'
- "
-}
-
-file { '/etc/puppet/hieradata/production.yaml':
- ensure => present,
- content => "---
- http_port: 9090
- monitor: enable
- ntp_servers: ['0.ntp.puppetlabs.com', '1.ntp.puppetlabs.com']
- "
-}
-
-file { '/etc/puppet/scope.yaml':
- ensure => present,
- content => "---
- environment: production
- "
-}
-PP
-
-step "Try to lookup string data using a scope from a yaml file"
-on master, hiera('monitor', '--yaml', '/etc/puppet/scope.yaml'),
- :acceptable_exit_codes => [0] do
- assert_output <<-OUTPUT
- STDOUT> enable
- OUTPUT
-end
-
-# TODO: Add a test for supplying scope from a json file.
-# We need to workout the requirement on the json gem.
-step "Try to lookup string data using a scope from a yaml file"
-
-ensure step "Teardown"
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata':
- ensure => directory,
- recurse => true,
- purge => true,
- force => true,
-}
-file { '/etc/puppet/scope.yaml': ensure => absent }
-file { '/etc/puppet/scope.json': ensure => absent }
-PP
-end
diff --git a/acceptance_tests/tests/yaml_backend/04-lookup_data_with_array_search.rb b/acceptance_tests/tests/yaml_backend/04-lookup_data_with_array_search.rb
deleted file mode 100644
index 65ec265..0000000
--- a/acceptance_tests/tests/yaml_backend/04-lookup_data_with_array_search.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-begin test_name "Lookup data with Array search"
-
-step 'Setup'
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata/production.yaml':
- ensure => present,
- content => "---
- ntpservers: ['production.ntp.puppetlabs.com']
- "
-}
-
-file { '/etc/puppet/hieradata/global.yaml':
- ensure => present,
- content => "---
- ntpservers: ['global.ntp.puppetlabs.com']
- "
-}
-
-file { '/etc/puppet/scope.yaml':
- ensure => present,
- content => "---
- environment: production
- "
-}
-PP
-
-step "Try to lookup data using array search"
-on master, hiera('ntpservers', '--yaml', '/etc/puppet/scope.yaml', '--array'),
- :acceptable_exit_codes => [0] do
- assert_output <<-OUTPUT
- STDOUT> ["production.ntp.puppetlabs.com", "global.ntp.puppetlabs.com"]
- OUTPUT
-end
-
-ensure step "Teardown"
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata':
- ensure => directory,
- recurse => true,
- purge => true,
- force => true,
-}
-file { '/etc/puppet/scope.yaml': ensure => absent }
-file { '/etc/puppet/scope.json': ensure => absent }
-PP
-end
diff --git a/acceptance_tests/tests/yaml_backend/05-lookup_data_with_hash_search.rb b/acceptance_tests/tests/yaml_backend/05-lookup_data_with_hash_search.rb
deleted file mode 100644
index 8baffae..0000000
--- a/acceptance_tests/tests/yaml_backend/05-lookup_data_with_hash_search.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-begin test_name "Lookup data with Hash search"
-
-step 'Setup'
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata/production.yaml':
- ensure => present,
- content => "---
- users:
- joe:
- uid: 1000
- "
-}
-
-file { '/etc/puppet/hieradata/global.yaml':
- ensure => present,
- content => "---
- users:
- pete:
- uid: 1001
- "
-}
-
-file { '/etc/puppet/scope.yaml':
- ensure => present,
- content => "---
- environment: production
- "
-}
-PP
-
-step "Try to lookup data using hash search"
-on master, hiera('users', '--yaml', '/etc/puppet/scope.yaml', '--hash'),
- :acceptable_exit_codes => [0] do
- assert_match /joe[^}]+"uid"=>1000}/, result.output
- assert_match /pete[^}]+"uid"=>1001}/, result.output
-end
-
-ensure step "Teardown"
-apply_manifest_on master, <<-PP
-file { '/etc/puppet/hieradata':
- ensure => directory,
- recurse => true,
- purge => true,
- force => true,
-}
-file { '/etc/puppet/scope.yaml': ensure => absent }
-file { '/etc/puppet/scope.json': ensure => absent }
-PP
-end
diff --git a/docs/images/hiera_hierarchy_resolution.png b/docs/images/hiera_hierarchy_resolution.png
deleted file mode 100644
index 1b37cf8..0000000
Binary files a/docs/images/hiera_hierarchy_resolution.png and /dev/null differ
diff --git a/docs/images/hiera_hierarchy_resolution_empty_scope.png b/docs/images/hiera_hierarchy_resolution_empty_scope.png
deleted file mode 100644
index 217839b..0000000
Binary files a/docs/images/hiera_hierarchy_resolution_empty_scope.png and /dev/null differ
diff --git a/docs/tutorials/getting_started.md b/docs/tutorials/getting_started.md
deleted file mode 100644
index 04b8912..0000000
--- a/docs/tutorials/getting_started.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# Getting Started
-
-Hiera is a simple hierarchal database which provides an easy to use interface
-for looking up data using a key.
-
- $ hiera puppetlabs_home_page
- http://puppetlabs.com
-
-## Installation
-
-We are going to install Hiera using Rubygems, so now is a good time to make
-sure you meet the prerequisites.
-
-### Prerequisites
-
- * Ruby 1.8.5+
- * Rubygems 1.3.0+
-
-### Installing Hiera via Rubygems
-
- $ gem install hiera
- Successfully installed hiera-0.3.0
- 1 gem installed
- Installing ri documentation for hiera-0.3.0...
- Installing RDoc documentation for hiera-0.3.0...
-
-Make sure we can run the hiera command:
-
- $ hiera -v
- 0.3.0
-
--
-
-**Note:** Some Linux distributions such as Debian squeeze do not put the gem bin
-directory (`/var/lib/gems/1.8/bin`) in your PATH by default. You may have
-to call hiera using the full path:
-
- $ /var/lib/gems/1.8/bin/hiera -v
- 0.3.0
-
-## Configuration
-
-Before using Hiera we need to create a configuration file. By default Hiera
-attempts to load `hiera.yaml` from the `/etc/` directory. Lets create that
-file now:
-
- $ vim /etc/hiera.yaml
- ---
- :backends:
- - yaml
-
- :hierarchy:
- - global
-
- :yaml:
- :datadir: /var/lib/hiera/data
-
--
-
-**Note:** If Hiera cannot locate `/etc/hiera.yaml` you will receive the follow
-error when trying to lookup a value:
-
- $ hiera key
- Failed to start Hiera: RuntimeError: Config file /etc/hiera.yaml not found
-
-You can specify a different configuration file using the `--config` option:
-
- $ hiera --config ~/hiera.yaml key
-
-## Adding data
-
-With configuration out of the way, lets add some data. The yaml backend
-expects to find data files under the `datadir` we configured earlier.
-
-Create the `/var/lib/hiera/data` data directory:
-
- $ mkdir -p /var/lib/hiera/data
-
-For each source in the `hierarchy`, the yaml backend will search for a
-corresponding YAML file under the `datadir`.
-
-For example, our `hierarchy` consists of a single source named `global`. The
-yaml backend will look for `/var/lib/hiera/data/global.yaml`, and if missing
-skips it and move on to the next source in the hierarchy.
-
-Lets add some data to the `global` source:
-
- $ vim /var/lib/hiera/data/global.yaml
- ---
- driftfile: '/etc/ntp/drift'
- ntpservers:
- - '0.north-america.pool.ntp.org'
- - '1.north-america.pool.ntp.org'
-
-## Looking up data
-
-Now that we have our configuration setup and some data, lets lookup the
-'driftfile' key:
-
- $ /var/lib/gems/1.8/bin/hiera driftfile
- /etc/ntp/drift
-
-We get extacaly what we expected, '/etc/ntp/drift'.
-
-Running the lookup command with the `--debug` flag, we can see the details
-of how Hiera lookups data:
-
- $ /var/lib/gems/1.8/bin/hiera driftfile --debug
- DEBUG: Thu Jun 28 09:54:04 -0400 2012: Hiera YAML backend starting
- DEBUG: Thu Jun 28 09:54:04 -0400 2012: Looking up driftfile in YAML backend
- DEBUG: Thu Jun 28 09:54:04 -0400 2012: Looking for data source global
- /etc/ntp/drift
-
diff --git a/docs/tutorials/hierarchies_sources_and_scope.md b/docs/tutorials/hierarchies_sources_and_scope.md
deleted file mode 100644
index 3b64290..0000000
--- a/docs/tutorials/hierarchies_sources_and_scope.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# Hierarchies, Sources, and Scope
-
-The key to mastering Hiera is understanding the following concepts:
-
- * Hierarchies
- * Sources
- * Scope
-
-## Hierarchies
-
-At the very core of Hiera are the data hierarchies, which are made up of
-sources. Hierarchies are specified in Hiera configuration file `hiera.yaml` via the
-`:hierarchy:` array.
-
- :hierarchy:
- - "%{certname}"
- - "%{environment}"
- - default
-
-There are three sources in the above hierarchy, `%{certname}`, `%{environment}`,
-and `default`. The first two sources, `%{certname}` and `%{environment}`,
-represent dynamic sources which will be resolved at runtime. The third source
-`default` is static.
-
-
-When looking up a key Hiera iterates through each source in the hierarchy
-starting with the first one in the list. In our case `%{certname}`. There is
-no limit to the number of sources you can have. But lets not go crazy; try and
-keep your hierarchy below 5 - 6 levels deep. Any more than this you should
-start thinking about custom facts or how your data is organized.
-
-### Order is important
-
-Hiera uses the priority resolution type by default. This means Hiera stops at
-the first source in the hierarchy that provides a non `nil` answer. The
-behavior is a slightly different for the array and hash resolution types. Every
-scope in the hierarchy will be searched, but data is appended not overridden!
-
-## Sources
-
-Each level of the hierarchy is represented by a source which comes in two
-flavors, static and dynamic.
-
-### Static sources
-
-A source is considered static when it appears in the hierarchy as a simple
-string.
-
- :hierarchy:
- - default
-
--
-You should consider using a static source when you want a certain level in
-the hierarchy to apply to all nodes.
-
-### Dynamic sources
-
-A source is considered dynamic when it appears in the hierarchy as a string
-enclosed between `%{}` like this:
-
- :hierarchy:
- - %{certname}
-
-Dynamic sources are interpolated by Hiera at runtime.
-
--
-You should consider using a dynamic source when you want to provide different
-data based on Facter Facts.
-
-## Scope
-
-A scope is a collection of key/value pairs:
-
- certname: agent.puppetlabs.com
- environment: production
- operatingsystem: Debian
-
-If you are thinking scopes look a lot like Facter Facts you are on to
-something. Hiera was designed around Facter Facts being the primary input
-for scope.
-
-### Source interpolation
-
-Hiera uses the scope when interpolating sources in the hierarchy.
-
-<img src='https://github.com/kelseyhightower/hiera/raw/maint/1.0rc/add_getting_started_tutorial/docs/images/hiera_hierarchy_resolution.png' />
-
-Scopes can be empty, and when they are, dynamic sources are excluded from the
-hierarchy at run time.
-
-<img src='https://github.com/kelseyhightower/hiera/raw/maint/1.0rc/add_getting_started_tutorial/docs/images/hiera_hierarchy_resolution_empty_scope.png' />
-
-### Feeding Hiera your scope
-
-You can provide Hiera a scope via the command line using the `--yaml` or
-`--json` options.
-
-For example:
-
-If we had the following scope:
-
- $ cat /tmp/scope.yaml
- ---
- certname: agent.example.com
- environment: production
-
-
-
-You can feed it to Hiera like this:
-
- $ hiera --yaml /tmp/scope.yaml driftfile
- /etc/ntp/drift
-
--
-**Note:** If you run into the follow error, you need to make sure Puppet is installed:
-
- Could not load YAML scope: LoadError: no such file to load -- puppet
-
-The reason for this is that the scope yaml file could have been produced by
-Puppet, and contained serialized objects. Since it would be desirable to use
-Hiera without Puppet, this restrict will be removed in the future.
-
-
diff --git a/ext/build_defaults.yaml b/ext/build_defaults.yaml
deleted file mode 100644
index 320704b..0000000
--- a/ext/build_defaults.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-packaging_url: 'git://github.com/puppetlabs/packaging.git --branch=master'
-packaging_repo: 'packaging'
-default_cow: 'base-squeeze-i386.cow'
-cows: 'base-lucid-i386.cow base-natty-i386.cow base-oneiric-i386.cow base-precise-i386.cow base-quantal-i386.cow base-sid-i386.cow base-squeeze-i386.cow base-stable-i386.cow base-testing-i386.cow base-unstable-i386.cow base-wheezy-i386.cow'
-pbuild_conf: '/etc/pbuilderrc'
-packager: 'puppetlabs'
-gpg_name: 'info at puppetlabs.com'
-gpg_key: '4BD6EC30'
-sign_tar: FALSE
-# a space separated list of mock configs
-final_mocks: 'pl-5-i386 pl-6-i386 fedora-16-i386 fedora-17-i386'
-rc_mocks: 'pl-5-i386-dev pl-6-i386-dev fedora-16-i386-dev fedora-17-i386-dev'
-build_gem: TRUE
-build_dmg: TRUE
-yum_host: 'burji.puppetlabs.com'
-yum_repo_path: '/opt/repository/yum/'
-apt_host: 'burji.puppetlabs.com'
-apt_repo_url: 'http://apt.puppetlabs.com'
-apt_repo_path: '/opt/repository/incoming'
-ips_repo: '/var/pkgrepo'
-ips_store: '/opt/repository'
-ips_host: 'solaris-11-ips-repo.acctest.dc1.puppetlabs.net'
diff --git a/ext/debian/changelog.erb b/ext/debian/changelog.erb
deleted file mode 100644
index b178c6e..0000000
--- a/ext/debian/changelog.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-hiera (<%= @debversion %>) lucid maverick natty lenny squeeze precise wheezy sid unstable; urgency=low
-
- * update to version <%= @debversion %>
-
- -- Puppet Labs Release <info at puppetlabs.com> <%= Time.now.strftime("%a, %d %b %Y %H:%M:%S %z") %>
-
-hiera (0.99+1.0.0rc2-1puppet1) unstable; urgency=low
-
- * Release of 1.0.0rc2
-
- -- Matthaus Litteken <matthaus at puppetlabs.com> Tue, 15 May 2012 04:45:08 +0000
-
-hiera (0.99+1.0.0rc1-1puppet1) unstable; urgency=low
-
- * Release of 1.0.0rc1
-
- -- Puppet Labs Release Key (Puppet Labs Release Key) <info at puppetlabs.com> Mon, 14 May 2012 23:55:54 +0000
-
-hiera (0.3.0.24-1) unstable; urgency=low
-
- * Initial release of upstream 0.3.0.24
-
- -- Puppet Labs Release Key (Puppet Labs Release Key) <info at puppetlabs.com> Fri, 04 May 2012 20:43:22 +0000
diff --git a/ext/debian/compat b/ext/debian/compat
deleted file mode 100644
index 7f8f011..0000000
--- a/ext/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-7
diff --git a/ext/debian/control b/ext/debian/control
deleted file mode 100644
index 2f160aa..0000000
--- a/ext/debian/control
+++ /dev/null
@@ -1,13 +0,0 @@
-Source: hiera
-Section: utils
-Priority: extra
-Maintainer: Puppet Labs <info at puppetlabs.com>
-Build-Depends: debhelper (>= 7.0.0), cdbs, quilt, ruby | ruby-interpreter
-Standards-Version: 3.9.2
-Homepage: http://projects.puppetlabs.com/projects/hiera
-
-Package: hiera
-Architecture: all
-Depends: ${shlibs:Depends}, ${misc:Depends}, ruby | ruby-interpreter, libjson-ruby | ruby-json
-Description: A simple pluggable Hierarchical Database.
- Hiera is a simple pluggable Hierarchical Database.
diff --git a/ext/debian/copyright b/ext/debian/copyright
deleted file mode 100644
index a27ad7b..0000000
--- a/ext/debian/copyright
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/common-licenses/Apache-2.0
diff --git a/ext/debian/rules b/ext/debian/rules
deleted file mode 100755
index 84d7e4e..0000000
--- a/ext/debian/rules
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/rules/patchsys-quilt.mk
-
-BUILD_ROOT=$(DESTDIR)/$(CURDIR)/debian/$(cdbs_curpkg)
-LIBDIR=$(shell /usr/bin/ruby -rrbconfig -e 'puts RbConfig::CONFIG["vendordir"]')
-BIN_DIR=$(shell /usr/bin/ruby -rrbconfig -e 'puts RbConfig::CONFIG["bindir"]')
-RUBYLIB=$(BUILD_ROOT)/$(LIBDIR)
-RUBYBIN=$(BUILD_ROOT)/$(BIN_DIR)
-DOC_DIR=$(BUILD_ROOT)/usr/share/doc/hiera/
-DATA_DIR=$(BUILD_ROOT)/var/lib/hiera
-
-install/hiera::
- mkdir -p $(RUBYLIB)
- mkdir -p $(RUBYBIN)
- mkdir -p $(DOC_DIR)
- mkdir -p $(DATA_DIR)
- mkdir -p $(BUILD_ROOT)/etc
- cp -pr lib/hiera $(RUBYLIB)
- cp -p lib/hiera.rb $(RUBYLIB)
- cp -p bin/* $(RUBYBIN)
- cp -pr ext/hiera.yaml $(BUILD_ROOT)/etc
- cp -p COPYING README.md $(DOC_DIR)
-
-clean::
diff --git a/ext/debian/source/format b/ext/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/ext/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/ext/hiera.yaml b/ext/hiera.yaml
deleted file mode 100644
index c005288..0000000
--- a/ext/hiera.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
----
-:backends:
- - yaml
-:hierarchy:
- - defaults
- - %{clientcert}
- - %{environment}
- - global
-
-:yaml:
-# datadir is empty here, so hiera uses its defaults:
-# - /var/lib/hiera on *nix
-# - %CommonAppData%\PuppetLabs\hiera\var on Windows
-# When specifying a datadir, make sure the directory exists.
- :datadir:
diff --git a/ext/ips/hiera.p5m.erb b/ext/ips/hiera.p5m.erb
deleted file mode 100644
index 37c8a3d..0000000
--- a/ext/ips/hiera.p5m.erb
+++ /dev/null
@@ -1,10 +0,0 @@
-set name=pkg.fmri value=pkg://puppetlabs.com/application/<%=@name%>@<%=@ipsversion%>
-set name=pkg.summary value="<%=@summary%>"
-set name=pkg.human-version value="<%=@version%>"
-set name=pkg.description value="<%=@description%>"
-set name=info.classification value="org.opensolaris.category.2008:Applications/System Utilities"
-set name=org.opensolaris.consolidation value="puppet"
-set name=description value="<%=@description%>"
-set name=variant.opensolaris.zone value=global value=nonglobal
-set name=variant.arch value=sparc value=i386
-license hiera.license license="Apache v2.0"
diff --git a/ext/ips/rules b/ext/ips/rules
deleted file mode 100755
index cd87e8d..0000000
--- a/ext/ips/rules
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/make -f
-
-LIBDIR=$(shell /usr/bin/ruby18 -rrbconfig -e 'puts RbConfig::CONFIG["rubylibdir"]')
-DESTDIR=$(CURDIR)/pkg/ips/proto
-
-install/hiera::
- mkdir -p $(DESTDIR)/$(LIBDIR)
- mkdir -p $(DESTDIR)/usr/bin
- mkdir -p $(DESTDIR)/usr/share/doc/hiera
- mkdir -p $(DESTDIR)/var/lib/hiera
- mkdir -p $(DESTDIR)/etc
- cp -pr lib/hiera $(DESTDIR)/$(LIBDIR)
- cp -p lib/hiera.rb $(DESTDIR)/$(LIBDIR)
- cp -p bin/* $(DESTDIR)/usr/bin
- cp -pr ext/hiera.yaml $(DESTDIR)/etc
- cp -p COPYING README.md $(DESTDIR)/usr/share/doc/hiera
-
diff --git a/ext/ips/transforms b/ext/ips/transforms
deleted file mode 100644
index e4a8e5b..0000000
--- a/ext/ips/transforms
+++ /dev/null
@@ -1,20 +0,0 @@
-<transform file dir link hardlink path=usr/share/man/.+(/.+)? -> default facet.doc.man true>
-<transform file path=usr/share/man/.+(/.+)? -> add restart_fmri svc:/application/man-index:default>
-
-# drop user
-<transform dir path=usr$->drop>
-<transform dir path=usr/bin$->drop>
-<transform dir path=etc$->drop>
-<transform dir path=var$->drop>
-<transform dir path=var/lib$->drop>
-<transform dir path=usr/share$->drop>
-<transform dir path=usr/share/doc$->drop>
-<transform dir path=usr/ruby$->drop>
-<transform dir path=usr/ruby/1.8$->drop>
-<transform dir path=usr/ruby/1.8/lib$->drop>
-<transform dir path=usr/ruby/1.8/lib/ruby$->drop>
-<transform dir path=usr/ruby/1.8/lib/ruby/1.8$->drop>
-
-
-# saner dependencies
-<transform depend -> edit fmri "@[^ \t\n\r\f\v]*" "">
diff --git a/ext/osx/file_mapping.yaml b/ext/osx/file_mapping.yaml
deleted file mode 100644
index 99fc090..0000000
--- a/ext/osx/file_mapping.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-directories:
- lib:
- path: 'usr/lib/ruby/site_ruby/1.8'
- owner: 'root'
- group: 'wheel'
- perms: '0644'
- bin:
- path: 'usr/bin'
- owner: 'root'
- group: 'wheel'
- perms: '0755'
- hiera:
- path: 'var/lib/hiera'
- owner: 'root'
- group: 'wheel'
- perms: '0644'
- etc:
- path: 'etc'
- owner: 'root'
- group: 'wheel'
- perms: '0644'
-files:
- '[A-Z]*':
- path: 'usr/share/doc/hiera'
- owner: 'root'
- group: 'wheel'
- perms: '0644'
- 'ext/hiera.yaml':
- path: 'etc'
- owner: 'root'
- group: 'wheel'
- perms: '0644'
diff --git a/ext/osx/preflight.erb b/ext/osx/preflight.erb
deleted file mode 100644
index 93ecc00..0000000
--- a/ext/osx/preflight.erb
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-#
-# Make sure that old hiera cruft is removed
-# This also allows us to downgrade facter as
-# it's more likely that installing old versions
-# over new will cause issues.
-#
-# ${3} is the destination volume so that this works correctly
-# when being installed to volumes other than the current OS.
-
-<% begin %>
-<% require 'rubygems' %>
-<% rescue LoadError %>
-<% end %>
-<% require 'rake' %>
-
-# remove libdir
-<% Dir.chdir("lib") %>
-<% FileList["**/*"].select {|i| File.file?(i)}.each do |file| %>
-/bin/rm -Rf "${3}<%= @apple_libdir %>/<%=file%>"
-<% end %>
-# remove bin files
-<% Dir.chdir("../bin") %>
-<% FileList["**/*"].select {|i| File.file?(i)}.each do |file| %>
-/bin/rm -Rf "${3}<%= @apple_bindir %>/<%=file%>"
-<% end %>
-<% Dir.chdir("..") %>
-
-# remove old doc files
-/bin/rm -Rf "${3}<%= @apple_docdir %>/<%=@package_name%>"
diff --git a/ext/osx/prototype.plist.erb b/ext/osx/prototype.plist.erb
deleted file mode 100644
index e3afe30..0000000
--- a/ext/osx/prototype.plist.erb
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist>
-<dict>
- <key>CFBundleIdentifier</key>
- <string><%= @title %></string>
- <key>CFBundleShortVersionString</key>
- <string><%= @version %></string>
- <key>IFMajorVersion</key>
- <integer><%= @package_major_version %></integer>
- <key>IFMinorVersion</key>
- <integer><%= @package_minor_version %></integer>
- <key>IFPkgBuildDate</key>
- <date><%= @build_date %></date>
- <key>IFPkgFlagAllowBackRev</key>
- <false/>
- <key>IFPkgFlagAuthorizationAction</key>
- <string>RootAuthorization</string>
- <key>IFPkgFlagDefaultLocation</key>
- <string>/</string>
- <key>IFPkgFlagFollowLinks</key>
- <true/>
- <key>IFPkgFlagInstallFat</key>
- <false/>
- <key>IFPkgFlagIsRequired</key>
- <false/>
- <key>IFPkgFlagOverwritePermissions</key>
- <false/>
- <key>IFPkgFlagRelocatable</key>
- <false/>
- <key>IFPkgFlagRestartAction</key>
- <string><%= @pm_restart %></string>
- <key>IFPkgFlagRootVolumeOnly</key>
- <true/>
- <key>IFPkgFlagUpdateInstalledLanguages</key>
- <false/>
-</dict>
-</plist>
diff --git a/ext/project_data.yaml b/ext/project_data.yaml
deleted file mode 100644
index b034577..0000000
--- a/ext/project_data.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
----
-project: 'hiera'
-author: 'Puppet Labs'
-email: 'info at puppetlabs.com'
-homepage: 'https://github.com/puppetlabs/hiera'
-summary: 'Light weight hierarchical data store'
-description: 'A pluggable data store for hierarcical data'
-version_file: 'lib/hiera.rb'
-# files and gem_files are space separated lists
-files: '[A-Z]* ext lib bin spec acceptance_tests'
-gem_files: '{bin,lib}/**/* COPYING README.md LICENSE'
-gem_require_path: 'lib'
-gem_test_files: 'spec/**/*'
-gem_executables: 'hiera'
-gem_runtime_dependencies:
- json_pure:
-gem_default_executables: 'hiera'
diff --git a/ext/redhat/hiera.spec.erb b/ext/redhat/hiera.spec.erb
deleted file mode 100644
index 73c1b76..0000000
--- a/ext/redhat/hiera.spec.erb
+++ /dev/null
@@ -1,80 +0,0 @@
-# Fedora 17 ships with ruby 1.9, which uses vendorlibdir instead
-# of sitelibdir
-%if 0%{?fedora} >= 17
-%global hiera_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["vendorlibdir"]')
-%else
-%global hiera_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["sitelibdir"]')
-%endif
-
-%if 0%{?rhel} == 5
-%global _sharedstatedir %{_prefix}/lib
-%endif
-
-# VERSION is subbed out during rake srpm process
-%global realversion <%= @version %>
-%global rpmversion <%= @rpmversion %>
-
-Name: hiera
-Version: %{rpmversion}
-Release: <%= @rpmrelease -%>%{?dist}
-Summary: A simple pluggable Hierarchical Database
-Vendor: %{?_host_vendor}
-Group: System Environment/Base
-License: ASL 2.0
-URL: http://projects.puppetlabs.com/projects/%{name}/
-Source0: http://downloads.puppetlabs.com/%{name}/%{name}-%{realversion}.tar.gz
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-BuildArch: noarch
-BuildRequires: ruby >= 1.8.5
-Requires: ruby(abi) >= 1.8
-Requires: ruby >= 1.8.5
-Requires: rubygem-json
-
-%description
-A simple pluggable Hierarchical Database.
-
-%prep
-%setup -q -n %{name}-%{realversion}
-
-
-%build
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/%{hiera_libdir}
-mkdir -p $RPM_BUILD_ROOT/%{_bindir}
-mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}
-mkdir -p $RPM_BUILD_ROOT/%{_sharedstatedir}/hiera
-cp -pr lib/hiera $RPM_BUILD_ROOT/%{hiera_libdir}
-cp -pr lib/hiera.rb $RPM_BUILD_ROOT/%{hiera_libdir}
-install -p -m0755 bin/hiera $RPM_BUILD_ROOT/%{_bindir}
-install -p -m0644 ext/hiera.yaml $RPM_BUILD_ROOT/%{_sysconfdir}
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%files
-%defattr(-,root,root,-)
-%{_bindir}/hiera
-%{hiera_libdir}/hiera.rb
-%{hiera_libdir}/hiera
-%config(noreplace) %{_sysconfdir}/hiera.yaml
-%{_sharedstatedir}/hiera
-%doc COPYING README.md
-
-
-%changelog
-* <%= Time.now.strftime("%a %b %d %Y") %> Puppet Labs Release <info at puppetlabs.com> - <%= @rpmversion %>-<%= @rpmrelease %>
-- Build for <%= @version %>
-
-* Mon May 14 2012 Matthaus Litteken <matthaus at puppetlabs.com> - 1.0.0-0.1rc2
-- 1.0.0rc2 release
-
-* Mon May 14 2012 Matthaus Litteken <matthaus at puppetlabs.com> - 1.0.0-0.1rc1
-- 1.0.0rc1 release
-
-* Thu May 03 2012 Matthaus Litteken <matthaus at puppetlabs.com> - 0.3.0.28-1
-- Initial Hiera Packaging. Upstream version 0.3.0.28
-
diff --git a/lib/hiera.rb b/lib/hiera.rb
index c1707f3..ec9e28b 100644
--- a/lib/hiera.rb
+++ b/lib/hiera.rb
@@ -1,14 +1,16 @@
require 'yaml'
class Hiera
- VERSION = "1.1.2"
+ VERSION = "1.2.1"
- autoload :Config, "hiera/config"
- autoload :Util, "hiera/util"
- autoload :Backend, "hiera/backend"
- autoload :Console_logger, "hiera/console_logger"
- autoload :Puppet_logger, "hiera/puppet_logger"
- autoload :Noop_logger, "hiera/noop_logger"
+ require "hiera/config"
+ require "hiera/util"
+ require "hiera/backend"
+ require "hiera/console_logger"
+ require "hiera/puppet_logger"
+ require "hiera/noop_logger"
+ require "hiera/fallback_logger"
+ require "hiera/filecache"
class << self
attr_reader :logger
@@ -23,13 +25,13 @@ class Hiera
# See hiera-puppet for an example that uses the Puppet
# loging system instead of our own
def logger=(logger)
- loggerclass = "#{logger.capitalize}_logger"
+ require "hiera/#{logger}_logger"
- require "hiera/#{logger}_logger" unless constants.include?(loggerclass)
-
- @logger = const_get(loggerclass)
+ @logger = Hiera::FallbackLogger.new(
+ Hiera.const_get("#{logger.capitalize}_logger"),
+ Hiera::Console_logger)
rescue Exception => e
- @logger = Console_logger
+ @logger = Hiera::Console_logger
warn("Failed to load #{logger} logger: #{e.class}: #{e}")
end
diff --git a/lib/hiera/backend.rb b/lib/hiera/backend.rb
index 27cc1c6..9b3af5e 100644
--- a/lib/hiera/backend.rb
+++ b/lib/hiera/backend.rb
@@ -1,7 +1,15 @@
require 'hiera/util'
+require 'hiera/recursive_lookup'
+
+begin
+ require 'deep_merge'
+rescue LoadError
+end
class Hiera
module Backend
+ INTERPOLATION = /%\{([^\}]*)\}/
+
class << self
# Data lives in /var/lib/hiera by default. If a backend
# supplies a datadir in the config it will be used and
@@ -61,43 +69,38 @@ class Hiera
end
end
- # Parse a string like '%{foo}' against a supplied
+ # Parse a string like <code>'%{foo}'</code> against a supplied
# scope and additional scope. If either scope or
- # extra_scope includes the varaible 'foo' it will
+ # extra_scope includes the variable 'foo', then it will
# be replaced else an empty string will be placed.
#
- # If both scope and extra_data has "foo" scope
- # will win. See hiera-puppet for an example of
- # this to make hiera aware of additional non scope
- # variables
+ # If both scope and extra_data has "foo", then the value in scope
+ # will be used.
+ #
+ # @param data [String] The string to perform substitutions on.
+ # This will not be modified, instead a new string will be returned.
+ # @param scope [#[]] The primary source of data for substitutions.
+ # @param extra_data [#[]] The secondary source of data for substitutions.
+ # @return [String] A copy of the data with all instances of <code>%{...}</code> replaced.
+ #
+ # @api public
def parse_string(data, scope, extra_data={})
- return nil unless data
-
- tdata = data.clone
-
- if tdata.is_a?(String)
- while tdata =~ /%\{(.+?)\}/
- begin
- var = $1
-
- val = ""
-
- # Puppet can return :undefined for unknown scope vars,
- # If it does then we still need to evaluate extra_data
- # before returning an empty string.
- if scope[var] && scope[var] != :undefined
- val = scope[var]
- elsif extra_data[var]
- val = extra_data[var]
- end
- end until val != "" || var !~ /::(.+)/
+ interpolate(data, Hiera::RecursiveLookup.new(scope, extra_data))
+ end
- tdata.gsub!(/%\{(::)?#{var}\}/, val)
+ def interpolate(data, values)
+ if data.is_a?(String)
+ data.gsub(INTERPOLATION) do
+ name = $1
+ values.lookup(name) do |value|
+ interpolate(value, values)
+ end
end
+ else
+ data
end
-
- return tdata
end
+ private :interpolate
# Parses a answer received from data files
#
@@ -136,6 +139,26 @@ class Hiera
end
end
+ # Merges two hashes answers with the configured merge behavior.
+ # :merge_behavior: {:native|:deep|:deeper}
+ #
+ # Deep merge options use the Hash utility function provided by [deep_merge](https://github.com/peritor/deep_merge)
+ #
+ # :native => Native Hash.merge
+ # :deep => Use Hash.deep_merge
+ # :deeper => Use Hash.deep_merge!
+ #
+ def merge_answer(left,right)
+ case Config[:merge_behavior]
+ when :deeper,'deeper'
+ left.deep_merge!(right)
+ when :deep,'deep'
+ left.deep_merge(right)
+ else # Native and undefined
+ left.merge(right)
+ end
+ end
+
# Calls out to all configured backends in the order they
# were specified. The first one to answer will win.
#
@@ -167,7 +190,7 @@ class Hiera
when :hash
raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
answer ||= {}
- answer = new_answer.merge answer
+ answer = merge_answer(new_answer,answer)
else
answer = new_answer
break
diff --git a/lib/hiera/backend/json_backend.rb b/lib/hiera/backend/json_backend.rb
index 3919511..4ca9481 100644
--- a/lib/hiera/backend/json_backend.rb
+++ b/lib/hiera/backend/json_backend.rb
@@ -1,10 +1,12 @@
class Hiera
module Backend
class Json_backend
- def initialize
+ def initialize(cache=nil)
require 'json'
Hiera.debug("Hiera JSON backend starting")
+
+ @cache = cache || Filecache.new
end
def lookup(key, scope, order_override, resolution_type)
@@ -17,7 +19,11 @@ class Hiera
jsonfile = Backend.datafile(:json, scope, source, "json") || next
- data = JSON.parse(File.read(jsonfile))
+ next unless File.exist?(jsonfile)
+
+ data = @cache.read(jsonfile, Hash, {}) do |data|
+ JSON.parse(data)
+ end
next if data.empty?
next unless data.include?(key)
@@ -30,10 +36,15 @@ class Hiera
new_answer = Backend.parse_answer(data[key], scope)
case resolution_type
when :array
+ raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
answer ||= []
answer << new_answer
+ when :hash
+ raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
+ answer ||= {}
+ answer = Backend.merge_answer(new_answer,answer)
else
- answer = Backend.parse_answer(data[key], scope)
+ answer = new_answer
break
end
end
diff --git a/lib/hiera/backend/yaml_backend.rb b/lib/hiera/backend/yaml_backend.rb
index 06a9d1e..1ce6bd1 100644
--- a/lib/hiera/backend/yaml_backend.rb
+++ b/lib/hiera/backend/yaml_backend.rb
@@ -1,11 +1,11 @@
class Hiera
module Backend
class Yaml_backend
- def initialize
+ def initialize(cache=nil)
require 'yaml'
Hiera.debug("Hiera YAML backend starting")
- @data = Hash.new
- @cache = Hash.new
+
+ @cache = cache || Filecache.new
end
def lookup(key, scope, order_override, resolution_type)
@@ -17,20 +17,14 @@ class Hiera
Hiera.debug("Looking for data source #{source}")
yamlfile = Backend.datafile(:yaml, scope, source, "yaml") || next
- # If you call stale? BEFORE you do encounter the YAML.load_file line
- # it will populate the @cache variable and return true. The second
- # time you call it, it will return false because @cache has been
- # populated. Because of this there are two conditions to check:
- # is @data[yamlfile] populated AND is the cache stale.
- if @data[yamlfile]
- @data[yamlfile] = YAML.load_file(yamlfile) if stale?(yamlfile)
- else
- @data[yamlfile] = YAML.load_file(yamlfile)
+ next unless File.exist?(yamlfile)
+
+ data = @cache.read(yamlfile, Hash, {}) do |data|
+ YAML.load(data)
end
- next if ! @data[yamlfile]
- next if @data[yamlfile].empty?
- next unless @data[yamlfile].include?(key)
+ next if data.empty?
+ next unless data.include?(key)
# Extra logging that we found the key. This can be outputted
# multiple times if the resolution type is array or hash but that
@@ -43,7 +37,7 @@ class Hiera
# the array
#
# for priority searches we break after the first found data item
- new_answer = Backend.parse_answer(@data[yamlfile][key], scope)
+ new_answer = Backend.parse_answer(data[key], scope)
case resolution_type
when :array
raise Exception, "Hiera type mismatch: expected Array and got #{new_answer.class}" unless new_answer.kind_of? Array or new_answer.kind_of? String
@@ -52,7 +46,7 @@ class Hiera
when :hash
raise Exception, "Hiera type mismatch: expected Hash and got #{new_answer.class}" unless new_answer.kind_of? Hash
answer ||= {}
- answer = new_answer.merge answer
+ answer = Backend.merge_answer(new_answer,answer)
else
answer = new_answer
break
@@ -61,18 +55,6 @@ class Hiera
return answer
end
-
- def stale?(yamlfile)
- # NOTE: The mtime change in a file MUST be > 1 second before being
- # recognized as stale. File mtime changes within 1 second will
- # not be recognized.
- stat = File.stat(yamlfile)
- current = { 'inode' => stat.ino, 'mtime' => stat.mtime, 'size' => stat.size }
- return false if @cache[yamlfile] == current
-
- @cache[yamlfile] = current
- return true
- end
end
end
end
diff --git a/lib/hiera/config.rb b/lib/hiera/config.rb
index 807ed59..d29da7d 100644
--- a/lib/hiera/config.rb
+++ b/lib/hiera/config.rb
@@ -11,7 +11,8 @@ class Hiera::Config
# {:backends => "yaml", :hierarchy => "common"}
def load(source)
@config = {:backends => "yaml",
- :hierarchy => "common"}
+ :hierarchy => "common",
+ :merge_behavior => :native }
if source.is_a?(String)
if File.exist?(source)
@@ -41,10 +42,25 @@ class Hiera::Config
@config[:logger] = "console"
Hiera.logger = "console"
end
+
+ self.validate!
@config
end
+ def validate!
+ case @config[:merge_behavior]
+ when :deep,'deep',:deeper,'deeper'
+ begin
+ require "deep_merge"
+ rescue LoadError
+ Hiera.warn "Ignoring configured merge_behavior"
+ Hiera.warn "Must have 'deep_merge' gem installed."
+ @config[:merge_behavior] = :native
+ end
+ end
+ end
+
##
# yaml_load_file directly delegates to YAML.load_file and is intended to be
# a private, internal method suitable for stubbing and mocking.
diff --git a/lib/hiera/fallback_logger.rb b/lib/hiera/fallback_logger.rb
new file mode 100644
index 0000000..222bda1
--- /dev/null
+++ b/lib/hiera/fallback_logger.rb
@@ -0,0 +1,41 @@
+# Select from a given list of loggers the first one that
+# it suitable and use that as the actual logger
+#
+# @api private
+class Hiera::FallbackLogger
+ # Chooses the first suitable logger. For all of the loggers that are
+ # unsuitable it will issue a warning using the suitable logger stating that
+ # the unsuitable logger is not being used.
+ #
+ # @param implementations [Array<Hiera::Logger>] the implementations to choose from
+ # @raises when there are no suitable loggers
+ def initialize(*implementations)
+ warnings = []
+ @implementation = implementations.find do |impl|
+ if impl.respond_to?(:suitable?)
+ if impl.suitable?
+ true
+ else
+ warnings << "Not using #{impl.name}. It does not report itself to be suitable."
+ false
+ end
+ else
+ true
+ end
+ end
+
+ if @implementation.nil?
+ raise "No suitable logging implementation found."
+ end
+
+ warnings.each { |message| warn(message) }
+ end
+
+ def warn(message)
+ @implementation.warn(message)
+ end
+
+ def debug(message)
+ @implementation.debug(message)
+ end
+end
diff --git a/lib/hiera/filecache.rb b/lib/hiera/filecache.rb
new file mode 100644
index 0000000..ac46e02
--- /dev/null
+++ b/lib/hiera/filecache.rb
@@ -0,0 +1,74 @@
+class Hiera
+ class Filecache
+ def initialize
+ @cache = {}
+ end
+
+ # Reads a file, optionally parse it in some way check the
+ # output type and set a default
+ #
+ # Simply invoking it this way will return the file contents
+ #
+ # data = read("/some/file")
+ #
+ # But as most cases of file reading in hiera involves some kind
+ # of parsing through a serializer there's some help for those
+ # cases:
+ #
+ # data = read("/some/file", Hash, {}) do |data|
+ # JSON.parse(data)
+ # end
+ #
+ # In this case it will read the file, parse it using JSON then
+ # check that the end result is a Hash, if it's not a hash or if
+ # reading/parsing fails it will return {} instead
+ #
+ # Prior to calling this method you should be sure the file exist
+ def read(path, expected_type=nil, default=nil)
+ @cache[path] ||= {:data => nil, :meta => path_metadata(path)}
+
+ if File.exist?(path) && !@cache[path][:data] || stale?(path)
+ if block_given?
+ begin
+ @cache[path][:data] = yield(File.read(path))
+ rescue => e
+ Hiera.debug("Reading data from %s failed: %s: %S" % [path, e.class, e.to_s])
+ @cache[path][:data] = default
+ end
+ else
+ @cache[path][:data] = File.read(path)
+ end
+ end
+
+ if block_given? && !expected_type.nil?
+ unless @cache[path][:data].is_a?(expected_type)
+ Hiera.debug("Data retrieved from %s is not a %s, setting defaults" % [path, expected_type])
+ @cache[path][:data] = default
+ end
+ end
+
+ @cache[path][:data]
+ end
+
+ def stale?(path)
+ meta = path_metadata(path)
+
+ @cache[path] ||= {:data => nil, :meta => nil}
+
+ if @cache[path][:meta] == meta
+ return false
+ else
+ @cache[path][:meta] = meta
+ return true
+ end
+ end
+
+ # This is based on the old caching in the YAML backend and has a
+ # resolution of 1 second, changes made within the same second of
+ # a previous read will be ignored
+ def path_metadata(path)
+ stat = File.stat(path)
+ {:inode => stat.ino, :mtime => stat.mtime, :size => stat.size}
+ end
+ end
+end
diff --git a/lib/hiera/puppet_logger.rb b/lib/hiera/puppet_logger.rb
index abe0b60..fb1185e 100644
--- a/lib/hiera/puppet_logger.rb
+++ b/lib/hiera/puppet_logger.rb
@@ -1,6 +1,10 @@
class Hiera
module Puppet_logger
class << self
+ def suitable?
+ defined?(::Puppet) == "constant"
+ end
+
def warn(msg)
Puppet.notice("hiera(): #{msg}")
end
diff --git a/lib/hiera/recursive_lookup.rb b/lib/hiera/recursive_lookup.rb
new file mode 100644
index 0000000..5dfc53b
--- /dev/null
+++ b/lib/hiera/recursive_lookup.rb
@@ -0,0 +1,31 @@
+# Allow for safe recursive lookup of values during variable interpolation.
+#
+# @api private
+class Hiera::RecursiveLookup
+ def initialize(scope, extra_data)
+ @seen = []
+ @scope = scope
+ @extra_data = extra_data
+ end
+
+ def lookup(name, &block)
+ if @seen.include?(name)
+ raise Exception, "Interpolation loop detected in [#{@seen.join(', ')}]"
+ end
+ @seen.push(name)
+ ret = yield(current_value)
+ @seen.pop
+ ret
+ end
+
+ def current_value
+ name = @seen.last
+
+ scope_val = @scope[name]
+ if scope_val.nil? || scope_val == :undefined
+ @extra_data[name]
+ else
+ scope_val
+ end
+ end
+end
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..fb04e08
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,114 @@
+--- !ruby/object:Gem::Specification
+name: hiera
+version: !ruby/object:Gem::Version
+ hash: 29
+ prerelease:
+ segments:
+ - 1
+ - 2
+ - 1
+ version: 1.2.1
+platform: ruby
+authors:
+- Puppet Labs
+autorequire:
+bindir: bin
+cert_chain: []
+
+date: 2013-04-18 00:00:00 Z
+dependencies:
+- !ruby/object:Gem::Dependency
+ name: json_pure
+ prerelease: false
+ requirement: &id001 !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+ type: :runtime
+ version_requirements: *id001
+description: A pluggable data store for hierarcical data
+email: info at puppetlabs.com
+executables:
+- hiera
+extensions: []
+
+extra_rdoc_files: []
+
+files:
+- bin/hiera
+- lib/hiera/puppet_logger.rb
+- lib/hiera/recursive_lookup.rb
+- lib/hiera/console_logger.rb
+- lib/hiera/filecache.rb
+- lib/hiera/fallback_logger.rb
+- lib/hiera/util.rb
+- lib/hiera/backend.rb
+- lib/hiera/noop_logger.rb
+- lib/hiera/config.rb
+- lib/hiera/backend/yaml_backend.rb
+- lib/hiera/backend/json_backend.rb
+- lib/hiera.rb
+- COPYING
+- README.md
+- LICENSE
+- spec/unit/util_spec.rb
+- spec/unit/puppet_logger_spec.rb
+- spec/unit/config_spec.rb
+- spec/unit/backend_spec.rb
+- spec/unit/filecache_spec.rb
+- spec/unit/hiera_spec.rb
+- spec/unit/console_logger_spec.rb
+- spec/unit/backend/yaml_backend_spec.rb
+- spec/unit/backend/json_backend_spec.rb
+- spec/unit/fallback_logger_spec.rb
+- spec/spec_helper.rb
+homepage: https://github.com/puppetlabs/hiera
+licenses: []
+
+post_install_message:
+rdoc_options: []
+
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+required_rubygems_version: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ hash: 3
+ segments:
+ - 0
+ version: "0"
+requirements: []
+
+rubyforge_project:
+rubygems_version: 1.8.24
+signing_key:
+specification_version: 3
+summary: Light weight hierarchical data store
+test_files:
+- spec/unit/util_spec.rb
+- spec/unit/puppet_logger_spec.rb
+- spec/unit/config_spec.rb
+- spec/unit/backend_spec.rb
+- spec/unit/filecache_spec.rb
+- spec/unit/hiera_spec.rb
+- spec/unit/console_logger_spec.rb
+- spec/unit/backend/yaml_backend_spec.rb
+- spec/unit/backend/json_backend_spec.rb
+- spec/unit/fallback_logger_spec.rb
+- spec/spec_helper.rb
diff --git a/spec/unit/backend/json_backend_spec.rb b/spec/unit/backend/json_backend_spec.rb
index 76e486c..57497de 100644
--- a/spec/unit/backend/json_backend_spec.rb
+++ b/spec/unit/backend/json_backend_spec.rb
@@ -8,7 +8,8 @@ class Hiera
Hiera.stubs(:debug)
Hiera.stubs(:warn)
Hiera::Backend.stubs(:empty_answer).returns(nil)
- @backend = Json_backend.new
+ @cache = mock
+ @backend = Json_backend.new(@cache)
end
describe "#initialize" do
@@ -30,13 +31,9 @@ class Hiera
it "should retain the data types found in data files" do
Backend.expects(:datasources).yields("one").times(3)
Backend.expects(:datafile).with(:json, {}, "one", "json").returns("/nonexisting/one.json").times(3)
- File.expects(:read).with("/nonexisting/one.json").returns('{"stringval":"string",
- "boolval":true,
- "numericval":1}').times(3)
+ File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
- Backend.stubs(:parse_answer).with('string', {}).returns('string')
- Backend.stubs(:parse_answer).with(true, {}).returns(true)
- Backend.stubs(:parse_answer).with(1, {}).returns(1)
+ @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"stringval" => "string", "boolval" => true, "numericval" => 1}).times(3)
@backend.lookup("stringval", {}, nil, :priority).should == "string"
@backend.lookup("boolval", {}, nil, :priority).should == true
@@ -45,13 +42,12 @@ class Hiera
it "should pick data earliest source that has it for priority searches" do
scope = {"rspec" => "test"}
- Backend.stubs(:parse_answer).with('answer', scope).returns("answer")
- Backend.stubs(:parse_answer).with('test_%{rspec}', scope).returns("test_test")
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:json, scope, "one", "json").returns("/nonexisting/one.json")
- Backend.expects(:datafile).with(:json, scope, "two", "json").returns(nil).never
- File.expects(:read).with("/nonexisting/one.json").returns("one.json")
- JSON.expects(:parse).with("one.json").returns({"key" => "test_%{rspec}"})
+ Backend.expects(:datafile).with(:json, scope, "two", "json").never
+
+ File.stubs(:exist?).with("/nonexisting/one.json").returns(true)
+ @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "test_%{rspec}"})
@backend.lookup("key", scope, nil, :priority).should == "test_test"
end
@@ -64,11 +60,11 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
- File.expects(:read).with("/nonexisting/one.json").returns("one.json")
- File.expects(:read).with("/nonexisting/two.json").returns("two.json")
+ File.expects(:exist?).with("/nonexisting/one.json").returns(true)
+ File.expects(:exist?).with("/nonexisting/two.json").returns(true)
- JSON.expects(:parse).with("one.json").returns({"key" => "answer"})
- JSON.expects(:parse).with("two.json").returns({"key" => "answer"})
+ @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "answer"})
+ @cache.expects(:read).with("/nonexisting/two.json", Hash, {}).returns({"key" => "answer"})
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
end
@@ -78,8 +74,8 @@ class Hiera
Backend.expects(:datasources).yields("one")
Backend.expects(:datafile).with(:json, {"rspec" => "test"}, "one", "json").returns("/nonexisting/one.json")
- File.expects(:read).with("/nonexisting/one.json").returns("one.json")
- JSON.expects(:parse).with("one.json").returns({"key" => "test_%{rspec}"})
+ File.expects(:exist?).with("/nonexisting/one.json").returns(true)
+ @cache.expects(:read).with("/nonexisting/one.json", Hash, {}).returns({"key" => "test_%{rspec}"})
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
end
diff --git a/spec/unit/backend/yaml_backend_spec.rb b/spec/unit/backend/yaml_backend_spec.rb
index 2f0608d..72048c2 100644
--- a/spec/unit/backend/yaml_backend_spec.rb
+++ b/spec/unit/backend/yaml_backend_spec.rb
@@ -5,10 +5,11 @@ class Hiera
module Backend
describe Yaml_backend do
before do
+ Config.load({})
Hiera.stubs(:debug)
Hiera.stubs(:warn)
- @backend = Yaml_backend.new
- @backend.stubs(:stale?).returns(true)
+ @cache = mock
+ @backend = Yaml_backend.new(@cache)
end
describe "#initialize" do
@@ -31,7 +32,8 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns(nil).never
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: answer"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"answer"})
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
@backend.lookup("key", {}, nil, :priority).should == "answer"
end
@@ -47,7 +49,8 @@ class Hiera
it "should return nil for empty data files" do
Backend.expects(:datasources).multiple_yields(["one"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load(""))
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({})
@backend.lookup("key", {}, nil, :priority).should be_nil
end
@@ -56,9 +59,11 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: answer"))
- YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey: answer"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"answer"})
+ @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>"answer"})
@backend.lookup("key", {}, nil, :array).should == ["answer", "answer"]
end
@@ -67,9 +72,11 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load(""))
- YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: answer"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({})
+ @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer"}
end
@@ -78,9 +85,11 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n a: answer"))
- YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: wrong\n b: answer"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"b"=>"answer", "a"=>"wrong"}})
@backend.lookup("key", {}, nil, :hash).should == {"a" => "answer", "b" => "answer"}
end
@@ -89,28 +98,34 @@ class Hiera
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n- a\n- answer"))
- YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n a: answer"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>["a", "answer"]})
+ @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
- lambda {@backend.lookup("key", {}, nil, :array)}.should raise_error(Exception, "Hiera type mismatch: expected Array and got Hash")
+ expect {@backend.lookup("key", {}, nil, :array)}.to raise_error(Exception, "Hiera type mismatch: expected Array and got Hash")
end
it "should fail when trying to merge an Array" do
Backend.expects(:datasources).multiple_yields(["one"], ["two"])
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml")
Backend.expects(:datafile).with(:yaml, {}, "two", "yaml").returns("/nonexisting/two.yaml")
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+ File.stubs(:exist?).with("/nonexisting/two.yaml").returns(true)
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey:\n a: answer"))
- YAML.expects(:load_file).with("/nonexisting/two.yaml").returns(YAML.load("---\nkey:\n- a\n- wrong"))
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>{"a"=>"answer"}})
+ @cache.expects(:read).with("/nonexisting/two.yaml", Hash, {}).returns({"key"=>["a", "wrong"]})
- lambda {@backend.lookup("key", {}, nil, :hash)}.should raise_error(Exception, "Hiera type mismatch: expected Hash and got Array")
+ expect { @backend.lookup("key", {}, nil, :hash) }.to raise_error(Exception, "Hiera type mismatch: expected Hash and got Array")
end
it "should parse the answer for scope variables" do
Backend.expects(:datasources).yields("one")
Backend.expects(:datafile).with(:yaml, {"rspec" => "test"}, "one", "yaml").returns("/nonexisting/one.yaml")
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nkey: 'test_%{rspec}'"))
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).returns({"key"=>"test_%{rspec}"})
@backend.lookup("key", {"rspec" => "test"}, nil, :priority).should == "test_test"
end
@@ -118,8 +133,11 @@ class Hiera
it "should retain datatypes found in yaml files" do
Backend.expects(:datasources).yields("one").times(3)
Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns("/nonexisting/one.yaml").times(3)
+ File.stubs(:exist?).with("/nonexisting/one.yaml").returns(true)
+
+ yaml = "---\nstringval: 'string'\nboolval: true\nnumericval: 1"
- YAML.expects(:load_file).with("/nonexisting/one.yaml").returns(YAML.load("---\nstringval: 'string'\nboolval: true\nnumericval: 1")).times(3)
+ @cache.expects(:read).with("/nonexisting/one.yaml", Hash, {}).times(3).returns({"boolval"=>true, "numericval"=>1, "stringval"=>"string"})
@backend.lookup("stringval", {}, nil, :priority).should == "string"
@backend.lookup("boolval", {}, nil, :priority).should == true
@@ -127,60 +145,5 @@ class Hiera
end
end
end
-
- describe '#stale?' do
- before do
- Hiera.stubs(:debug)
- Hiera.stubs(:warn)
- @backend = Yaml_backend.new
- @fakestat = Struct.new(:ino, :mtime, :size)
- end
-
- def create_yaml_file(data, path)
- File.open(path, 'w') do |f|
- f.write(data)
- end
- end
-
- def update_file(data, path)
- File.open(path, 'a') do |f|
- f.write(data)
- end
- end
-
- it 'should report a stale cache if a data lookup has not been performed' do
- tmp_yamlfile = Pathname(Dir.mktmpdir('yaml')) + 'yamlfile'
- create_yaml_file({'foo' => 'bar'}.to_yaml, tmp_yamlfile)
- @backend.stale?(tmp_yamlfile).should == true
- end
-
- describe 'lookup tests' do
- before(:each) do
- @tmp_yamlfile = Pathname(Dir.mktmpdir('yaml')) + 'yamlfile'
- create_yaml_file({'foo' => 'bar'}.to_yaml, @tmp_yamlfile)
- Backend.expects(:datasources).yields("one")
- Backend.expects(:datafile).with(:yaml, {}, "one", "yaml").returns(@tmp_yamlfile)
- end
-
- it 'should not report a stale cache after a data lookup' do
- @backend.stale?(@tmp_yamlfile).should == true
- @backend.lookup('foo', {}, nil, :priority).should == 'bar'
- @backend.stale?(@tmp_yamlfile).should == false
- end
-
- [:ino, :mtime, :size].each do |attribute|
- it "should report a stale cache if a backend file's #{attribute} has changed" do
- @stat_instance = @fakestat.new(1234, 1234, 1234)
- File.expects(:stat).with(@tmp_yamlfile).returns(@stat_instance).twice
- @backend.stale?(@tmp_yamlfile).should == true
- @backend.lookup('foo', {}, nil, :priority).should == 'bar'
- @backend.stale?(@tmp_yamlfile).should == false
- @stat_instance[attribute] += 1
- File.unstub && File.expects(:stat).with(@tmp_yamlfile).returns(@stat_instance)
- @backend.stale?(@tmp_yamlfile).should == true
- end
- end
- end
- end
end
end
diff --git a/spec/unit/backend_spec.rb b/spec/unit/backend_spec.rb
index 2a55497..d5147c2 100644
--- a/spec/unit/backend_spec.rb
+++ b/spec/unit/backend_spec.rb
@@ -4,13 +4,13 @@ require 'hiera/util'
class Hiera
describe Backend do
describe "#datadir" do
- it "should use the backend configured dir" do
+ it "interpolates any values in the configured value" do
Config.load({:rspec => {:datadir => "/tmp"}})
Backend.expects(:parse_string).with("/tmp", {})
Backend.datadir(:rspec, {})
end
- it "should use a default var directory" do
+ it "defaults to a directory in var" do
Config.load({})
Backend.expects(:parse_string).with(Hiera::Util.var_dir, {})
Backend.datadir(:rspec, {})
@@ -18,13 +18,13 @@ class Hiera
end
describe "#datafile" do
- it "should check if the file exist and return nil if not" do
+ it "translates a non-existant datafile into nil" do
Hiera.expects(:debug).with("Cannot find datafile /nonexisting/test.yaml, skipping")
Backend.expects(:datadir).returns("/nonexisting")
Backend.datafile(:yaml, {}, "test", "yaml").should == nil
end
- it "should return the correct file name" do
+ it "concatenates the datadir and datafile and format to produce the full datafile filename" do
Backend.expects(:datadir).returns("/nonexisting")
File.expects(:exist?).with("/nonexisting/test.yaml").returns(true)
Backend.datafile(:yaml, {}, "test", "yaml").should == "/nonexisting/test.yaml"
@@ -32,7 +32,7 @@ class Hiera
end
describe "#datasources" do
- it "should use the supplied hierarchy" do
+ it "iterates over the datasources in the order of the given hierarchy" do
expected = ["one", "two"]
Backend.datasources({}, nil, ["one", "two"]) do |backend|
backend.should == expected.delete_at(0)
@@ -41,7 +41,7 @@ class Hiera
expected.empty?.should == true
end
- it "should use the configured hierarchy if none is supplied" do
+ it "uses the configured hierarchy no specific hierarchy is given" do
Config.load(:hierarchy => "test")
Backend.datasources({}) do |backend|
@@ -49,7 +49,7 @@ class Hiera
end
end
- it "should default to common if not configured or supplied" do
+ it "defaults to a hierarchy of only 'common' if not configured or given" do
Config.load({})
Backend.datasources({}) do |backend|
@@ -57,7 +57,7 @@ class Hiera
end
end
- it "should insert the override if provided" do
+ it "prefixes the hierarchy with the override if an override is provided" do
Config.load({})
expected = ["override", "common"]
@@ -68,12 +68,12 @@ class Hiera
expected.empty?.should == true
end
- it "should parse the sources based on scope" do
+ it "parses the names of the hierarchy levels using the given scope" do
Backend.expects(:parse_string).with("common", {:rspec => :tests})
Backend.datasources({:rspec => :tests}) { }
end
- it "should not return empty sources" do
+ it "defaults to 'common' if the hierarchy contains no hierarchies with non-empty names" do
Config.load({})
expected = ["common"]
@@ -86,101 +86,153 @@ class Hiera
end
describe "#parse_string" do
- it "should not try to parse invalid data" do
+ it "passes nil through untouched" do
Backend.parse_string(nil, {}).should == nil
end
- it "should clone the supplied data" do
- data = ""
- data.expects(:clone).returns("")
- Backend.parse_string(data, {})
+ it "does not modify the input data" do
+ data = "%{value}"
+ Backend.parse_string(data, { "value" => "replacement" })
+
+ data.should == "%{value}"
end
- it "should only parse string data" do
- data = ""
- data.expects(:is_a?).with(String)
- Backend.parse_string(data, {})
+ it "passes non-string data through untouched" do
+ input = { "not a" => "string" }
+
+ Backend.parse_string(input, {}).should == input
end
- it "should match data from scope" do
- input = "test_%{rspec}_test"
- Backend.parse_string(input, {"rspec" => "test"}).should == "test_test_test"
+ it "replaces interpolations with data looked up in the scope" do
+ input = "replace %{part1} and %{part2}"
+ scope = {"part1" => "value of part1", "part2" => "value of part2"}
+
+ Backend.parse_string(input, scope).should == "replace value of part1 and value of part2"
end
- it "should match data from extra_data" do
+ it "replaces interpolations with data looked up in extra_data when scope does not contain the value" do
input = "test_%{rspec}_test"
- Backend.parse_string(input, {}, {"rspec" => "test"}).should == "test_test_test"
+ Backend.parse_string(input, {}, {"rspec" => "extra"}).should == "test_extra_test"
end
- it "should prefer scope over extra_data" do
+ it "prefers data from scope over data from extra_data" do
input = "test_%{rspec}_test"
Backend.parse_string(input, {"rspec" => "test"}, {"rspec" => "fail"}).should == "test_test_test"
end
- it "should treat :undefined in scope as empty" do
+ it "interprets nil in scope as a non-value" do
+ input = "test_%{rspec}_test"
+ Backend.parse_string(input, {"rspec" => nil}).should == "test__test"
+ end
+
+ it "interprets false in scope as a real value" do
+ input = "test_%{rspec}_test"
+ Backend.parse_string(input, {"rspec" => false}).should == "test_false_test"
+ end
+
+ it "interprets false in extra_data as a real value" do
+ input = "test_%{rspec}_test"
+ Backend.parse_string(input, {}, {"rspec" => false}).should == "test_false_test"
+ end
+
+ it "interprets nil in extra_data as a non-value" do
+ input = "test_%{rspec}_test"
+ Backend.parse_string(input, {}, {"rspec" => nil}).should == "test__test"
+ end
+
+ it "interprets :undefined in scope as a non-value" do
input = "test_%{rspec}_test"
Backend.parse_string(input, {"rspec" => :undefined}).should == "test__test"
end
- it "should match data from extra_data when scope contains :undefined" do
+ it "uses the value from extra_data when scope is :undefined" do
input = "test_%{rspec}_test"
- Backend.parse_string(input, {"rspec" => :undefined}, {"rspec" => "test"}).should == "test_test_test"
+ Backend.parse_string(input, {"rspec" => :undefined}, { "rspec" => "extra" }).should == "test_extra_test"
+ end
+
+ it "looks up the interpolated value exactly as it appears in the input" do
+ input = "test_%{::rspec::data}_test"
+ Backend.parse_string(input, {"::rspec::data" => "value"}).should == "test_value_test"
+ end
+
+ it "does not remove any surrounding whitespace when parsing the key to lookup" do
+ input = "test_%{\trspec::data }_test"
+ Backend.parse_string(input, {"\trspec::data " => "value"}).should == "test_value_test"
end
- it "should match data in puppet ${::fact} style" do
- input = "test_%{::rspec}_test"
- Backend.parse_string(input, {"rspec" => "test"}).should == "test_test_test"
+ it "does not try removing leading :: when a full lookup fails (#17434)" do
+ input = "test_%{::rspec::data}_test"
+ Backend.parse_string(input, {"rspec::data" => "value"}).should == "test__test"
+ end
+
+ it "does not try removing leading sections separated by :: when a full lookup fails (#17434)" do
+ input = "test_%{::rspec::data}_test"
+ Backend.parse_string(input, {"data" => "value"}).should == "test__test"
+ end
+
+ it "looks up recursively" do
+ scope = {"rspec" => "%{first}", "first" => "%{last}", "last" => "final"}
+ input = "test_%{rspec}_test"
+ Backend.parse_string(input, scope).should == "test_final_test"
+ end
+
+ it "raises an error if the recursive lookup results in an infinite loop" do
+ scope = {"first" => "%{second}", "second" => "%{first}"}
+ input = "test_%{first}_test"
+ expect do
+ Backend.parse_string(input, scope)
+ end.to raise_error Exception, "Interpolation loop detected in [first, second]"
end
end
describe "#parse_answer" do
- it "should parse strings correctly" do
+ it "interpolates values in strings" do
input = "test_%{rspec}_test"
Backend.parse_answer(input, {"rspec" => "test"}).should == "test_test_test"
end
- it "should parse each string in an array" do
+ it "interpolates each string in an array" do
input = ["test_%{rspec}_test", "test_%{rspec}_test", ["test_%{rspec}_test"]]
Backend.parse_answer(input, {"rspec" => "test"}).should == ["test_test_test", "test_test_test", ["test_test_test"]]
end
- it "should parse each string in a hash" do
+ it "interpolates each string in a hash" do
input = {"foo" => "test_%{rspec}_test", "bar" => "test_%{rspec}_test"}
Backend.parse_answer(input, {"rspec" => "test"}).should == {"foo"=>"test_test_test", "bar"=>"test_test_test"}
end
- it "should parse mixed arrays and hashes" do
+ it "interpolates strings in a mixed structure of arrays and hashes" do
input = {"foo" => "test_%{rspec}_test", "bar" => ["test_%{rspec}_test", "test_%{rspec}_test"]}
Backend.parse_answer(input, {"rspec" => "test"}).should == {"foo"=>"test_test_test", "bar"=>["test_test_test", "test_test_test"]}
end
- it "should parse integers correctly" do
+ it "passes integers unchanged" do
input = 1
Backend.parse_answer(input, {"rspec" => "test"}).should == 1
end
- it "should parse floats correctly" do
+ it "passes floats unchanged" do
input = 0.233
Backend.parse_answer(input, {"rspec" => "test"}).should == 0.233
end
- it "should parse true boolean values correctly" do
+ it "passes the boolean true unchanged" do
input = true
Backend.parse_answer(input, {"rspec" => "test"}).should == true
end
- it "should parse false boolean values correctly" do
+ it "passes the boolean false unchanged" do
input = false
Backend.parse_answer(input, {"rspec" => "test"}).should == false
end
end
describe "#resolve_answer" do
- it "should correctly parse array data" do
+ it "flattens and removes duplicate values from arrays during an array lookup" do
Backend.resolve_answer(["foo", ["foo", "foo"], "bar"], :array).should == ["foo", "bar"]
end
- it "should just return the answer for non array data" do
+ it "returns the data unchanged during a priority lookup" do
Backend.resolve_answer(["foo", ["foo", "foo"], "bar"], :priority).should == ["foo", ["foo", "foo"], "bar"]
end
end
@@ -191,7 +243,7 @@ class Hiera
Hiera.stubs(:warn)
end
- it "should cache backends" do
+ it "caches loaded backends" do
Hiera.expects(:debug).with(regexp_matches(/Hiera YAML backend starting/)).once
Config.load({:yaml => {:datadir => "/tmp"}})
@@ -201,7 +253,7 @@ class Hiera
Backend.lookup("key", "default", {}, nil, nil)
end
- it "should return the answer from the backend" do
+ it "returns the answer from the backend" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
@@ -210,7 +262,7 @@ class Hiera
Backend.lookup("key", "default", {}, nil, nil).should == "answer"
end
- it "should retain the datatypes as returned by the backend" do
+ it "retains the datatypes as returned by the backend" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
@@ -223,7 +275,7 @@ class Hiera
Backend.lookup("numericval", "default", {}, nil, nil).should == 1
end
- it "should call to all backends till an answer is found" do
+ it "calls to all backends till an answer is found" do
backend = mock
backend.expects(:lookup).returns("answer")
Config.load({})
@@ -235,7 +287,7 @@ class Hiera
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, nil).should == "answer"
end
- it "should call to all backends till an answer is found when doing array lookups" do
+ it "calls to all backends till an answer is found when doing array lookups" do
backend = mock
backend.expects(:lookup).returns(["answer"])
Config.load({})
@@ -246,7 +298,7 @@ class Hiera
Backend.lookup("key", "notfound", {"rspec" => "test"}, nil, :array).should == ["answer"]
end
- it "should call to all backends till an answer is found when doing hash lookups" do
+ it "calls to all backends till an answer is found when doing hash lookups" do
thehash = {:answer => "value"}
backend = mock
backend.expects(:lookup).returns(thehash)
@@ -258,7 +310,7 @@ class Hiera
Backend.lookup("key", "notfound", {"rspec" => "test"}, nil, :hash).should == thehash
end
- it "should build a merged hash from all backends for hash searches" do
+ it "builds a merged hash from all backends for hash searches" do
backend1 = mock :lookup => {"a" => "answer"}
backend2 = mock :lookup => {"b" => "bnswer"}
Config.load({})
@@ -269,7 +321,7 @@ class Hiera
Backend.lookup("key", {}, {"rspec" => "test"}, nil, :hash).should == {"a" => "answer", "b" => "bnswer"}
end
- it "should build an array from all backends for array searches" do
+ it "builds an array from all backends for array searches" do
backend1 = mock :lookup => ["a", "b"]
backend2 = mock :lookup => ["c", "d"]
Config.load({})
@@ -280,7 +332,7 @@ class Hiera
Backend.lookup("key", {}, {"rspec" => "test"}, nil, :array).should == ["a", "b", "c", "d"]
end
- it "should use the earliest backend result for priority searches" do
+ it "uses the earliest backend result for priority searches" do
backend1 = mock
backend1.stubs(:lookup).returns(["a", "b"])
backend2 = mock
@@ -293,7 +345,7 @@ class Hiera
Backend.lookup("key", {}, {"rspec" => "test"}, nil, :priority).should == ["a", "b"]
end
- it "should parse the answers based on resolution_type" do
+ it "parses the answers based on resolution_type" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
@@ -303,7 +355,7 @@ class Hiera
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, :priority).should == "parsed"
end
- it "should return the default with variables parsed if nothing is found" do
+ it "returns the default with variables parsed if nothing is found" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
@@ -312,26 +364,52 @@ class Hiera
Backend.lookup("key", "test_%{rspec}", {"rspec" => "test"}, nil, nil).should == "test_test"
end
- it "should correctly handle string default data" do
+ it "keeps string default data as a string" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, nil)
Backend.lookup("key", "test", {}, nil, nil).should == "test"
end
- it "should correctly handle array default data" do
+ it "keeps array default data as an array" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :array)
Backend.lookup("key", ["test"], {}, nil, :array).should == ["test"]
end
- it "should correctly handle hash default data" do
+ it "keeps hash default data as a hash" do
Config.load({:yaml => {:datadir => "/tmp"}})
Config.load_backends
Backend::Yaml_backend.any_instance.expects(:lookup).with("key", {}, nil, :hash)
Backend.lookup("key", {"test" => "value"}, {}, nil, :hash).should == {"test" => "value"}
end
end
+
+ describe '#merge_answer' do
+ before do
+ Hiera.stubs(:debug)
+ Hiera.stubs(:warn)
+ Config.stubs(:validate!)
+ end
+
+ it "uses Hash.merge when configured with :merge_behavior => :native" do
+ Config.load({:merge_behavior => :native})
+ Hash.any_instance.expects(:merge).with({"b" => "bnswer"}).returns({"a" => "answer", "b" => "bnswer"})
+ Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
+ end
+
+ it "uses deep_merge! when configured with :merge_behavior => :deeper" do
+ Config.load({:merge_behavior => :deeper})
+ Hash.any_instance.expects('deep_merge!').with({"b" => "bnswer"}).returns({"a" => "answer", "b" => "bnswer"})
+ Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
+ end
+
+ it "uses deep_merge when configured with :merge_behavior => :deep" do
+ Config.load({:merge_behavior => :deep})
+ Hash.any_instance.expects('deep_merge').with({"b" => "bnswer"}).returns({"a" => "answer", "b" => "bnswer"})
+ Backend.merge_answer({"a" => "answer"},{"b" => "bnswer"}).should == {"a" => "answer", "b" => "bnswer"}
+ end
+ end
end
end
diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb
index 60a1627..44f3064 100644
--- a/spec/unit/config_spec.rb
+++ b/spec/unit/config_spec.rb
@@ -7,7 +7,8 @@ class Hiera
{
:backends => ["yaml"],
:hierarchy => "common",
- :logger => "console"
+ :logger => "console",
+ :merge_behavior=>:native
}
end
@@ -43,11 +44,11 @@ class Hiera
it "should merge defaults with the loaded or supplied config" do
config = Config.load({})
- config.should == {:backends => ["yaml"], :hierarchy => "common", :logger => "console"}
+ config.should == {:backends => ["yaml"], :hierarchy => "common", :logger => "console", :merge_behavior=>:native}
end
it "should force :backends to be a flattened array" do
- Config.load({:backends => [["foo", ["bar"]]]}).should == {:backends => ["foo", "bar"], :hierarchy => "common", :logger => "console"}
+ Config.load({:backends => [["foo", ["bar"]]]}).should == {:backends => ["foo", "bar"], :hierarchy => "common", :logger => "console", :merge_behavior=>:native}
end
it "should load the supplied logger" do
diff --git a/spec/unit/fallback_logger_spec.rb b/spec/unit/fallback_logger_spec.rb
new file mode 100644
index 0000000..bf864d0
--- /dev/null
+++ b/spec/unit/fallback_logger_spec.rb
@@ -0,0 +1,80 @@
+require 'hiera/fallback_logger'
+
+describe Hiera::FallbackLogger do
+ before :each do
+ InMemoryLogger.reset
+ SuitableLogger.reset
+ end
+
+ it "delegates #warn to the logger implemenation" do
+ logger = Hiera::FallbackLogger.new(InMemoryLogger)
+
+ logger.warn("the message")
+
+ InMemoryLogger.warnings.should == ["the message"]
+ end
+
+ it "delegates #debug to the logger implemenation" do
+ logger = Hiera::FallbackLogger.new(InMemoryLogger)
+
+ logger.debug("the message")
+
+ InMemoryLogger.debugs.should == ["the message"]
+ end
+
+ it "chooses the first logger that is suitable" do
+ logger = Hiera::FallbackLogger.new(UnsuitableLogger, SuitableLogger)
+
+ logger.warn("for the suitable logger")
+
+ SuitableLogger.warnings.should include("for the suitable logger")
+ end
+
+ it "raises an error if no implementation is suitable" do
+ expect do
+ Hiera::FallbackLogger.new(UnsuitableLogger)
+ end.to raise_error "No suitable logging implementation found."
+ end
+
+ it "issues a warning for each implementation that is not suitable" do
+ Hiera::FallbackLogger.new(UnsuitableLogger, UnsuitableLogger, SuitableLogger)
+
+ SuitableLogger.warnings.should == [
+ "Not using UnsuitableLogger. It does not report itself to be suitable.",
+ "Not using UnsuitableLogger. It does not report itself to be suitable."]
+ end
+
+ # Preserves log messages in memory
+ # and also serves as a "legacy" logger that has no
+ # suitable? method
+ class InMemoryLogger
+ class << self
+ attr_accessor :warnings, :debugs
+ end
+
+ def self.reset
+ self.warnings = []
+ self.debugs = []
+ end
+
+ def self.warn(message)
+ self.warnings << message
+ end
+
+ def self.debug(message)
+ self.debugs << message
+ end
+ end
+
+ class UnsuitableLogger
+ def self.suitable?
+ false
+ end
+ end
+
+ class SuitableLogger < InMemoryLogger
+ def self.suitable?
+ true
+ end
+ end
+end
diff --git a/spec/unit/filecache_spec.rb b/spec/unit/filecache_spec.rb
new file mode 100644
index 0000000..2a7dd72
--- /dev/null
+++ b/spec/unit/filecache_spec.rb
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+class Hiera
+ describe Filecache do
+ before do
+ File.stubs(:exist?).returns(true)
+ @cache = Filecache.new
+ end
+
+ describe "#read" do
+ it "should cache and read data" do
+ File.expects(:read).with("/nonexisting").returns("text")
+ @cache.expects(:path_metadata).returns(File.stat(__FILE__)).once
+ @cache.expects(:stale?).once.returns(false)
+
+ @cache.read("/nonexisting").should == "text"
+ @cache.read("/nonexisting").should == "text"
+ end
+
+ it "should support validating return types and setting defaults" do
+ File.expects(:read).with("/nonexisting").returns('{"rspec":1}')
+
+ @cache.expects(:path_metadata).returns(File.stat(__FILE__))
+
+ Hiera.expects(:debug).with(regexp_matches(/is not a Hash, setting defaults/))
+
+ # return bogus data on purpose, triggers setting defaults
+ data = @cache.read("/nonexisting", Hash, {"rspec" => 1}) do |data|
+ nil
+ end
+
+ data.should == {"rspec" => 1}
+ end
+ end
+
+ describe "#stale?" do
+ it "should return false when the file has not changed" do
+ stat = File.stat(__FILE__)
+
+ @cache.stubs(:path_metadata).returns(stat)
+ @cache.stale?("/nonexisting").should == true
+ @cache.stale?("/nonexisting").should == false
+ end
+
+ it "should update and return true when the file changed" do
+ @cache.expects(:path_metadata).returns({:inode => 1, :mtime => Time.now, :size => 1})
+ @cache.stale?("/nonexisting").should == true
+ @cache.expects(:path_metadata).returns({:inode => 2, :mtime => Time.now, :size => 1})
+ @cache.stale?("/nonexisting").should == true
+ end
+ end
+
+ describe "#path_metadata" do
+ it "should return the right data" do
+ stat = File.stat(__FILE__)
+
+ File.expects(:stat).with("/nonexisting").returns(stat)
+
+ @cache.path_metadata("/nonexisting").should == {:inode => stat.ino, :mtime => stat.mtime, :size => stat.size}
+ end
+ end
+ end
+end
diff --git a/spec/unit/hiera_spec.rb b/spec/unit/hiera_spec.rb
index e9edaef..99ec89a 100644
--- a/spec/unit/hiera_spec.rb
+++ b/spec/unit/hiera_spec.rb
@@ -1,50 +1,69 @@
require 'spec_helper'
require 'hiera/util'
+# This is only around for the logger setup tests
+module Hiera::Foo_logger
+end
+
describe "Hiera" do
describe "#logger=" do
- it "should attempt to load the supplied logger" do
- Hiera.stubs(:warn)
- Hiera.expects(:require).with("hiera/foo_logger").raises("fail")
+ it "loads the given logger" do
+ Hiera.expects(:require).with("hiera/foo_logger")
+
Hiera.logger = "foo"
end
- it "should fall back to the Console logger on failure" do
+ it "falls back to the Console logger when the logger could not be loaded" do
Hiera.expects(:warn)
- Hiera.logger = "foo"
+
+ Hiera.logger = "no_such_logger"
+
+ Hiera.logger.should be Hiera::Console_logger
+ end
+
+ it "falls back to the Console logger when the logger class could not be found" do
+ Hiera.expects(:warn)
+ Hiera.expects(:require).with("hiera/no_constant_logger")
+
+ Hiera.logger = "no_constant"
+
Hiera.logger.should be Hiera::Console_logger
end
end
describe "#warn" do
- it "should call the supplied logger" do
+ it "delegates to the configured logger" do
+ Hiera.logger = 'console'
Hiera::Console_logger.expects(:warn).with("rspec")
+
Hiera.warn("rspec")
end
end
describe "#debug" do
- it "should call the supplied logger" do
+ it "delegates to the configured logger" do
+ Hiera.logger = 'console'
Hiera::Console_logger.expects(:debug).with("rspec")
+
Hiera.debug("rspec")
end
end
describe "#initialize" do
- it "should use a default config" do
+ it "uses a default config file when none is provided" do
config_file = File.join(Hiera::Util.config_dir, 'hiera.yaml')
Hiera::Config.expects(:load).with(config_file)
Hiera::Config.stubs(:load_backends)
Hiera.new
end
- it "should pass the supplied config to the config class" do
+ it "passes the supplied config to the config class" do
Hiera::Config.expects(:load).with({"test" => "rspec"})
Hiera::Config.stubs(:load_backends)
Hiera.new(:config => {"test" => "rspec"})
end
- it "should load all backends on start" do
+ it "loads all backends on start" do
Hiera::Config.stubs(:load)
Hiera::Config.expects(:load_backends)
Hiera.new
@@ -52,7 +71,7 @@ describe "Hiera" do
end
describe "#lookup" do
- it "should proxy to the Backend#lookup method" do
+ it "delegates to the Backend#lookup method" do
Hiera::Config.stubs(:load)
Hiera::Config.stubs(:load_backends)
Hiera::Backend.expects(:lookup).with(:key, :default, :scope, :order_override, :resolution_type)
diff --git a/spec/unit/puppet_logger_spec.rb b/spec/unit/puppet_logger_spec.rb
new file mode 100644
index 0000000..c3e23ad
--- /dev/null
+++ b/spec/unit/puppet_logger_spec.rb
@@ -0,0 +1,31 @@
+require 'hiera/puppet_logger'
+
+describe Hiera::Puppet_logger do
+ it "is not suitable when Puppet is not defined" do
+ ensure_puppet_not_defined
+
+ Hiera::Puppet_logger.suitable?.should == false
+ end
+
+ it "is suitable when Puppet is defined" do
+ ensure_puppet_defined
+
+ Hiera::Puppet_logger.suitable?.should == true
+ end
+
+ after :each do
+ ensure_puppet_not_defined
+ end
+
+ def ensure_puppet_defined
+ if !Kernel.const_defined? :Puppet
+ Kernel.const_set(:Puppet, "Fake Puppet")
+ end
+ end
+
+ def ensure_puppet_not_defined
+ if Kernel.const_defined? :Puppet
+ Kernel.send(:remove_const, :Puppet)
+ end
+ end
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-hiera.git
More information about the Pkg-ruby-extras-commits
mailing list