Jira (PUP-10302) Puppet rspec tests from 'agent_spec.rb' clean up

6 views
Skip to first unread message

Luchian Nemes (JIRA)

unread,
Feb 20, 2020, 4:32:03 AM2/20/20
to puppe...@googlegroups.com
Luchian Nemes created an issue
 
Puppet / Improvement PUP-10302
Puppet rspec tests from 'agent_spec.rb' clean up
Issue Type: Improvement Improvement
Assignee: Unassigned
Created: 2020/02/20 1:31 AM
Priority: Normal Normal
Reporter: Luchian Nemes

One of the newly introduced tests in 'pidlock_spec.rb' was being influenced by other tests from 'agent_spec.rb' (if they were run before it). This order dependency issue was solved by making sure that all the tests in 'pidlock_spec.rb' are fully mocked (since before there were expectations based on real executions of a command).

As this situation can occur again in the future so these problematic tests from 'agent_spec.rb' need to be checked and revamped accordingly:

  • should exit with 1 if an exception is raised
  • should exit child process if child exit
  • should run the agent in a forked process
  • should return the block exit code as the child exit code

The story behind is mostly about a fork mechanism, which is covered by the mentioned tests. This ends up making changes to the rspec's process argument instead of doing the intended action of creating a child process and do said modification to it (not the parent process). The method referred to can be seen in 'agent.rb' as follows:

def run_in_fork(forking = true)
  return yield unless forking or Puppet.features.windows?
 
  atForkHandler = Puppet::Util::AtFork.get_handler
 
  atForkHandler.prepare
 
  begin
    child_pid = Kernel.fork do
      atForkHandler.child
      $0 = _("puppet agent: applying configuration") # <-- Here the child process args are changed
      begin
        exit(yield)
      rescue SystemExit
        exit(-1)
      rescue NoMemoryError
        exit(-2)
      end
    end
  ensure
    atForkHandler.parent
  end
 
  exit_code = Process.waitpid2(child_pid)
  case exit_code[1].exitstatus
  when -1
    raise SystemExit
  when -2
    raise NoMemoryError
  end
  exit_code[1].exitstatus
end

An additional interesting finding here (might not be relevant, but seems worth mentioning) was that both 'comm' and 'args' columns of 'ps' show the same information ('puppet agent: applying configuration') when this modification takes place on MacOSX (for any process). Did a quick check on a RedHat 7 VM and there it seems to run as expected (changing only args). This can be easily reproduced by running following ruby script:

#Get current process pid
pid = Process.pid
 
before = `ps -p #\{pid\} -o comm,args`
puts("comm and args before:\n" + before + "\n")
 
#Change args
$0 = 'changed'
 
after = `ps -p #\{pid\} -o comm,args`
puts("comm and args after\n" + after)

This was important for our case solved in 'pidlock_spec.rb' since the command name and it's arguments are checked when deciding whether to unlock or not a stale pidfile in 'pidlock.rb'. The valid cases are either having a process which contains 'ruby' and any arguments containing the word 'puppet' or just a process name ending with the word 'puppet'. Since on MacOSX the process name did not fall under any of the valid cases, the faulty test obviously failed, while on Linux passed.

Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Luchian Nemes (JIRA)

unread,
Feb 20, 2020, 7:40:04 AM2/20/20
to puppe...@googlegroups.com
Luchian Nemes updated an issue
Change By: Luchian Nemes
Environment: *Puppet Agent version:* 6.13.0
Acceptance Criteria: # Add the following test in 'pidlock_spec.rb':
{code:ruby}    it "should pass after repairing the faulty tests from 'agent_spec.rb'" do
      @lock.lock

      pid = @lock.lock_pid
      comm = `ps -p #{pid} -o comm`
      args = `ps -p #{pid} -o args`
      
      expect(comm).not_to match(/puppet agent: applying configuration/)
      expect(args).not_to match(/puppet agent: applying configuration/)

      expect(comm).to match(/spec\/unit\/util\/pidlock_spec.rb/)
      expect(args).to match(/ruby/)
    end
{code}
# Then run:
>> bundle exec rspec spec/unit/agent_spec.rb spec/unit/util/pidlock_spec.rb
or
>> bundle exec rake parallel:spec
# If correction done correctly, it should pass.

This should be obtained by either mocking the 'run_in_fork' method from 'agent.rb' in the tests or finding a solution for rspec to act as expected.
Priority: Normal Low

Mihai Buzgau (Jira)

unread,
Mar 5, 2020, 11:27:04 AM3/5/20
to puppe...@googlegroups.com
Mihai Buzgau updated an issue
Change By: Mihai Buzgau
Sprint: PR - Triage
This message was sent by Atlassian Jira (v8.5.2#805002-sha1:a66f935)
Atlassian logo
Reply all
Reply to author
Forward
0 new messages