diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f3ffb57..2240a97 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,279 +1,281 @@ # Contribution guidelines ## Table of contents * [Contributing](#contributing) * [Writing proper commits - short version](#writing-proper-commits-short-version) * [Writing proper commits - long version](#writing-proper-commits-long-version) * [Dependencies](#dependencies) * [Note for OS X users](#note-for-os-x-users) * [The test matrix](#the-test-matrix) * [Syntax and style](#syntax-and-style) * [Running the unit tests](#running-the-unit-tests) * [Unit tests in docker](#unit-tests-in-docker) * [Integration tests](#integration-tests) This module has grown over time based on a range of contributions from people using it. If you follow these contributing guidelines your patch will likely make it into a release a little more quickly. ## Contributing Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. [Contributor Code of Conduct](https://voxpupuli.org/coc/). * Fork the repo. * Create a separate branch for your change. * We only take pull requests with passing tests, and documentation. [travis-ci](http://travis-ci.org) runs the tests for us. You can also execute them locally. This is explained [in a later section](#the-test-matrix). * Checkout [our docs](https://voxpupuli.org/docs/reviewing_pr/) we use to review a module and the [official styleguide](https://puppet.com/docs/puppet/6.0/style_guide.html). They provide some guidance for new code that might help you before you submit a pull request. * Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, please add a test. * Squash your commits down into logical components. Make sure to rebase against our current master. * Push the branch to your fork and submit a pull request. Please be prepared to repeat some of these steps as our contributors review your code. ## Writing proper commits - short version * Make commits of logical units. * Check for unnecessary whitespace with "git diff --check" before committing. * Commit using Unix line endings (check the settings around "crlf" in git-config(1)). * Do not check in commented out code or unneeded files. * The first line of the commit message should be a short description (50 characters is the soft limit, excluding ticket number(s)), and should skip the full stop. * Associate the issue in the message. The first line should include the issue number in the form "(#XXXX) Rest of message". * The body should provide a meaningful commit message, which: *uses the imperative, present tense: `change`, not `changed` or `changes`. * includes motivation for the change, and contrasts its implementation with the previous behavior. * Make sure that you have tests for the bug you are fixing, or feature you are adding. * Make sure the test suites passes after your commit: * When introducing a new feature, make sure it is properly documented in the README.md ## Writing proper commits - long version 1. Make separate commits for logically separate changes. Please break your commits down into logically consistent units which include new or changed tests relevant to the rest of the change. The goal of doing this is to make the diff easier to read for whoever is reviewing your code. In general, the easier your diff is to read, the more likely someone will be happy to review it and get it into the code base. If you are going to refactor a piece of code, please do so as a separate commit from your feature or bug fix changes. We also really appreciate changes that include tests to make sure the bug is not re-introduced, and that the feature is not accidentally broken. Describe the technical detail of the change(s). If your description starts to get too long, that is a good sign that you probably need to split up your commit into more finely grained pieces. Commits which plainly describe the things which help reviewers check the patch and future developers understand the code are much more likely to be merged in with a minimum of bike-shedding or requested changes. Ideally, the commit message would include information, and be in a form suitable for inclusion in the release notes for the version of Puppet that includes them. Please also check that you are not introducing any trailing whitespace or other "whitespace errors". You can do this by running "git diff --check" on your changes before you commit. 2. Sending your patches To submit your changes via a GitHub pull request, we _highly_ recommend that you have them on a topic branch, instead of directly on `master`. It makes things much easier to keep track of, especially if you decide to work on another thing before your first change is merged in. GitHub has some pretty good [general documentation](http://help.github.com/) on using their site. They also have documentation on [creating pull requests](http://help.github.com/send-pull-requests/). In general, after pushing your topic branch up to your repository on GitHub, you can switch to the branch in the GitHub UI and click "Pull Request" towards the top of the page in order to open a pull request. 3. Update the related GitHub issue. If there is a GitHub issue associated with the change you submitted, then you should update the ticket to include the location of your branch, along with any other commentary you may wish to make. ## Dependencies The testing and development tools have a bunch of dependencies, all managed by [bundler](http://bundler.io/) according to the [Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). By default the tests use a baseline version of Puppet. If you have Ruby 2.x or want a specific version of Puppet, you must set an environment variable such as: ```sh export PUPPET_VERSION="~> 5.5.6" ``` You can install all needed gems for spec tests into the modules directory by running: ```sh bundle install --path .vendor/ --without development system_tests release --jobs "$(nproc)" ``` If you also want to run acceptance tests: ```sh bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)" ``` Our all in one solution if you don't know if you need to install or update gems: ```sh bundle install --path .vendor/ --with system_tests --without development release --jobs "$(nproc)"; bundle update; bundle clean ``` As an alternative to the `--jobs "$(nproc)` parameter, you can set an environment variable: ```sh BUNDLE_JOBS="$(nproc)" ``` ### Note for OS X users `nproc` isn't a valid command under OS x. As an alternative, you can do: ```sh --jobs "$(sysctl -n hw.ncpu)" ``` ## The test matrix ### Syntax and style The test suite will run [Puppet Lint](http://puppet-lint.com/) and [Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to check various syntax and style things. You can run these locally with: ```sh bundle exec rake lint bundle exec rake validate ``` It will also run some [Rubocop](http://batsov.com/rubocop/) tests against it. You can run those locally ahead of time with: ```sh bundle exec rake rubocop ``` ### Running the unit tests The unit test suite covers most of the code, as mentioned above please add tests if you're adding new functionality. If you've not used [rspec-puppet](http://rspec-puppet.com/) before then feel free to ask about how best to test your new feature. To run the linter, the syntax checker and the unit tests: ```sh bundle exec rake test ``` To run your all the unit tests ```sh bundle exec rake spec ``` To run a specific spec test set the `SPEC` variable: ```sh bundle exec rake spec SPEC=spec/foo_spec.rb ``` #### Unit tests in docker Some people don't want to run the dependencies locally or don't want to install ruby. We ship a Dockerfile that enables you to run all unit tests and linting. You only need to run: ```sh docker build . ``` Please ensure that a docker daemon is running and that your user has the permission to talk to it. You can specify a remote docker host by setting the `DOCKER_HOST` environment variable. it will copy the content of the module into the docker image. So it will not work if a Gemfile.lock exists. ### Integration tests The unit tests just check the code runs, not that it does exactly what we want on a real machine. For that we're using [beaker](https://github.com/puppetlabs/beaker). This fires up a new virtual machine (using vagrant) and runs a series of simple tests against it after applying the module. You can run this with: ```sh bundle exec rake acceptance ``` This will run the tests on the module's default nodeset. You can override the nodeset used, e.g., ```sh BEAKER_set=centos-7-x64 bundle exec rake acceptance ``` There are default rake tasks for the various acceptance test modules, e.g., ```sh bundle exec rake beaker:centos-7-x64 bundle exec rake beaker:ssh:centos-7-x64 ``` If you don't want to have to recreate the virtual machine every time you can use `BEAKER_destroy=no` and `BEAKER_provision=no`. On the first run you will at least need `BEAKER_provision` set to yes (the default). The Vagrantfile for the created virtual machines will be in `.vagrant/beaker_vagrant_files`. Beaker also supports docker containers. We also use that in our automated CI pipeline at [travis-ci](http://travis-ci.org). To use that instead of Vagrant: ```sh -PUPPET_INSTALL_TYPE=agent BEAKER_IS_PE=no BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=debian9-64{hypervisor=docker} BEAKER_destroy=yes bundle exec rake beaker +PUPPET_INSTALL_TYPE=agent BEAKER_IS_PE=no BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian10-64{hypervisor=docker} BEAKER_destroy=yes bundle exec rake beaker ``` -You can replace the string `debian9` with any common operating system. +You can replace the string `debian10` with any common operating system. The following strings are known to work: * ubuntu1604 * ubuntu1804 * debian8 * debian9 +* debian10 * centos6 * centos7 +* centos8 The easiest way to debug in a docker container is to open a shell: ```sh docker exec -it -u root ${container_id_or_name} bash ``` The source of this file is in our [modulesync_config](https://github.com/voxpupuli/modulesync_config/blob/master/moduleroot/.github/CONTRIBUTING.md.erb) repository. diff --git a/.msync.yml b/.msync.yml index 11aed5f..8864fc0 100644 --- a/.msync.yml +++ b/.msync.yml @@ -1 +1 @@ -modulesync_config_version: '2.10.0' +modulesync_config_version: '2.12.0' diff --git a/.rubocop.yml b/.rubocop.yml index 5984ccc..c2ebc88 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,545 +1,546 @@ require: rubocop-rspec AllCops: - TargetRubyVersion: 2.1 +# Puppet Server 5 defaults to jruby 1.7 so TargetRubyVersion must stay at 1.9 until we drop support for puppet 5 + TargetRubyVersion: 1.9 Include: - ./**/*.rb Exclude: - files/**/* - vendor/**/* - .vendor/**/* - pkg/**/* - spec/fixtures/**/* - Gemfile - Rakefile - Guardfile - Vagrantfile Lint/ConditionPosition: Enabled: True Lint/ElseLayout: Enabled: True Lint/UnreachableCode: Enabled: True Lint/UselessComparison: Enabled: True Lint/EnsureReturn: Enabled: True Lint/HandleExceptions: Enabled: True Lint/LiteralInCondition: Enabled: True Lint/ShadowingOuterLocalVariable: Enabled: True Lint/LiteralInInterpolation: Enabled: True Style/HashSyntax: Enabled: True Style/RedundantReturn: Enabled: True Layout/EndOfLine: Enabled: False Lint/AmbiguousOperator: Enabled: True Lint/AssignmentInCondition: Enabled: True Layout/SpaceBeforeComment: Enabled: True Style/AndOr: Enabled: True Style/RedundantSelf: Enabled: True Metrics/BlockLength: Enabled: False # Method length is not necessarily an indicator of code quality Metrics/MethodLength: Enabled: False # Module length is not necessarily an indicator of code quality Metrics/ModuleLength: Enabled: False Style/WhileUntilModifier: Enabled: True Lint/AmbiguousRegexpLiteral: Enabled: True Security/Eval: Enabled: True Lint/BlockAlignment: Enabled: True Lint/DefEndAlignment: Enabled: True Lint/EndAlignment: Enabled: True Lint/DeprecatedClassMethods: Enabled: True Lint/Loop: Enabled: True Lint/ParenthesesAsGroupedExpression: Enabled: True Lint/RescueException: Enabled: True Lint/StringConversionInInterpolation: Enabled: True Lint/UnusedBlockArgument: Enabled: True Lint/UnusedMethodArgument: Enabled: True Lint/UselessAccessModifier: Enabled: True Lint/UselessAssignment: Enabled: True Lint/Void: Enabled: True Layout/AccessModifierIndentation: Enabled: True Style/AccessorMethodName: Enabled: True Style/Alias: Enabled: True Layout/AlignArray: Enabled: True Layout/AlignHash: Enabled: True Layout/AlignParameters: Enabled: True Metrics/BlockNesting: Enabled: True Style/AsciiComments: Enabled: True Style/Attr: Enabled: True Style/BracesAroundHashParameters: Enabled: True Style/CaseEquality: Enabled: True Layout/CaseIndentation: Enabled: True Style/CharacterLiteral: Enabled: True Style/ClassAndModuleCamelCase: Enabled: True Style/ClassAndModuleChildren: Enabled: False Style/ClassCheck: Enabled: True # Class length is not necessarily an indicator of code quality Metrics/ClassLength: Enabled: False Style/ClassMethods: Enabled: True Style/ClassVars: Enabled: True Style/WhenThen: Enabled: True Style/WordArray: Enabled: True Style/UnneededPercentQ: Enabled: True Layout/Tab: Enabled: True Layout/SpaceBeforeSemicolon: Enabled: True Layout/TrailingBlankLines: Enabled: True Layout/SpaceInsideBlockBraces: Enabled: True Layout/SpaceInsideBrackets: Enabled: True Layout/SpaceInsideHashLiteralBraces: Enabled: True Layout/SpaceInsideParens: Enabled: True Layout/LeadingCommentSpace: Enabled: True Layout/SpaceBeforeFirstArg: Enabled: True Layout/SpaceAfterColon: Enabled: True Layout/SpaceAfterComma: Enabled: True Layout/SpaceAfterMethodName: Enabled: True Layout/SpaceAfterNot: Enabled: True Layout/SpaceAfterSemicolon: Enabled: True Layout/SpaceAroundEqualsInParameterDefault: Enabled: True Layout/SpaceAroundOperators: Enabled: True Layout/SpaceBeforeBlockBraces: Enabled: True Layout/SpaceBeforeComma: Enabled: True Style/CollectionMethods: Enabled: True Layout/CommentIndentation: Enabled: True Style/ColonMethodCall: Enabled: True Style/CommentAnnotation: Enabled: True # 'Complexity' is very relative Metrics/CyclomaticComplexity: Enabled: False Style/ConstantName: Enabled: True Style/Documentation: Enabled: False Style/DefWithParentheses: Enabled: True Style/PreferredHashMethods: Enabled: True Layout/DotPosition: EnforcedStyle: trailing Style/DoubleNegation: Enabled: True Style/EachWithObject: Enabled: True Layout/EmptyLineBetweenDefs: Enabled: True Layout/IndentArray: Enabled: True Layout/IndentHash: Enabled: True Layout/IndentationConsistency: Enabled: True Layout/IndentationWidth: Enabled: True Layout/EmptyLines: Enabled: True Layout/EmptyLinesAroundAccessModifier: Enabled: True Style/EmptyLiteral: Enabled: True # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Enabled: False Style/MethodCallWithoutArgsParentheses: Enabled: True Style/MethodDefParentheses: Enabled: True Style/LineEndConcatenation: Enabled: True Layout/TrailingWhitespace: Enabled: True Style/StringLiterals: Enabled: True Style/TrailingCommaInArguments: Enabled: True Style/TrailingCommaInLiteral: Enabled: True Style/GlobalVars: Enabled: True Style/GuardClause: Enabled: True Style/IfUnlessModifier: Enabled: True Style/MultilineIfThen: Enabled: True Style/NegatedIf: Enabled: True Style/NegatedWhile: Enabled: True Style/Next: Enabled: True Style/SingleLineBlockParams: Enabled: True Style/SingleLineMethods: Enabled: True Style/SpecialGlobalVars: Enabled: True Style/TrivialAccessors: Enabled: True Style/UnlessElse: Enabled: True Style/VariableInterpolation: Enabled: True Style/VariableName: Enabled: True Style/WhileUntilDo: Enabled: True Style/EvenOdd: Enabled: True Style/FileName: Enabled: True Style/For: Enabled: True Style/Lambda: Enabled: True Style/MethodName: Enabled: True Style/MultilineTernaryOperator: Enabled: True Style/NestedTernaryOperator: Enabled: True Style/NilComparison: Enabled: True Style/FormatString: Enabled: True Style/MultilineBlockChain: Enabled: True Style/Semicolon: Enabled: True Style/SignalException: Enabled: True Style/NonNilCheck: Enabled: True Style/Not: Enabled: True Style/NumericLiterals: Enabled: True Style/OneLineConditional: Enabled: True Style/OpMethod: Enabled: True Style/ParenthesesAroundCondition: Enabled: True Style/PercentLiteralDelimiters: Enabled: True Style/PerlBackrefs: Enabled: True Style/PredicateName: Enabled: True Style/RedundantException: Enabled: True Style/SelfAssignment: Enabled: True Style/Proc: Enabled: True Style/RaiseArgs: Enabled: True Style/RedundantBegin: Enabled: True Style/RescueModifier: Enabled: True # based on https://github.com/voxpupuli/modulesync_config/issues/168 Style/RegexpLiteral: EnforcedStyle: percent_r Enabled: True Lint/UnderscorePrefixedVariableName: Enabled: True Metrics/ParameterLists: Enabled: False Lint/RequireParentheses: Enabled: True Style/ModuleFunction: Enabled: True Lint/Debugger: Enabled: True Style/IfWithSemicolon: Enabled: True Style/Encoding: Enabled: True Style/BlockDelimiters: Enabled: True Layout/MultilineBlockLayout: Enabled: True # 'Complexity' is very relative Metrics/AbcSize: Enabled: False # 'Complexity' is very relative Metrics/PerceivedComplexity: Enabled: False Lint/UselessAssignment: Enabled: True Layout/ClosingParenthesisIndentation: Enabled: True # RSpec RSpec/BeforeAfterAll: Exclude: - spec/acceptance/**/* # We don't use rspec in this way RSpec/DescribeClass: Enabled: False # Example length is not necessarily an indicator of code quality RSpec/ExampleLength: Enabled: False RSpec/NamedSubject: Enabled: False # disabled for now since they cause a lot of issues # these issues aren't easy to fix RSpec/RepeatedDescription: Enabled: False RSpec/NestedGroups: Enabled: False # this is broken on ruby1.9 Layout/IndentHeredoc: Enabled: False # disable Yaml safe_load. This is needed to support ruby2.0.0 development envs Security/YAMLLoad: Enabled: false # This affects hiera interpolation, as well as some configs that we push. Style/FormatStringToken: Enabled: false # This is useful, but sometimes a little too picky about where unit tests files # are located. RSpec/FilePath: Enabled: false diff --git a/Gemfile b/Gemfile index a555803..187a851 100644 --- a/Gemfile +++ b/Gemfile @@ -1,87 +1,70 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" def location_for(place, fake_version = nil) if place =~ /^(git[:@][^#]*)#(.*)/ [fake_version, { :git => $1, :branch => $2, :require => false }].compact elsif place =~ /^file:\/\/(.*)/ ['>= 0', { :path => File.expand_path($1), :require => false }] else [place, { :require => false }] end end group :test do - gem 'puppetlabs_spec_helper', '>= 2.14.0', :require => false - gem 'rspec-puppet-facts', '>= 1.9.5', :require => false - gem 'rspec-puppet-utils', :require => false - gem 'puppet-lint-leading_zero-check', :require => false - gem 'puppet-lint-trailing_comma-check', :require => false - gem 'puppet-lint-version_comparison-check', :require => false - gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false - gem 'puppet-lint-unquoted_string-check', :require => false - gem 'puppet-lint-variable_contains_upcase', :require => false - gem 'puppet-lint-absolute_classname-check', '>= 2.0.0', :require => false - gem 'puppet-lint-topscope-variable-check', :require => false - gem 'puppet-lint-legacy_facts-check', :require => false - gem 'puppet-lint-anchor-check', :require => false - gem 'metadata-json-lint', :require => false - gem 'redcarpet', :require => false - gem 'rubocop', '~> 0.49.1', :require => false - gem 'rubocop-rspec', '~> 1.15.0', :require => false - gem 'mocha', '~> 1.4.0', :require => false - gem 'coveralls', :require => false - gem 'simplecov-console', :require => false - gem 'parallel_tests', :require => false - gem 'redis', :require => false - gem 'mock_redis', :require => false + gem 'voxpupuli-test', '>= 1.0.0', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false + gem 'redis', :require => false + gem 'mock_redis', :require => false end group :development do gem 'travis', :require => false gem 'travis-lint', :require => false gem 'guard-rake', :require => false gem 'overcommit', '>= 0.39.1', :require => false end group :system_tests do gem 'winrm', :require => false if beaker_version = ENV['BEAKER_VERSION'] gem 'beaker', *location_for(beaker_version) else gem 'beaker', '>= 4.2.0', :require => false end if beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] gem 'beaker-rspec', *location_for(beaker_rspec_version) else gem 'beaker-rspec', :require => false end gem 'serverspec', :require => false gem 'beaker-hostgenerator', '>= 1.1.22', :require => false gem 'beaker-docker', :require => false gem 'beaker-puppet', :require => false gem 'beaker-puppet_install_helper', :require => false gem 'beaker-module_install_helper', :require => false gem 'rbnacl', '>= 4', :require => false gem 'rbnacl-libsodium', :require => false gem 'bcrypt_pbkdf', :require => false + gem 'ed25519', :require => false end group :release do gem 'github_changelog_generator', :require => false, :git => 'https://github.com/voxpupuli/github-changelog-generator', :branch => 'voxpupuli_essential_fixes' gem 'puppet-blacksmith', :require => false gem 'voxpupuli-release', :require => false gem 'puppet-strings', '>= 2.2', :require => false end if facterversion = ENV['FACTER_GEM_VERSION'] gem 'facter', facterversion.to_s, :require => false, :groups => [:test] else gem 'facter', :require => false, :groups => [:test] end ENV['PUPPET_VERSION'].nil? ? puppetversion = '~> 6.0' : puppetversion = ENV['PUPPET_VERSION'].to_s gem 'puppet', puppetversion, :require => false, :groups => [:test] # vim: syntax=ruby diff --git a/Rakefile b/Rakefile index c0f2d37..b450fe7 100644 --- a/Rakefile +++ b/Rakefile @@ -1,85 +1,54 @@ -require 'puppetlabs_spec_helper/rake_tasks' +require 'voxpupuli/test/rake' # load optional tasks for releases # only available if gem group releases is installed begin require 'voxpupuli/release/rake_tasks' rescue LoadError end -PuppetLint.configuration.log_format = '%{path}:%{line}:%{check}:%{KIND}:%{message}' - -desc 'Auto-correct puppet-lint offenses' -task 'lint:auto_correct' do - Rake::Task[:lint_fix].invoke -end - -desc 'Run acceptance tests' -RSpec::Core::RakeTask.new(:acceptance) do |t| - t.pattern = 'spec/acceptance' -end - -desc 'Run tests' -task test: [:release_checks] - -namespace :check do - desc 'Check for trailing whitespace' - task :trailing_whitespace do - Dir.glob('**/*.md', File::FNM_DOTMATCH).sort.each do |filename| - next if filename =~ %r{^((modules|acceptance|\.?vendor|spec/fixtures|pkg)/|REFERENCE.md)} - File.foreach(filename).each_with_index do |line, index| - if line =~ %r{\s\n$} - puts "#{filename} has trailing whitespace on line #{index + 1}" - exit 1 - end - end - end - end -end -Rake::Task[:release_checks].enhance ['check:trailing_whitespace'] - desc "Run main 'test' task and report merged results to coveralls" task test_with_coveralls: [:test] do if Dir.exist?(File.expand_path('../lib', __FILE__)) require 'coveralls/rake/task' Coveralls::RakeTask.new Rake::Task['coveralls:push'].invoke else puts 'Skipping reporting to coveralls. Module has no lib dir' end end desc 'Generate REFERENCE.md' task :reference, [:debug, :backtrace] do |t, args| patterns = '' Rake::Task['strings:generate:reference'].invoke(patterns, args[:debug], args[:backtrace]) end begin require 'github_changelog_generator/task' GitHubChangelogGenerator::RakeTask.new :changelog do |config| version = (Blacksmith::Modulefile.new).version config.future_release = "v#{version}" if version =~ /^\d+\.\d+.\d+$/ config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file.\nEach new release typically also includes the latest modulesync defaults.\nThese should not affect the functionality of the module." config.exclude_labels = %w{duplicate question invalid wontfix wont-fix modulesync skip-changelog} config.user = 'voxpupuli' metadata_json = File.join(File.dirname(__FILE__), 'metadata.json') metadata = JSON.load(File.read(metadata_json)) config.project = metadata['name'] end # Workaround for https://github.com/github-changelog-generator/github-changelog-generator/issues/715 require 'rbconfig' if RbConfig::CONFIG['host_os'] =~ /linux/ task :changelog do puts 'Fixing line endings...' changelog_file = File.join(__dir__, 'CHANGELOG.md') changelog_txt = File.read(changelog_file) new_contents = changelog_txt.gsub(%r{\r\n}, "\n") File.open(changelog_file, "w") {|file| file.puts new_contents } end end rescue LoadError end # vim: syntax=ruby diff --git a/spec/classes/redis_spec.rb b/spec/classes/redis_spec.rb index 84396d3..8eee80b 100644 --- a/spec/classes/redis_spec.rb +++ b/spec/classes/redis_spec.rb @@ -1,1415 +1,1421 @@ require 'spec_helper' describe 'redis' do - let(:service_file) { redis_service_file(service_provider: facts['service_provider']) } + let(:service_file) do + if facts['service_provider'] == 'systemd' + "/etc/systemd/system/#{service_name}.service" + else + "/etc/init.d/#{service_name}" + end + end let(:package_name) { manifest_vars[:package_name] } let(:service_name) { manifest_vars[:service_name] } let(:config_file) { manifest_vars[:config_file] } let(:config_file_orig) { manifest_vars[:config_file_orig] } on_supported_os.each do |os, facts| context "on #{os}" do let(:facts) { facts } if facts[:operatingsystem] == 'Ubuntu' && facts[:operatingsystemmajrelease] == '16.04' let(:systemd) { '' } let(:servicetype) { 'forking' } else let(:systemd) { ' --supervised systemd' } let(:servicetype) { 'notify' } end describe 'without parameters' do it { is_expected.to compile.with_all_deps } it { is_expected.to create_class('redis') } it { is_expected.to contain_class('redis::preinstall') } it { is_expected.to contain_class('redis::install') } it { is_expected.to contain_class('redis::config') } it { is_expected.to contain_class('redis::service') } it { is_expected.to contain_package(package_name).with_ensure('present') } it do is_expected.to contain_file(config_file_orig). with_ensure('file'). without_content(%r{undef}) if facts[:osfamily] == 'FreeBSD' is_expected.to contain_file(config_file_orig). with_content(%r{dir /var/db/redis}). with_content(%r{pidfile /var/run/redis/redis\.pid}) end end it do is_expected.to contain_service(service_name).with( 'ensure' => 'running', 'enable' => 'true', 'hasrestart' => 'true', 'hasstatus' => 'true' ) end context 'with SCL', if: facts[:osfamily] == 'RedHat' && facts[:operatingsystemmajrelease] < '8' do let(:pre_condition) do <<-PUPPET class { 'redis::globals': scl => 'rh-redis5', } PUPPET end it { is_expected.to compile.with_all_deps } it do is_expected.to create_class('redis'). with_package_name('rh-redis5-redis'). with_config_file('/etc/opt/rh/rh-redis5/redis.conf'). with_service_name('rh-redis5-redis') end context 'manage_repo => true', if: facts[:operatingsystem] == 'CentOS' do let(:params) { { manage_repo: true } } it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('centos-release-scl-rh') } end end end context 'with managed_by_cluster_manager true' do let(:params) { { managed_by_cluster_manager: true } } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file('/etc/security/limits.d/redis.conf').with( 'ensure' => 'file', 'owner' => 'root', 'group' => 'root', 'mode' => '0644', 'content' => "redis soft nofile 65536\nredis hard nofile 65536\n" ) end context 'when not managing service' do let(:params) { super().merge(service_manage: false, notify_service: false) } it { is_expected.to compile.with_all_deps } it do is_expected.to contain_file('/etc/security/limits.d/redis.conf').with( 'ensure' => 'file', 'owner' => 'root', 'group' => 'root', 'mode' => '0644', 'content' => "redis soft nofile 65536\nredis hard nofile 65536\n" ) end end end context 'with ulimit' do let(:params) { { ulimit: 7777 } } it { is_expected.to compile.with_all_deps } it do if facts['service_provider'] == 'systemd' is_expected.to contain_file("/etc/systemd/system/#{service_name}.service.d/limit.conf"). with_ensure('file'). with_owner('root'). with_group('root'). with_mode('0444') # Only necessary for Puppet < 6.1.0, # See https://github.com/puppetlabs/puppet/commit/f8d5c60ddb130c6429ff12736bfdb4ae669a9fd4 if Puppet.version < '6.1' is_expected.to contain_augeas('Systemd redis ulimit'). with_incl("/etc/systemd/system/#{service_name}.service.d/limit.conf"). with_lens('Systemd.lns'). with_changes(['defnode nofile Service/LimitNOFILE ""', 'set $nofile/value "7777"']). that_notifies('Class[systemd::systemctl::daemon_reload]') else is_expected.to contain_augeas('Systemd redis ulimit'). with_incl("/etc/systemd/system/#{service_name}.service.d/limit.conf"). with_lens('Systemd.lns'). with_changes(['defnode nofile Service/LimitNOFILE ""', 'set $nofile/value "7777"']) end else is_expected.not_to contain_file('/etc/systemd/system/redis-server.service.d/limit.conf') is_expected.not_to contain_augeas('Systemd redis ulimit') if %w[Debian RedHat].include?(facts[:osfamily]) ulimit_context = case facts[:osfamily] when 'Debian' '/files/etc/default/redis-server' when 'RedHat' '/files/etc/sysconfig/redis' end if ulimit_context is_expected.to contain_augeas('redis ulimit'). with_changes('set ULIMIT 7777'). with_context(ulimit_context) else is_expected.not_to contain_augeas('redis ulimit') end end end end end describe 'with parameter activerehashing' do let(:params) do { activerehashing: true } end it { is_expected.to contain_file(config_file_orig).with_content(%r{activerehashing.*yes}) } end describe 'with parameter aof_load_truncated' do let(:params) do { aof_load_truncated: true } end it { is_expected.to contain_file(config_file_orig).with_content(%r{aof-load-truncated.*yes}) } end describe 'with parameter aof_rewrite_incremental_fsync' do let(:params) do { aof_rewrite_incremental_fsync: true } end it { is_expected.to contain_file(config_file_orig).with_content(%r{aof-rewrite-incremental-fsync.*yes}) } end describe 'with parameter appendfilename' do let(:params) do { appendfilename: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with_content(%r{appendfilename.*_VALUE_}) } end describe 'with parameter appendfsync' do let(:params) do { appendfsync: 'no' } end it { is_expected.to contain_file(config_file_orig).with_content(%r{^appendfsync no$}) } end describe 'with parameter appendonly' do let(:params) do { appendonly: true } end it { is_expected.to contain_file(config_file_orig).with_content(%r{appendonly.*yes}) } end describe 'with parameter auto_aof_rewrite_min_size' do let(:params) do { auto_aof_rewrite_min_size: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with_content(%r{auto-aof-rewrite-min-size.*_VALUE_}) } end describe 'with parameter auto_aof_rewrite_percentage' do let(:params) do { auto_aof_rewrite_percentage: 75 } end it { is_expected.to contain_file(config_file_orig).with_content(%r{auto-aof-rewrite-percentage 75}) } end describe 'parameter bind' do context 'by default' do it 'binds to localhost' do is_expected.to contain_file(config_file_orig).with_content(%r{bind 127\.0\.0\.1$}) end end context 'with a single IP address' do let(:params) { { bind: '10.0.0.1' } } it { is_expected.to contain_file(config_file_orig).with_content(%r{bind 10\.0\.0\.1$}) } end context 'with array of IP addresses' do let(:params) do { bind: ['127.0.0.1', '::1'] } end it { is_expected.to contain_file(config_file_orig).with_content(%r{bind 127\.0\.0\.1 ::1}) } end context 'with empty array' do let(:params) { { bind: [] } } it { is_expected.not_to contain_file(config_file_orig).with_content(%r{^bind}) } end end describe 'with parameter output_buffer_limit_slave' do let(:params) do { output_buffer_limit_slave: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with_content(%r{client-output-buffer-limit slave.*_VALUE_}) } end describe 'with parameter output_buffer_limit_pubsub' do let(:params) do { output_buffer_limit_pubsub: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with_content(%r{client-output-buffer-limit pubsub.*_VALUE_}) } end describe 'with parameter: config_dir' do let(:params) { { config_dir: '/etc/config_dir' } } it { is_expected.to contain_file('/etc/config_dir').with_ensure('directory') } end describe 'with parameter: config_dir_mode' do let(:params) { { config_dir_mode: '0700' } } it { is_expected.to contain_file('/etc/redis').with_mode('0700') } end describe 'with parameter: log_dir_mode' do let(:params) { { log_dir_mode: '0660' } } it { is_expected.to contain_file('/var/log/redis').with_mode('0660') } end describe 'with parameter: config_file_orig' do let(:params) { { config_file_orig: '/path/to/orig' } } it { is_expected.to contain_file('/path/to/orig') } end describe 'with parameter: config_file_mode' do let(:params) { { config_file_mode: '0600' } } it { is_expected.to contain_file(config_file_orig).with_mode('0600') } end describe 'with parameter: config_group' do let(:params) { { config_group: '_VALUE_' } } it { is_expected.to contain_file('/etc/redis').with_group('_VALUE_') } end describe 'with parameter: config_owner' do let(:params) { { config_owner: '_VALUE_' } } it { is_expected.to contain_file('/etc/redis').with_owner('_VALUE_') } end describe 'with parameter daemonize' do let(:params) do { daemonize: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{daemonize.*yes} ) } end describe 'with parameter databases' do let(:params) do { databases: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{databases 42} ) } end describe 'with parameter dbfilename' do let(:params) do { dbfilename: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{dbfilename.*_VALUE_} ) } end describe 'without parameter dbfilename' do let(:params) do { dbfilename: false } end it { is_expected.to contain_file(config_file_orig).without_content(%r{^dbfilename}) } end describe 'with parameter hash_max_ziplist_entries' do let(:params) do { hash_max_ziplist_entries: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{hash-max-ziplist-entries 42} ) } end describe 'with parameter hash_max_ziplist_value' do let(:params) do { hash_max_ziplist_value: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{hash-max-ziplist-value 42} ) } end # TODO: Only present in 3.0 describe 'with parameter list_max_ziplist_entries' do let(:params) do { list_max_ziplist_entries: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{list-max-ziplist-entries 42} ) } end describe 'with parameter list_max_ziplist_value' do let(:params) do { list_max_ziplist_value: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{list-max-ziplist-value 42} ) } end describe 'with parameter log_dir' do let(:params) do { log_dir: '/var/log/redis' } end it { is_expected.to contain_file('/var/log/redis').with( 'ensure' => 'directory' ) } end describe 'with parameter log_file' do let(:params) do { log_file: '/var/log/redis/redis.log' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^logfile /var/log/redis/redis\.log$} ) } end describe 'with parameter log_level' do let(:params) do { log_level: 'debug' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^loglevel debug$} ) } end describe 'with parameter: manage_repo' do let(:params) { { manage_repo: true } } case facts[:operatingsystem] when 'Debian' context 'on Debian' do it do is_expected.to create_apt__source('dotdeb').with(location: 'http://packages.dotdeb.org/', repos: 'all', key: { 'id' => '6572BBEF1B5FF28B28B706837E3F070089DF5277', 'source' => 'http://www.dotdeb.org/dotdeb.gpg' }, include: { 'src' => true }) end end when 'Ubuntu' it { is_expected.to contain_apt__ppa('ppa:chris-lea/redis-server') } when 'RedHat', 'CentOS', 'Scientific', 'OEL', 'Amazon' it { is_expected.to contain_class('epel') } end end describe 'with parameter unixsocket' do describe '/tmp/redis.sock' do let(:params) { { unixsocket: '/tmp/redis.sock' } } it { is_expected.to contain_file(config_file_orig).with_content(%r{^unixsocket /tmp/redis\.sock$}) } end describe 'empty string' do let(:params) { { unixsocket: '' } } it { is_expected.to contain_file(config_file_orig).without_content(%r{^unixsocket }) } end end describe 'with parameter unixsocketperm' do describe '777' do let(:params) { { unixsocketperm: '777' } } it { is_expected.to contain_file(config_file_orig).with_content(%r{^unixsocketperm 777$}) } end describe 'empty string' do let(:params) { { unixsocketperm: '' } } it { is_expected.to contain_file(config_file_orig).without_content(%r{^unixsocketperm }) } end end describe 'with parameter masterauth' do let(:params) do { masterauth: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{masterauth.*_VALUE_} ) } end describe 'with parameter maxclients' do let(:params) do { maxclients: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^maxclients 42$} ) } end describe 'with parameter maxmemory' do let(:params) do { maxmemory: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{maxmemory.*_VALUE_} ) } end describe 'with parameter maxmemory_policy' do let(:params) do { maxmemory_policy: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{maxmemory-policy.*_VALUE_} ) } end describe 'with parameter maxmemory_samples' do let(:params) do { maxmemory_samples: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{maxmemory-samples.*_VALUE_} ) } end describe 'with parameter min_slaves_max_lag' do let(:params) do { min_slaves_max_lag: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^min-slaves-max-lag 42$} ) } end describe 'with parameter min_slaves_to_write' do let(:params) do { min_slaves_to_write: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^min-slaves-to-write 42$} ) } end describe 'with parameter notify_keyspace_events' do let(:params) do { notify_keyspace_events: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{notify-keyspace-events.*_VALUE_} ) } end describe 'with parameter notify_service' do let(:params) do { notify_service: true } end it { is_expected.to contain_file(config_file_orig).that_notifies("Service[#{service_name}]") } end describe 'with parameter no_appendfsync_on_rewrite' do let(:params) do { no_appendfsync_on_rewrite: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{no-appendfsync-on-rewrite.*yes} ) } end describe 'with parameter: package_ensure' do let(:params) { { package_ensure: '_VALUE_' } } it { is_expected.to contain_package(package_name).with( 'ensure' => '_VALUE_' ) } end describe 'with parameter: package_name' do let(:params) { { package_name: '_VALUE_' } } it { is_expected.to contain_package('_VALUE_') } end describe 'with parameter pid_file' do let(:params) do { pid_file: '/path/to/redis.pid' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^pidfile /path/to/redis.pid$} ) } end describe 'with parameter port' do let(:params) do { port: 6666 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^port 6666$} ) } end describe 'with parameter protected-mode' do let(:params) do { protected_mode: false } end it do if facts[:operatingsystem] == 'Ubuntu' && facts[:operatingsystemmajrelease] == '16.04' is_expected.not_to contain_file(config_file_orig).with_content(%r{protected-mode}) else is_expected.to contain_file(config_file_orig).with_content(%r{^protected-mode no$}) end end end describe 'with parameter hll_sparse_max_bytes' do let(:params) do { hll_sparse_max_bytes: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^hll-sparse-max-bytes 42$} ) } end describe 'with parameter hz' do let(:params) do { hz: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^hz 42$} ) } end describe 'with parameter latency_monitor_threshold' do let(:params) do { latency_monitor_threshold: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^latency-monitor-threshold 42$} ) } end describe 'with parameter rdbcompression' do let(:params) do { rdbcompression: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{rdbcompression.*yes} ) } end describe 'with parameter repl_backlog_size' do let(:params) do { repl_backlog_size: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{repl-backlog-size.*_VALUE_} ) } end describe 'with parameter repl_backlog_ttl' do let(:params) do { repl_backlog_ttl: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^repl-backlog-ttl 42$} ) } end describe 'with parameter repl_disable_tcp_nodelay' do let(:params) do { repl_disable_tcp_nodelay: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{repl-disable-tcp-nodelay.*yes} ) } end describe 'with parameter repl_ping_slave_period' do let(:params) do { repl_ping_slave_period: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^repl-ping-slave-period 42} ) } end describe 'with parameter repl_timeout' do let(:params) do { repl_timeout: 1 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{repl-timeout.*1} ) } end describe 'with parameter requirepass' do let(:params) do { requirepass: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{requirepass.*_VALUE_} ) } end describe 'with parameter save_db_to_disk' do context 'true' do let(:params) do { save_db_to_disk: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^save} ) } end context 'false' do let(:params) do { save_db_to_disk: false } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^(?!save)} ) } end end describe 'with parameter save_db_to_disk_interval' do context 'with save_db_to_disk true' do context 'default' do let(:params) do { save_db_to_disk: true } end it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 900 1}) } it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 300 10}) } it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 60 10000}) } end context 'default' do let(:params) do { save_db_to_disk: true, save_db_to_disk_interval: { '900' => '2', '300' => '11', '60' => '10011' } } end it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 900 2}) } it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 300 11}) } it { is_expected.to contain_file(config_file_orig).with('content' => %r{save 60 10011}) } end end context 'with save_db_to_disk false' do context 'default' do let(:params) do { save_db_to_disk: false } end it { is_expected.to contain_file(config_file_orig).without('content' => %r{save 900 1}) } it { is_expected.to contain_file(config_file_orig).without('content' => %r{save 300 10}) } it { is_expected.to contain_file(config_file_orig).without('content' => %r{save 60 10000}) } end end end describe 'with parameter: service_manage (set to false)' do let(:params) { { service_manage: false } } it { is_expected.not_to contain_service(package_name) } end describe 'with parameter: service_enable' do let(:params) { { service_enable: true } } it { is_expected.to contain_service(package_name).with_enable(true) } end describe 'with parameter: service_ensure' do let(:params) { { service_ensure: 'stopped' } } it { is_expected.to contain_service(package_name).with_ensure('stopped') } end describe 'with parameter: service_group' do let(:params) { { service_group: '_VALUE_' } } it { is_expected.to contain_file('/var/log/redis').with_group('_VALUE_') } end describe 'with parameter: service_hasrestart' do let(:params) { { service_hasrestart: true } } it { is_expected.to contain_service(package_name).with_hasrestart(true) } end describe 'with parameter: service_hasstatus' do let(:params) { { service_hasstatus: true } } it { is_expected.to contain_service(package_name).with_hasstatus(true) } end describe 'with parameter: service_name' do let(:params) { { service_name: '_VALUE_' } } it { is_expected.to contain_service('_VALUE_').with_name('_VALUE_') } end describe 'with parameter: service_user' do let(:params) { { service_user: '_VALUE_' } } it { is_expected.to contain_file('/var/log/redis').with_owner('_VALUE_') } end describe 'with parameter set_max_intset_entries' do let(:params) do { set_max_intset_entries: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^set-max-intset-entries 42$} ) } end describe 'with parameter slave_priority' do let(:params) do { slave_priority: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^slave-priority 42$} ) } end describe 'with parameter slave_read_only' do let(:params) do { slave_read_only: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{slave-read-only.*yes} ) } end describe 'with parameter slave_serve_stale_data' do let(:params) do { slave_serve_stale_data: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{slave-serve-stale-data.*yes} ) } end describe 'with parameter: slaveof' do context 'binding to localhost' do let(:params) do { bind: '127.0.0.1', slaveof: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^slaveof _VALUE_} ) } end context 'binding to external ip' do let(:params) do { bind: '10.0.0.1', slaveof: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^slaveof _VALUE_} ) } end end describe 'with parameter slowlog_log_slower_than' do let(:params) do { slowlog_log_slower_than: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^slowlog-log-slower-than 42$} ) } end describe 'with parameter slowlog_max_len' do let(:params) do { slowlog_max_len: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^slowlog-max-len 42$} ) } end describe 'with parameter stop_writes_on_bgsave_error' do let(:params) do { stop_writes_on_bgsave_error: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{stop-writes-on-bgsave-error.*yes} ) } end describe 'with parameter syslog_enabled' do let(:params) do { syslog_enabled: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{syslog-enabled yes} ) } end describe 'with parameter syslog_facility' do let(:params) do { syslog_enabled: true, syslog_facility: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{syslog-facility.*_VALUE_} ) } end describe 'with parameter tcp_backlog' do let(:params) do { tcp_backlog: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^tcp-backlog 42$} ) } end describe 'with parameter tcp_keepalive' do let(:params) do { tcp_keepalive: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^tcp-keepalive 42$} ) } end describe 'with parameter timeout' do let(:params) do { timeout: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^timeout 42$} ) } end describe 'with parameter workdir' do let(:params) do { workdir: '/var/workdir' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{^dir /var/workdir$} ) } end describe 'with parameter zset_max_ziplist_entries' do let(:params) do { zset_max_ziplist_entries: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{zset-max-ziplist-entries 42} ) } end describe 'with parameter zset_max_ziplist_value' do let(:params) do { zset_max_ziplist_value: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{zset-max-ziplist-value 42} ) } end describe 'with parameter cluster_enabled-false' do let(:params) do { cluster_enabled: false } end it { is_expected.not_to contain_file(config_file_orig).with( 'content' => %r{cluster-enabled} ) } end describe 'with parameter cluster_enabled-true' do let(:params) do { cluster_enabled: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{cluster-enabled.*yes} ) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_config_file: '_VALUE_' } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{cluster-config-file.*_VALUE_} ) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_node_timeout: 42 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{cluster-node-timeout 42} ) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_slave_validity_factor: 1 } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{cluster-slave-validity-factor.*1} ) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_require_full_coverage: true } end it { is_expected.to contain_file(config_file_orig).with( 'content' => %r{cluster-require-full-coverage.*yes} ) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_require_full_coverage: false } end it { is_expected.to contain_file(config_file_orig).with_content(%r{cluster-require-full-coverage.*no}) } end describe 'with parameter cluster_config_file' do let(:params) do { cluster_enabled: true, cluster_migration_barrier: 1 } end it { is_expected.to contain_file(config_file_orig).with_content(%r{cluster-migration-barrier.*1}) } end describe 'with parameter manage_service_file' do let(:params) do { manage_service_file: true } end it { is_expected.to contain_file(service_file) } it do content = <<-END.gsub(%r{^\s+\|}, '') |[Unit] |Description=Redis Advanced key-value store for instance default |After=network.target |After=network-online.target |Wants=network-online.target | |[Service] |RuntimeDirectory=redis |RuntimeDirectoryMode=2755 |Type=#{servicetype} |ExecStart=/usr/bin/redis-server #{config_file}#{systemd} |ExecStop=/usr/bin/redis-server -p 6379 shutdown |Restart=always |User=redis |Group=redis |LimitNOFILE=65536 | |[Install] |WantedBy=multi-user.target END if facts['service_provider'] == 'systemd' is_expected.to contain_file(service_file).with_content(content) else is_expected.to contain_file(service_file).with_content(%r{Required-Start:}) end end end describe 'with parameter manage_service_file' do let(:params) do { manage_service_file: false } end it { is_expected.not_to contain_file(service_file) } end context 'when $::redis_server_version fact is not present' do let(:facts) { super().merge(redis_server_version: nil) } context 'when package_ensure is version (3.2.1)' do let(:params) { { package_ensure: '3.2.1' } } it { is_expected.to contain_file(config_file_orig).with_content(%r{^protected-mode}) } end context 'when package_ensure is a newer version(4.0-rc3) (older features enabled)' do let(:params) { { package_ensure: '4.0-rc3' } } it { is_expected.to contain_file(config_file_orig).with_content(%r{^protected-mode}) } end end context 'when $::redis_server_version fact is present but a newer version (older features enabled)' do let(:facts) { super().merge(redis_server_version: '3.2.1') } it { is_expected.to contain_file(config_file_orig).with_content(%r{^protected-mode}) } end end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ee5bb7e..8858124 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,103 +1,85 @@ RSpec.configure do |c| c.mock_with :mocha end require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' include RspecPuppetFacts def manifest_vars vars = {} case facts[:osfamily].to_s when 'RedHat' vars[:package_name] = 'redis' vars[:service_name] = 'redis' vars[:config_file] = '/etc/redis.conf' vars[:config_file_orig] = '/etc/redis.conf.puppet' when 'FreeBSD', vars[:package_name] = 'redis' vars[:service_name] = 'redis' vars[:config_file] = '/usr/local/etc/redis.conf' vars[:config_file_orig] = '/usr/local/etc/redis.conf.puppet' when 'Debian' vars[:package_name] = 'redis-server' vars[:service_name] = 'redis-server' vars[:config_file] = '/etc/redis/redis.conf' vars[:config_file_orig] = '/etc/redis/redis.conf.puppet' when 'Archlinux' vars[:package_name] = 'redis' vars[:service_name] = 'redis' vars[:config_file] = '/etc/redis/redis.conf' vars[:config_file_orig] = '/etc/redis/redis.conf.puppet' end vars end -def redis_service_name(service_name: 'default') - case service_name.to_s - when 'default' - manifest_vars[:service_name] - else - "#{manifest_vars[:service_name]}-#{service_name}" - end -end - -def redis_service_file(service_name: redis_service_name, service_provider: nil) - case service_provider.to_s - when 'systemd' - "/etc/systemd/system/#{service_name}.service" - else - "/etc/init.d/#{service_name}" - end -end - if ENV['DEBUG'] Puppet::Util::Log.level = :debug Puppet::Util::Log.newdestination(:console) end add_custom_fact :service_provider, (lambda do |_os, facts| case facts[:osfamily].downcase when 'archlinux' 'systemd' when 'darwin' 'launchd' when 'debian' 'systemd' when 'freebsd' 'freebsd' when 'gentoo' 'openrc' when 'openbsd' 'openbsd' when 'redhat' facts[:operatingsystemrelease].to_i >= 7 ? 'systemd' : 'redhat' when 'suse' facts[:operatingsystemmajrelease].to_i >= 12 ? 'systemd' : 'redhat' when 'windows' 'windows' else 'init' end end) RSpec.configure do |c| # getting the correct facter version is tricky. We use facterdb as a source to mock facts # see https://github.com/camptocamp/facterdb # people might provide a specific facter version. In that case we use it. # Otherwise we need to match the correct facter version to the used puppet version. # as of 2019-10-31, puppet 5 ships facter 3.11 and puppet 6 ships facter 3.14 # https://puppet.com/docs/puppet/5.5/about_agent.html c.default_facter_version = if ENV['FACTERDB_FACTS_VERSION'] ENV['FACTERDB_FACTS_VERSION'] else Gem::Dependency.new('', ENV['PUPPET_VERSION']).match?('', '5') ? '3.11.0' : '3.14.0' end # Coverage generation c.after(:suite) do RSpec::Puppet::Coverage.report! end end