rspec-puppet-utils 2.2.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de78cb06b14b34d3a9193f34585c28b139181f3b
4
- data.tar.gz: 880c5cb408b1821ede607aca8856b3f7faed8c2f
3
+ metadata.gz: b31522fac4fbed8dc6baec05a6bee345a9f47930
4
+ data.tar.gz: b81fd7100d872efcf62856306b49cd2c9848fbf4
5
5
  SHA512:
6
- metadata.gz: f17a5991f2febc75f534c9f32d80cc4a2627985978fda0c5b3f85e52ddda198cdb205578375b4ad98f24dd6baa228640f15c0e03fd92d5f578d54d99e5188df7
7
- data.tar.gz: 9735e55bb916dbd6eac1fee36dd649790be5b5caa153534ea69e5483e889d241898448cf51635cb30437384e2aea748201c861a26e2445d2cf423318950e9f10
6
+ metadata.gz: 06b599705b6ee01e0aadac7494286c8e6191539ef66c9db7f3b97b1ff46d3180598b5f7119af8e7a401c44c1de7ecd59e3bfa3f0a346a663b7f5ea641461a927
7
+ data.tar.gz: e6279da7519fda3c31400d1099e0e590ee67a401a7dffc59148888eb629e0e66091e732791ccfa13b6b4a2028f54ac3c5c63b0267beb86ed91343086ba432368
data/DESIGN.md ADDED
@@ -0,0 +1,23 @@
1
+ # Design Thoughts
2
+
3
+ This is to explain our design thoughts for anyone that's interested, although it's mainly to remind ourselves in the future ;)
4
+
5
+ ## Rake Tasks
6
+
7
+ ### Project Tasks
8
+
9
+ The spec rake tasks are structured on the basis that each module in a project (ignoring external modules for now) has its own set of rspec tests.
10
+
11
+ We could fix the issues with the main `spec` task by changing it to scan all modules' spec directories for spec files and run them:
12
+
13
+ ```ruby
14
+ RSpec::Core::RakeTask.new :spec do |t|
15
+ t.pattern = "#{module_path}/**/#{RSpec::Core::RakeTask::DEFAULT_PATTERN}"
16
+ end
17
+ ```
18
+
19
+ However that means that we need a toplevel project `spec_helper` file, and there could be other issues as well (I'm not an rspec expert).
20
+
21
+ Another option would be to move all module specs into one project `spec` directory,
22
+ however (putting aside potential `rspec-puppet` file structure issues) having all specs for all modules in one directory could make tests hard to isolate,
23
+ and it will make it hard to separate a module into it's own repo in the future.
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source 'https://rubygems.org/'
2
2
 
3
3
  gemspec
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ end
data/README.md CHANGED
@@ -4,17 +4,23 @@ This is a more refined version of a previous project about [rspec-puppet unit te
4
4
 
5
5
  See [release notes](../../wiki/Release-Notes) about latest version
6
6
 
7
- ## Usage
7
+ ## Updates:
8
8
 
9
- ### MockFunction
9
+ #### v3.0.0
10
+
11
+ The project is now developed against ruby 2.1.0 and so it may not be backwards compatible when running on ruby 1.8.7.
12
+
13
+ The internal file structure has also changed, which shouldn't affect usage, but it might :)
10
14
 
11
- #####Update:
15
+ #### v2.1.0
12
16
 
13
- As of version 2.1.0 the `#stub` and `#expect` methods have been superseded by `#stubbed` and `#expected` so that you can use parameter matchers. The only difference in usage from previous versions is that the methods take a set of parameters rather than a single array (e.g. `f.expected.with(1, 2, 3)` instead of `f.expect.with([1, 2, 3])`)
17
+ The `MockFunction` `#stub` and `#expect` methods have been superseded by `#stubbed` and `#expected` so that you can use parameter matchers. The only difference in usage from previous versions is that the methods take a set of parameters rather than a single array (e.g. `f.expected.with(1, 2, 3)` instead of `f.expect.with([1, 2, 3])`)
14
18
 
15
19
  The change is backwards compatible so `#stub` and `#expect` are still available and function as before
16
20
 
17
- #####Usage:
21
+ ## Usage
22
+
23
+ ### MockFunction
18
24
 
19
25
  The basic usage is to create your mock function with `MockFunction.new` and then use `mocha` to stub any particular calls that you need
20
26
 
@@ -54,14 +60,14 @@ If you use let, **use `let!()` and not `let()`**, this is because lets are lazy-
54
60
 
55
61
  Also if you use `let` when mocking hiera, **you can't use `:hiera` as the name due to conflicts** so you have to do something like `let!(:mock_hiera) { MockFunction.new('hiera') }`
56
62
 
57
- #####Mocha stubs and expects:
63
+ ##### Mocha stubs and expects:
58
64
  `f.stubbed` and `f.expected` are helper methods for `f.stubs(:execute)` and `f.expects(:execute)`
59
65
 
60
66
  Internally `#expected` will clear the rspec-puppet catalog cache. This is because rspec-puppet will only re-compile the catalog for a test if `:title`, `:params`, or `:facts` are changed. This means that if you setup an expectaion in a test, it might not be satisfied because the catalog was already compiled for a previous test, and so the functions weren't called!
61
67
 
62
68
  Clearing the cache ensures tests aren't coupled and order dependent. The downside is that the catalog isn't cached and has to be re-compiled which slows down your tests. If you're concerned about performance and you are explicitly changing `:title`, `:params`, or `:facts` for a test, you can keep the cache intact with `f.expected(:keep_cache)`
63
69
 
64
- #####Notes:
70
+ ##### Notes:
65
71
  - You always stub the `execute` method as that gets called internally
66
72
  - The `execute` method takes a set of arguments instead of an array of arguments
67
73
 
@@ -69,7 +75,7 @@ Clearing the cache ensures tests aren't coupled and order dependent. The downsid
69
75
 
70
76
  I've created a rough version for now just to help myself out, if people find it useful or find bugs, let me know
71
77
 
72
- #####Usage:
78
+ ##### Usage:
73
79
 
74
80
  To stop your tests dissapearing down a rabbit hole, you can use the rspec-puppet `let(:pre_condition) { ... }` feature to create mock versions of resources that your puppet class depends on. For example:
75
81
 
@@ -221,6 +227,70 @@ Diff:
221
227
 
222
228
  For more about usage see the [wiki page](../../wiki/Hiera-Data-Validator)
223
229
 
224
- ## Setup
230
+ ### Setup
225
231
  - Add `rspec-puppet-utils` to your Gemfile (or use `gem install rspec-puppet-utils`)
226
232
  - Add `require 'rspec-puppet-utils'` to the top of your `spec_helper`
233
+
234
+ ## Rake Tasks (experimental feature)
235
+
236
+ `rspec-puppet-utils` also provides helper classes to add common rake tasks to a Puppet project or module.
237
+
238
+ ### Project Tasks
239
+
240
+ The `Rake::Puppet` class provides tasks that handle testing and building a Puppet project.
241
+
242
+ ##### Usage:
243
+
244
+ An example `Rakefile` might look like this:
245
+
246
+ ```ruby
247
+ require 'rake'
248
+ require 'rspec_puppet_utils/rake/project_tasks'
249
+
250
+ puppet = Rake::Puppet.new
251
+ puppet.package_version = '1.0.0'
252
+ puppet.load_tasks
253
+ ```
254
+
255
+ Running `rake -T` afterwords should show a list of spec and build tasks:
256
+
257
+ ```bash
258
+ $ rake -T
259
+ rake build # Build puppet.zip v1.0.0
260
+ rake quick_build # Build puppet.zip v1.0.0 without tests
261
+ rake spec # Run specs in all modules
262
+ rake spec:<mod a> # Run <mod a> module specs
263
+ rake spec:<mod b> # Run <mod b> module specs
264
+ ...
265
+ ```
266
+
267
+ There is an spec task for each module, as well as a main `spec` task that will run all specs in a project.
268
+
269
+ The `build` task will bundle all Puppet code (modules, hiera data file, environment.conf files, etc) into a .zip file which can then be deployed.
270
+
271
+ In the example above `package_version` is set as it's a required field. The other accessible properties are:
272
+
273
+ - module_path - The directory containing all the modules to test (default: 'modules')
274
+ - excluded_modules - Modules to exclude from rspec testing (default: [])
275
+ - package_dir - Where the puppet zip package will be created (default: 'pkg')
276
+ - package_files - Files and directories to include in the package (default: ['modules', 'modules-lib', 'config/environment.conf'])
277
+ - package_version - The version of the package (e.g. 2.1.0)
278
+
279
+ ##### NB:
280
+
281
+ The `package_files` list is setup for the modules-lib pattern by default. In this pattern external (e.g. Puppet Forge) modules are installed in a separate 'modules-lib', leaving the 'modules' dir for project modules such as 'components', 'profiles', 'role', etc.
282
+ If you're not using this pattern then just provide a new array for `package_files`.
283
+
284
+ Running the `build` or `quick_build` tasks will delete any existing builds in the `pkg` directory.
285
+ This is so the same build task can be run over and over on a build server (e.g. Jenkins) without filling up the disk.
286
+ It also guarantees that the binary at the end of a build was just built, and wasn't left over from a previous build.
287
+
288
+ ##### ToDo:
289
+
290
+ Currently the `spec` task runs all the `spec::<module>` tasks. If one of these fails then none of the subsequent tasks will run. This isn't ideal!
291
+
292
+ The zip commands need to be replaced by ruby zip library to avoid shelling out, this helps with support for Windows environments
293
+
294
+ ### Module Tasks
295
+
296
+ WIP
@@ -1,7 +1,7 @@
1
- require 'mock_function'
2
- require 'mock_resource'
3
- require 'template_harness'
4
- require 'hieradata/validator'
5
- require 'hieradata/yaml_validator'
1
+ require 'rspec_puppet_utils/mock_function'
2
+ require 'rspec_puppet_utils/mock_resource'
3
+ require 'rspec_puppet_utils/template_harness'
4
+ require 'rspec_puppet_utils/hieradata/validator'
5
+ require 'rspec_puppet_utils/hieradata/yaml_validator'
6
6
 
7
7
  include RSpecPuppetUtils
@@ -1,4 +1,4 @@
1
- require 'hieradata/validator'
1
+ require 'rspec_puppet_utils/hieradata/validator'
2
2
  require 'yaml'
3
3
 
4
4
  module RSpecPuppetUtils
@@ -0,0 +1,117 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+ require 'fileutils'
4
+
5
+ # ToDo: Add flag to include version in package file name or not e.g. puppet-1.2.3.zip
6
+ # ToDo: replace zip cmds with ruby zip lib to avoid shelling out
7
+
8
+ module Rake
9
+
10
+ class Puppet
11
+
12
+ attr_accessor :module_path, :excluded_modules
13
+ attr_accessor :package_dir, :package_files, :package_version
14
+
15
+ @module_path # The directory containing all the modules to test
16
+ @excluded_dirs # Directories excluded from rspec search
17
+ @excluded_modules # Modules to exclude from rspec testing
18
+ @package_dir # Where the puppet zip package will be created
19
+ @package_files # Files and directories to include in the package
20
+ @package_name # Name of the package
21
+ @package_version # The version of the package (e.g. 2.1.0)
22
+
23
+ def initialize
24
+ extend Rake::DSL # makes 'namespace' and 'task' methods available to instance
25
+
26
+ @module_path = 'modules' # Deliberately excludes modules-lib dir
27
+ @excluded_dirs = ['.', '..']
28
+ @excluded_modules = []
29
+ @package_dir = 'pkg'
30
+ @package_files = ['modules', 'modules-lib', 'config/environment.conf']
31
+ @package_name = 'puppet'
32
+ @package_version = nil
33
+ end
34
+
35
+ def load_tasks
36
+ load_spec_tasks
37
+ load_build_tasks
38
+ end
39
+
40
+ def testable_modules
41
+ raise ArgumentError, 'Excluded modules must be an array' unless @excluded_modules.is_a? Array
42
+ module_dirs = Dir.entries(@module_path) - @excluded_dirs - @excluded_modules
43
+ module_dirs.select! {|e| File.directory?("#{@module_path}/#{e}/spec") }
44
+ module_dirs
45
+ end
46
+
47
+ def load_spec_tasks
48
+
49
+ modules = testable_modules
50
+ module_tasks = modules.collect { |m| "#{:spec}:#{m}" }
51
+
52
+ namespace :spec do
53
+ modules.each { |puppet_module|
54
+ module_root = "#{@module_path}/#{puppet_module}"
55
+ opts_path = "#{module_root}/spec/spec.opts"
56
+
57
+ desc "Run #{puppet_module} module specs"
58
+ RSpec::Core::RakeTask.new puppet_module do |t|
59
+ t.ruby_opts = "-C#{module_root}"
60
+ t.rspec_opts = File.exists?(opts_path) ? File.read(opts_path).chomp : ''
61
+ end
62
+ }
63
+ end
64
+
65
+ desc 'Run specs in all modules'
66
+ task :spec => module_tasks
67
+ task :default => :spec
68
+ end
69
+
70
+ def load_build_tasks
71
+
72
+ raise(ArgumentError, 'Please provide a package_version (e.g. "1.0.0")') if @package_version.nil?
73
+
74
+ namespace :build do
75
+
76
+ # The build_dir (i.e. 'puppet') is the root dir of the files when the zip is extracted
77
+ build_dir = "#{@package_dir}/puppet"
78
+
79
+ # Preps build directory
80
+ task :prep do
81
+ puts 'Preparing build'
82
+ FileUtils.rm_r @package_dir if File.exist?(@package_dir)
83
+ FileUtils.mkdir_p build_dir
84
+ @package_files.each {|f|
85
+ if File.exist? f
86
+ puts "Copying #{f} to #{build_dir}"
87
+ FileUtils.cp_r f, build_dir
88
+ else
89
+ fail "Could not find #{f} file or directory: Ensure that the package_files list is correct"
90
+ end
91
+ }
92
+ end
93
+
94
+ task :package => [:prep] do
95
+ # Exclude modules' spec directories as they're not needed once deployed
96
+ exclude_patterns = '-x puppet/modules/\*/spec/\* puppet/modules-lib/\*/spec/\*'
97
+ cmds = ["cd #{@package_dir}", '&&', "zip -qr #{@package_name}.zip . #{exclude_patterns}", '&&', 'cd -']
98
+ puts `#{cmds.join(' ')}`
99
+ end
100
+
101
+ task :cleanup do
102
+ puts "Cleaning up #{build_dir}/"
103
+ FileUtils.rm_r build_dir if File.exist?(build_dir)
104
+ end
105
+ end
106
+
107
+ desc "Build #{@package_name}.zip v#{@package_version} without tests"
108
+ task :quick_build => ['build:package', 'build:cleanup'] do
109
+ puts "Built #{@package_name}.zip version #{@package_version}"
110
+ end
111
+
112
+ desc "Build #{@package_name}.zip v#{@package_version}"
113
+ task :build => [:spec, :quick_build]
114
+ end
115
+
116
+ end
117
+ end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = 'rspec-puppet-utils'
4
- gem.version = '2.2.2'
4
+ gem.version = '3.0.0'
5
5
  gem.description = 'Helper classes for mock/stub functions, templates and hieradata'
6
6
  gem.summary = ''
7
7
  gem.author = 'Tom Poulton'
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/hieradata/validator'
2
+ require 'lib/rspec_puppet_utils/hieradata/validator'
3
3
 
4
4
  include RSpecPuppetUtils
5
5
 
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/hieradata/yaml_validator'
2
+ require 'lib/rspec_puppet_utils/hieradata/yaml_validator'
3
3
 
4
4
  include RSpecPuppetUtils
5
5
 
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/mock_function'
2
+ require 'lib/rspec_puppet_utils/mock_function'
3
3
 
4
4
  include RSpecPuppetUtils
5
5
 
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/mock_resource'
2
+ require 'lib/rspec_puppet_utils/mock_resource'
3
3
 
4
4
  include RSpecPuppetUtils
5
5
 
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'lib/rspec_puppet_utils/rake/project_tasks'
3
+
4
+ describe Rake::Puppet do
5
+
6
+ module_path = 'modules'
7
+ testable_modules = [ 'core', 'base' ]
8
+ modules_dir_list = [ 'core', 'base', 'role', 'profiles' ]
9
+
10
+ let(:puppet) { Rake::Puppet.new }
11
+
12
+ describe 'load_spec_tasks' do
13
+
14
+ before(:each) do
15
+ puppet.stubs(:testable_modules).returns(testable_modules) # not exactly best practice, but hey
16
+ end
17
+
18
+ it 'includes namespace and task methods from Rake::DSL' do
19
+ # It would throw error on load if task or namespace methods are missing
20
+ expect { puppet.load_spec_tasks }.to_not raise_error
21
+ end
22
+
23
+ it 'creates a task for each module' do
24
+ puppet.load_spec_tasks
25
+ testable_modules.each { |mod|
26
+ expect(Rake::Task.task_defined?("spec:#{mod}")).to eq true
27
+ }
28
+ end
29
+
30
+ it 'loads the main spec task' do
31
+ puppet.load_spec_tasks
32
+ expect(Rake::Task.task_defined?(:spec)).to eq true
33
+ end
34
+
35
+ end
36
+
37
+ describe 'load_build_tasks' do
38
+
39
+ it 'fails if no version is provided' do
40
+ expect { puppet.load_build_tasks }.to raise_error(ArgumentError, /provide a package_version/)
41
+ end
42
+
43
+ context 'when version is set' do
44
+
45
+ let(:package_version) { '1.2.3' }
46
+ before(:each) {
47
+ puppet.package_version = package_version
48
+ puppet.load_build_tasks
49
+ }
50
+
51
+ it 'loads the "build" task' do
52
+ expect(Rake::Task.task_defined?(:build)).to eq true
53
+ end
54
+
55
+ it 'loads the "quick_build" task' do
56
+ expect(Rake::Task.task_defined?(:quick_build)).to eq true
57
+ end
58
+
59
+ it 'includes package_version in task description' do
60
+ build_task = Rake::Task[:build]
61
+ expect(build_task.application.last_description).to match /v#{package_version}/
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe 'testable_modules' do
69
+
70
+ it 'finds modules with a spec directory' do
71
+ Dir.stubs(:entries).with(module_path).returns modules_dir_list.clone
72
+
73
+ File.stubs(:directory?).returns(false)
74
+ File.stubs(:directory?).with(regexp_matches( /(#{testable_modules.join '|'})\/spec$/ )).returns(true)
75
+
76
+ result = puppet.testable_modules
77
+ expect(result).to match_array testable_modules
78
+ end
79
+
80
+ it 'finds modules within module_path' do
81
+ alt_module_path = 'modules-alt'
82
+
83
+ Dir.expects(:entries).with(alt_module_path).returns testable_modules
84
+ testable_modules.each { |m|
85
+ File.expects(:directory?).with(regexp_matches( /#{alt_module_path}\/#{m}/ )).returns(true)
86
+ }
87
+
88
+ puppet.module_path = alt_module_path
89
+ puppet.testable_modules
90
+ end
91
+
92
+ it 'ignores excluded modules' do
93
+ Dir.stubs(:entries).with(module_path).returns testable_modules.clone
94
+ File.stubs(:directory?).returns(true)
95
+
96
+ puppet.excluded_modules = ['core']
97
+ result = puppet.testable_modules
98
+ expect(result).to match_array ['base']
99
+ end
100
+
101
+ it 'throws error if excluded modules is not an array' do
102
+ puppet.excluded_modules = 'not an array'
103
+ expect { puppet.testable_modules }.to raise_error(ArgumentError, /must be an array/)
104
+ end
105
+
106
+ it 'ignores excluded directories' do
107
+ Dir.stubs(:entries).with(module_path).returns testable_modules + ['.', '..']
108
+ File.stubs(:directory?).returns(true)
109
+
110
+ result = puppet.testable_modules
111
+ expect(result).to match_array testable_modules
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lib/template_harness'
2
+ require 'lib/rspec_puppet_utils/template_harness'
3
3
 
4
4
  include RSpecPuppetUtils
5
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-puppet-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Poulton
@@ -87,21 +87,24 @@ extensions: []
87
87
  extra_rdoc_files: []
88
88
  files:
89
89
  - ".gitignore"
90
+ - DESIGN.md
90
91
  - Gemfile
91
92
  - LICENSE.txt
92
93
  - README.md
93
94
  - Rakefile
94
- - lib/hieradata/validator.rb
95
- - lib/hieradata/yaml_validator.rb
96
- - lib/mock_function.rb
97
- - lib/mock_resource.rb
98
95
  - lib/rspec-puppet-utils.rb
99
- - lib/template_harness.rb
96
+ - lib/rspec_puppet_utils/hieradata/validator.rb
97
+ - lib/rspec_puppet_utils/hieradata/yaml_validator.rb
98
+ - lib/rspec_puppet_utils/mock_function.rb
99
+ - lib/rspec_puppet_utils/mock_resource.rb
100
+ - lib/rspec_puppet_utils/rake/project_tasks.rb
101
+ - lib/rspec_puppet_utils/template_harness.rb
100
102
  - rspec-puppet-utils.gemspec
101
103
  - spec/classes/hieradata/validator_spec.rb
102
104
  - spec/classes/hieradata/yaml_validator_spec.rb
103
105
  - spec/classes/mock_function_spec.rb
104
106
  - spec/classes/mock_resource_spec.rb
107
+ - spec/classes/rake/project_tasks_spec.rb
105
108
  - spec/classes/template_harness_spec.rb
106
109
  - spec/classes/utils_spec.rb
107
110
  - spec/fixtures/hieradata/empty/empty.yaml
@@ -145,6 +148,7 @@ test_files:
145
148
  - spec/classes/hieradata/yaml_validator_spec.rb
146
149
  - spec/classes/mock_function_spec.rb
147
150
  - spec/classes/mock_resource_spec.rb
151
+ - spec/classes/rake/project_tasks_spec.rb
148
152
  - spec/classes/template_harness_spec.rb
149
153
  - spec/classes/utils_spec.rb
150
154
  - spec/fixtures/hieradata/empty/empty.yaml