diff options
-rw-r--r-- | CHANGELOG | 3 | ||||
-rw-r--r-- | LICENSE | 15 | ||||
-rw-r--r-- | Modulefile | 11 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | Rakefile | 35 | ||||
-rw-r--r-- | manifests/params.pp | 5 | ||||
-rw-r--r-- | spec/classes/tftp_spec.rb | 28 | ||||
-rw-r--r-- | spec/defines/tftp_file_spec.rb | 49 | ||||
-rw-r--r-- | spec/fixtures/manifests/site.pp | 0 | ||||
l--------- | spec/fixtures/modules/tftp | 1 | ||||
-rw-r--r-- | spec/puppetlabs_spec/files.rb | 57 | ||||
-rw-r--r-- | spec/puppetlabs_spec/fixtures.rb | 49 | ||||
-rw-r--r-- | spec/puppetlabs_spec/matchers.rb | 87 | ||||
-rw-r--r-- | spec/puppetlabs_spec_helper.rb | 25 | ||||
-rw-r--r-- | spec/spec_helper.rb | 20 |
15 files changed, 384 insertions, 3 deletions
diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..ccb202d --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,3 @@ +0.1.0 2012-05-1 Nan Liu <nan@puppetlabs.com> + +* Initial release of module. @@ -0,0 +1,15 @@ +Copyright (C) 2012 Puppet Labs Inc + +Puppet Labs can be contacted at: info@puppetlabs.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Modulefile b/Modulefile new file mode 100644 index 0000000..8855f8b --- /dev/null +++ b/Modulefile @@ -0,0 +1,11 @@ +name 'puppetlabs-tftp' +version '0.1.0' +source 'git://github.com/puppetlabs/puppetlabs-tftp' +author 'puppetlabs' +license 'Apache 2.0' +summary 'tftp Puppet Module' +description 'tftp Puppet Module.' +project_page 'https://github.com/puppetlabs/puppetlabs-tftp' + +## Add dependencies, if any: +# dependency 'username/name', '>= 1.2.0' @@ -1,4 +1,4 @@ -# puppet-tftp module +# puppet tftp module ## Overview diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..6f28836 --- /dev/null +++ b/Rakefile @@ -0,0 +1,35 @@ +require 'rubygems' +require 'rake' +require 'rspec/core/rake_task' + +task :default do + system("rake -T") +end + +task :specs => [:spec] + +desc "Run all rspec-puppet tests" +RSpec::Core::RakeTask.new(:spec) do |t| + t.rspec_opts = ['--color'] + # ignores fixtures directory. + t.pattern = 'spec/{classes,defines,unit}/**/*_spec.rb' +end + +desc "Build puppet module package" +task :build do + # This will be deprecated once puppet-module is a face. + begin + Gem::Specification.find_by_name('puppet-module') + rescue Gem::LoadError, NoMethodError + require 'puppet/face' + pmod = Puppet::Face['module', :current] + pmod.build('./') + end +end + +desc "Check puppet manifests with puppet-lint" +task :lint do + # This requires pull request: https://github.com/rodjek/puppet-lint/pull/81 + system("puppet-lint manifests") + system("puppet-lint tests") +end diff --git a/manifests/params.pp b/manifests/params.pp index df43e6c..b268114 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -16,7 +16,8 @@ class tftp::params { case $::operatingsystem { 'debian': { - # hasstatus is to get around an issue where the service script appears to be broken. + # hasstatus is to get around an issue where the service script appears to + # be broken. $directory = '/srv/tftp' $hasstatus = false $provider = undef @@ -27,7 +28,7 @@ class tftp::params { $provider = 'upstart' } default: { - warning("tftp:: module not verified on operatingsystem ${::operatingsystem}.") + warning("tftp:: not verified on operatingsystem ${::operatingsystem}.") $directory = '/var/lib/tftpboot' $hasstatus = true $provider = undef diff --git a/spec/classes/tftp_spec.rb b/spec/classes/tftp_spec.rb new file mode 100644 index 0000000..3e17286 --- /dev/null +++ b/spec/classes/tftp_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +describe 'tftp', :type => :class do + + describe 'when deploying on debian' do + let(:facts) { { :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { should contain_file('/etc/default/tftpd-hpa') } + it { should contain_package('tftpd-hpa') } + it { should contain_service('tftpd-hpa').with({ + 'hasstatus' => false, + 'provider' => nil, + }) } + end + + describe 'when deploying on ubuntu' do + let(:facts) { { :operatingsystem => 'ubuntu', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { should contain_package('tftpd-hpa') } + it { should contain_file('/etc/default/tftpd-hpa') } + it { should contain_service('tftpd-hpa').with({ + 'hasstatus' => true, + 'provider' => 'upstart', + }) } + end + +end diff --git a/spec/defines/tftp_file_spec.rb b/spec/defines/tftp_file_spec.rb new file mode 100644 index 0000000..00072e6 --- /dev/null +++ b/spec/defines/tftp_file_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +describe 'tftp::file' do + + let(:title) { 'sample' } + + describe 'when deploying on debian' do + let(:facts) { { :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { should include_class('tftp') } + it { should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'file', + 'owner' => 'tftp', + 'group' => 'tftp', + 'mode' => '0644' + }) } + end + + describe 'when deploying on ubuntu' do + let(:facts) { { :operatingsystem => 'ubuntu', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { should include_class('tftp') } + it { should contain_file('/var/lib/tftpboot/sample').with({ + 'ensure' => 'file', + 'owner' => 'tftp', + 'group' => 'tftp', + 'mode' => '0644' + }) } + end + + describe 'when deploying with parameters' do + let(:params) { {:ensure => 'directory', + :owner => 'root', + :group => 'root', + :mode => '0755' }} + let(:facts) { { :operatingsystem => 'Debian', + :path => '/usr/local/bin:/usr/bin:/bin', } } + + it { should include_class('tftp') } + it { should contain_file('/srv/tftp/sample').with({ + 'ensure' => 'directory', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0755' + }) } + end +end diff --git a/spec/fixtures/manifests/site.pp b/spec/fixtures/manifests/site.pp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/spec/fixtures/manifests/site.pp diff --git a/spec/fixtures/modules/tftp b/spec/fixtures/modules/tftp new file mode 120000 index 0000000..1b20c9f --- /dev/null +++ b/spec/fixtures/modules/tftp @@ -0,0 +1 @@ +../../../
\ No newline at end of file diff --git a/spec/puppetlabs_spec/files.rb b/spec/puppetlabs_spec/files.rb new file mode 100644 index 0000000..d64cb3f --- /dev/null +++ b/spec/puppetlabs_spec/files.rb @@ -0,0 +1,57 @@ +require 'fileutils' +require 'tempfile' +require 'pathname' + +# A support module for testing files. +module PuppetlabsSpec::Files + # This code exists only to support tests that run as root, pretty much. + # Once they have finally been eliminated this can all go... --daniel 2011-04-08 + def self.in_tmp(path) + tempdir = Dir.tmpdir + + Pathname.new(path).ascend do |dir| + return true if File.identical?(tempdir, dir) + end + + false + end + + def self.cleanup + $global_tempfiles ||= [] + while path = $global_tempfiles.pop do + fail "Not deleting tmpfile #{path} outside regular tmpdir" unless in_tmp(path) + + begin + FileUtils.rm_r path, :secure => true + rescue Errno::ENOENT + # nothing to do + end + end + end + + def make_absolute(path) + path = File.expand_path(path) + path[0] = 'c' if Puppet.features.microsoft_windows? + path + end + + def tmpfilename(name) + # Generate a temporary file, just for the name... + source = Tempfile.new(name) + path = source.path + source.close! + + # ...record it for cleanup, + $global_tempfiles ||= [] + $global_tempfiles << File.expand_path(path) + + # ...and bam. + path + end + + def tmpdir(name) + path = tmpfilename(name) + FileUtils.mkdir_p(path) + path + end +end diff --git a/spec/puppetlabs_spec/fixtures.rb b/spec/puppetlabs_spec/fixtures.rb new file mode 100644 index 0000000..9ce0a6b --- /dev/null +++ b/spec/puppetlabs_spec/fixtures.rb @@ -0,0 +1,49 @@ +# This module provides some helper methods to assist with fixtures. It's +# methods are designed to help when you have a conforming fixture layout so we +# get project consistency. +module PuppetlabsSpec::Fixtures + + # Returns the joined path of the global FIXTURE_DIR plus any path given to it + def fixtures(*rest) + File.join(PuppetlabsSpec::FIXTURE_DIR, *rest) + end + + # Returns the path to your relative fixture dir. So if your spec test is + # <project>/spec/unit/facter/foo_spec.rb then your relative dir will be + # <project>/spec/fixture/unit/facter/foo + def my_fixture_dir + callers = caller + while line = callers.shift do + next unless found = line.match(%r{/spec/(.*)_spec\.rb:}) + return fixtures(found[1]) + end + fail "sorry, I couldn't work out your path from the caller stack!" + end + + # Given a name, returns the full path of a file from your relative fixture + # dir as returned by my_fixture_dir. + def my_fixture(name) + file = File.join(my_fixture_dir, name) + unless File.readable? file then + fail "fixture '#{name}' for #{my_fixture_dir} is not readable" + end + return file + end + + # Return the contents of the file using read when given a name. Uses + # my_fixture to work out the relative path. + def my_fixture_read(name) + File.read(my_fixture(name)) + end + + # Provides a block mechanism for iterating across the files in your fixture + # area. + def my_fixtures(glob = '*', flags = 0) + files = Dir.glob(File.join(my_fixture_dir, glob), flags) + unless files.length > 0 then + fail "fixture '#{glob}' for #{my_fixture_dir} had no files!" + end + block_given? and files.each do |file| yield file end + files + end +end diff --git a/spec/puppetlabs_spec/matchers.rb b/spec/puppetlabs_spec/matchers.rb new file mode 100644 index 0000000..77f5803 --- /dev/null +++ b/spec/puppetlabs_spec/matchers.rb @@ -0,0 +1,87 @@ +require 'stringio' + +######################################################################## +# Backward compatibility for Jenkins outdated environment. +module RSpec + module Matchers + module BlockAliases + alias_method :to, :should unless method_defined? :to + alias_method :to_not, :should_not unless method_defined? :to_not + alias_method :not_to, :should_not unless method_defined? :not_to + end + end +end + + +######################################################################## +# Custom matchers... +RSpec::Matchers.define :have_matching_element do |expected| + match do |actual| + actual.any? { |item| item =~ expected } + end +end + + +RSpec::Matchers.define :exit_with do |expected| + actual = nil + match do |block| + begin + block.call + rescue SystemExit => e + actual = e.status + end + actual and actual == expected + end + failure_message_for_should do |block| + "expected exit with code #{expected} but " + + (actual.nil? ? " exit was not called" : "we exited with #{actual} instead") + end + failure_message_for_should_not do |block| + "expected that exit would not be called with #{expected}" + end + description do + "expect exit with #{expected}" + end +end + + +RSpec::Matchers.define :have_printed do |expected| + match do |block| + $stderr = $stdout = StringIO.new + + begin + block.call + ensure + $stdout.rewind + @actual = $stdout.read + + $stdout = STDOUT + $stderr = STDERR + end + + if @actual then + case expected + when String + @actual.include? expected + when Regexp + expected.match @actual + else + raise ArgumentError, "No idea how to match a #{@actual.class.name}" + end + end + end + + failure_message_for_should do |actual| + if actual.nil? then + "expected #{expected.inspect}, but nothing was printed" + else + "expected #{expected.inspect} to be printed; got:\n#{actual}" + end + end + + description do + "expect #{expected.inspect} to be printed" + end + + diffable +end diff --git a/spec/puppetlabs_spec_helper.rb b/spec/puppetlabs_spec_helper.rb new file mode 100644 index 0000000..ba2ae7a --- /dev/null +++ b/spec/puppetlabs_spec_helper.rb @@ -0,0 +1,25 @@ +# Define the main module namespace for use by the helper modules +module PuppetlabsSpec + # FIXTURE_DIR represents the standard locations of all fixture data. Normally + # this represents <project>/spec/fixtures. This will be used by the fixtures + # library to find relative fixture data. + FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), \ + "fixtures") unless defined?(FIXTURE_DIR) +end + +# Require all necessary helper libraries so they can be used later +require 'puppetlabs_spec/files' +require 'puppetlabs_spec/fixtures' +require 'puppetlabs_spec/matchers' + +RSpec.configure do |config| + # Include PuppetlabsSpec helpers so they can be called at convenience + config.extend PuppetlabsSpec::Files + config.extend PuppetlabsSpec::Fixtures + config.include PuppetlabsSpec::Fixtures + + # This will cleanup any files that were created with tmpdir or tmpfile + config.after :each do + PuppetlabsSpec::Files.cleanup + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..b47eaea --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,20 @@ +require 'puppet' +require 'mocha' +require 'rspec' +require 'rspec-puppet' +require 'rspec/expectations' +require 'puppetlabs_spec_helper' + +def param_value(subject, type, title, param) + subject.resource(type, title).send(:parameters)[param.to_sym] +end + +RSpec.configure do |c| + c.module_path = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures/modules')) + # Using an empty site.pp file to avoid: https://github.com/rodjek/rspec-puppet/issues/15 + c.manifest_dir = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures/manifests')) + # Use fixtures for config file mainly to support using our own hiera.yaml settings. + # Pending: https://github.com/rodjek/rspec-puppet/pull/21 + # c.config = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures/puppet.conf')) + c.mock_with :mocha +end |