From a2af7dd0b9713f279724d2c7e6f17bfd8ce2d95b Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Tue, 31 Jul 2018 14:56:46 -0500 Subject: Initial cron import from puppet 7a4c5f07bdf61a7bc7aa32a50e99489a604eac52 --- lib/puppet/provider/cron/crontab.rb | 297 ++++++++++++++++++++++ lib/puppet/type/cron.rb | 480 ++++++++++++++++++++++++++++++++++++ 2 files changed, 777 insertions(+) create mode 100644 lib/puppet/provider/cron/crontab.rb create mode 100644 lib/puppet/type/cron.rb (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb new file mode 100644 index 0000000..b24ed14 --- /dev/null +++ b/lib/puppet/provider/cron/crontab.rb @@ -0,0 +1,297 @@ +require 'puppet/provider/parsedfile' + +Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFile, :default_target => ENV["USER"] || "root") do + commands :crontab => "crontab" + + text_line :comment, :match => %r{^\s*#}, :post_parse => proc { |record| + record[:name] = $1 if record[:line] =~ /Puppet Name: (.+)\s*$/ + } + + text_line :blank, :match => %r{^\s*$} + + text_line :environment, :match => %r{^\s*\w+\s*=} + + def self.filetype + tabname = case Facter.value(:osfamily) + when "Solaris" + :suntab + when "AIX" + :aixtab + else + :crontab + end + + Puppet::Util::FileType.filetype(tabname) + end + + self::TIME_FIELDS = [:minute, :hour, :monthday, :month, :weekday] + + record_line :crontab, + :fields => %w{time command}, + :match => %r{^\s*(@\w+|\S+\s+\S+\s+\S+\s+\S+\s+\S+)\s+(.+)$}, + :absent => '*', + :block_eval => :instance do + + def post_parse(record) + time = record.delete(:time) + if match = /@(\S+)/.match(time) + # is there another way to access the constant? + Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.each { |f| record[f] = :absent } + record[:special] = match.captures[0] + elsif match = /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/.match(time) + record[:special] = :absent + Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.zip(match.captures).each do |field,value| + if value == self.absent + record[field] = :absent + else + record[field] = value.split(",") + end + end + else + raise Puppet::Error, _("Line got parsed as a crontab entry but cannot be handled. Please file a bug with the contents of your crontab") + end + record + end + + def pre_gen(record) + if record[:special] and record[:special] != :absent + record[:special] = "@#{record[:special]}" + end + + Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.each do |field| + if vals = record[field] and vals.is_a?(Array) + record[field] = vals.join(",") + end + end + record + end + + def to_line(record) + str = "" + record[:name] = nil if record[:unmanaged] + str = "# Puppet Name: #{record[:name]}\n" if record[:name] + if record[:environment] and record[:environment] != :absent + str += record[:environment].map {|line| "#{line}\n"}.join('') + end + if record[:special] and record[:special] != :absent + fields = [:special, :command] + else + fields = Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS + [:command] + end + str += record.values_at(*fields).map do |field| + if field.nil? or field == :absent + self.absent + else + field + end + end.join(self.joiner) + str + end + end + + def create + if resource.should(:command) then + super + else + resource.err _("no command specified, cannot create") + end + end + + # Look up a resource with a given name whose user matches a record target + # + # @api private + # + # @note This overrides the ParsedFile method for finding resources by name, + # so that only records for a given user are matched to resources of the + # same user so that orphaned records in other crontabs don't get falsely + # matched (#2251) + # + # @param [Hash] record + # @param [Array] resources + # + # @return [Puppet::Resource, nil] The resource if found, else nil + def self.resource_for_record(record, resources) + resource = super + + if resource + target = resource[:target] || resource[:user] + if record[:target] == target + resource + end + end + end + + # Return the header placed at the top of each generated file, warning + # users that modifying this file manually is probably a bad idea. + def self.header +%{# HEADER: This file was autogenerated at #{Time.now} by puppet. +# HEADER: While it can still be managed manually, it is definitely not recommended. +# HEADER: Note particularly that the comments starting with 'Puppet Name' should +# HEADER: not be deleted, as doing so could cause duplicate cron jobs.\n} + end + + # Regex for finding one vixie cron header. + def self.native_header_regex + /# DO NOT EDIT THIS FILE.*?Cron version.*?vixie.*?\n/m + end + + # If a vixie cron header is found, it should be dropped, cron will insert + # a new one in any case, so we need to avoid duplicates. + def self.drop_native_header + true + end + + # See if we can match the record against an existing cron job. + def self.match(record, resources) + # if the record is named, do not even bother (#19876) + # except the resource name was implicitly generated (#3220) + return false if record[:name] and !record[:unmanaged] + resources.each do |name, resource| + # Match the command first, since it's the most important one. + next unless record[:target] == resource[:target] + next unless record[:command] == resource.value(:command) + + # Now check the time fields + compare_fields = self::TIME_FIELDS + [:special] + + matched = true + compare_fields.each do |field| + # If the resource does not manage a property (say monthday) it should + # always match. If it is the other way around (e.g. resource defines + # a should value for :special but the record does not have it, we do + # not match + next unless resource[field] + unless record.include?(field) + matched = false + break + end + + if record_value = record[field] and resource_value = resource.value(field) + # The record translates '*' into absent in the post_parse hook and + # the resource type does exactly the opposite (alias :absent to *) + next if resource_value == '*' and record_value == :absent + next if resource_value == record_value + end + matched =false + break + end + return resource if matched + end + false + end + + @name_index = 0 + + # Collapse name and env records. + def self.prefetch_hook(records) + name = nil + envs = nil + result = records.each { |record| + case record[:record_type] + when :comment + if record[:name] + name = record[:name] + record[:skip] = true + + # Start collecting env values + envs = [] + end + when :environment + # If we're collecting env values (meaning we're in a named cronjob), + # store the line and skip the record. + if envs + envs << record[:line] + record[:skip] = true + end + when :blank + # nothing + else + if name + record[:name] = name + name = nil + else + cmd_string = record[:command].gsub(/\s+/, "_") + index = ( @name_index += 1 ) + record[:name] = "unmanaged:#{cmd_string}-#{ index.to_s }" + record[:unmanaged] = true + end + if envs.nil? or envs.empty? + record[:environment] = :absent + else + # Collect all of the environment lines, and mark the records to be skipped, + # since their data is included in our crontab record. + record[:environment] = envs + + # And turn off env collection again + envs = nil + end + end + }.reject { |record| record[:skip] } + result + end + + def self.to_file(records) + text = super + # Apparently Freebsd will "helpfully" add a new TZ line to every + # single cron line, but not in all cases (e.g., it doesn't do it + # on my machine). This is my attempt to fix it so the TZ lines don't + # multiply. + if text =~ /(^TZ=.+\n)/ + tz = $1 + text.sub!(tz, '') + text = tz + text + end + text + end + + def user=(user) + # we have to mark the target as modified first, to make sure that if + # we move a cronjob from userA to userB, userA's crontab will also + # be rewritten + mark_target_modified + @property_hash[:user] = user + @property_hash[:target] = user + end + + def user + @property_hash[:user] || @property_hash[:target] + end + + CRONTAB_DIR = case Facter.value("osfamily") + when "Debian", "HP-UX" + "/var/spool/cron/crontabs" + when /BSD/ + "/var/cron/tabs" + when "Darwin" + "/usr/lib/cron/tabs/" + else + "/var/spool/cron" + end + + # Yield the names of all crontab files stored on the local system. + # + # @note Ignores files that are not writable for the puppet process. + # + # @api private + def self.enumerate_crontabs + Puppet.debug "looking for crontabs in #{CRONTAB_DIR}" + return unless File.readable?(CRONTAB_DIR) + Dir.foreach(CRONTAB_DIR) do |file| + path = "#{CRONTAB_DIR}/#{file}" + yield(file) if File.file?(path) and File.writable?(path) + end + end + + + # Include all plausible crontab files on the system + # in the list of targets (#11383 / PUP-1381) + def self.targets(resources = nil) + targets = super(resources) + enumerate_crontabs do |target| + targets << target + end + targets.uniq + end + +end + diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb new file mode 100644 index 0000000..a4f1f91 --- /dev/null +++ b/lib/puppet/type/cron.rb @@ -0,0 +1,480 @@ +require 'etc' +require 'facter' +require 'puppet/util/filetype' + +Puppet::Type.newtype(:cron) do + @doc = <<-'EOT' + Installs and manages cron jobs. Every cron resource created by Puppet + requires a command and at least one periodic attribute (hour, minute, + month, monthday, weekday, or special). While the name of the cron job is + not part of the actual job, the name is stored in a comment beginning with + `# Puppet Name: `. These comments are used to match crontab entries created + by Puppet with cron resources. + + If an existing crontab entry happens to match the scheduling and command of a + cron resource that has never been synced, Puppet will defer to the existing + crontab entry and will not create a new entry tagged with the `# Puppet Name: ` + comment. + + Example: + + cron { 'logrotate': + command => '/usr/sbin/logrotate', + user => 'root', + hour => 2, + minute => 0, + } + + Note that all periodic attributes can be specified as an array of values: + + cron { 'logrotate': + command => '/usr/sbin/logrotate', + user => 'root', + hour => [2, 4], + } + + ...or using ranges or the step syntax `*/2` (although there's no guarantee + that your `cron` daemon supports these): + + cron { 'logrotate': + command => '/usr/sbin/logrotate', + user => 'root', + hour => ['2-4'], + minute => '*/10', + } + + An important note: _the Cron type will not reset parameters that are + removed from a manifest_. For example, removing a `minute => 10` parameter + will not reset the minute component of the associated cronjob to `*`. + These changes must be expressed by setting the parameter to + `minute => absent` because Puppet only manages parameters that are out of + sync with manifest entries. + + **Autorequires:** If Puppet is managing the user account specified by the + `user` property of a cron resource, then the cron resource will autorequire + that user. + EOT + ensurable + + # A base class for all of the Cron parameters, since they all have + # similar argument checking going on. + class CronParam < Puppet::Property + class << self + attr_accessor :boundaries, :default + end + + # We have to override the parent method, because we consume the entire + # "should" array + def insync?(is) + self.is_to_s(is) == self.should_to_s + end + + # A method used to do parameter input handling. Converts integers + # in string form to actual integers, and returns the value if it's + # an integer or false if it's just a normal string. + def numfix(num) + if num =~ /^\d+$/ + return num.to_i + elsif num.is_a?(Integer) + return num + else + return false + end + end + + # Verify that a number is within the specified limits. Return the + # number if it is, or false if it is not. + def limitcheck(num, lower, upper) + (num >= lower and num <= upper) && num + end + + # Verify that a value falls within the specified array. Does case + # insensitive matching, and supports matching either the entire word + # or the first three letters of the word. + def alphacheck(value, ary) + tmp = value.downcase + + # If they specified a shortened version of the name, then see + # if we can lengthen it (e.g., mon => monday). + if tmp.length == 3 + ary.each_with_index { |name, index| + if tmp.upcase == name[0..2].upcase + return index + end + } + else + return ary.index(tmp) if ary.include?(tmp) + end + + false + end + + def should_to_s(value = @should) + if value + if value.is_a?(Array) && (name == :command || value[0].is_a?(Symbol)) + value = value[0] + end + super(value) + else + nil + end + end + + def is_to_s(value = @is) + if value + if value.is_a?(Array) && (name == :command || value[0].is_a?(Symbol)) + value = value[0] + end + super(value) + else + nil + end + end + + def should + if @should and @should[0] == :absent + :absent + else + @should + end + end + + def should=(ary) + super + @should.flatten! + end + + # The method that does all of the actual parameter value + # checking; called by all of the +param=+ methods. + # Requires the value, type, and bounds, and optionally supports + # a boolean of whether to do alpha checking, and if so requires + # the ary against which to do the checking. + munge do |value| + # Support 'absent' as a value, so that they can remove + # a value + if value == "absent" or value == :absent + return :absent + end + + # Allow the */2 syntax + if value =~ /^\*\/[0-9]+$/ + return value + end + + # Allow ranges + if value =~ /^[0-9]+-[0-9]+$/ + return value + end + + # Allow ranges + */2 + if value =~ /^[0-9]+-[0-9]+\/[0-9]+$/ + return value + end + + if value == "*" + return :absent + end + + return value unless self.class.boundaries + lower, upper = self.class.boundaries + retval = nil + if num = numfix(value) + retval = limitcheck(num, lower, upper) + elsif respond_to?(:alpha) + # If it has an alpha method defined, then we check + # to see if our value is in that list and if so we turn + # it into a number + retval = alphacheck(value, alpha) + end + + if retval + return retval.to_s + else + self.fail _("%{value} is not a valid %{name}") % { value: value, name: self.class.name } + end + end + end + + # Somewhat uniquely, this property does not actually change anything -- it + # just calls +@resource.sync+, which writes out the whole cron tab for + # the user in question. There is no real way to change individual cron + # jobs without rewriting the entire cron file. + # + # Note that this means that managing many cron jobs for a given user + # could currently result in multiple write sessions for that user. + newproperty(:command, :parent => CronParam) do + desc "The command to execute in the cron job. The environment + provided to the command varies by local system rules, and it is + best to always provide a fully qualified command. The user's + profile is not sourced when the command is run, so if the + user's environment is desired it should be sourced manually. + + All cron parameters support `absent` as a value; this will + remove any existing values for that field." + + def retrieve + return_value = super + return_value = return_value[0] if return_value && return_value.is_a?(Array) + + return_value + end + + def should + if @should + if @should.is_a? Array + @should[0] + else + devfail "command is not an array" + end + else + nil + end + end + + def munge(value) + value.strip + end + end + + newproperty(:special) do + desc "A special value such as 'reboot' or 'annually'. + Only available on supported systems such as Vixie Cron. + Overrides more specific time of day/week settings. + Set to 'absent' to make puppet revert to a plain numeric schedule." + + def specials + %w{reboot yearly annually monthly weekly daily midnight hourly absent} + + [ :absent ] + end + + validate do |value| + raise ArgumentError, _("Invalid special schedule %{value}") % { value: value.inspect } unless specials.include?(value) + end + + def munge(value) + # Support value absent so that a schedule can be + # forced to change to numeric. + if value == "absent" or value == :absent + return :absent + end + value + end + end + + newproperty(:minute, :parent => CronParam) do + self.boundaries = [0, 59] + desc "The minute at which to run the cron job. + Optional; if specified, must be between 0 and 59, inclusive." + end + + newproperty(:hour, :parent => CronParam) do + self.boundaries = [0, 23] + desc "The hour at which to run the cron job. Optional; + if specified, must be between 0 and 23, inclusive." + end + + newproperty(:weekday, :parent => CronParam) do + def alpha + %w{sunday monday tuesday wednesday thursday friday saturday} + end + self.boundaries = [0, 7] + desc "The weekday on which to run the command. Optional; if specified, + must be either: + + - A number between 0 and 7, inclusive, with 0 or 7 being Sunday + - The name of the day, such as 'Tuesday'." + end + + newproperty(:month, :parent => CronParam) do + def alpha + # The ___placeholder accounts for the fact that month is unique among + # "nameable" crontab entries in that it does not use 0-based indexing. + # Padding the array with a placeholder introduces the appropriate shift + # in indices. + %w{___placeholder january february march april may june july + august september october november december} + end + self.boundaries = [1, 12] + desc "The month of the year. Optional; if specified, + must be either: + + - A number between 1 and 12, inclusive, with 1 being January + - The name of the month, such as 'December'." + end + + newproperty(:monthday, :parent => CronParam) do + self.boundaries = [1, 31] + desc "The day of the month on which to run the + command. Optional; if specified, must be between 1 and 31." + end + + newproperty(:environment) do + desc "Any environment settings associated with this cron job. They + will be stored between the header and the job in the crontab. There + can be no guarantees that other, earlier settings will not also + affect a given cron job. + + + Also, Puppet cannot automatically determine whether an existing, + unmanaged environment setting is associated with a given cron + job. If you already have cron jobs with environment settings, + then Puppet will keep those settings in the same place in the file, + but will not associate them with a specific job. + + Settings should be specified exactly as they should appear in + the crontab, like `PATH=/bin:/usr/bin:/usr/sbin`." + + validate do |value| + unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent" + raise ArgumentError, _("Invalid environment setting %{value}") % { value: value.inspect } + end + end + + def insync?(is) + if is.is_a? Array + return is.sort == @should.sort + else + return is == @should + end + end + + def should + @should + end + + def should_to_s(newvalue = @should) + if newvalue + newvalue.join(",") + else + nil + end + end + end + + newparam(:name) do + desc "The symbolic name of the cron job. This name + is used for human reference only and is generated automatically + for cron jobs found on the system. This generally won't + matter, as Puppet will do its best to match existing cron jobs + against specified jobs (and Puppet adds a comment to cron jobs it adds), + but it is at least possible that converting from unmanaged jobs to + managed jobs might require manual intervention." + + isnamevar + end + + newproperty(:user) do + desc "The user who owns the cron job. This user must + be allowed to run cron jobs, which is not currently checked by + Puppet. + + This property defaults to the user running Puppet or `root`. + + The default crontab provider executes the system `crontab` using + the user account specified by this property." + + defaultto { + if not provider.is_a?(@resource.class.provider(:crontab)) + struct = Etc.getpwuid(Process.uid) + struct.respond_to?(:name) && struct.name or 'root' + end + } + end + + # Autorequire the owner of the crontab entry. + autorequire(:user) do + self[:user] + end + + newproperty(:target) do + desc "The name of the crontab file in which the cron job should be stored. + + This property defaults to the value of the `user` property if set, the + user running Puppet or `root`. + + For the default crontab provider, this property is functionally + equivalent to the `user` property and should be avoided. In particular, + setting both `user` and `target` to different values will result in + undefined behavior." + + defaultto { + if provider.is_a?(@resource.class.provider(:crontab)) + if val = @resource.should(:user) + val + else + struct = Etc.getpwuid(Process.uid) + struct.respond_to?(:name) && struct.name or 'root' + end + elsif provider.class.ancestors.include?(Puppet::Provider::ParsedFile) + provider.class.default_target + else + nil + end + } + end + + validate do + return true unless self[:special] + return true if self[:special] == :absent + # there is a special schedule in @should, so we don't want to see + # any numeric should values + [ :minute, :hour, :weekday, :monthday, :month ].each do |field| + next unless self[field] + next if self[field] == :absent + raise ArgumentError, _("%{cron} cannot specify both a special schedule and a value for %{field}") % { cron: self.ref, field: field } + end + end + + # We have to reorder things so that :provide is before :target + + attr_accessor :uid + + # Marks the resource as "being purged". + # + # @api public + # + # @note This overrides the Puppet::Type method in order to handle + # an edge case that has so far been observed during testing only. + # Without forcing the should-value for the user property to be + # identical to the original cron file, purging from a fixture + # will not work, because the user property defaults to the user + # running the test. It is not clear whether this scenario can apply + # during normal operation. + # + # @note Also, when not forcing the should-value for the target + # property, unpurged file content (such as comments) can end up + # being written to the default target (i.e. the current login name). + def purging + self[:target] = provider.target + self[:user] = provider.target + super + end + + def value(name) + name = name.intern + ret = nil + if obj = @parameters[name] + ret = obj.should + + ret ||= obj.retrieve + + if ret == :absent + ret = nil + end + end + + unless ret + case name + when :command + when :special + # nothing + else + #ret = (self.class.validproperty?(name).default || "*").to_s + ret = "*" + end + end + + ret + end +end + -- cgit v1.2.3 From 90216d84f8a2da1f77107dc5f0e3d76a3d72aacc Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Tue, 31 Jul 2018 17:01:34 -0500 Subject: Apply automatic pdk validate fixes --- lib/puppet/provider/cron/crontab.rb | 141 +++-- lib/puppet/type/cron.rb | 94 ++-- .../cron/should_allow_changing_parameters.rb | 64 ++- .../tests/resource/cron/should_be_idempotent.rb | 25 +- .../tests/resource/cron/should_create_cron.rb | 23 +- .../tests/resource/cron/should_match_existing.rb | 28 +- .../tests/resource/cron/should_remove_cron.rb | 27 +- ...hould_remove_leading_and_trailing_whitespace.rb | 36 +- .../tests/resource/cron/should_remove_matching.rb | 31 +- .../tests/resource/cron/should_update_existing.rb | 30 +- spec/integration/provider/cron/crontab_spec.rb | 43 +- spec/lib/puppet_spec/compiler.rb | 10 +- spec/lib/puppet_spec/files.rb | 32 +- spec/spec_helper_local.rb | 2 +- spec/unit/provider/cron/crontab_spec.rb | 107 ++-- spec/unit/provider/cron/parsed_spec.rb | 349 ++++++------ spec/unit/type/cron_spec.rb | 582 ++++++++++----------- 17 files changed, 794 insertions(+), 830 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index b24ed14..a664629 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -1,99 +1,99 @@ require 'puppet/provider/parsedfile' -Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFile, :default_target => ENV["USER"] || "root") do - commands :crontab => "crontab" +Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, default_target: ENV['USER'] || 'root') do + commands crontab: 'crontab' - text_line :comment, :match => %r{^\s*#}, :post_parse => proc { |record| - record[:name] = $1 if record[:line] =~ /Puppet Name: (.+)\s*$/ + text_line :comment, match: %r{^\s*#}, post_parse: proc { |record| + record[:name] = Regexp.last_match(1) if record[:line] =~ %r{Puppet Name: (.+)\s*$} } - text_line :blank, :match => %r{^\s*$} + text_line :blank, match: %r{^\s*$} - text_line :environment, :match => %r{^\s*\w+\s*=} + text_line :environment, match: %r{^\s*\w+\s*=} def self.filetype - tabname = case Facter.value(:osfamily) - when "Solaris" - :suntab - when "AIX" - :aixtab - else - :crontab - end + tabname = case Facter.value(:osfamily) + when 'Solaris' + :suntab + when 'AIX' + :aixtab + else + :crontab + end Puppet::Util::FileType.filetype(tabname) end - self::TIME_FIELDS = [:minute, :hour, :monthday, :month, :weekday] + self::TIME_FIELDS = [:minute, :hour, :monthday, :month, :weekday].freeze record_line :crontab, - :fields => %w{time command}, - :match => %r{^\s*(@\w+|\S+\s+\S+\s+\S+\s+\S+\s+\S+)\s+(.+)$}, - :absent => '*', - :block_eval => :instance do + fields: ['time', 'command'], + match: %r{^\s*(@\w+|\S+\s+\S+\s+\S+\s+\S+\s+\S+)\s+(.+)$}, + absent: '*', + block_eval: :instance do def post_parse(record) time = record.delete(:time) - if match = /@(\S+)/.match(time) + if match = %r{@(\S+)}.match(time) # is there another way to access the constant? Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.each { |f| record[f] = :absent } record[:special] = match.captures[0] - elsif match = /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/.match(time) + elsif match = %r{(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)}.match(time) record[:special] = :absent - Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.zip(match.captures).each do |field,value| - if value == self.absent - record[field] = :absent - else - record[field] = value.split(",") - end + Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.zip(match.captures).each do |field, value| + record[field] = if value == absent + :absent + else + value.split(',') + end end else - raise Puppet::Error, _("Line got parsed as a crontab entry but cannot be handled. Please file a bug with the contents of your crontab") + raise Puppet::Error, _('Line got parsed as a crontab entry but cannot be handled. Please file a bug with the contents of your crontab') end record end def pre_gen(record) - if record[:special] and record[:special] != :absent + if record[:special] && record[:special] != :absent record[:special] = "@#{record[:special]}" end Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.each do |field| - if vals = record[field] and vals.is_a?(Array) - record[field] = vals.join(",") + if (vals = record[field]) && vals.is_a?(Array) + record[field] = vals.join(',') end end record end def to_line(record) - str = "" + str = '' record[:name] = nil if record[:unmanaged] str = "# Puppet Name: #{record[:name]}\n" if record[:name] - if record[:environment] and record[:environment] != :absent - str += record[:environment].map {|line| "#{line}\n"}.join('') + if record[:environment] && record[:environment] != :absent + str += record[:environment].map { |line| "#{line}\n" }.join('') end - if record[:special] and record[:special] != :absent - fields = [:special, :command] - else - fields = Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS + [:command] - end - str += record.values_at(*fields).map do |field| - if field.nil? or field == :absent - self.absent + fields = if record[:special] && record[:special] != :absent + [:special, :command] + else + Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS + [:command] + end + str += record.values_at(*fields).map { |field| + if field.nil? || field == :absent + absent else field end - end.join(self.joiner) + }.join(joiner) str end end def create - if resource.should(:command) then + if resource.should(:command) super else - resource.err _("no command specified, cannot create") + resource.err _('no command specified, cannot create') end end @@ -124,15 +124,15 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi # Return the header placed at the top of each generated file, warning # users that modifying this file manually is probably a bad idea. def self.header -%{# HEADER: This file was autogenerated at #{Time.now} by puppet. + %(# HEADER: This file was autogenerated at #{Time.now} by puppet. # HEADER: While it can still be managed manually, it is definitely not recommended. # HEADER: Note particularly that the comments starting with 'Puppet Name' should -# HEADER: not be deleted, as doing so could cause duplicate cron jobs.\n} +# HEADER: not be deleted, as doing so could cause duplicate cron jobs.\n) end # Regex for finding one vixie cron header. def self.native_header_regex - /# DO NOT EDIT THIS FILE.*?Cron version.*?vixie.*?\n/m + %r{# DO NOT EDIT THIS FILE.*?Cron version.*?vixie.*?\n}m end # If a vixie cron header is found, it should be dropped, cron will insert @@ -145,8 +145,8 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi def self.match(record, resources) # if the record is named, do not even bother (#19876) # except the resource name was implicitly generated (#3220) - return false if record[:name] and !record[:unmanaged] - resources.each do |name, resource| + return false if record[:name] && !record[:unmanaged] + resources.each do |_name, resource| # Match the command first, since it's the most important one. next unless record[:target] == resource[:target] next unless record[:command] == resource.value(:command) @@ -166,13 +166,13 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi break end - if record_value = record[field] and resource_value = resource.value(field) + if (record_value = record[field]) && (resource_value = resource.value(field)) # The record translates '*' into absent in the post_parse hook and # the resource type does exactly the opposite (alias :absent to *) - next if resource_value == '*' and record_value == :absent + next if resource_value == '*' && record_value == :absent next if resource_value == record_value end - matched =false + matched = false break end return resource if matched @@ -210,12 +210,12 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi record[:name] = name name = nil else - cmd_string = record[:command].gsub(/\s+/, "_") - index = ( @name_index += 1 ) - record[:name] = "unmanaged:#{cmd_string}-#{ index.to_s }" + cmd_string = record[:command].gsub(%r{\s+}, '_') + index = (@name_index += 1) + record[:name] = "unmanaged:#{cmd_string}-#{index}" record[:unmanaged] = true end - if envs.nil? or envs.empty? + if envs.nil? || envs.empty? record[:environment] = :absent else # Collect all of the environment lines, and mark the records to be skipped, @@ -236,8 +236,8 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi # single cron line, but not in all cases (e.g., it doesn't do it # on my machine). This is my attempt to fix it so the TZ lines don't # multiply. - if text =~ /(^TZ=.+\n)/ - tz = $1 + if text =~ %r{(^TZ=.+\n)} + tz = Regexp.last_match(1) text.sub!(tz, '') text = tz + text end @@ -257,15 +257,15 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi @property_hash[:user] || @property_hash[:target] end - CRONTAB_DIR = case Facter.value("osfamily") - when "Debian", "HP-UX" - "/var/spool/cron/crontabs" - when /BSD/ - "/var/cron/tabs" - when "Darwin" - "/usr/lib/cron/tabs/" - else - "/var/spool/cron" + CRONTAB_DIR = case Facter.value('osfamily') + when 'Debian', 'HP-UX' + '/var/spool/cron/crontabs' + when %r{BSD} + '/var/cron/tabs' + when 'Darwin' + '/usr/lib/cron/tabs/' + else + '/var/spool/cron' end # Yield the names of all crontab files stored on the local system. @@ -278,11 +278,10 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi return unless File.readable?(CRONTAB_DIR) Dir.foreach(CRONTAB_DIR) do |file| path = "#{CRONTAB_DIR}/#{file}" - yield(file) if File.file?(path) and File.writable?(path) + yield(file) if File.file?(path) && File.writable?(path) end end - # Include all plausible crontab files on the system # in the list of targets (#11383 / PUP-1381) def self.targets(resources = nil) @@ -292,6 +291,4 @@ Puppet::Type.type(:cron).provide(:crontab, :parent => Puppet::Provider::ParsedFi end targets.uniq end - end - diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index a4f1f91..3a106c4 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -66,26 +66,26 @@ Puppet::Type.newtype(:cron) do # We have to override the parent method, because we consume the entire # "should" array def insync?(is) - self.is_to_s(is) == self.should_to_s + is_to_s(is) == should_to_s end # A method used to do parameter input handling. Converts integers # in string form to actual integers, and returns the value if it's # an integer or false if it's just a normal string. def numfix(num) - if num =~ /^\d+$/ - return num.to_i + if num =~ %r{^\d+$} + num.to_i elsif num.is_a?(Integer) - return num + num else - return false + false end end # Verify that a number is within the specified limits. Return the # number if it is, or false if it is not. def limitcheck(num, lower, upper) - (num >= lower and num <= upper) && num + (num >= lower && num <= upper) && num end # Verify that a value falls within the specified array. Does case @@ -97,11 +97,11 @@ Puppet::Type.newtype(:cron) do # If they specified a shortened version of the name, then see # if we can lengthen it (e.g., mon => monday). if tmp.length == 3 - ary.each_with_index { |name, index| - if tmp.upcase == name[0..2].upcase + ary.each_with_index do |name, index| + if tmp.casecmp(name[0..2]).zero? return index end - } + end else return ary.index(tmp) if ary.include?(tmp) end @@ -132,7 +132,7 @@ Puppet::Type.newtype(:cron) do end def should - if @should and @should[0] == :absent + if @should && @should[0] == :absent :absent else @should @@ -152,7 +152,7 @@ Puppet::Type.newtype(:cron) do munge do |value| # Support 'absent' as a value, so that they can remove # a value - if value == "absent" or value == :absent + if value == 'absent' || value == :absent return :absent end @@ -162,7 +162,7 @@ Puppet::Type.newtype(:cron) do end # Allow ranges - if value =~ /^[0-9]+-[0-9]+$/ + if value =~ %r{^[0-9]+-[0-9]+$} return value end @@ -171,7 +171,7 @@ Puppet::Type.newtype(:cron) do return value end - if value == "*" + if value == '*' return :absent end @@ -190,7 +190,7 @@ Puppet::Type.newtype(:cron) do if retval return retval.to_s else - self.fail _("%{value} is not a valid %{name}") % { value: value, name: self.class.name } + self.fail _('%{value} is not a valid %{name}') % { value: value, name: self.class.name } end end end @@ -202,7 +202,7 @@ Puppet::Type.newtype(:cron) do # # Note that this means that managing many cron jobs for a given user # could currently result in multiple write sessions for that user. - newproperty(:command, :parent => CronParam) do + newproperty(:command, parent: CronParam) do desc "The command to execute in the cron job. The environment provided to the command varies by local system rules, and it is best to always provide a fully qualified command. The user's @@ -224,7 +224,7 @@ Puppet::Type.newtype(:cron) do if @should.is_a? Array @should[0] else - devfail "command is not an array" + devfail 'command is not an array' end else nil @@ -243,39 +243,39 @@ Puppet::Type.newtype(:cron) do Set to 'absent' to make puppet revert to a plain numeric schedule." def specials - %w{reboot yearly annually monthly weekly daily midnight hourly absent} + - [ :absent ] + ['reboot', 'yearly', 'annually', 'monthly', 'weekly', 'daily', 'midnight', 'hourly', 'absent'] + + [:absent] end validate do |value| - raise ArgumentError, _("Invalid special schedule %{value}") % { value: value.inspect } unless specials.include?(value) + raise ArgumentError, _('Invalid special schedule %{value}') % { value: value.inspect } unless specials.include?(value) end def munge(value) # Support value absent so that a schedule can be # forced to change to numeric. - if value == "absent" or value == :absent + if value == 'absent' || value == :absent return :absent end value end end - newproperty(:minute, :parent => CronParam) do + newproperty(:minute, parent: CronParam) do self.boundaries = [0, 59] desc "The minute at which to run the cron job. Optional; if specified, must be between 0 and 59, inclusive." end - newproperty(:hour, :parent => CronParam) do + newproperty(:hour, parent: CronParam) do self.boundaries = [0, 23] desc "The hour at which to run the cron job. Optional; if specified, must be between 0 and 23, inclusive." end - newproperty(:weekday, :parent => CronParam) do + newproperty(:weekday, parent: CronParam) do def alpha - %w{sunday monday tuesday wednesday thursday friday saturday} + ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] end self.boundaries = [0, 7] desc "The weekday on which to run the command. Optional; if specified, @@ -285,14 +285,13 @@ Puppet::Type.newtype(:cron) do - The name of the day, such as 'Tuesday'." end - newproperty(:month, :parent => CronParam) do + newproperty(:month, parent: CronParam) do def alpha # The ___placeholder accounts for the fact that month is unique among # "nameable" crontab entries in that it does not use 0-based indexing. # Padding the array with a placeholder introduces the appropriate shift # in indices. - %w{___placeholder january february march april may june july - august september october november december} + ['___placeholder', 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'] end self.boundaries = [1, 12] desc "The month of the year. Optional; if specified, @@ -302,7 +301,7 @@ Puppet::Type.newtype(:cron) do - The name of the month, such as 'December'." end - newproperty(:monthday, :parent => CronParam) do + newproperty(:monthday, parent: CronParam) do self.boundaries = [1, 31] desc "The day of the month on which to run the command. Optional; if specified, must be between 1 and 31." @@ -325,26 +324,24 @@ Puppet::Type.newtype(:cron) do the crontab, like `PATH=/bin:/usr/bin:/usr/sbin`." validate do |value| - unless value =~ /^\s*(\w+)\s*=\s*(.*)\s*$/ or value == :absent or value == "absent" - raise ArgumentError, _("Invalid environment setting %{value}") % { value: value.inspect } + unless value =~ %r{^\s*(\w+)\s*=\s*(.*)\s*$} || value == :absent || value == 'absent' + raise ArgumentError, _('Invalid environment setting %{value}') % { value: value.inspect } end end def insync?(is) if is.is_a? Array - return is.sort == @should.sort + is.sort == @should.sort else - return is == @should + is == @should end end - def should - @should - end + attr_reader :should def should_to_s(newvalue = @should) if newvalue - newvalue.join(",") + newvalue.join(',') else nil end @@ -373,12 +370,12 @@ Puppet::Type.newtype(:cron) do The default crontab provider executes the system `crontab` using the user account specified by this property." - defaultto { - if not provider.is_a?(@resource.class.provider(:crontab)) + defaultto do + unless provider.is_a?(@resource.class.provider(:crontab)) struct = Etc.getpwuid(Process.uid) - struct.respond_to?(:name) && struct.name or 'root' + struct.respond_to?(:name) && struct.name || 'root' end - } + end end # Autorequire the owner of the crontab entry. @@ -397,20 +394,20 @@ Puppet::Type.newtype(:cron) do setting both `user` and `target` to different values will result in undefined behavior." - defaultto { + defaultto do if provider.is_a?(@resource.class.provider(:crontab)) if val = @resource.should(:user) val else struct = Etc.getpwuid(Process.uid) - struct.respond_to?(:name) && struct.name or 'root' + struct.respond_to?(:name) && struct.name || 'root' end elsif provider.class.ancestors.include?(Puppet::Provider::ParsedFile) provider.class.default_target else nil end - } + end end validate do @@ -418,10 +415,10 @@ Puppet::Type.newtype(:cron) do return true if self[:special] == :absent # there is a special schedule in @should, so we don't want to see # any numeric should values - [ :minute, :hour, :weekday, :monthday, :month ].each do |field| + [:minute, :hour, :weekday, :monthday, :month].each do |field| next unless self[field] next if self[field] == :absent - raise ArgumentError, _("%{cron} cannot specify both a special schedule and a value for %{field}") % { cron: self.ref, field: field } + raise ArgumentError, _('%{cron} cannot specify both a special schedule and a value for %{field}') % { cron: ref, field: field } end end @@ -451,7 +448,7 @@ Puppet::Type.newtype(:cron) do end def value(name) - name = name.intern + name = name.to_sym ret = nil if obj = @parameters[name] ret = obj.should @@ -469,12 +466,11 @@ Puppet::Type.newtype(:cron) do when :special # nothing else - #ret = (self.class.validproperty?(name).default || "*").to_s - ret = "*" + # ret = (self.class.validproperty?(name).default || "*").to_s + ret = '*' end end ret end end - diff --git a/spec/acceptance/tests/resource/cron/should_allow_changing_parameters.rb b/spec/acceptance/tests/resource/cron/should_allow_changing_parameters.rb index 4a14371..0e0821d 100644 --- a/spec/acceptance/tests/resource/cron/should_allow_changing_parameters.rb +++ b/spec/acceptance/tests/resource/cron/should_allow_changing_parameters.rb @@ -1,7 +1,7 @@ -test_name "Cron: should allow changing parameters after creation" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'Cron: should allow changing parameters after creation' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,63 +12,61 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end - agents.each do |agent| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup agent - step "Cron: basic - verify that it can be created" + step 'Cron: basic - verify that it can be created' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/false", user => "tstuser", hour => "*", minute => [1], ensure => present,}') do - assert_match( /ensure: created/, result.stdout, "err: #{agent}") + assert_match(%r{ensure: created}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/.bin.false/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{.bin.false}, result.stdout, "err: #{agent}") end - step "Cron: allow changing command" + step 'Cron: allow changing command' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => "*", minute => [1], ensure => present,}') do - assert_match(/command changed '.bin.false'.* to '.bin.true'/, result.stdout, "err: #{agent}") + assert_match(%r{command changed '.bin.false'.* to '.bin.true'}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/1 . . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{1 . . . . .bin.true}, result.stdout, "err: #{agent}") end - step "Cron: allow changing time" + step 'Cron: allow changing time' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => "1", minute => [1], ensure => present,}') do - assert_match(/hour: defined 'hour' as \['1'\]/, result.stdout, "err: #{agent}") + assert_match(%r{hour: defined 'hour' as \['1'\]}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/1 1 . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{1 1 . . . .bin.true}, result.stdout, "err: #{agent}") end - step "Cron: allow changing time(array)" + step 'Cron: allow changing time(array)' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => ["1","2"], minute => [1], ensure => present,}') do - assert_match(/hour: hour changed \['1'\].* to \['1', '2'\]/, result.stdout, "err: #{agent}") + assert_match(%r{hour: hour changed \['1'\].* to \['1', '2'\]}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/1 1,2 . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{1 1,2 . . . .bin.true}, result.stdout, "err: #{agent}") end - step "Cron: allow changing time(array modification)" + step 'Cron: allow changing time(array modification)' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => ["3","2"], minute => [1], ensure => present,}') do - assert_match(/hour: hour changed \['1', '2'\].* to \['3', '2'\]/, result.stdout, "err: #{agent}") + assert_match(%r{hour: hour changed \['1', '2'\].* to \['3', '2'\]}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/1 3,2 . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{1 3,2 . . . .bin.true}, result.stdout, "err: #{agent}") end - step "Cron: allow changing time(array modification to *)" + step 'Cron: allow changing time(array modification to *)' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => "*", minute => "*", ensure => present,}') do - assert_match(/minute: undefined 'minute' from \['1'\]/,result.stdout, "err: #{agent}") - assert_match(/hour: undefined 'hour' from \['3', '2'\]/,result.stdout, "err: #{agent}") + assert_match(%r{minute: undefined 'minute' from \['1'\]}, result.stdout, "err: #{agent}") + assert_match(%r{hour: undefined 'hour' from \['3', '2'\]}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/\* \* . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{\* \* . . . .bin.true}, result.stdout, "err: #{agent}") end - end diff --git a/spec/acceptance/tests/resource/cron/should_be_idempotent.rb b/spec/acceptance/tests/resource/cron/should_be_idempotent.rb index 0d302c2..9b286f7 100644 --- a/spec/acceptance/tests/resource/cron/should_be_idempotent.rb +++ b/spec/acceptance/tests/resource/cron/should_be_idempotent.rb @@ -1,7 +1,7 @@ -test_name "Cron: check idempotency" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'Cron: check idempotency' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,27 +12,26 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end - agents.each do |agent| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup agent - step "Cron: basic - verify that it can be created" + step 'Cron: basic - verify that it can be created' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => "*", minute => [1], ensure => present,}') do - assert_match( /ensure: created/, result.stdout, "err: #{agent}") + assert_match(%r{ensure: created}, result.stdout, "err: #{agent}") end - run_cron_on(agent,:list,'tstuser') do - assert_match(/. . . . . .bin.true/, result.stdout, "err: #{agent}") + run_cron_on(agent, :list, 'tstuser') do + assert_match(%r{. . . . . .bin.true}, result.stdout, "err: #{agent}") end - step "Cron: basic - should not create again" + step 'Cron: basic - should not create again' apply_manifest_on(agent, 'cron { "myjob": command => "/bin/true", user => "tstuser", hour => "*", minute => [1], ensure => present,}') do - assert_no_match( /ensure: created/, result.stdout, "err: #{agent}") + assert_no_match(%r{ensure: created}, result.stdout, "err: #{agent}") end end diff --git a/spec/acceptance/tests/resource/cron/should_create_cron.rb b/spec/acceptance/tests/resource/cron/should_create_cron.rb index 7c3b53f..29dcfc4 100644 --- a/spec/acceptance/tests/resource/cron/should_create_cron.rb +++ b/spec/acceptance/tests/resource/cron/should_create_cron.rb @@ -1,7 +1,7 @@ -test_name "should create cron" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'should create cron' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,25 +12,24 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup host - step "apply the resource on the host using puppet resource" - on(host, puppet_resource("cron", "crontest", "user=tstuser", - "command=/bin/true", "ensure=present")) do - assert_match(/created/, stdout, "Did not create crontab for tstuser on #{host}") + step 'apply the resource on the host using puppet resource' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', + 'command=/bin/true', 'ensure=present')) do + assert_match(%r{created}, stdout, "Did not create crontab for tstuser on #{host}") end - step "verify that crontab -l contains what you expected" + step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Incorrect crontab for tstuser on #{host}") end - end diff --git a/spec/acceptance/tests/resource/cron/should_match_existing.rb b/spec/acceptance/tests/resource/cron/should_match_existing.rb index a59d8ed..d309a84 100644 --- a/spec/acceptance/tests/resource/cron/should_match_existing.rb +++ b/spec/acceptance/tests/resource/cron/should_match_existing.rb @@ -1,35 +1,35 @@ -test_name "puppet should match existing job" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'puppet should match existing job' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', - 'audit:refactor', # Use block style `test_name` + 'audit:refactor', # Use block style `test_name` 'audit:unit' require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup host - step "Create the existing cron job by hand..." - run_cron_on(host,:add,'tstuser',"* * * * * /bin/true") + step 'Create the existing cron job by hand...' + run_cron_on(host, :add, 'tstuser', '* * * * * /bin/true') - step "Apply the resource on the host using puppet resource" - on(host, puppet_resource("cron", "crontest", "user=tstuser", - "command=/bin/true", "ensure=present")) do - assert_match(/present/, stdout, "Failed creating crontab for tstuser on #{host}") + step 'Apply the resource on the host using puppet resource' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', + 'command=/bin/true', 'ensure=present')) do + assert_match(%r{present}, stdout, "Failed creating crontab for tstuser on #{host}") end - step "Verify that crontab -l contains what you expected" + step 'Verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Did not find crontab for tstuser on #{host}") end diff --git a/spec/acceptance/tests/resource/cron/should_remove_cron.rb b/spec/acceptance/tests/resource/cron/should_remove_cron.rb index 1320272..1759172 100644 --- a/spec/acceptance/tests/resource/cron/should_remove_cron.rb +++ b/spec/acceptance/tests/resource/cron/should_remove_cron.rb @@ -1,7 +1,7 @@ -test_name "puppet should remove a crontab entry as expected" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'puppet should remove a crontab entry as expected' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,28 +12,27 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup host - step "create the existing job by hand..." - run_cron_on(host,:add,'tstuser',"* * * * * /bin/true") + step 'create the existing job by hand...' + run_cron_on(host, :add, 'tstuser', '* * * * * /bin/true') - step "apply the resource on the host using puppet resource" - on(host, puppet_resource("cron", "crontest", "user=tstuser", - "command=/bin/true", "ensure=absent")) do - assert_match(/crontest\D+ensure:\s+removed/, stdout, "Didn't remove crobtab entry for tstuser on #{host}") + step 'apply the resource on the host using puppet resource' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', + 'command=/bin/true', 'ensure=absent')) do + assert_match(%r{crontest\D+ensure:\s+removed}, stdout, "Didn't remove crobtab entry for tstuser on #{host}") end - step "verify that crontab -l contains what you expected" + step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do assert_no_match(/\/bin\/true/, stderr, "Error: Found entry for tstuser on #{host}") end - end diff --git a/spec/acceptance/tests/resource/cron/should_remove_leading_and_trailing_whitespace.rb b/spec/acceptance/tests/resource/cron/should_remove_leading_and_trailing_whitespace.rb index 33f7142..b643156 100644 --- a/spec/acceptance/tests/resource/cron/should_remove_leading_and_trailing_whitespace.rb +++ b/spec/acceptance/tests/resource/cron/should_remove_leading_and_trailing_whitespace.rb @@ -1,42 +1,42 @@ -test_name "(#656) leading and trailing whitespace in cron entries should should be stripped" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name '(#656) leading and trailing whitespace in cron entries should should be stripped' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', - 'audit:refactor', # Use block style `test_name` + 'audit:refactor', # Use block style `test_name` 'audit:unit' require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "create user account for testing cron entries" + step 'create user account for testing cron entries' setup host - step "apply the resource on the host using puppet resource" - on(host, puppet_resource("cron", "crontest", "user=tstuser", "command=' date > /dev/null '", "ensure=present")) do - assert_match(/created/, stdout, "Did not create crontab for tstuser on #{host}") + step 'apply the resource on the host using puppet resource' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', "command=' date > /dev/null '", 'ensure=present')) do + assert_match(%r{created}, stdout, "Did not create crontab for tstuser on #{host}") end - step "verify the added crontab entry has stripped whitespace" + step 'verify the added crontab entry has stripped whitespace' run_cron_on(host, :list, 'tstuser') do - assert_match(/\* \* \* \* \* date > .dev.null/, stdout, "Incorrect crontab for tstuser on #{host}") + assert_match(%r{\* \* \* \* \* date > .dev.null}, stdout, "Incorrect crontab for tstuser on #{host}") end - step "apply the resource with trailing whitespace and check nothing happened" - on(host, puppet_resource("cron", "crontest", "user=tstuser", "command='date > /dev/null '", "ensure=present")) do - assert_no_match(/ensure: created/, stdout, "Rewrote the line with trailing space in crontab for tstuser on #{host}") + step 'apply the resource with trailing whitespace and check nothing happened' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', "command='date > /dev/null '", 'ensure=present')) do + assert_no_match(%r{ensure: created}, stdout, "Rewrote the line with trailing space in crontab for tstuser on #{host}") end - step "apply the resource with leading whitespace and check nothing happened" - on(host, puppet_resource("cron", "crontest", "user=tstuser", "command=' date > /dev/null'", "ensure=present")) do - assert_no_match(/ensure: created/, stdout, "Rewrote the line with trailing space in crontab for tstuser on #{host}") + step 'apply the resource with leading whitespace and check nothing happened' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', "command=' date > /dev/null'", 'ensure=present')) do + assert_no_match(%r{ensure: created}, stdout, "Rewrote the line with trailing space in crontab for tstuser on #{host}") end end diff --git a/spec/acceptance/tests/resource/cron/should_remove_matching.rb b/spec/acceptance/tests/resource/cron/should_remove_matching.rb index 2857a4f..cfa3c17 100644 --- a/spec/acceptance/tests/resource/cron/should_remove_matching.rb +++ b/spec/acceptance/tests/resource/cron/should_remove_matching.rb @@ -1,7 +1,7 @@ -test_name "puppet should remove a crontab entry based on command matching" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'puppet should remove a crontab entry based on command matching' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,29 +12,28 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup host - step "create the existing job by hand..." - run_cron_on(host,:add,'tstuser',"* * * * * /bin/true") + step 'create the existing job by hand...' + run_cron_on(host, :add, 'tstuser', '* * * * * /bin/true') - step "Remove cron resource" - on(host, puppet_resource("cron", "bogus", "user=tstuser", - "command=/bin/true", "ensure=absent")) do - assert_match(/bogus\D+ensure: removed/, stdout, "Removing cron entry failed for tstuser on #{host}") + step 'Remove cron resource' + on(host, puppet_resource('cron', 'bogus', 'user=tstuser', + 'command=/bin/true', 'ensure=absent')) do + assert_match(%r{bogus\D+ensure: removed}, stdout, "Removing cron entry failed for tstuser on #{host}") end - step "verify that crontab -l contains what you expected" - run_cron_on(host,:list,'tstuser') do - count = stdout.scan("/bin/true").length + step 'verify that crontab -l contains what you expected' + run_cron_on(host, :list, 'tstuser') do + count = stdout.scan('/bin/true').length fail_test "found /bin/true the wrong number of times (#{count})" unless count == 0 end - end diff --git a/spec/acceptance/tests/resource/cron/should_update_existing.rb b/spec/acceptance/tests/resource/cron/should_update_existing.rb index a4bf177..eff634b 100644 --- a/spec/acceptance/tests/resource/cron/should_update_existing.rb +++ b/spec/acceptance/tests/resource/cron/should_update_existing.rb @@ -1,7 +1,7 @@ -test_name "puppet should update existing crontab entry" -confine :except, :platform => 'windows' -confine :except, :platform => /^eos-/ # See PUP-5500 -confine :except, :platform => /^fedora-28/ +test_name 'puppet should update existing crontab entry' +confine :except, platform: 'windows' +confine :except, platform: %r{^eos-} # See PUP-5500 +confine :except, platform: %r{^fedora-28} tag 'audit:medium', 'audit:refactor', # Use block style `test_name` 'audit:acceptance' # Could be done at the integration (or unit) layer though @@ -12,31 +12,31 @@ require 'puppet/acceptance/common_utils' extend Puppet::Acceptance::CronUtils teardown do - step "Cron: cleanup" + step 'Cron: cleanup' agents.each do |agent| clean agent end end agents.each do |host| - step "ensure the user exist via puppet" + step 'ensure the user exist via puppet' setup host - step "create the existing job by hand..." - run_cron_on(host,:add,'tstuser',"* * * * * /bin/true") + step 'create the existing job by hand...' + run_cron_on(host, :add, 'tstuser', '* * * * * /bin/true') - step "verify that crontab -l contains what you expected" - run_cron_on(host,:list,'tstuser') do + step 'verify that crontab -l contains what you expected' + run_cron_on(host, :list, 'tstuser') do assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Didn't find correct crobtab entry for tstuser on #{host}") end - step "apply the resource change on the host" - on(host, puppet_resource("cron", "crontest", "user=tstuser", "command=/bin/true", "ensure=present", "hour='0-6'")) do - assert_match(/hour\s+=>\s+\['0-6'\]/, stdout, "Modifying cron entry failed for tstuser on #{host}") + step 'apply the resource change on the host' + on(host, puppet_resource('cron', 'crontest', 'user=tstuser', 'command=/bin/true', 'ensure=present', "hour='0-6'")) do + assert_match(%r{hour\s+=>\s+\['0-6'\]}, stdout, "Modifying cron entry failed for tstuser on #{host}") end - step "verify that crontab -l contains what you expected" - run_cron_on(host,:list,'tstuser') do + step 'verify that crontab -l contains what you expected' + run_cron_on(host, :list, 'tstuser') do assert_match(/\* 0-6 \* \* \* \/bin\/true/, stdout, "Didn't find correctly modified time entry in crobtab entry for tstuser on #{host}") end end diff --git a/spec/integration/provider/cron/crontab_spec.rb b/spec/integration/provider/cron/crontab_spec.rb index 192674f..a4b57a2 100644 --- a/spec/integration/provider/cron/crontab_spec.rb +++ b/spec/integration/provider/cron/crontab_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' require 'puppet/file_bucket/dipper' require 'puppet_spec/compiler' -describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless => Puppet.features.microsoft_windows? do +describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', unless: Puppet.features.microsoft_windows? do include PuppetSpec::Files include PuppetSpec::Compiler @@ -40,9 +40,8 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect(File.read(crontab_user1)).to eq(File.read(my_fixture(fixture_name))) end - describe "when managing a cron entry" do - - it "should be able to purge unmanaged entries" do + describe 'when managing a cron entry' do + it 'is able to purge unmanaged entries' do apply_with_error_check(<<-MANIFEST) cron { 'only managed entry': @@ -55,8 +54,8 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('purged') end - describe "with ensure absent" do - it "should do nothing if entry already absent" do + describe 'with ensure absent' do + it 'does nothing if entry already absent' do apply_with_error_check(<<-MANIFEST) cron { 'no_such_entry': @@ -67,7 +66,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('crontab_user1') end - it "should remove the resource from crontab if present" do + it 'removes the resource from crontab if present' do apply_with_error_check(<<-MANIFEST) cron { 'My daily failure': @@ -78,7 +77,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('remove_named_resource') end - it "should remove a matching cronentry if present" do + it 'removes a matching cronentry if present' do apply_with_error_check(<<-MANIFEST) cron { 'no_such_named_resource_in_crontab': @@ -94,10 +93,9 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = end end - describe "with ensure present" do - - context "and no command specified" do - it "should work if the resource is already present" do + describe 'with ensure present' do + context 'and no command specified' do + it 'works if the resource is already present' do apply_with_error_check(<<-MANIFEST) cron { 'My daily failure': @@ -107,7 +105,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = MANIFEST expect_output('crontab_user1') end - it "should fail if the resource needs creating" do + it 'fails if the resource needs creating' do manifest = <<-MANIFEST cron { 'Entirely new resource': @@ -117,7 +115,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = MANIFEST apply_compiled_manifest(manifest) do |res| if res.ref == 'Cron[Entirely new resource]' - res.expects(:err).with(regexp_matches(/no command/)) + res.expects(:err).with(regexp_matches(%r{no command})) else res.expects(:err).never end @@ -125,7 +123,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = end end - it "should do nothing if entry already present" do + it 'does nothing if entry already present' do apply_with_error_check(<<-MANIFEST) cron { 'My daily failure': @@ -137,7 +135,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('crontab_user1') end - it "should work correctly when managing 'target' but not 'user'" do + it "works correctly when managing 'target' but not 'user'" do apply_with_error_check(<<-MANIFEST) cron { 'My daily failure': @@ -149,7 +147,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('crontab_user1') end - it "should do nothing if a matching entry already present" do + it 'does nothing if a matching entry already present' do apply_with_error_check(<<-MANIFEST) cron { 'no_such_named_resource_in_crontab': @@ -163,7 +161,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('crontab_user1') end - it "should add a new normal entry if currently absent" do + it 'adds a new normal entry if currently absent' do apply_with_error_check(<<-MANIFEST) cron { 'new entry': @@ -181,7 +179,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('create_normal_entry') end - it "should add a new special entry if currently absent" do + it 'adds a new special entry if currently absent' do apply_with_error_check(<<-MANIFEST) cron { 'new special entry': @@ -195,7 +193,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = expect_output('create_special_entry') end - it "should change existing entry if out of sync" do + it 'changes existing entry if out of sync' do apply_with_error_check(<<-MANIFEST) cron { 'Monthly job': @@ -209,7 +207,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = MANIFEST expect_output('modify_entry') end - it "should change a special schedule to numeric if requested" do + it 'changes a special schedule to numeric if requested' do apply_with_error_check(<<-MANIFEST) cron { 'My daily failure': @@ -220,7 +218,7 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = MANIFEST expect_output('unspecialized') end - it "should not try to move an entry from one file to another" do + it 'does not try to move an entry from one file to another' do # force the parsedfile provider to also parse user1's crontab apply_with_error_check(<<-MANIFEST) cron { @@ -238,5 +236,4 @@ describe Puppet::Type.type(:cron).provider(:crontab), '(integration)', :unless = end end end - end diff --git a/spec/lib/puppet_spec/compiler.rb b/spec/lib/puppet_spec/compiler.rb index 8964a26..c3d33a5 100644 --- a/spec/lib/puppet_spec/compiler.rb +++ b/spec/lib/puppet_spec/compiler.rb @@ -34,8 +34,8 @@ module PuppetSpec::Compiler catalog.resources.each { |res| yield res } end transaction = Puppet::Transaction.new(catalog, - Puppet::Transaction::Report.new, - prioritizer) + Puppet::Transaction::Report.new, + prioritizer) transaction.evaluate transaction.report.finalize_report @@ -70,7 +70,7 @@ module PuppetSpec::Compiler collect_notices(code, node) do |compiler| unless topscope_vars.empty? scope = compiler.topscope - topscope_vars.each {|k,v| scope.setvar(k, v) } + topscope_vars.each { |k, v| scope.setvar(k, v) } end if block_given? compiler.compile do |catalog| @@ -95,7 +95,7 @@ module PuppetSpec::Compiler compiler = Puppet::Parser::Compiler.new(node) unless variables.empty? scope = compiler.topscope - variables.each {|k,v| scope.setvar(k, v) } + variables.each { |k, v| scope.setvar(k, v) } end if source.nil? @@ -105,7 +105,7 @@ module PuppetSpec::Compiler end # evaluate given source is the context of the compiled state and return its result - compiler.compile do |catalog | + compiler.compile do |_catalog| Puppet::Pops::Parser::EvaluatingParser.singleton.evaluate_string(compiler.topscope, source, source_location) end end diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index b34daed..ebbe1a9 100644 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -7,10 +7,10 @@ require 'pathname' module PuppetSpec::Files def self.cleanup $global_tempfiles ||= [] - while path = $global_tempfiles.pop do + while path = $global_tempfiles.pop begin Dir.unstub(:entries) - FileUtils.rm_rf path, :secure => true + FileUtils.rm_rf path, secure: true rescue Errno::ENOENT # nothing to do end @@ -48,7 +48,7 @@ module PuppetSpec::Files text = contents[:posix] end File.open(file, 'wb') { |f| f.write(text) } - Puppet::FileSystem.chmod(0755, file) + Puppet::FileSystem.chmod(0o755, file) file end @@ -62,12 +62,12 @@ module PuppetSpec::Files # Copied from ruby 2.4 source def make_tmpname((prefix, suffix), n) - prefix = (String.try_convert(prefix) or - raise ArgumentError, "unexpected prefix: #{prefix.inspect}") - suffix &&= (String.try_convert(suffix) or - raise ArgumentError, "unexpected suffix: #{suffix.inspect}") - t = Time.now.strftime("%Y%m%d") - path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}".dup + prefix = (String.try_convert(prefix) || + raise(ArgumentError, "unexpected prefix: #{prefix.inspect}")) + suffix &&= (String.try_convert(suffix) || + raise(ArgumentError, "unexpected suffix: #{suffix.inspect}")) + t = Time.now.strftime('%Y%m%d') + path = "#{prefix}#{t}-#{$PROCESS_ID}-#{rand(0x100000000).to_s(36)}".dup path << "-#{n}" if n path << suffix if suffix path @@ -78,13 +78,13 @@ module PuppetSpec::Files end def dir_contained_in(dir, contents_hash) - contents_hash.each do |k,v| + contents_hash.each do |k, v| if v.is_a?(Hash) - Dir.mkdir(tmp = File.join(dir,k)) + Dir.mkdir(tmp = File.join(dir, k)) dir_contained_in(tmp, v) else file = File.join(dir, k) - File.open(file, 'wb') {|f| f.write(v) } + File.open(file, 'wb') { |f| f.write(v) } end end dir @@ -97,11 +97,11 @@ module PuppetSpec::Files end def expect_file_mode(file, mode) - actual_mode = "%o" % Puppet::FileSystem.stat(file).mode + actual_mode = '%o' % Puppet::FileSystem.stat(file).mode target_mode = if Puppet.features.microsoft_windows? - mode - else - "10" + "%04i" % mode.to_i + mode + else + '10' + '%04i' % mode.to_i end expect(actual_mode).to eq(target_mode) end diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb index 8757be6..f06b4bb 100644 --- a/spec/spec_helper_local.rb +++ b/spec/spec_helper_local.rb @@ -14,4 +14,4 @@ RSpec.configure do |config| FileUtils.mkdir_p Puppet[:statedir] end -end \ No newline at end of file +end diff --git a/spec/unit/provider/cron/crontab_spec.rb b/spec/unit/provider/cron/crontab_spec.rb index 98ae589..92924ae 100644 --- a/spec/unit/provider/cron/crontab_spec.rb +++ b/spec/unit/provider/cron/crontab_spec.rb @@ -10,17 +10,17 @@ describe Puppet::Type.type(:cron).provider(:crontab) do def compare_crontab_text(have, want) # We should have four header lines, and then the text... - expect(have.lines.to_a[0..3]).to be_all {|x| x =~ /^# / } + expect(have.lines.to_a[0..3]).to be_all { |x| x =~ %r{^# } } expect(have.lines.to_a[4..-1].join('')).to eq(want) end - context "with the simple samples" do + context 'with the simple samples' do FIELDS = { - :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern }, - :environment => [:line], - :blank => [:line], - :comment => [:line], - } + crontab: ['command', 'minute', 'hour', 'month', 'monthday', 'weekday'].map { |o| o.to_sym }, + environment: [:line], + blank: [:line], + comment: [:line], + }.freeze def compare_crontab_record(have, want) want.each do |param, value| @@ -48,52 +48,51 @@ describe Puppet::Type.type(:cron).provider(:crontab) do end records = [] - text = "" + text = '' # Sorting is from the original, and avoids :empty being the last line, # since the provider will ignore that and cause this to fail. - samples.sort_by {|x| x.first.to_s }.each do |name, data| + samples.sort_by { |x| x.first.to_s }.each do |_name, data| records << data[:record] text << data[:text] + "\n" end - it "should parse all sample records at once" do + it 'parses all sample records at once' do subject.parse(text).zip(records).each do |round| compare_crontab_record(*round) end end - it "should reconstitute the file from the records" do + it 'reconstitutes the file from the records' do compare_crontab_text subject.to_file(records), text end - context "multi-line crontabs" do - tests = { :simple => [:spaces_in_command_with_times], - :with_name => [:name, :spaces_in_command_with_times], - :with_env => [:environment, :spaces_in_command_with_times], - :with_multiple_envs => [:environment, :lowercase_environment, :spaces_in_command_with_times], - :with_name_and_env => [:name_with_spaces, :another_env, :spaces_in_command_with_times], - :with_name_and_multiple_envs => [:long_name, :another_env, :fourth_env, :spaces_in_command_with_times] - } + context 'multi-line crontabs' do + tests = { simple: [:spaces_in_command_with_times], + with_name: [:name, :spaces_in_command_with_times], + with_env: [:environment, :spaces_in_command_with_times], + with_multiple_envs: [:environment, :lowercase_environment, :spaces_in_command_with_times], + with_name_and_env: [:name_with_spaces, :another_env, :spaces_in_command_with_times], + with_name_and_multiple_envs: [:long_name, :another_env, :fourth_env, :spaces_in_command_with_times] } all_records = [] all_text = '' tests.each do |name, content| - data = content.map {|x| samples[x] or raise "missing sample data #{x}" } - text = data.map {|x| x[:text] }.join("\n") + "\n" - records = data.map {|x| x[:record] } + data = content.map { |x| samples[x] || raise("missing sample data #{x}") } + text = data.map { |x| x[:text] }.join("\n") + "\n" + records = data.map { |x| x[:record] } # Capture the whole thing for later, too... all_records += records all_text += text - context name.to_s.gsub('_', ' ') do - it "should regenerate the text from the record" do + context name.to_s.tr('_', ' ') do + it 'regenerates the text from the record' do compare_crontab_text subject.to_file(records), text end - it "should parse the records from the text" do + it 'parses the records from the text' do subject.parse(text).zip(records).each do |round| compare_crontab_record(*round) end @@ -101,30 +100,30 @@ describe Puppet::Type.type(:cron).provider(:crontab) do end end - it "should parse the whole set of records from the text" do + it 'parses the whole set of records from the text' do subject.parse(all_text).zip(all_records).each do |round| compare_crontab_record(*round) end end - it "should regenerate the whole text from the set of all records" do + it 'regenerates the whole text from the set of all records' do compare_crontab_text subject.to_file(all_records), all_text end end end - context "when receiving a vixie cron header from the cron interface" do - it "should not write that header back to disk" do + context 'when receiving a vixie cron header from the cron interface' do + it 'does not write that header back to disk' do vixie_header = File.read(my_fixture('vixie_header.txt')) vixie_records = subject.parse(vixie_header) - compare_crontab_text subject.to_file(vixie_records), "" + compare_crontab_text subject.to_file(vixie_records), '' end end - context "when adding a cronjob with the same command as an existing job" do - let(:record) { {:name => "existing", :user => "root", :command => "/bin/true", :record_type => :crontab} } - let(:resource) { Puppet::Type::Cron.new(:name => "test", :user => "root", :command => "/bin/true") } - let(:resources) { { "test" => resource } } + context 'when adding a cronjob with the same command as an existing job' do + let(:record) { { name: 'existing', user: 'root', command: '/bin/true', record_type: :crontab } } + let(:resource) { Puppet::Type::Cron.new(name: 'test', user: 'root', command: '/bin/true') } + let(:resources) { { 'test' => resource } } before :each do subject.stubs(:prefetch_all_targets).returns([record]) @@ -142,64 +141,64 @@ describe Puppet::Type.type(:cron).provider(:crontab) do # subject.to_file(subject.records).should match /Puppet name: test/ # end - it "should not base the new resource's provider on the existing record" do + it "does not base the new resource's provider on the existing record" do subject.expects(:new).with(record).never subject.stubs(:new) subject.prefetch(resources) end end - context "when prefetching an entry now managed for another user" do + context 'when prefetching an entry now managed for another user' do let(:resource) do - s = stub(:resource) - s.stubs(:[]).with(:user).returns 'root' - s.stubs(:[]).with(:target).returns 'root' - s + s = stub(:resource) + s.stubs(:[]).with(:user).returns 'root' + s.stubs(:[]).with(:target).returns 'root' + s end - let(:record) { {:name => "test", :user => "nobody", :command => "/bin/true", :record_type => :crontab} } - let(:resources) { { "test" => resource } } + let(:record) { { name: 'test', user: 'nobody', command: '/bin/true', record_type: :crontab } } + let(:resources) { { 'test' => resource } } before :each do subject.stubs(:prefetch_all_targets).returns([record]) end - it "should try and use the match method to find a more fitting record" do + it 'tries and use the match method to find a more fitting record' do subject.expects(:match).with(record, resources) subject.prefetch(resources) end - it "should not match a provider to the resource" do + it 'does not match a provider to the resource' do resource.expects(:provider=).never subject.prefetch(resources) end - it "should not find the resource when looking up the on-disk record" do + it 'does not find the resource when looking up the on-disk record' do subject.prefetch(resources) expect(subject.resource_for_record(record, resources)).to be_nil end end - context "when matching resources to existing crontab entries" do - let(:first_resource) { Puppet::Type::Cron.new(:name => :one, :user => 'root', :command => '/bin/true') } - let(:second_resource) { Puppet::Type::Cron.new(:name => :two, :user => 'nobody', :command => '/bin/false') } + context 'when matching resources to existing crontab entries' do + let(:first_resource) { Puppet::Type::Cron.new(name: :one, user: 'root', command: '/bin/true') } + let(:second_resource) { Puppet::Type::Cron.new(name: :two, user: 'nobody', command: '/bin/false') } - let(:resources) {{:one => first_resource, :two => second_resource}} + let(:resources) { { one: first_resource, two: second_resource } } - describe "with a record with a matching name and mismatching user (#2251)" do + describe 'with a record with a matching name and mismatching user (#2251)' do # Puppet::Resource objects have #should defined on them, so in these # examples we have to use the monkey patched `must` alias for the rspec # `should` method. it "doesn't match the record to the resource" do - record = {:name => :one, :user => 'notroot', :record_type => :crontab} + record = { name: :one, user: 'notroot', record_type: :crontab } expect(subject.resource_for_record(record, resources)).to be_nil end end - describe "with a record with a matching name and matching user" do - it "matches the record to the resource" do - record = {:name => :two, :target => 'nobody', :command => '/bin/false'} + describe 'with a record with a matching name and matching user' do + it 'matches the record to the resource' do + record = { name: :two, target: 'nobody', command: '/bin/false' } expect(subject.resource_for_record(record, resources)).to eq(second_resource) end end diff --git a/spec/unit/provider/cron/parsed_spec.rb b/spec/unit/provider/cron/parsed_spec.rb index 6cec867..6d5b752 100644 --- a/spec/unit/provider/cron/parsed_spec.rb +++ b/spec/unit/provider/cron/parsed_spec.rb @@ -3,79 +3,78 @@ require 'spec_helper' describe Puppet::Type.type(:cron).provider(:crontab) do - let :provider do - described_class.new(:command => '/bin/true') + described_class.new(command: '/bin/true') end let :resource do Puppet::Type.type(:cron).new( - :minute => %w{0 15 30 45}, - :hour => %w{8-18 20-22}, - :monthday => %w{31}, - :month => %w{12}, - :weekday => %w{7}, - :name => 'basic', - :command => '/bin/true', - :target => 'root', - :provider => provider + minute: ['0', '15', '30', '45'], + hour: ['8-18', '20-22'], + monthday: ['31'], + month: ['12'], + weekday: ['7'], + name: 'basic', + command: '/bin/true', + target: 'root', + provider: provider, ) end let :resource_special do Puppet::Type.type(:cron).new( - :special => 'reboot', - :name => 'special', - :command => '/bin/true', - :target => 'nobody' + special: 'reboot', + name: 'special', + command: '/bin/true', + target: 'nobody', ) end let :resource_sparse do Puppet::Type.type(:cron).new( - :minute => %w{42}, - :target => 'root', - :name => 'sparse' + minute: ['42'], + target: 'root', + name: 'sparse', ) end let :record_special do { - :record_type => :crontab, - :special => 'reboot', - :command => '/bin/true', - :on_disk => true, - :target => 'nobody' + record_type: :crontab, + special: 'reboot', + command: '/bin/true', + on_disk: true, + target: 'nobody', } end let :record do { - :record_type => :crontab, - :minute => %w{0 15 30 45}, - :hour => %w{8-18 20-22}, - :monthday => %w{31}, - :month => %w{12}, - :weekday => %w{7}, - :special => :absent, - :command => '/bin/true', - :on_disk => true, - :target => 'root' + record_type: :crontab, + minute: ['0', '15', '30', '45'], + hour: ['8-18', '20-22'], + monthday: ['31'], + month: ['12'], + weekday: ['7'], + special: :absent, + command: '/bin/true', + on_disk: true, + target: 'root', } end - describe "when determining the correct filetype" do - it "should use the suntab filetype on Solaris" do + describe 'when determining the correct filetype' do + it 'uses the suntab filetype on Solaris' do Facter.stubs(:value).with(:osfamily).returns 'Solaris' expect(described_class.filetype).to eq(Puppet::Util::FileType::FileTypeSuntab) end - it "should use the aixtab filetype on AIX" do + it 'uses the aixtab filetype on AIX' do Facter.stubs(:value).with(:osfamily).returns 'AIX' expect(described_class.filetype).to eq(Puppet::Util::FileType::FileTypeAixtab) end - it "should use the crontab filetype on other platforms" do + it 'uses the crontab filetype on other platforms' do Facter.stubs(:value).with(:osfamily).returns 'Not a real operating system family' expect(described_class.filetype).to eq(Puppet::Util::FileType::FileTypeCrontab) end @@ -83,155 +82,144 @@ describe Puppet::Type.type(:cron).provider(:crontab) do # I'd use ENV.expects(:[]).with('USER') but this does not work because # ENV["USER"] is evaluated at load time. - describe "when determining the default target" do - it "should use the current user #{ENV['USER']}", :if => ENV['USER'] do + describe 'when determining the default target' do + it "should use the current user #{ENV['USER']}", if: ENV['USER'] do expect(described_class.default_target).to eq(ENV['USER']) end - it "should fallback to root", :unless => ENV['USER'] do - expect(described_class.default_target).to eq("root") + it 'fallbacks to root', unless: ENV['USER'] do + expect(described_class.default_target).to eq('root') end end - describe ".targets" do - let(:tabs) { [ described_class.default_target ] + %w{foo bar} } - before do + describe '.targets' do + let(:tabs) { [described_class.default_target] + ['foo', 'bar'] } + + before(:each) do File.expects(:readable?).returns true File.stubs(:file?).returns true File.stubs(:writable?).returns true end - after do + after(:each) do File.unstub :readable?, :file?, :writable? Dir.unstub :foreach end - it "should add all crontabs as targets" do + it 'adds all crontabs as targets' do Dir.expects(:foreach).multiple_yields(*tabs) expect(described_class.targets).to eq(tabs) end end - describe "when parsing a record" do - it "should parse a comment" do - expect(described_class.parse_line("# This is a test")).to eq({ - :record_type => :comment, - :line => "# This is a test", - }) + describe 'when parsing a record' do + it 'parses a comment' do + expect(described_class.parse_line('# This is a test')).to eq(record_type: :comment, + line: '# This is a test') end - it "should get the resource name of a PUPPET NAME comment" do - expect(described_class.parse_line('# Puppet Name: My Fancy Cronjob')).to eq({ - :record_type => :comment, - :name => 'My Fancy Cronjob', - :line => '# Puppet Name: My Fancy Cronjob', - }) + it 'gets the resource name of a PUPPET NAME comment' do + expect(described_class.parse_line('# Puppet Name: My Fancy Cronjob')).to eq(record_type: :comment, + name: 'My Fancy Cronjob', + line: '# Puppet Name: My Fancy Cronjob') end - it "should ignore blank lines" do - expect(described_class.parse_line('')).to eq({:record_type => :blank, :line => ''}) - expect(described_class.parse_line(' ')).to eq({:record_type => :blank, :line => ' '}) - expect(described_class.parse_line("\t")).to eq({:record_type => :blank, :line => "\t"}) - expect(described_class.parse_line(" \t ")).to eq({:record_type => :blank, :line => " \t "}) + it 'ignores blank lines' do + expect(described_class.parse_line('')).to eq(record_type: :blank, line: '') + expect(described_class.parse_line(' ')).to eq(record_type: :blank, line: ' ') + expect(described_class.parse_line("\t")).to eq(record_type: :blank, line: "\t") + expect(described_class.parse_line(" \t ")).to eq(record_type: :blank, line: " \t ") end - it "should extract environment assignments" do + it 'extracts environment assignments' do # man 5 crontab: MAILTO="" with no value can be used to surpress sending # mails at all - expect(described_class.parse_line('MAILTO=""')).to eq({:record_type => :environment, :line => 'MAILTO=""'}) - expect(described_class.parse_line('FOO=BAR')).to eq({:record_type => :environment, :line => 'FOO=BAR'}) - expect(described_class.parse_line('FOO_BAR=BAR')).to eq({:record_type => :environment, :line => 'FOO_BAR=BAR'}) - expect(described_class.parse_line('SPACE = BAR')).to eq({:record_type => :environment, :line => 'SPACE = BAR'}) + expect(described_class.parse_line('MAILTO=""')).to eq(record_type: :environment, line: 'MAILTO=""') + expect(described_class.parse_line('FOO=BAR')).to eq(record_type: :environment, line: 'FOO=BAR') + expect(described_class.parse_line('FOO_BAR=BAR')).to eq(record_type: :environment, line: 'FOO_BAR=BAR') + expect(described_class.parse_line('SPACE = BAR')).to eq(record_type: :environment, line: 'SPACE = BAR') end - it "should extract a cron entry" do - expect(described_class.parse_line('* * * * * /bin/true')).to eq({ - :record_type => :crontab, - :hour => :absent, - :minute => :absent, - :month => :absent, - :weekday => :absent, - :monthday => :absent, - :special => :absent, - :command => '/bin/true' - }) - expect(described_class.parse_line('0,15,30,45 8-18,20-22 31 12 7 /bin/true')).to eq({ - :record_type => :crontab, - :minute => %w{0 15 30 45}, - :hour => %w{8-18 20-22}, - :monthday => %w{31}, - :month => %w{12}, - :weekday => %w{7}, - :special => :absent, - :command => '/bin/true' - }) + it 'extracts a cron entry' do + expect(described_class.parse_line('* * * * * /bin/true')).to eq(record_type: :crontab, + hour: :absent, + minute: :absent, + month: :absent, + weekday: :absent, + monthday: :absent, + special: :absent, + command: '/bin/true') + expect(described_class.parse_line('0,15,30,45 8-18,20-22 31 12 7 /bin/true')).to eq(record_type: :crontab, + minute: ['0', '15', '30', '45'], + hour: ['8-18', '20-22'], + monthday: ['31'], + month: ['12'], + weekday: ['7'], + special: :absent, + command: '/bin/true') # A percent sign will cause the rest of the string to be passed as # standard input and will also act as a newline character. Not sure # if puppet should convert % to a \n as the command property so the # test covers the current behaviour: Do not do any conversions - expect(described_class.parse_line('0 22 * * 1-5 mail -s "It\'s 10pm" joe%Joe,%%Where are your kids?%')).to eq({ - :record_type => :crontab, - :minute => %w{0}, - :hour => %w{22}, - :monthday => :absent, - :month => :absent, - :weekday => %w{1-5}, - :special => :absent, - :command => 'mail -s "It\'s 10pm" joe%Joe,%%Where are your kids?%' - }) + expect(described_class.parse_line('0 22 * * 1-5 mail -s "It\'s 10pm" joe%Joe,%%Where are your kids?%')).to eq(record_type: :crontab, + minute: ['0'], + hour: ['22'], + monthday: :absent, + month: :absent, + weekday: ['1-5'], + special: :absent, + command: 'mail -s "It\'s 10pm" joe%Joe,%%Where are your kids?%') end - describe "it should support special strings" do - ['reboot','yearly','anually','monthly', 'weekly', 'daily', 'midnight', 'hourly'].each do |special| + describe 'it should support special strings' do + ['reboot', 'yearly', 'anually', 'monthly', 'weekly', 'daily', 'midnight', 'hourly'].each do |special| it "should support @#{special}" do - expect(described_class.parse_line("@#{special} /bin/true")).to eq({ - :record_type => :crontab, - :hour => :absent, - :minute => :absent, - :month => :absent, - :weekday => :absent, - :monthday => :absent, - :special => special, - :command => '/bin/true' - }) + expect(described_class.parse_line("@#{special} /bin/true")).to eq(record_type: :crontab, + hour: :absent, + minute: :absent, + month: :absent, + weekday: :absent, + monthday: :absent, + special: special, + command: '/bin/true') end end end end - describe ".instances" do + describe '.instances' do before :each do described_class.stubs(:default_target).returns 'foobar' end - describe "on linux" do - before do + describe 'on linux' do + before(:each) do Facter.stubs(:value).with(:osfamily).returns 'Linux' Facter.stubs(:value).with(:operatingsystem) end - it "should contain no resources for a user who has no crontab" do + it 'contains no resources for a user who has no crontab' do # `crontab...` does only capture stdout here. On vixie-cron-4.1 # STDERR shows "no crontab for foobar" but stderr is ignored as # well as the exitcode. - described_class.target_object('foobar').expects(:`).with('crontab -u foobar -l 2>/dev/null').returns "" - expect(described_class.instances.select { |resource| + described_class.target_object('foobar').expects(:`).with('crontab -u foobar -l 2>/dev/null').returns '' + expect(described_class.instances.select do |resource| resource.get('target') == 'foobar' - }).to be_empty + end).to be_empty end - it "should contain no resources for a user who is absent" do + it 'contains no resources for a user who is absent' do # `crontab...` does only capture stdout. On vixie-cron-4.1 # STDERR shows "crontab: user `foobar' unknown" but stderr is # ignored as well as the exitcode - described_class.target_object('foobar').expects(:`).with('crontab -u foobar -l 2>/dev/null').returns "" - expect(described_class.instances.select { |resource| + described_class.target_object('foobar').expects(:`).with('crontab -u foobar -l 2>/dev/null').returns '' + expect(described_class.instances.select do |resource| resource.get('target') == 'foobar' - }).to be_empty + end).to be_empty end - it "should be able to create records from not-managed records" do + it 'is able to create records from not-managed records' do described_class.stubs(:target_object).returns File.new(my_fixture('simple')) parameters = described_class.instances.map do |p| - h = {:name => p.get(:name)} + h = { name: p.get(:name) } Puppet::Type.type(:cron).validproperties.each do |property| h[property] = p.get(property) end @@ -264,95 +252,94 @@ describe Puppet::Type.type(:cron).provider(:crontab) do expect(parameters[1][:target]).to eq('foobar') end - it "should be able to parse puppet managed cronjobs" do + it 'is able to parse puppet managed cronjobs' do described_class.stubs(:target_object).returns File.new(my_fixture('managed')) expect(described_class.instances.map do |p| - h = {:name => p.get(:name)} + h = { name: p.get(:name) } Puppet::Type.type(:cron).validproperties.each do |property| h[property] = p.get(property) end h end).to eq([ - { - :name => 'real_job', - :minute => :absent, - :hour => :absent, - :weekday => :absent, - :month => :absent, - :monthday => :absent, - :special => :absent, - :command => '/bin/true', - :ensure => :present, - :environment => :absent, - :user => :absent, - :target => 'foobar' - }, - { - :name => 'complex_job', - :minute => :absent, - :hour => :absent, - :weekday => :absent, - :month => :absent, - :monthday => :absent, - :special => 'reboot', - :command => '/bin/true >> /dev/null 2>&1', - :ensure => :present, - :environment => [ - 'MAILTO=foo@example.com', - 'SHELL=/bin/sh' - ], - :user => :absent, - :target => 'foobar' - } - ]) + { + name: 'real_job', + minute: :absent, + hour: :absent, + weekday: :absent, + month: :absent, + monthday: :absent, + special: :absent, + command: '/bin/true', + ensure: :present, + environment: :absent, + user: :absent, + target: 'foobar', + }, + { + name: 'complex_job', + minute: :absent, + hour: :absent, + weekday: :absent, + month: :absent, + monthday: :absent, + special: 'reboot', + command: '/bin/true >> /dev/null 2>&1', + ensure: :present, + environment: [ + 'MAILTO=foo@example.com', + 'SHELL=/bin/sh', + ], + user: :absent, + target: 'foobar', + }, + ]) end end end - describe ".match" do - describe "normal records" do - it "should match when all fields are the same" do - expect(described_class.match(record,{resource[:name] => resource})).to eq(resource) + describe '.match' do + describe 'normal records' do + it 'matches when all fields are the same' do + expect(described_class.match(record, resource[:name] => resource)).to eq(resource) end { - :minute => %w{0 15 31 45}, - :hour => %w{8-18}, - :monthday => %w{30 31}, - :month => %w{12 23}, - :weekday => %w{4}, - :command => '/bin/false', - :target => 'nobody' + minute: ['0', '15', '31', '45'], + hour: ['8-18'], + monthday: ['30', '31'], + month: ['12', '23'], + weekday: ['4'], + command: '/bin/false', + target: 'nobody', }.each_pair do |field, new_value| it "should not match a record when #{field} does not match" do record[field] = new_value - expect(described_class.match(record,{resource[:name] => resource})).to be_falsey + expect(described_class.match(record, resource[:name] => resource)).to be_falsey end end end - describe "special records" do - it "should match when all fields are the same" do - expect(described_class.match(record_special,{resource_special[:name] => resource_special})).to eq(resource_special) + describe 'special records' do + it 'matches when all fields are the same' do + expect(described_class.match(record_special, resource_special[:name] => resource_special)).to eq(resource_special) end { - :special => 'monthly', - :command => '/bin/false', - :target => 'root' + special: 'monthly', + command: '/bin/false', + target: 'root', }.each_pair do |field, new_value| it "should not match a record when #{field} does not match" do record_special[field] = new_value - expect(described_class.match(record_special,{resource_special[:name] => resource_special})).to be_falsey + expect(described_class.match(record_special, resource_special[:name] => resource_special)).to be_falsey end end end - describe "with a resource without a command" do - it "should not raise an error" do - expect { described_class.match(record,{resource_sparse[:name] => resource_sparse}) }.to_not raise_error + describe 'with a resource without a command' do + it 'does not raise an error' do + expect { described_class.match(record, resource_sparse[:name] => resource_sparse) }.not_to raise_error end end - end end diff --git a/spec/unit/type/cron_spec.rb b/spec/unit/type/cron_spec.rb index 4241e51..80970d0 100644 --- a/spec/unit/type/cron_spec.rb +++ b/spec/unit/type/cron_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Puppet::Type.type(:cron), :unless => Puppet.features.microsoft_windows? do +describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do let(:simple_provider) do @provider_class = described_class.provide(:simple) { mk_resource_methods } @provider_class.stubs(:suitable?).returns true @@ -17,11 +17,11 @@ describe Puppet::Type.type(:cron), :unless => Puppet.features.microsoft_windows? described_class.unprovide(:simple) end - it "should have :name be its namevar" do + it 'has :name be its namevar' do expect(described_class.key_attributes).to eq([:name]) end - describe "when validating attributes" do + describe 'when validating attributes' do [:name, :provider].each do |param| it "should have a #{param} parameter" do expect(described_class.attrtype(param)).to eq(:param) @@ -41,487 +41,481 @@ describe Puppet::Type.type(:cron), :unless => Puppet.features.microsoft_windows? end end - - describe "when validating values" do - - describe "ensure" do - it "should support present as a value for ensure" do - expect { described_class.new(:name => 'foo', :ensure => :present) }.to_not raise_error + describe 'when validating values' do + describe 'ensure' do + it 'supports present as a value for ensure' do + expect { described_class.new(name: 'foo', ensure: :present) }.not_to raise_error end - it "should support absent as a value for ensure" do - expect { described_class.new(:name => 'foo', :ensure => :present) }.to_not raise_error + it 'supports absent as a value for ensure' do + expect { described_class.new(name: 'foo', ensure: :present) }.not_to raise_error end - it "should not support other values" do - expect { described_class.new(:name => 'foo', :ensure => :foo) }.to raise_error(Puppet::Error, /Invalid value/) + it 'does not support other values' do + expect { described_class.new(name: 'foo', ensure: :foo) }.to raise_error(Puppet::Error, %r{Invalid value}) end end - describe "command" do - it "should discard leading spaces" do - expect(described_class.new(:name => 'foo', :command => " /bin/true")[:command]).not_to match Regexp.new(" ") + describe 'command' do + it 'discards leading spaces' do + expect(described_class.new(name: 'foo', command: ' /bin/true')[:command]).not_to match Regexp.new(' ') end - it "should discard trailing spaces" do - expect(described_class.new(:name => 'foo', :command => "/bin/true ")[:command]).not_to match Regexp.new(" ") + it 'discards trailing spaces' do + expect(described_class.new(name: 'foo', command: '/bin/true ')[:command]).not_to match Regexp.new(' ') end end - describe "minute" do - it "should support absent" do - expect { described_class.new(:name => 'foo', :minute => 'absent') }.to_not raise_error + describe 'minute' do + it 'supports absent' do + expect { described_class.new(name: 'foo', minute: 'absent') }.not_to raise_error end - it "should support *" do - expect { described_class.new(:name => 'foo', :minute => '*') }.to_not raise_error + it 'supports *' do + expect { described_class.new(name: 'foo', minute: '*') }.not_to raise_error end - it "should translate absent to :absent" do - expect(described_class.new(:name => 'foo', :minute => 'absent')[:minute]).to eq(:absent) + it 'translates absent to :absent' do + expect(described_class.new(name: 'foo', minute: 'absent')[:minute]).to eq(:absent) end - it "should translate * to :absent" do - expect(described_class.new(:name => 'foo', :minute => '*')[:minute]).to eq(:absent) + it 'translates * to :absent' do + expect(described_class.new(name: 'foo', minute: '*')[:minute]).to eq(:absent) end - it "should support valid single values" do - expect { described_class.new(:name => 'foo', :minute => '0') }.to_not raise_error - expect { described_class.new(:name => 'foo', :minute => '1') }.to_not raise_error - expect { described_class.new(:name => 'foo', :minute => '59') }.to_not raise_error + it 'supports valid single values' do + expect { described_class.new(name: 'foo', minute: '0') }.not_to raise_error + expect { described_class.new(name: 'foo', minute: '1') }.not_to raise_error + expect { described_class.new(name: 'foo', minute: '59') }.not_to raise_error end - it "should not support non numeric characters" do - expect { described_class.new(:name => 'foo', :minute => 'z59') }.to raise_error(Puppet::Error, /z59 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '5z9') }.to raise_error(Puppet::Error, /5z9 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '59z') }.to raise_error(Puppet::Error, /59z is not a valid minute/) + it 'does not support non numeric characters' do + expect { described_class.new(name: 'foo', minute: 'z59') }.to raise_error(Puppet::Error, %r{z59 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '5z9') }.to raise_error(Puppet::Error, %r{5z9 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '59z') }.to raise_error(Puppet::Error, %r{59z is not a valid minute}) end - it "should not support single values out of range" do - - expect { described_class.new(:name => 'foo', :minute => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '60') }.to raise_error(Puppet::Error, /60 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '61') }.to raise_error(Puppet::Error, /61 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '120') }.to raise_error(Puppet::Error, /120 is not a valid minute/) + it 'does not support single values out of range' do + expect { described_class.new(name: 'foo', minute: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '60') }.to raise_error(Puppet::Error, %r{60 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '61') }.to raise_error(Puppet::Error, %r{61 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '120') }.to raise_error(Puppet::Error, %r{120 is not a valid minute}) end - it "should support valid multiple values" do - expect { described_class.new(:name => 'foo', :minute => ['0','1','59'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :minute => ['40','30','20'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :minute => ['10','30','20'] ) }.to_not raise_error + it 'supports valid multiple values' do + expect { described_class.new(name: 'foo', minute: ['0', '1', '59']) }.not_to raise_error + expect { described_class.new(name: 'foo', minute: ['40', '30', '20']) }.not_to raise_error + expect { described_class.new(name: 'foo', minute: ['10', '30', '20']) }.not_to raise_error end - it "should not support multiple values if at least one is invalid" do + it 'does not support multiple values if at least one is invalid' do # one invalid - expect { described_class.new(:name => 'foo', :minute => ['0','1','60'] ) }.to raise_error(Puppet::Error, /60 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => ['0','120','59'] ) }.to raise_error(Puppet::Error, /120 is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => ['-1','1','59'] ) }.to raise_error(Puppet::Error, /-1 is not a valid minute/) + expect { described_class.new(name: 'foo', minute: ['0', '1', '60']) }.to raise_error(Puppet::Error, %r{60 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: ['0', '120', '59']) }.to raise_error(Puppet::Error, %r{120 is not a valid minute}) + expect { described_class.new(name: 'foo', minute: ['-1', '1', '59']) }.to raise_error(Puppet::Error, %r{-1 is not a valid minute}) # two invalid - expect { described_class.new(:name => 'foo', :minute => ['0','61','62'] ) }.to raise_error(Puppet::Error, /(61|62) is not a valid minute/) + expect { described_class.new(name: 'foo', minute: ['0', '61', '62']) }.to raise_error(Puppet::Error, %r{(61|62) is not a valid minute}) # all invalid - expect { described_class.new(:name => 'foo', :minute => ['-1','61','62'] ) }.to raise_error(Puppet::Error, /(-1|61|62) is not a valid minute/) + expect { described_class.new(name: 'foo', minute: ['-1', '61', '62']) }.to raise_error(Puppet::Error, %r{(-1|61|62) is not a valid minute}) end - it "should support valid step syntax" do - expect { described_class.new(:name => 'foo', :minute => '*/2' ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :minute => '10-16/2' ) }.to_not raise_error + it 'supports valid step syntax' do + expect { described_class.new(name: 'foo', minute: '*/2') }.not_to raise_error + expect { described_class.new(name: 'foo', minute: '10-16/2') }.not_to raise_error end - it "should not support invalid steps" do - expect { described_class.new(:name => 'foo', :minute => '*/A' ) }.to raise_error(Puppet::Error, /\*\/A is not a valid minute/) - expect { described_class.new(:name => 'foo', :minute => '*/2A' ) }.to raise_error(Puppet::Error, /\*\/2A is not a valid minute/) + it 'does not support invalid steps' do + expect { described_class.new(name: 'foo', minute: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid minute/) + expect { described_class.new(name: 'foo', minute: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid minute/) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :minute => '*/120' ) }.to raise_error(Puppet::Error, /is not a valid minute/) end end - describe "hour" do - it "should support absent" do - expect { described_class.new(:name => 'foo', :hour => 'absent') }.to_not raise_error + describe 'hour' do + it 'supports absent' do + expect { described_class.new(name: 'foo', hour: 'absent') }.not_to raise_error end - it "should support *" do - expect { described_class.new(:name => 'foo', :hour => '*') }.to_not raise_error + it 'supports *' do + expect { described_class.new(name: 'foo', hour: '*') }.not_to raise_error end - it "should translate absent to :absent" do - expect(described_class.new(:name => 'foo', :hour => 'absent')[:hour]).to eq(:absent) + it 'translates absent to :absent' do + expect(described_class.new(name: 'foo', hour: 'absent')[:hour]).to eq(:absent) end - it "should translate * to :absent" do - expect(described_class.new(:name => 'foo', :hour => '*')[:hour]).to eq(:absent) + it 'translates * to :absent' do + expect(described_class.new(name: 'foo', hour: '*')[:hour]).to eq(:absent) end - it "should support valid single values" do - expect { described_class.new(:name => 'foo', :hour => '0') }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => '11') }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => '12') }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => '13') }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => '23') }.to_not raise_error + it 'supports valid single values' do + expect { described_class.new(name: 'foo', hour: '0') }.not_to raise_error + expect { described_class.new(name: 'foo', hour: '11') }.not_to raise_error + expect { described_class.new(name: 'foo', hour: '12') }.not_to raise_error + expect { described_class.new(name: 'foo', hour: '13') }.not_to raise_error + expect { described_class.new(name: 'foo', hour: '23') }.not_to raise_error end - it "should not support non numeric characters" do - expect { described_class.new(:name => 'foo', :hour => 'z15') }.to raise_error(Puppet::Error, /z15 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => '1z5') }.to raise_error(Puppet::Error, /1z5 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => '15z') }.to raise_error(Puppet::Error, /15z is not a valid hour/) + it 'does not support non numeric characters' do + expect { described_class.new(name: 'foo', hour: 'z15') }.to raise_error(Puppet::Error, %r{z15 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: '1z5') }.to raise_error(Puppet::Error, %r{1z5 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: '15z') }.to raise_error(Puppet::Error, %r{15z is not a valid hour}) end - it "should not support single values out of range" do - expect { described_class.new(:name => 'foo', :hour => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => '24') }.to raise_error(Puppet::Error, /24 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => '120') }.to raise_error(Puppet::Error, /120 is not a valid hour/) + it 'does not support single values out of range' do + expect { described_class.new(name: 'foo', hour: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: '24') }.to raise_error(Puppet::Error, %r{24 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: '120') }.to raise_error(Puppet::Error, %r{120 is not a valid hour}) end - it "should support valid multiple values" do - expect { described_class.new(:name => 'foo', :hour => ['0','1','23'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => ['5','16','14'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => ['16','13','9'] ) }.to_not raise_error + it 'supports valid multiple values' do + expect { described_class.new(name: 'foo', hour: ['0', '1', '23']) }.not_to raise_error + expect { described_class.new(name: 'foo', hour: ['5', '16', '14']) }.not_to raise_error + expect { described_class.new(name: 'foo', hour: ['16', '13', '9']) }.not_to raise_error end - it "should not support multiple values if at least one is invalid" do + it 'does not support multiple values if at least one is invalid' do # one invalid - expect { described_class.new(:name => 'foo', :hour => ['0','1','24'] ) }.to raise_error(Puppet::Error, /24 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => ['0','-1','5'] ) }.to raise_error(Puppet::Error, /-1 is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => ['-1','1','23'] ) }.to raise_error(Puppet::Error, /-1 is not a valid hour/) + expect { described_class.new(name: 'foo', hour: ['0', '1', '24']) }.to raise_error(Puppet::Error, %r{24 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: ['0', '-1', '5']) }.to raise_error(Puppet::Error, %r{-1 is not a valid hour}) + expect { described_class.new(name: 'foo', hour: ['-1', '1', '23']) }.to raise_error(Puppet::Error, %r{-1 is not a valid hour}) # two invalid - expect { described_class.new(:name => 'foo', :hour => ['0','25','26'] ) }.to raise_error(Puppet::Error, /(25|26) is not a valid hour/) + expect { described_class.new(name: 'foo', hour: ['0', '25', '26']) }.to raise_error(Puppet::Error, %r{(25|26) is not a valid hour}) # all invalid - expect { described_class.new(:name => 'foo', :hour => ['-1','24','120'] ) }.to raise_error(Puppet::Error, /(-1|24|120) is not a valid hour/) + expect { described_class.new(name: 'foo', hour: ['-1', '24', '120']) }.to raise_error(Puppet::Error, %r{(-1|24|120) is not a valid hour}) end - it "should support valid step syntax" do - expect { described_class.new(:name => 'foo', :hour => '*/2' ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :hour => '10-18/4' ) }.to_not raise_error + it 'supports valid step syntax' do + expect { described_class.new(name: 'foo', hour: '*/2') }.not_to raise_error + expect { described_class.new(name: 'foo', hour: '10-18/4') }.not_to raise_error end - it "should not support invalid steps" do - expect { described_class.new(:name => 'foo', :hour => '*/A' ) }.to raise_error(Puppet::Error, /\*\/A is not a valid hour/) - expect { described_class.new(:name => 'foo', :hour => '*/2A' ) }.to raise_error(Puppet::Error, /\*\/2A is not a valid hour/) + it 'does not support invalid steps' do + expect { described_class.new(name: 'foo', hour: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid hour/) + expect { described_class.new(name: 'foo', hour: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid hour/) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :hour => '*/26' ) }.to raise_error(Puppet::Error, /is not a valid hour/) end end - describe "weekday" do - it "should support absent" do - expect { described_class.new(:name => 'foo', :weekday => 'absent') }.to_not raise_error + describe 'weekday' do + it 'supports absent' do + expect { described_class.new(name: 'foo', weekday: 'absent') }.not_to raise_error end - it "should support *" do - expect { described_class.new(:name => 'foo', :weekday => '*') }.to_not raise_error + it 'supports *' do + expect { described_class.new(name: 'foo', weekday: '*') }.not_to raise_error end - it "should translate absent to :absent" do - expect(described_class.new(:name => 'foo', :weekday => 'absent')[:weekday]).to eq(:absent) + it 'translates absent to :absent' do + expect(described_class.new(name: 'foo', weekday: 'absent')[:weekday]).to eq(:absent) end - it "should translate * to :absent" do - expect(described_class.new(:name => 'foo', :weekday => '*')[:weekday]).to eq(:absent) + it 'translates * to :absent' do + expect(described_class.new(name: 'foo', weekday: '*')[:weekday]).to eq(:absent) end - it "should support valid numeric weekdays" do - expect { described_class.new(:name => 'foo', :weekday => '0') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => '1') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => '6') }.to_not raise_error + it 'supports valid numeric weekdays' do + expect { described_class.new(name: 'foo', weekday: '0') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: '1') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: '6') }.not_to raise_error # According to http://www.manpagez.com/man/5/crontab 7 is also valid (Sunday) - expect { described_class.new(:name => 'foo', :weekday => '7') }.to_not raise_error + expect { described_class.new(name: 'foo', weekday: '7') }.not_to raise_error end - it "should support valid weekdays as words (long version)" do - expect { described_class.new(:name => 'foo', :weekday => 'Monday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Tuesday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Wednesday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Thursday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Friday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Saturday') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Sunday') }.to_not raise_error + it 'supports valid weekdays as words (long version)' do + expect { described_class.new(name: 'foo', weekday: 'Monday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Tuesday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Wednesday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Thursday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Friday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Saturday') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Sunday') }.not_to raise_error end - it "should support valid weekdays as words (3 character version)" do - expect { described_class.new(:name => 'foo', :weekday => 'Mon') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Tue') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Wed') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Thu') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Fri') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Sat') }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => 'Sun') }.to_not raise_error + it 'supports valid weekdays as words (3 character version)' do + expect { described_class.new(name: 'foo', weekday: 'Mon') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Tue') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Wed') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Thu') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Fri') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Sat') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: 'Sun') }.not_to raise_error end - it "should not support numeric values out of range" do - expect { described_class.new(:name => 'foo', :weekday => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid weekday/) - expect { described_class.new(:name => 'foo', :weekday => '8') }.to raise_error(Puppet::Error, /8 is not a valid weekday/) + it 'does not support numeric values out of range' do + expect { described_class.new(name: 'foo', weekday: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid weekday}) + expect { described_class.new(name: 'foo', weekday: '8') }.to raise_error(Puppet::Error, %r{8 is not a valid weekday}) end - it "should not support invalid weekday names" do - expect { described_class.new(:name => 'foo', :weekday => 'Sar') }.to raise_error(Puppet::Error, /Sar is not a valid weekday/) + it 'does not support invalid weekday names' do + expect { described_class.new(name: 'foo', weekday: 'Sar') }.to raise_error(Puppet::Error, %r{Sar is not a valid weekday}) end - it "should support valid multiple values" do - expect { described_class.new(:name => 'foo', :weekday => ['0','1','6'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => ['Mon','Wed','Friday'] ) }.to_not raise_error + it 'supports valid multiple values' do + expect { described_class.new(name: 'foo', weekday: ['0', '1', '6']) }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: ['Mon', 'Wed', 'Friday']) }.not_to raise_error end - it "should not support multiple values if at least one is invalid" do + it 'does not support multiple values if at least one is invalid' do # one invalid - expect { described_class.new(:name => 'foo', :weekday => ['0','1','8'] ) }.to raise_error(Puppet::Error, /8 is not a valid weekday/) - expect { described_class.new(:name => 'foo', :weekday => ['Mon','Fii','Sat'] ) }.to raise_error(Puppet::Error, /Fii is not a valid weekday/) + expect { described_class.new(name: 'foo', weekday: ['0', '1', '8']) }.to raise_error(Puppet::Error, %r{8 is not a valid weekday}) + expect { described_class.new(name: 'foo', weekday: ['Mon', 'Fii', 'Sat']) }.to raise_error(Puppet::Error, %r{Fii is not a valid weekday}) # two invalid - expect { described_class.new(:name => 'foo', :weekday => ['Mos','Fii','Sat'] ) }.to raise_error(Puppet::Error, /(Mos|Fii) is not a valid weekday/) + expect { described_class.new(name: 'foo', weekday: ['Mos', 'Fii', 'Sat']) }.to raise_error(Puppet::Error, %r{(Mos|Fii) is not a valid weekday}) # all invalid - expect { described_class.new(:name => 'foo', :weekday => ['Mos','Fii','Saa'] ) }.to raise_error(Puppet::Error, /(Mos|Fii|Saa) is not a valid weekday/) - expect { described_class.new(:name => 'foo', :weekday => ['-1','8','11'] ) }.to raise_error(Puppet::Error, /(-1|8|11) is not a valid weekday/) + expect { described_class.new(name: 'foo', weekday: ['Mos', 'Fii', 'Saa']) }.to raise_error(Puppet::Error, %r{(Mos|Fii|Saa) is not a valid weekday}) + expect { described_class.new(name: 'foo', weekday: ['-1', '8', '11']) }.to raise_error(Puppet::Error, %r{(-1|8|11) is not a valid weekday}) end - it "should support valid step syntax" do - expect { described_class.new(:name => 'foo', :weekday => '*/2' ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :weekday => '0-4/2' ) }.to_not raise_error + it 'supports valid step syntax' do + expect { described_class.new(name: 'foo', weekday: '*/2') }.not_to raise_error + expect { described_class.new(name: 'foo', weekday: '0-4/2') }.not_to raise_error end - it "should not support invalid steps" do - expect { described_class.new(:name => 'foo', :weekday => '*/A' ) }.to raise_error(Puppet::Error, /\*\/A is not a valid weekday/) - expect { described_class.new(:name => 'foo', :weekday => '*/2A' ) }.to raise_error(Puppet::Error, /\*\/2A is not a valid weekday/) + it 'does not support invalid steps' do + expect { described_class.new(name: 'foo', weekday: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid weekday/) + expect { described_class.new(name: 'foo', weekday: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid weekday/) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :weekday => '*/9' ) }.to raise_error(Puppet::Error, /is not a valid weekday/) end end - describe "month" do - it "should support absent" do - expect { described_class.new(:name => 'foo', :month => 'absent') }.to_not raise_error + describe 'month' do + it 'supports absent' do + expect { described_class.new(name: 'foo', month: 'absent') }.not_to raise_error end - it "should support *" do - expect { described_class.new(:name => 'foo', :month => '*') }.to_not raise_error + it 'supports *' do + expect { described_class.new(name: 'foo', month: '*') }.not_to raise_error end - it "should translate absent to :absent" do - expect(described_class.new(:name => 'foo', :month => 'absent')[:month]).to eq(:absent) + it 'translates absent to :absent' do + expect(described_class.new(name: 'foo', month: 'absent')[:month]).to eq(:absent) end - it "should translate * to :absent" do - expect(described_class.new(:name => 'foo', :month => '*')[:month]).to eq(:absent) + it 'translates * to :absent' do + expect(described_class.new(name: 'foo', month: '*')[:month]).to eq(:absent) end - it "should support valid numeric values" do - expect { described_class.new(:name => 'foo', :month => '1') }.to_not raise_error - expect { described_class.new(:name => 'foo', :month => '12') }.to_not raise_error + it 'supports valid numeric values' do + expect { described_class.new(name: 'foo', month: '1') }.not_to raise_error + expect { described_class.new(name: 'foo', month: '12') }.not_to raise_error end - it "should support valid months as words" do - expect( described_class.new(:name => 'foo', :month => 'January')[:month] ).to eq(['1']) - expect( described_class.new(:name => 'foo', :month => 'February')[:month] ).to eq(['2']) - expect( described_class.new(:name => 'foo', :month => 'March')[:month] ).to eq(['3']) - expect( described_class.new(:name => 'foo', :month => 'April')[:month] ).to eq(['4']) - expect( described_class.new(:name => 'foo', :month => 'May')[:month] ).to eq(['5']) - expect( described_class.new(:name => 'foo', :month => 'June')[:month] ).to eq(['6']) - expect( described_class.new(:name => 'foo', :month => 'July')[:month] ).to eq(['7']) - expect( described_class.new(:name => 'foo', :month => 'August')[:month] ).to eq(['8']) - expect( described_class.new(:name => 'foo', :month => 'September')[:month] ).to eq(['9']) - expect( described_class.new(:name => 'foo', :month => 'October')[:month] ).to eq(['10']) - expect( described_class.new(:name => 'foo', :month => 'November')[:month] ).to eq(['11']) - expect( described_class.new(:name => 'foo', :month => 'December')[:month] ).to eq(['12']) + it 'supports valid months as words' do + expect(described_class.new(name: 'foo', month: 'January')[:month]).to eq(['1']) + expect(described_class.new(name: 'foo', month: 'February')[:month]).to eq(['2']) + expect(described_class.new(name: 'foo', month: 'March')[:month]).to eq(['3']) + expect(described_class.new(name: 'foo', month: 'April')[:month]).to eq(['4']) + expect(described_class.new(name: 'foo', month: 'May')[:month]).to eq(['5']) + expect(described_class.new(name: 'foo', month: 'June')[:month]).to eq(['6']) + expect(described_class.new(name: 'foo', month: 'July')[:month]).to eq(['7']) + expect(described_class.new(name: 'foo', month: 'August')[:month]).to eq(['8']) + expect(described_class.new(name: 'foo', month: 'September')[:month]).to eq(['9']) + expect(described_class.new(name: 'foo', month: 'October')[:month]).to eq(['10']) + expect(described_class.new(name: 'foo', month: 'November')[:month]).to eq(['11']) + expect(described_class.new(name: 'foo', month: 'December')[:month]).to eq(['12']) end - it "should support valid months as words (3 character short version)" do - expect( described_class.new(:name => 'foo', :month => 'Jan')[:month] ).to eq(['1']) - expect( described_class.new(:name => 'foo', :month => 'Feb')[:month] ).to eq(['2']) - expect( described_class.new(:name => 'foo', :month => 'Mar')[:month] ).to eq(['3']) - expect( described_class.new(:name => 'foo', :month => 'Apr')[:month] ).to eq(['4']) - expect( described_class.new(:name => 'foo', :month => 'May')[:month] ).to eq(['5']) - expect( described_class.new(:name => 'foo', :month => 'Jun')[:month] ).to eq(['6']) - expect( described_class.new(:name => 'foo', :month => 'Jul')[:month] ).to eq(['7']) - expect( described_class.new(:name => 'foo', :month => 'Aug')[:month] ).to eq(['8']) - expect( described_class.new(:name => 'foo', :month => 'Sep')[:month] ).to eq(['9']) - expect( described_class.new(:name => 'foo', :month => 'Oct')[:month] ).to eq(['10']) - expect( described_class.new(:name => 'foo', :month => 'Nov')[:month] ).to eq(['11']) - expect( described_class.new(:name => 'foo', :month => 'Dec')[:month] ).to eq(['12']) + it 'supports valid months as words (3 character short version)' do + expect(described_class.new(name: 'foo', month: 'Jan')[:month]).to eq(['1']) + expect(described_class.new(name: 'foo', month: 'Feb')[:month]).to eq(['2']) + expect(described_class.new(name: 'foo', month: 'Mar')[:month]).to eq(['3']) + expect(described_class.new(name: 'foo', month: 'Apr')[:month]).to eq(['4']) + expect(described_class.new(name: 'foo', month: 'May')[:month]).to eq(['5']) + expect(described_class.new(name: 'foo', month: 'Jun')[:month]).to eq(['6']) + expect(described_class.new(name: 'foo', month: 'Jul')[:month]).to eq(['7']) + expect(described_class.new(name: 'foo', month: 'Aug')[:month]).to eq(['8']) + expect(described_class.new(name: 'foo', month: 'Sep')[:month]).to eq(['9']) + expect(described_class.new(name: 'foo', month: 'Oct')[:month]).to eq(['10']) + expect(described_class.new(name: 'foo', month: 'Nov')[:month]).to eq(['11']) + expect(described_class.new(name: 'foo', month: 'Dec')[:month]).to eq(['12']) end - it "should not support numeric values out of range" do - expect { described_class.new(:name => 'foo', :month => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '0') }.to raise_error(Puppet::Error, /0 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '13') }.to raise_error(Puppet::Error, /13 is not a valid month/) + it 'does not support numeric values out of range' do + expect { described_class.new(name: 'foo', month: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid month}) + expect { described_class.new(name: 'foo', month: '0') }.to raise_error(Puppet::Error, %r{0 is not a valid month}) + expect { described_class.new(name: 'foo', month: '13') }.to raise_error(Puppet::Error, %r{13 is not a valid month}) end - it "should not support words that are not valid months" do - expect { described_class.new(:name => 'foo', :month => 'Jal') }.to raise_error(Puppet::Error, /Jal is not a valid month/) + it 'does not support words that are not valid months' do + expect { described_class.new(name: 'foo', month: 'Jal') }.to raise_error(Puppet::Error, %r{Jal is not a valid month}) end - it "should not support single values out of range" do - - expect { described_class.new(:name => 'foo', :month => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '60') }.to raise_error(Puppet::Error, /60 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '61') }.to raise_error(Puppet::Error, /61 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '120') }.to raise_error(Puppet::Error, /120 is not a valid month/) + it 'does not support single values out of range' do + expect { described_class.new(name: 'foo', month: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid month}) + expect { described_class.new(name: 'foo', month: '60') }.to raise_error(Puppet::Error, %r{60 is not a valid month}) + expect { described_class.new(name: 'foo', month: '61') }.to raise_error(Puppet::Error, %r{61 is not a valid month}) + expect { described_class.new(name: 'foo', month: '120') }.to raise_error(Puppet::Error, %r{120 is not a valid month}) end - it "should support valid multiple values" do - expect { described_class.new(:name => 'foo', :month => ['1','9','12'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :month => ['Jan','March','Jul'] ) }.to_not raise_error + it 'supports valid multiple values' do + expect { described_class.new(name: 'foo', month: ['1', '9', '12']) }.not_to raise_error + expect { described_class.new(name: 'foo', month: ['Jan', 'March', 'Jul']) }.not_to raise_error end - it "should not support multiple values if at least one is invalid" do + it 'does not support multiple values if at least one is invalid' do # one invalid - expect { described_class.new(:name => 'foo', :month => ['0','1','12'] ) }.to raise_error(Puppet::Error, /0 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => ['1','13','10'] ) }.to raise_error(Puppet::Error, /13 is not a valid month/) - expect { described_class.new(:name => 'foo', :month => ['Jan','Feb','Jxx'] ) }.to raise_error(Puppet::Error, /Jxx is not a valid month/) + expect { described_class.new(name: 'foo', month: ['0', '1', '12']) }.to raise_error(Puppet::Error, %r{0 is not a valid month}) + expect { described_class.new(name: 'foo', month: ['1', '13', '10']) }.to raise_error(Puppet::Error, %r{13 is not a valid month}) + expect { described_class.new(name: 'foo', month: ['Jan', 'Feb', 'Jxx']) }.to raise_error(Puppet::Error, %r{Jxx is not a valid month}) # two invalid - expect { described_class.new(:name => 'foo', :month => ['Jan','Fex','Jux'] ) }.to raise_error(Puppet::Error, /(Fex|Jux) is not a valid month/) + expect { described_class.new(name: 'foo', month: ['Jan', 'Fex', 'Jux']) }.to raise_error(Puppet::Error, %r{(Fex|Jux) is not a valid month}) # all invalid - expect { described_class.new(:name => 'foo', :month => ['-1','0','13'] ) }.to raise_error(Puppet::Error, /(-1|0|13) is not a valid month/) - expect { described_class.new(:name => 'foo', :month => ['Jax','Fex','Aux'] ) }.to raise_error(Puppet::Error, /(Jax|Fex|Aux) is not a valid month/) + expect { described_class.new(name: 'foo', month: ['-1', '0', '13']) }.to raise_error(Puppet::Error, %r{(-1|0|13) is not a valid month}) + expect { described_class.new(name: 'foo', month: ['Jax', 'Fex', 'Aux']) }.to raise_error(Puppet::Error, %r{(Jax|Fex|Aux) is not a valid month}) end - it "should support valid step syntax" do - expect { described_class.new(:name => 'foo', :month => '*/2' ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :month => '1-12/3' ) }.to_not raise_error + it 'supports valid step syntax' do + expect { described_class.new(name: 'foo', month: '*/2') }.not_to raise_error + expect { described_class.new(name: 'foo', month: '1-12/3') }.not_to raise_error end - it "should not support invalid steps" do - expect { described_class.new(:name => 'foo', :month => '*/A' ) }.to raise_error(Puppet::Error, /\*\/A is not a valid month/) - expect { described_class.new(:name => 'foo', :month => '*/2A' ) }.to raise_error(Puppet::Error, /\*\/2A is not a valid month/) + it 'does not support invalid steps' do + expect { described_class.new(name: 'foo', month: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid month/) + expect { described_class.new(name: 'foo', month: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid month/) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :month => '*/13' ) }.to raise_error(Puppet::Error, /is not a valid month/) end end - describe "monthday" do - it "should support absent" do - expect { described_class.new(:name => 'foo', :monthday => 'absent') }.to_not raise_error + describe 'monthday' do + it 'supports absent' do + expect { described_class.new(name: 'foo', monthday: 'absent') }.not_to raise_error end - it "should support *" do - expect { described_class.new(:name => 'foo', :monthday => '*') }.to_not raise_error + it 'supports *' do + expect { described_class.new(name: 'foo', monthday: '*') }.not_to raise_error end - it "should translate absent to :absent" do - expect(described_class.new(:name => 'foo', :monthday => 'absent')[:monthday]).to eq(:absent) + it 'translates absent to :absent' do + expect(described_class.new(name: 'foo', monthday: 'absent')[:monthday]).to eq(:absent) end - it "should translate * to :absent" do - expect(described_class.new(:name => 'foo', :monthday => '*')[:monthday]).to eq(:absent) + it 'translates * to :absent' do + expect(described_class.new(name: 'foo', monthday: '*')[:monthday]).to eq(:absent) end - it "should support valid single values" do - expect { described_class.new(:name => 'foo', :monthday => '1') }.to_not raise_error - expect { described_class.new(:name => 'foo', :monthday => '30') }.to_not raise_error - expect { described_class.new(:name => 'foo', :monthday => '31') }.to_not raise_error + it 'supports valid single values' do + expect { described_class.new(name: 'foo', monthday: '1') }.not_to raise_error + expect { described_class.new(name: 'foo', monthday: '30') }.not_to raise_error + expect { described_class.new(name: 'foo', monthday: '31') }.not_to raise_error end - it "should not support non numeric characters" do - expect { described_class.new(:name => 'foo', :monthday => 'z23') }.to raise_error(Puppet::Error, /z23 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => '2z3') }.to raise_error(Puppet::Error, /2z3 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => '23z') }.to raise_error(Puppet::Error, /23z is not a valid monthday/) + it 'does not support non numeric characters' do + expect { described_class.new(name: 'foo', monthday: 'z23') }.to raise_error(Puppet::Error, %r{z23 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: '2z3') }.to raise_error(Puppet::Error, %r{2z3 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: '23z') }.to raise_error(Puppet::Error, %r{23z is not a valid monthday}) end - it "should not support single values out of range" do - expect { described_class.new(:name => 'foo', :monthday => '-1') }.to raise_error(Puppet::Error, /-1 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => '0') }.to raise_error(Puppet::Error, /0 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => '32') }.to raise_error(Puppet::Error, /32 is not a valid monthday/) + it 'does not support single values out of range' do + expect { described_class.new(name: 'foo', monthday: '-1') }.to raise_error(Puppet::Error, %r{-1 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: '0') }.to raise_error(Puppet::Error, %r{0 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: '32') }.to raise_error(Puppet::Error, %r{32 is not a valid monthday}) end - it "should support valid multiple values" do - expect { described_class.new(:name => 'foo', :monthday => ['1','23','31'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :monthday => ['31','23','1'] ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :monthday => ['1','31','23'] ) }.to_not raise_error + it 'supports valid multiple values' do + expect { described_class.new(name: 'foo', monthday: ['1', '23', '31']) }.not_to raise_error + expect { described_class.new(name: 'foo', monthday: ['31', '23', '1']) }.not_to raise_error + expect { described_class.new(name: 'foo', monthday: ['1', '31', '23']) }.not_to raise_error end - it "should not support multiple values if at least one is invalid" do + it 'does not support multiple values if at least one is invalid' do # one invalid - expect { described_class.new(:name => 'foo', :monthday => ['1','23','32'] ) }.to raise_error(Puppet::Error, /32 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => ['-1','12','23'] ) }.to raise_error(Puppet::Error, /-1 is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => ['13','32','30'] ) }.to raise_error(Puppet::Error, /32 is not a valid monthday/) + expect { described_class.new(name: 'foo', monthday: ['1', '23', '32']) }.to raise_error(Puppet::Error, %r{32 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: ['-1', '12', '23']) }.to raise_error(Puppet::Error, %r{-1 is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: ['13', '32', '30']) }.to raise_error(Puppet::Error, %r{32 is not a valid monthday}) # two invalid - expect { described_class.new(:name => 'foo', :monthday => ['-1','0','23'] ) }.to raise_error(Puppet::Error, /(-1|0) is not a valid monthday/) + expect { described_class.new(name: 'foo', monthday: ['-1', '0', '23']) }.to raise_error(Puppet::Error, %r{(-1|0) is not a valid monthday}) # all invalid - expect { described_class.new(:name => 'foo', :monthday => ['-1','0','32'] ) }.to raise_error(Puppet::Error, /(-1|0|32) is not a valid monthday/) + expect { described_class.new(name: 'foo', monthday: ['-1', '0', '32']) }.to raise_error(Puppet::Error, %r{(-1|0|32) is not a valid monthday}) end - it "should support valid step syntax" do - expect { described_class.new(:name => 'foo', :monthday => '*/2' ) }.to_not raise_error - expect { described_class.new(:name => 'foo', :monthday => '10-16/2' ) }.to_not raise_error + it 'supports valid step syntax' do + expect { described_class.new(name: 'foo', monthday: '*/2') }.not_to raise_error + expect { described_class.new(name: 'foo', monthday: '10-16/2') }.not_to raise_error end - it "should not support invalid steps" do - expect { described_class.new(:name => 'foo', :monthday => '*/A' ) }.to raise_error(Puppet::Error, /\*\/A is not a valid monthday/) - expect { described_class.new(:name => 'foo', :monthday => '*/2A' ) }.to raise_error(Puppet::Error, /\*\/2A is not a valid monthday/) + it 'does not support invalid steps' do + expect { described_class.new(name: 'foo', monthday: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid monthday/) + expect { described_class.new(name: 'foo', monthday: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid monthday/) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :monthday => '*/32' ) }.to raise_error(Puppet::Error, /is not a valid monthday/) end end - describe "special" do - %w(reboot yearly annually monthly weekly daily midnight hourly).each do |value| + describe 'special' do + ['reboot', 'yearly', 'annually', 'monthly', 'weekly', 'daily', 'midnight', 'hourly'].each do |value| it "should support the value '#{value}'" do - expect { described_class.new(:name => 'foo', :special => value ) }.to_not raise_error + expect { described_class.new(name: 'foo', special: value) }.not_to raise_error end end - context "when combined with numeric schedule fields" do + context 'when combined with numeric schedule fields' do context "which are 'absent'" do - [ %w(reboot yearly annually monthly weekly daily midnight hourly), :absent ].flatten.each { |value| + [['reboot', 'yearly', 'annually', 'monthly', 'weekly', 'daily', 'midnight', 'hourly'], :absent].flatten.each do |value| it "should accept the value '#{value}' for special" do expect { - described_class.new(:name => 'foo', :minute => :absent, :special => value ) - }.to_not raise_error + described_class.new(name: 'foo', minute: :absent, special: value) + }.not_to raise_error end - } + end end - context "which are not absent" do - %w(reboot yearly annually monthly weekly daily midnight hourly).each { |value| + context 'which are not absent' do + ['reboot', 'yearly', 'annually', 'monthly', 'weekly', 'daily', 'midnight', 'hourly'].each do |value| it "should not accept the value '#{value}' for special" do expect { - described_class.new(:name => 'foo', :minute => "1", :special => value ) - }.to raise_error(Puppet::Error, /cannot specify both a special schedule and a value/) + described_class.new(name: 'foo', minute: '1', special: value) + }.to raise_error(Puppet::Error, %r{cannot specify both a special schedule and a value}) end - } - it "should accept the 'absent' value for special" do + end + it "accepts the 'absent' value for special" do expect { - described_class.new(:name => 'foo', :minute => "1", :special => :absent ) - }.to_not raise_error + described_class.new(name: 'foo', minute: '1', special: :absent) + }.not_to raise_error end end end end - describe "environment" do - it "it should accept an :environment that looks like a path" do - expect do - described_class.new(:name => 'foo',:environment => 'PATH=/bin:/usr/bin:/usr/sbin') - end.to_not raise_error + describe 'environment' do + it 'accepts an :environment that looks like a path' do + expect { + described_class.new(name: 'foo', environment: 'PATH=/bin:/usr/bin:/usr/sbin') + }.not_to raise_error end - it "should not accept environment variables that do not contain '='" do - expect do - described_class.new(:name => 'foo',:environment => 'INVALID') - end.to raise_error(Puppet::Error, /Invalid environment setting "INVALID"/) + it "does not accept environment variables that do not contain '='" do + expect { + described_class.new(name: 'foo', environment: 'INVALID') + }.to raise_error(Puppet::Error, %r{Invalid environment setting "INVALID"}) end - it "should accept empty environment variables that do not contain '='" do - expect do - described_class.new(:name => 'foo',:environment => 'MAILTO=') - end.to_not raise_error + it "accepts empty environment variables that do not contain '='" do + expect { + described_class.new(name: 'foo', environment: 'MAILTO=') + }.not_to raise_error end - it "should accept 'absent'" do - expect do - described_class.new(:name => 'foo',:environment => 'absent') - end.to_not raise_error + it "accepts 'absent'" do + expect { + described_class.new(name: 'foo', environment: 'absent') + }.not_to raise_error end - end end - describe "when autorequiring resources" do - + describe 'when autorequiring resources' do before :each do - @user_bob = Puppet::Type.type(:user).new(:name => 'bob', :ensure => :present) - @user_alice = Puppet::Type.type(:user).new(:name => 'alice', :ensure => :present) + @user_bob = Puppet::Type.type(:user).new(name: 'bob', ensure: :present) + @user_alice = Puppet::Type.type(:user).new(name: 'alice', ensure: :present) @catalog = Puppet::Resource::Catalog.new @catalog.add_resource @user_bob, @user_alice end - it "should autorequire the user" do - @resource = described_class.new(:name => 'dummy', :command => '/usr/bin/uptime', :user => 'alice') + it 'autorequires the user' do + @resource = described_class.new(name: 'dummy', command: '/usr/bin/uptime', user: 'alice') @catalog.add_resource @resource req = @resource.autorequire expect(req.size).to eq(1) @@ -530,14 +524,14 @@ describe Puppet::Type.type(:cron), :unless => Puppet.features.microsoft_windows? end end - it "should not require a command when removing an entry" do - entry = described_class.new(:name => "test_entry", :ensure => :absent) + it 'does not require a command when removing an entry' do + entry = described_class.new(name: 'test_entry', ensure: :absent) expect(entry.value(:command)).to eq(nil) end - it "should default to user => root if Etc.getpwuid(Process.uid) returns nil (#12357)" do + it 'defaults to user => root if Etc.getpwuid(Process.uid) returns nil (#12357)' do Etc.expects(:getpwuid).returns(nil) - entry = described_class.new(:name => "test_entry", :ensure => :present) - expect(entry.value(:user)).to eql "root" + entry = described_class.new(name: 'test_entry', ensure: :present) + expect(entry.value(:user)).to eql 'root' end end -- cgit v1.2.3 From 286f7aaa3a1387b689a6a00db705f15b46579ce6 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 1 Aug 2018 16:09:42 -0500 Subject: Fix Style/RegexpLiteral violations --- lib/puppet/type/cron.rb | 8 ++++---- .../tests/resource/cron/should_create_cron.rb | 2 +- .../tests/resource/cron/should_match_existing.rb | 2 +- .../tests/resource/cron/should_remove_cron.rb | 2 +- .../tests/resource/cron/should_update_existing.rb | 4 ++-- spec/unit/type/cron_spec.rb | 20 ++++++++++---------- 6 files changed, 19 insertions(+), 19 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 3a106c4..fada980 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -156,8 +156,8 @@ Puppet::Type.newtype(:cron) do return :absent end - # Allow the */2 syntax - if value =~ /^\*\/[0-9]+$/ + # Allow step syntax + if value =~ %r{^\*/[0-9]+$} return value end @@ -166,8 +166,8 @@ Puppet::Type.newtype(:cron) do return value end - # Allow ranges + */2 - if value =~ /^[0-9]+-[0-9]+\/[0-9]+$/ + # Allow ranges with step + if value =~ %r{^[0-9]+-[0-9]+/[0-9]+$} return value end diff --git a/spec/acceptance/tests/resource/cron/should_create_cron.rb b/spec/acceptance/tests/resource/cron/should_create_cron.rb index 29dcfc4..d01c091 100644 --- a/spec/acceptance/tests/resource/cron/should_create_cron.rb +++ b/spec/acceptance/tests/resource/cron/should_create_cron.rb @@ -30,6 +30,6 @@ agents.each do |host| step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do - assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Incorrect crontab for tstuser on #{host}") + assert_match(%r{\* \* \* \* \* /bin/true}, stdout, "Incorrect crontab for tstuser on #{host}") end end diff --git a/spec/acceptance/tests/resource/cron/should_match_existing.rb b/spec/acceptance/tests/resource/cron/should_match_existing.rb index d309a84..96545e3 100644 --- a/spec/acceptance/tests/resource/cron/should_match_existing.rb +++ b/spec/acceptance/tests/resource/cron/should_match_existing.rb @@ -31,6 +31,6 @@ agents.each do |host| step 'Verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do - assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Did not find crontab for tstuser on #{host}") + assert_match(%r{\* \* \* \* \* /bin/true}, stdout, "Did not find crontab for tstuser on #{host}") end end diff --git a/spec/acceptance/tests/resource/cron/should_remove_cron.rb b/spec/acceptance/tests/resource/cron/should_remove_cron.rb index 1759172..0713c95 100644 --- a/spec/acceptance/tests/resource/cron/should_remove_cron.rb +++ b/spec/acceptance/tests/resource/cron/should_remove_cron.rb @@ -33,6 +33,6 @@ agents.each do |host| step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do - assert_no_match(/\/bin\/true/, stderr, "Error: Found entry for tstuser on #{host}") + assert_no_match(%r{/bin/true}, stderr, "Error: Found entry for tstuser on #{host}") end end diff --git a/spec/acceptance/tests/resource/cron/should_update_existing.rb b/spec/acceptance/tests/resource/cron/should_update_existing.rb index eff634b..b9b9bec 100644 --- a/spec/acceptance/tests/resource/cron/should_update_existing.rb +++ b/spec/acceptance/tests/resource/cron/should_update_existing.rb @@ -27,7 +27,7 @@ agents.each do |host| step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do - assert_match(/\* \* \* \* \* \/bin\/true/, stdout, "Didn't find correct crobtab entry for tstuser on #{host}") + assert_match(%r{\* \* \* \* \* /bin/true}, stdout, "Didn't find correct crobtab entry for tstuser on #{host}") end step 'apply the resource change on the host' @@ -37,6 +37,6 @@ agents.each do |host| step 'verify that crontab -l contains what you expected' run_cron_on(host, :list, 'tstuser') do - assert_match(/\* 0-6 \* \* \* \/bin\/true/, stdout, "Didn't find correctly modified time entry in crobtab entry for tstuser on #{host}") + assert_match(%r{\* 0-6 \* \* \* /bin/true}, stdout, "Didn't find correctly modified time entry in crobtab entry for tstuser on #{host}") end end diff --git a/spec/unit/type/cron_spec.rb b/spec/unit/type/cron_spec.rb index 32cab5c..32bde11 100644 --- a/spec/unit/type/cron_spec.rb +++ b/spec/unit/type/cron_spec.rb @@ -122,8 +122,8 @@ describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do end it 'does not support invalid steps' do - expect { described_class.new(name: 'foo', minute: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid minute/) - expect { described_class.new(name: 'foo', minute: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid minute/) + expect { described_class.new(name: 'foo', minute: '*/A') }.to raise_error(Puppet::Error, %r{\*/A is not a valid minute}) + expect { described_class.new(name: 'foo', minute: '*/2A') }.to raise_error(Puppet::Error, %r{\*/2A is not a valid minute}) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :minute => '*/120' ) }.to raise_error(Puppet::Error, /is not a valid minute/) end @@ -189,8 +189,8 @@ describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do end it 'does not support invalid steps' do - expect { described_class.new(name: 'foo', hour: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid hour/) - expect { described_class.new(name: 'foo', hour: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid hour/) + expect { described_class.new(name: 'foo', hour: '*/A') }.to raise_error(Puppet::Error, %r{\*/A is not a valid hour}) + expect { described_class.new(name: 'foo', hour: '*/2A') }.to raise_error(Puppet::Error, %r{\*/2A is not a valid hour}) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :hour => '*/26' ) }.to raise_error(Puppet::Error, /is not a valid hour/) end @@ -272,8 +272,8 @@ describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do end it 'does not support invalid steps' do - expect { described_class.new(name: 'foo', weekday: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid weekday/) - expect { described_class.new(name: 'foo', weekday: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid weekday/) + expect { described_class.new(name: 'foo', weekday: '*/A') }.to raise_error(Puppet::Error, %r{\*/A is not a valid weekday}) + expect { described_class.new(name: 'foo', weekday: '*/2A') }.to raise_error(Puppet::Error, %r{\*/2A is not a valid weekday}) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :weekday => '*/9' ) }.to raise_error(Puppet::Error, /is not a valid weekday/) end @@ -371,8 +371,8 @@ describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do end it 'does not support invalid steps' do - expect { described_class.new(name: 'foo', month: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid month/) - expect { described_class.new(name: 'foo', month: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid month/) + expect { described_class.new(name: 'foo', month: '*/A') }.to raise_error(Puppet::Error, %r{\*/A is not a valid month}) + expect { described_class.new(name: 'foo', month: '*/2A') }.to raise_error(Puppet::Error, %r{\*/2A is not a valid month}) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :month => '*/13' ) }.to raise_error(Puppet::Error, /is not a valid month/) end @@ -436,8 +436,8 @@ describe Puppet::Type.type(:cron), unless: Puppet.features.microsoft_windows? do end it 'does not support invalid steps' do - expect { described_class.new(name: 'foo', monthday: '*/A') }.to raise_error(Puppet::Error, /\*\/A is not a valid monthday/) - expect { described_class.new(name: 'foo', monthday: '*/2A') }.to raise_error(Puppet::Error, /\*\/2A is not a valid monthday/) + expect { described_class.new(name: 'foo', monthday: '*/A') }.to raise_error(Puppet::Error, %r{\*/A is not a valid monthday}) + expect { described_class.new(name: 'foo', monthday: '*/2A') }.to raise_error(Puppet::Error, %r{\*/2A is not a valid monthday}) # As it turns out cron does not complaining about steps that exceed the valid range # expect { described_class.new(:name => 'foo', :monthday => '*/32' ) }.to raise_error(Puppet::Error, /is not a valid monthday/) end -- cgit v1.2.3 From 6e4c49d512272fcfe363867bcc82943168ac0361 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 1 Aug 2018 16:51:24 -0500 Subject: Fix Lint/AssignmentInCondition violations. --- lib/puppet/provider/cron/crontab.rb | 16 +++++++++++----- lib/puppet/type/cron.rb | 13 +++++++------ spec/lib/puppet_spec/files.rb | 3 ++- 3 files changed, 20 insertions(+), 12 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index a664629..e2cb6b6 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -34,11 +34,16 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, def post_parse(record) time = record.delete(:time) - if match = %r{@(\S+)}.match(time) + match = %r{@(\S+)}.match(time) + if match # is there another way to access the constant? Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.each { |f| record[f] = :absent } record[:special] = match.captures[0] - elsif match = %r{(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)}.match(time) + return record + end + + match = %r{(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)}.match(time) + if match record[:special] = :absent Puppet::Type::Cron::ProviderCrontab::TIME_FIELDS.zip(match.captures).each do |field, value| record[field] = if value == absent @@ -47,10 +52,11 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, value.split(',') end end - else - raise Puppet::Error, _('Line got parsed as a crontab entry but cannot be handled. Please file a bug with the contents of your crontab') + + return record end - record + + raise Puppet::Error, _('Line got parsed as a crontab entry but cannot be handled. Please file a bug with the contents of your crontab') end def pre_gen(record) diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index fada980..a811f94 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -178,7 +178,8 @@ Puppet::Type.newtype(:cron) do return value unless self.class.boundaries lower, upper = self.class.boundaries retval = nil - if num = numfix(value) + num = numfix(value) + if num retval = limitcheck(num, lower, upper) elsif respond_to?(:alpha) # If it has an alpha method defined, then we check @@ -396,7 +397,8 @@ Puppet::Type.newtype(:cron) do defaultto do if provider.is_a?(@resource.class.provider(:crontab)) - if val = @resource.should(:user) + val = @resource.should(:user) + if val val else struct = Etc.getpwuid(Process.uid) @@ -450,10 +452,9 @@ Puppet::Type.newtype(:cron) do def value(name) name = name.to_sym ret = nil - if obj = @parameters[name] - ret = obj.should - - ret ||= obj.retrieve + obj = @parameters[name] + if obj + ret = obj.should || obj.retrieve if ret == :absent ret = nil diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index c91f583..f8dde8d 100644 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -8,7 +8,7 @@ module PuppetSpec::Files def self.cleanup # rubocop:disable Style/GlobalVars $global_tempfiles ||= [] - while path = $global_tempfiles.pop + $global_tempfiles.each do |path| begin Dir.unstub(:entries) FileUtils.rm_rf path, secure: true @@ -16,6 +16,7 @@ module PuppetSpec::Files # nothing to do end end + $global_tempfiles = [] # rubocop:enable Style/GlobalVars end -- cgit v1.2.3 From 58a2f0a9ec29e5f2b8516bc1ba74edd447ac6e17 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 1 Aug 2018 16:59:24 -0500 Subject: Fix Lint/EndAlignment violations --- lib/puppet/provider/cron/crontab.rb | 2 +- spec/lib/puppet_spec/files.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index e2cb6b6..63a5e67 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -272,7 +272,7 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, '/usr/lib/cron/tabs/' else '/var/spool/cron' - end + end # Yield the names of all crontab files stored on the local system. # diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index af7d522..c8315c9 100644 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -106,7 +106,7 @@ module PuppetSpec::Files mode else '10' + '%04i' % mode.to_i - end + end expect(actual_mode).to eq(target_mode) end end -- cgit v1.2.3 From fc267d8ebba7485ef5e6acfa19751b17f77321e4 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Tue, 7 Aug 2018 11:26:43 -0500 Subject: Fix Style/GuardClause violations. --- lib/puppet/provider/cron/crontab.rb | 8 ++------ lib/puppet/type/cron.rb | 7 ++----- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index 63a5e67..bbd6442 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -119,12 +119,8 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, def self.resource_for_record(record, resources) resource = super - if resource - target = resource[:target] || resource[:user] - if record[:target] == target - resource - end - end + target = resource[:target] || resource[:user] if resource + return resource if record[:target] == target end # Return the header placed at the top of each generated file, warning diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index a811f94..4243bcf 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -188,11 +188,8 @@ Puppet::Type.newtype(:cron) do retval = alphacheck(value, alpha) end - if retval - return retval.to_s - else - self.fail _('%{value} is not a valid %{name}') % { value: value, name: self.class.name } - end + raise _('%{value} is not a valid %{name}') % { value: value, name: self.class.name } unless retval + return retval.to_s if retval end end -- cgit v1.2.3 From 5e6f975c439abf8c004e26d9bfad27204cab3b27 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 10:14:17 -0500 Subject: Fix Lint/EmptyWhen violation --- lib/puppet/type/cron.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 4243bcf..332affb 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -459,12 +459,7 @@ Puppet::Type.newtype(:cron) do end unless ret - case name - when :command - when :special - # nothing - else - # ret = (self.class.validproperty?(name).default || "*").to_s + unless [:command, :special].include? name ret = '*' end end -- cgit v1.2.3 From ddbf37f1d6cc969c002ef355ba04aedfb9020b89 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 10:24:31 -0500 Subject: Fix Style/IfInsideElse violation --- lib/puppet/type/cron.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 332affb..becaeae 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -102,8 +102,8 @@ Puppet::Type.newtype(:cron) do return index end end - else - return ary.index(tmp) if ary.include?(tmp) + elsif ary.include?(tmp) + return ary.index(tmp) end false -- cgit v1.2.3 From 651f1e53485f33001a8021399f3e0d43d8c7968c Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 10:33:30 -0500 Subject: Fix Style/MultipleComparison cop violations --- lib/puppet/type/cron.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index becaeae..9827f2c 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -152,7 +152,7 @@ Puppet::Type.newtype(:cron) do munge do |value| # Support 'absent' as a value, so that they can remove # a value - if value == 'absent' || value == :absent + if ['absent', :absent].include? value return :absent end @@ -252,7 +252,7 @@ Puppet::Type.newtype(:cron) do def munge(value) # Support value absent so that a schedule can be # forced to change to numeric. - if value == 'absent' || value == :absent + if ['absent', :absent].include? value return :absent end value -- cgit v1.2.3 From 9ae4388987ec26a3de7ed75d012a734297cbd43f Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 11:06:29 -0500 Subject: Fix Style/MultilineBlockChain violation --- lib/puppet/provider/cron/crontab.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index bbd6442..4d5f4f4 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -188,7 +188,8 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, def self.prefetch_hook(records) name = nil envs = nil - result = records.each { |record| + result = [] + records.each do |record| case record[:record_type] when :comment if record[:name] @@ -228,7 +229,8 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, envs = nil end end - }.reject { |record| record[:skip] } + result << record unless record[:skip] + end result end -- cgit v1.2.3 From 570f82c8486b993c3b571ecd8712a3c0dc0f19e6 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 11:10:19 -0500 Subject: Disable Lint/EmptyWhen cop --- lib/puppet/provider/cron/crontab.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/provider/cron/crontab.rb b/lib/puppet/provider/cron/crontab.rb index 4d5f4f4..fec5511 100644 --- a/lib/puppet/provider/cron/crontab.rb +++ b/lib/puppet/provider/cron/crontab.rb @@ -206,7 +206,7 @@ Puppet::Type.type(:cron).provide(:crontab, parent: Puppet::Provider::ParsedFile, envs << record[:line] record[:skip] = true end - when :blank + when :blank # rubocop: disable Lint/EmptyWhen # nothing else if name -- cgit v1.2.3 From 62266afd9e884d259ee6a7cd5c5f8942128691c2 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Wed, 8 Aug 2018 11:12:19 -0500 Subject: Disable Style/PredicateName cop --- lib/puppet/type/cron.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/puppet') diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 9827f2c..fa203c9 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -120,7 +120,7 @@ Puppet::Type.newtype(:cron) do end end - def is_to_s(value = @is) + def is_to_s(value = @is) # rubocop: disable Style/PredicateName if value if value.is_a?(Array) && (name == :command || value[0].is_a?(Symbol)) value = value[0] -- cgit v1.2.3 From c14a79b181595d265f1c726f646cfab491d02170 Mon Sep 17 00:00:00 2001 From: Jorie Tappa Date: Thu, 23 Aug 2018 13:34:54 -0700 Subject: Update readme and description --- README.md | 71 +++++++++---------------------------------------- lib/puppet/type/cron.rb | 10 +++---- 2 files changed, 18 insertions(+), 63 deletions(-) (limited to 'lib/puppet') diff --git a/README.md b/README.md index fb5902c..d3a3742 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ # cron_core -Welcome to your new module. A short overview of the generated parts can be found in the PDK documentation at https://puppet.com/pdk/latest/pdk_generating_modules.html . - -The README template below provides a starting point with details about what information to include in your README. - - - - - - - #### Table of Contents 1. [Description](#description) @@ -24,72 +14,37 @@ The README template below provides a starting point with details about what info ## Description -Briefly tell users why they might want to use your module. Explain what your module does and what kind of problems users can solve with it. - -This should be a fairly short description helps the user decide if your module is what they want. - - -## Setup - -### What cron_core affects **OPTIONAL** - -If it's obvious what your module touches, you can skip this section. For example, folks can probably figure out that your mysql_instance module affects their MySQL instances. +Install and manage `cron` resources. -If there's more that they should know about, though, this is the place to mention: - -* Files, packages, services, or operations that the module will alter, impact, or execute. -* Dependencies that your module automatically installs. -* Warnings or other important notices. - -### Setup Requirements **OPTIONAL** - -If your module requires anything extra before setting up (pluginsync enabled, another module, etc.), mention it here. - -If your most recent release breaks compatibility or requires particular steps for upgrading, you might want to include an additional "Upgrading" section here. - -### Beginning with cron_core - -The very basic steps needed for a user to get the module up and running. This can include setup steps, if necessary, or it can be an example of the most basic use of the module. ## Usage -Include usage examples for common use cases in the **Usage** section. Show your users how to use your module to solve problems, and be sure to include code examples. Include three to five examples of the most important or common tasks a user can accomplish with your module. Show users how to accomplish more complex tasks that involve different types, classes, and functions working in tandem. ## Reference -This section is deprecated. Instead, add reference information to your code as Puppet Strings comments, and then use Strings to generate a REFERENCE.md in your module. For details on how to add code comments and generate documentation with Strings, see the Puppet Strings [documentation](https://puppet.com/docs/puppet/latest/puppet_strings.html) and [style guide](https://puppet.com/docs/puppet/latest/puppet_strings_style.html) +Please see `REFERENCE.md` for the reference documentation. -If you aren't ready to use Strings yet, manually create a REFERENCE.md in the root of your module directory and list out each of your module's classes, defined types, facts, functions, Puppet tasks, task plans, and resource types and providers, along with the parameters for each. +This module is documented using Puppet Strings. -For each element (class, defined type, function, and so on), list: +For a quick primer on how Strings works, please see [this blog post](https://puppet.com/blog/using-puppet-strings-generate-great-documentation-puppet-modules) or the [README.md](https://github.com/puppetlabs/puppet-strings/blob/master/README.md) for Puppet Strings. - * The data type, if applicable. - * A description of what the element does. - * Valid values, if the data type doesn't make it obvious. - * Default value, if any. - -For example: +To generate documentation locally, run: ``` -### `pet::cat` - -#### Parameters - -##### `meow` - -Enables vocalization in your cat. Valid options: 'string'. - -Default: 'medium-loud'. +bundle install +bundle exec puppet strings generate ./lib/**/*.rb ``` +This command will create a browsable \_index.html file in the doc directory. The references available here are all generated from YARD-style comments embedded in the code base. When any development happens on this module, the impacted documentation should also be updated. + ## Limitations -In the Limitations section, list any incompatibilities, known issues, or other warnings. +`cron` is not compatible with Windows or Fedora 28. ## Development -In the Development section, tell other users the ground rules for contributing to your project and how they should submit their work. +Puppet Labs modules on the Puppet Forge are open projects, and community contributions are essential for keeping them great. We can't access the huge number of platforms and myriad of hardware, software, and deployment configurations that Puppet is intended to serve. -## Release Notes/Contributors/Etc. **Optional** +We want to keep it as easy as possible to contribute changes so that our modules work in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things. -If you aren't using changelog, put your release notes here (though you should consider using changelog). You can also add any additional sections you feel are necessary or important to include here. Please use the `## ` header. +For more information, see our [module contribution guide](https://docs.puppetlabs.com/forge/contributing.html). \ No newline at end of file diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index fa203c9..e07ce70 100644 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -4,16 +4,16 @@ require 'puppet/util/filetype' Puppet::Type.newtype(:cron) do @doc = <<-'EOT' - Installs and manages cron jobs. Every cron resource created by Puppet + Installs and manages cron jobs. Every cron resource created by Puppet requires a command and at least one periodic attribute (hour, minute, - month, monthday, weekday, or special). While the name of the cron job is + month, monthday, weekday, or special). While the name of the cron job is not part of the actual job, the name is stored in a comment beginning with `# Puppet Name: `. These comments are used to match crontab entries created by Puppet with cron resources. If an existing crontab entry happens to match the scheduling and command of a - cron resource that has never been synced, Puppet will defer to the existing - crontab entry and will not create a new entry tagged with the `# Puppet Name: ` + cron resource that has never been synced, Puppet defers to the existing + crontab entry and does not create a new entry tagged with the `# Puppet Name: ` comment. Example: @@ -43,7 +43,7 @@ Puppet::Type.newtype(:cron) do minute => '*/10', } - An important note: _the Cron type will not reset parameters that are + **Important:** _The Cron type will not reset parameters that are removed from a manifest_. For example, removing a `minute => 10` parameter will not reset the minute component of the associated cronjob to `*`. These changes must be expressed by setting the parameter to -- cgit v1.2.3