On Fri, 17 Jun 2011 09:18:38 -0700, deet wrote:
> 
>   Hello.
>   I have a patch languishing in "insufficient tests" status.   The bug
> is http://projects.puppetlabs.com/issues/5620#change-32352.  I'm
> making my first go at a test and i've run into a wall.  Hoping someone
> can point me in the right direction.
> 
>   The method in question is below as pulled from the patched puppet/
> provider/user/user_role_add.rb.   All the patch consists of is the
> line that reads "line_arr[2] = Time.now.to_i / 86400".  I'm not able
> to figure out how I can get the value associated with the variable
> "line_arr[2]" or the value associated with "line" to complete my
> test.  Is it possible in rspec to ask for the value associated with a
> variable that's localized to a method?  Do I need to redo the patch so
> that the lastchg value is set in a separate method and passed along
> with cryptopw to the below method?  Anyhoo any tips/pointers/ are
> appreciated.
> 
>  def password=(cryptopw)
>     begin
>       File.open("/etc/shadow", "r") do |shadow|
>         File.open("/etc/shadow_tmp", "w", 0600) do |shadow_tmp|
>           while line = shadow.gets
>             line_arr = line.split(':')
>             if line_arr[0] == @resource[:name]
>               line_arr[1] = cryptopw
>               line_arr[2] = Time.now.to_i / 86400
>               line = line_arr.join(':')
>             end
>             shadow_tmp.print line
>           end
>         end
>       end
>       File.rename("/etc/shadow_tmp", "/etc/shadow")
>     rescue => detail
>       fail "Could not write temporary shadow file: #{detail}"
> 
> 
> Here is my go at the test
>  it "should update the lastchg field" do
>       @resource.stubs(:[]).with(:name).returns("username")
>       File.stubs(:readlines).with("/etc/shadow").returns(["#comment",
> "   nonsense", "  ", "username:hashedpassword:6445:::::",
> "other:pword:yay:::"])
> 
>       here is where it breaks down.  Not sure how to ask for the value
> associated with "line_arr[2]" or "line" in the method.
>     end
> 
>    TIA.  Derek.
> 

Derek,

The best way that I can think off off hand actually involves further
refactoring of user_role_add.rb.

I'd probably move the usage of /etc/shadow to a method (and build
/etc/shadow_tmp based on that method) that could be overridden in the
tests.  This way you can have the resource operate on a real file that
you could then examine to make sure it was updated properly.

Probably something like:

  def shadow_file
    '/etc/shadow'
  end

  def password=(cryptopw)
    shadow_tmp_name = "#{shadow_file}_tmp"
    begin
      File.open(shadow_file, "r") do |shadow|
        File.open(shadow_tmp_name, "w", 0600) do |shadow_tmp|
          while line = shadow.gets
            line_arr = line.split(':')
            if line_arr[0] == @resource[:name]
              line_arr[1] = cryptopw
              line_arr[2] = Time.now.to_i / 86400
              line = line_arr.join(':')
            end
            shadow_tmp.print line
          end
        end
      end
      File.rename(shadow_tmp_name, shadow_file)
    rescue => detail
      fail "Could not write temporary shadow file: #{detail}"
    ensure
      # Make sure this *always* gets deleted
      File.unlink(shadow_tmp_name) if File.exist?(shadow_tmp_name)
    end
  end

Then you could do something like this in the spec:

  include PuppetSpec::Files

  it "should update the lastchg field" do
    shadow_file = tmpfile('shadow')
    Time.stubs(:now).returns(3628800) # 86499 * 42
    @provider.stubs(:shadow_file).returns(shadow_file)
    @resource.stubs(:[]).with(:name).returns("username")
    File.stubs(:readlines).with("/etc/shadow").returns(["#comment",
      "   nonsense", "  ", "username:hashedpassword:6445:::::",
      "other:pword:yay:::"])
    @provider.password = 'differenthashedpassword'

    # Check to make sure that the lastchg field was updated in
    # shadow_file
  end

Keep in mind that this is all completely untested (and composed entirely
in this email), but it should help out in writing up the test.

-- 
Jacob Helwig

Attachment: signature.asc
Description: Digital signature

Reply via email to