| 
									
										
										
										
											2020-10-10 14:16:11 +02:00
										 |  |  | # typed: false | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 17:52:44 +02:00
										 |  |  | describe SystemCommand do | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |   describe "#initialize" do | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |     subject(:command) { | 
					
						
							|  |  |  |       described_class.new( | 
					
						
							|  |  |  |         "env", | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |         args:         env_args, | 
					
						
							|  |  |  |         env:          env, | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |         must_succeed: true, | 
					
						
							| 
									
										
										
										
											2018-11-02 17:18:07 +00:00
										 |  |  |         sudo:         sudo, | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |       ) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-20 09:07:56 +01:00
										 |  |  |     let(:env_args) { ["bash", "-c", 'printf "%s" "${A?}" "${B?}" "${C?}"'] } | 
					
						
							|  |  |  |     let(:env) { { "A" => "1", "B" => "2", "C" => "3" } } | 
					
						
							|  |  |  |     let(:sudo) { false } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "when given some environment variables" do | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |       its("run!.stdout") { is_expected.to eq("123") } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe "the resulting command line" do | 
					
						
							| 
									
										
										
										
											2018-07-11 11:13:33 +02:00
										 |  |  |         it "includes the given variables explicitly" do | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |           expect(Open3) | 
					
						
							|  |  |  |             .to receive(:popen3) | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |             .with( | 
					
						
							|  |  |  |               an_instance_of(Hash), ["/usr/bin/env", "/usr/bin/env"], "A=1", "B=2", "C=3", | 
					
						
							|  |  |  |               "env", *env_args, | 
					
						
							|  |  |  |               pgroup: true | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |             .and_call_original | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |           command.run! | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |     context "when given an environment variable which is set to nil" do | 
					
						
							|  |  |  |       let(:env) { { "A" => "1", "B" => "2", "C" => nil } } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "unsets them" do | 
					
						
							|  |  |  |         expect { | 
					
						
							|  |  |  |           command.run! | 
					
						
							| 
									
										
										
										
											2020-04-05 11:05:30 -04:00
										 |  |  |         }.to raise_error(/C: parameter (null or )?not set/) | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "when given some environment variables and sudo: true" do | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |       let(:sudo) { true } | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       describe "the resulting command line" do | 
					
						
							|  |  |  |         it "includes the given variables explicitly" do | 
					
						
							|  |  |  |           expect(Open3) | 
					
						
							|  |  |  |             .to receive(:popen3) | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |             .with( | 
					
						
							|  |  |  |               an_instance_of(Hash), ["/usr/bin/sudo", "/usr/bin/sudo"], "-E", "--", | 
					
						
							| 
									
										
										
										
											2020-12-19 19:30:33 +01:00
										 |  |  |               "/usr/bin/env", "A=1", "B=2", "C=3", "env", *env_args, pgroup: nil | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |             .and_wrap_original do |original_popen3, *_, &block| | 
					
						
							| 
									
										
										
										
											2018-07-20 17:52:44 +02:00
										 |  |  |               original_popen3.call("true", &block) | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |           command.run! | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "when the exit code is 0" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     describe "its result" do | 
					
						
							| 
									
										
										
										
											2018-07-20 17:52:44 +02:00
										 |  |  |       subject { described_class.run("true") } | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it { is_expected.to be_a_success } | 
					
						
							|  |  |  |       its(:exit_status) { is_expected.to eq(0) } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "when the exit code is 1" do | 
					
						
							| 
									
										
										
										
											2018-07-20 17:52:44 +02:00
										 |  |  |     let(:command) { "false" } | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 23:15:33 +00:00
										 |  |  |     context "with a command that must succeed" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       it "throws an error" do | 
					
						
							|  |  |  |         expect { | 
					
						
							|  |  |  |           described_class.run!(command) | 
					
						
							| 
									
										
										
										
											2018-07-16 23:17:16 +02:00
										 |  |  |         }.to raise_error(ErrorDuringExecution) | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-19 23:15:33 +00:00
										 |  |  |     context "with a command that does not have to succeed" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       describe "its result" do | 
					
						
							|  |  |  |         subject { described_class.run(command) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it { is_expected.not_to be_a_success } | 
					
						
							|  |  |  |         its(:exit_status) { is_expected.to eq(1) } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "when given a pathname" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     let(:command) { "/bin/ls" } | 
					
						
							|  |  |  |     let(:path)    { Pathname(Dir.mktmpdir) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       FileUtils.touch(path.join("somefile")) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe "its result" do | 
					
						
							|  |  |  |       subject { described_class.run(command, args: [path]) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it { is_expected.to be_a_success } | 
					
						
							|  |  |  |       its(:stdout) { is_expected.to eq("somefile\n") } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "with both STDOUT and STDERR output from upstream" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     let(:command) { "/bin/bash" } | 
					
						
							|  |  |  |     let(:options) { | 
					
						
							|  |  |  |       { args: [ | 
					
						
							| 
									
										
										
										
											2016-10-14 20:33:16 +02:00
										 |  |  |         "-c", | 
					
						
							|  |  |  |         "for i in $(seq 1 2 5); do echo $i; echo $(($i + 1)) >&2; done", | 
					
						
							|  |  |  |       ] } | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shared_examples "it returns '1 2 3 4 5 6'" do | 
					
						
							|  |  |  |       describe "its result" do | 
					
						
							| 
									
										
										
										
											2017-07-29 19:55:05 +02:00
										 |  |  |         subject { described_class.run(command, options) } | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it { is_expected.to be_a_success } | 
					
						
							|  |  |  |         its(:stdout) { is_expected.to eq([1, 3, 5, nil].join("\n")) } | 
					
						
							|  |  |  |         its(:stderr) { is_expected.to eq([2, 4, 6, nil].join("\n")) } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "with default options" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       it "echoes only STDERR" do | 
					
						
							| 
									
										
										
										
											2018-06-14 22:45:07 +02:00
										 |  |  |         expected = [2, 4, 6].map { |i| "#{i}\n" }.join | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |         expect { | 
					
						
							|  |  |  |           described_class.run(command, options) | 
					
						
							| 
									
										
										
										
											2018-06-14 22:45:07 +02:00
										 |  |  |         }.to output(expected).to_stderr | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       include_examples("it returns '1 2 3 4 5 6'") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "with print_stdout" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       before do | 
					
						
							|  |  |  |         options.merge!(print_stdout: true) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-02 16:01:01 +02:00
										 |  |  |       it "echoes both STDOUT and STDERR" do | 
					
						
							| 
									
										
										
										
											2018-06-14 22:45:07 +02:00
										 |  |  |         expect { described_class.run(command, options) } | 
					
						
							|  |  |  |           .to output("1\n3\n5\n").to_stdout | 
					
						
							|  |  |  |           .and output("2\n4\n6\n").to_stderr | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       include_examples("it returns '1 2 3 4 5 6'") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "without print_stderr" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       before do | 
					
						
							|  |  |  |         options.merge!(print_stderr: false) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "echoes nothing" do | 
					
						
							|  |  |  |         expect { | 
					
						
							|  |  |  |           described_class.run(command, options) | 
					
						
							|  |  |  |         }.to output("").to_stdout | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       include_examples("it returns '1 2 3 4 5 6'") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     context "with print_stdout but without print_stderr" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       before do | 
					
						
							|  |  |  |         options.merge!(print_stdout: true, print_stderr: false) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "echoes only STDOUT" do | 
					
						
							| 
									
										
										
										
											2018-06-14 22:48:37 +02:00
										 |  |  |         expected = [1, 3, 5].map { |i| "#{i}\n" }.join | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |         expect { | 
					
						
							|  |  |  |           described_class.run(command, options) | 
					
						
							|  |  |  |         }.to output(expected).to_stdout | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       include_examples("it returns '1 2 3 4 5 6'") | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "with a very long STDERR output" do | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     let(:command) { "/bin/bash" } | 
					
						
							|  |  |  |     let(:options) { | 
					
						
							|  |  |  |       { args: [ | 
					
						
							| 
									
										
										
										
											2016-10-14 20:33:16 +02:00
										 |  |  |         "-c", | 
					
						
							|  |  |  |         "for i in $(seq 1 2 100000); do echo $i; echo $(($i + 1)) >&2; done", | 
					
						
							|  |  |  |       ] } | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns without deadlocking" do | 
					
						
							| 
									
										
										
										
											2018-07-22 16:27:16 +02:00
										 |  |  |       wait(30).for { | 
					
						
							| 
									
										
										
										
											2017-07-29 19:55:05 +02:00
										 |  |  |         described_class.run(command, options) | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  |       }.to be_a_success | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |   context "when given an invalid variable name" do | 
					
						
							| 
									
										
										
										
											2018-06-01 23:26:12 +02:00
										 |  |  |     it "raises an ArgumentError" do | 
					
						
							|  |  |  |       expect { described_class.run("true", env: { "1ABC" => true }) } | 
					
						
							|  |  |  |         .to raise_error(ArgumentError, /variable name/) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-11 11:13:33 +02:00
										 |  |  |   it "looks for executables in a custom PATH" do | 
					
						
							| 
									
										
										
										
											2018-07-11 09:14:53 +02:00
										 |  |  |     mktmpdir do |path| | 
					
						
							|  |  |  |       (path/"tool").write <<~SH | 
					
						
							|  |  |  |         #!/bin/sh | 
					
						
							|  |  |  |         echo Hello, world! | 
					
						
							|  |  |  |       SH | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       FileUtils.chmod "+x", path/"tool" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(described_class.run("tool", env: { "PATH" => path }).stdout).to include "Hello, world!" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2018-07-24 00:09:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe "#run" do | 
					
						
							|  |  |  |     it "does not raise a `SystemCallError` when the executable does not exist" do | 
					
						
							|  |  |  |       expect { | 
					
						
							|  |  |  |         described_class.run("non_existent_executable") | 
					
						
							|  |  |  |       }.not_to raise_error | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it 'does not format `stderr` when it starts with \r' do | 
					
						
							|  |  |  |       expect { | 
					
						
							| 
									
										
										
										
											2018-09-02 16:15:09 +01:00
										 |  |  |         system_command \ | 
					
						
							|  |  |  |           "bash", | 
					
						
							|  |  |  |           args: [ | 
					
						
							|  |  |  |             "-c", | 
					
						
							|  |  |  |             'printf "\r%s" "###################                                                       27.6%" 1>&2', | 
					
						
							|  |  |  |           ] | 
					
						
							|  |  |  |       }.to output( \ | 
					
						
							|  |  |  |         "\r###################                                                       27.6%", | 
					
						
							|  |  |  |       ).to_stderr | 
					
						
							| 
									
										
										
										
											2018-07-30 10:11:00 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-08-29 19:23:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     context "when given an executable with spaces and no arguments" do | 
					
						
							|  |  |  |       let(:executable) { mktmpdir/"App Uninstaller" } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-20 09:07:56 +01:00
										 |  |  |       before do | 
					
						
							| 
									
										
										
										
											2018-08-29 19:23:30 +02:00
										 |  |  |         executable.write <<~SH | 
					
						
							|  |  |  |           #!/usr/bin/env bash | 
					
						
							|  |  |  |           true | 
					
						
							|  |  |  |         SH | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         FileUtils.chmod "+x", executable | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "does not interpret the executable as a shell line" do | 
					
						
							|  |  |  |         expect(system_command(executable)).to be_a_success | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-06-28 14:50:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     context "when given arguments with secrets" do | 
					
						
							|  |  |  |       it "does not leak the secrets" do | 
					
						
							|  |  |  |         redacted_msg = /#{Regexp.escape("username:******")}/ | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |         expect { | 
					
						
							| 
									
										
										
										
											2019-06-28 14:50:38 +08:00
										 |  |  |           described_class.run! "curl", | 
					
						
							|  |  |  |                                args:    %w[--user username:hunter2], | 
					
						
							|  |  |  |                                verbose: true, | 
					
						
							|  |  |  |                                secrets: %w[hunter2] | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |         }.to raise_error.with_message(redacted_msg).and output(redacted_msg).to_stderr | 
					
						
							| 
									
										
										
										
											2019-06-28 14:50:38 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-07-13 23:22:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "does not leak the secrets set by environment" do | 
					
						
							|  |  |  |         redacted_msg = /#{Regexp.escape("username:******")}/ | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |         expect { | 
					
						
							| 
									
										
										
										
											2019-10-13 10:03:26 +01:00
										 |  |  |           ENV["PASSWORD"] = "hunter2" | 
					
						
							|  |  |  |           described_class.run! "curl", | 
					
						
							|  |  |  |                                args:    %w[--user username:hunter2], | 
					
						
							|  |  |  |                                verbose: true | 
					
						
							| 
									
										
										
										
											2020-12-17 15:45:50 +01:00
										 |  |  |         }.to raise_error.with_message(redacted_msg).and output(redacted_msg).to_stderr | 
					
						
							| 
									
										
										
										
											2019-07-13 23:22:18 +08:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2019-06-28 14:50:38 +08:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2020-12-17 18:09:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     context "when a `SIGINT` handler is set in the parent process" do | 
					
						
							|  |  |  |       it "is not interrupted" do | 
					
						
							|  |  |  |         start_time = Time.now | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pid = fork do | 
					
						
							|  |  |  |           trap("INT") do | 
					
						
							|  |  |  |             # Ignore SIGINT. | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           described_class.run! "sleep", args: [5] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           exit! | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sleep 1
 | 
					
						
							|  |  |  |         Process.kill("INT", pid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Process.waitpid(pid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(Time.now - start_time).to be >= 5
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-07-24 00:09:11 +02:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-08-18 22:11:42 +03:00
										 |  |  | end |