Ruby Signal.trap exit(-1) - ruby

I am trying to unit test a command line tool, that uses trollop. One of the calls it makes to trollop is Trollop::die "my message", which underneath calls exit(-1)
Now, this makes my unit tests to fail, because this kills rake - I've tried using Signal.trap to trap the signal, but it doesn't seem to have any effect. Does anyone have any idea on how to trap this kind of exit code ?

Related

Ruby exucution stuck at system() line

This is my code snippet
def execution_start
puts "About to start"
system("appium")
puts "Done!!"
end
When executing this I see the output About to start, and appium server is launched. But after that, I do not see anything happening. It's stuck forever. Any idea?
system blocks until the command it runs has completed. To run a command and return immediately, use Process#spawn:
def execution_start
puts "About to start"
pid = Process.spawn("appium")
puts "Done!!"
end
You can then use the returned PID to monitor whether the process has finished executing, and with what exit code, later in your program.
(Note that, per the documentation, you need to Process#wait the PID eventually, or at least register disinterest using Process#detach to prevent the subprocess from becoming a zombie.)

ensure block of code runs when program exits

I want to make sure that a peice of code runs when the ruby program ends. I used the following ways but they do not work in some situations.
def a_method
# do some work
ensure
# code that must be run when method ends and if program exits when it still in this method.
end
def a_method
at_exit{
# run code that needs to be run when process exists
}
# do some work
ensure
# do code that needs to be run when method ends
end
those two methods works very well when the process is killed with a signal other than kill -9 'although I didn't tried all the signals'.
So is there a way to make sure that code runs even if the process is killed with this signal?
Signal 9 is non-catchable, non-ignorable kill, by design. Your at_exit will not run because the operating system will simply terminate any process that receives this signal, not giving it any chance to do any extra work.

What is the difference between exit and abort?

The abort documentation says abort will
Terminate execution immediately, effectively by calling Kernel.exit(false).
What exactly does "immediately" mean? What is the difference between abort and exit with non-true status?
"Exit, Exit! Abort, Raiseā€¦Get Me Outta Here!" describes everything you'd want to know I think.
In short:
Kernel.exit(code) "exits" the script immediately and returns the code to the OS, however, just before doing it, it calls any registered at_exit handler that your code could have registered.
Kernel.exit!(code) does the same, but exits immediatelly, no at_exit handlers called.
Kernel.abort(message) takes a message that will be printed to STDERR just before exiting with a failure code=1.
Different values of exit codes are barely suitable for detecting problems and debugging the code. However, they are very simple to use and making the parent process read them is almost trivial. Hence, exit and exit!.
If you can spend more time and make the error checking more robust, you'll need some serious error messages, not just codes. Traditionally, you can print them to STDERR if it exists. You can print manually to STDERR via normal puts, but exit-codes will still be used at the lowest level.
Printing to STDERR does not mark your job automatically as failed, so, abort was created to allow you to write and quit easily. A default exit code of 1 is enough to mark the FAIL condition, as it's assumed that all the real contextual information will be included in the error messages provided by you.
Also note that any unhanded exceptions, such as raise "wtf" with no rescue anywhere, actually behave as if calling Kernel.abort: they print to STDERR and use exitcode=1.
You said exit(false) but the exit! documentation says that the parameter is status code to be used.
I've just checked that on Windows and Ruby 1.9.3:
exit 0 # quits with code: 0
exit 1 # quits with code: 1
exit false # quits with code: 1
exit true # quits with code: 0
which really surprises me, as I'd assume that false would be coerced to 0 in the traditional C way. So, maybe you should rather be using integers like 0 or 1 to be perfectly clear about what code will be used.

Make a rake task fail if system call return error

I have a Rakefile that I use to automate some tasks in my project.
Inside some tasks, I call system, but, even if the process return an error,
task continues without any issue.
How can I avoid that? I want to make rake exit when some subprocess return an error.
Thanks in advance
You can evaluate the return value of system
system('inexistent command') or exit!(1)
puts "This line is not reached"
sh is the Rake way to call a command. It will fail with a neat message. Compared with system, sh prints out the command as well.

run_later with rackup fails to exit with ctrl-c - Ruby

I'm running a Sinatra application with rackup using this run_later https://github.com/elecklider/sinatra_run_later module (my own fork of https://github.com/pmamediagroup/sinatra_run_later). I can't, however, seem to get it to exit cleanly when I send ctrl-c to rackup. It kicks back with the error ERROR SystemExit: exit on line 38. How can I get it to exit nicely when I close the rackup process?
EDIT:
I've been screwing around with this and the error is raised here:
trap :INT do
RunLater::Worker.shutdown
exit # here.
end
And it seems that commenting out the whole trap block gets it to clean up nicely. In essence, this answers the question of how to get it to clean up nicely but I have no idea why so if anyone can offer some clarification I'd really appreciate it.

Resources