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
signature.asc
Description: Digital signature
