# frozen_string_literal: false require 'test/unit' require 'shellwords' require 'tmpdir' begin require 'pty' rescue LoadError end class TestPTY < Test::Unit::TestCase RUBY = EnvUtil.rubybin def test_spawn_without_block r, w, pid = PTY.spawn(RUBY, '-e', 'puts "a"') rescue RuntimeError skip $! else assert_equal("a\r\n", r.gets) ensure r&.close w&.close Process.wait pid if pid end def test_spawn_with_block PTY.spawn(RUBY, '-e', 'puts "b"') {|r,w,pid| begin assert_equal("b\r\n", r.gets) ensure r.close w.close Process.wait(pid) end } rescue RuntimeError skip $! end def test_commandline commandline = Shellwords.join([RUBY, '-e', 'puts "foo"']) PTY.spawn(commandline) {|r,w,pid| begin assert_equal("foo\r\n", r.gets) ensure r.close w.close Process.wait(pid) end } rescue RuntimeError skip $! end def test_argv0 PTY.spawn([RUBY, "argv0"], '-e', 'puts "bar"') {|r,w,pid| begin assert_equal("bar\r\n", r.gets) ensure r.close w.close Process.wait(pid) end } rescue RuntimeError skip $! end def test_open_without_block ret = PTY.open rescue RuntimeError skip $! else assert_kind_of(Array, ret) assert_equal(2, ret.length) assert_equal(IO, ret[0].class) assert_equal(File, ret[1].class) _, slave = ret assert(slave.tty?) assert(File.chardev?(slave.path)) ensure if ret ret[0].close ret[1].close end end def test_open_with_block r = nil x = Object.new y = PTY.open {|ret| r = ret; assert_kind_of(Array, ret) assert_equal(2, ret.length) assert_equal(IO, ret[0].class) assert_equal(File, ret[1].class) _, slave = ret assert(slave.tty?) assert(File.chardev?(slave.path)) x } rescue RuntimeError skip $! else assert(r[0].closed?) assert(r[1].closed?) assert_equal(y, x) end def test_close_in_block PTY.open {|master, slave| slave.close master.close assert(slave.closed?) assert(master.closed?) } rescue RuntimeError skip $! else assert_nothing_raised { PTY.open {|master, slave| slave.close master.close } } end def test_open PTY.open {|master, slave| slave.puts "foo" assert_equal("foo", master.gets.chomp) master.puts "bar" assert_equal("bar", slave.gets.chomp) } rescue RuntimeError skip $! end def test_stat_slave PTY.open {|master, slave| s = File.stat(slave.path) assert_equal(Process.uid, s.uid) assert_equal(0600, s.mode & 0777) } rescue RuntimeError skip $! end def test_close_master PTY.open {|master, slave| master.close assert_raise(EOFError) { slave.readpartial(10) } } rescue RuntimeError skip $! end def test_close_slave PTY.open {|master, slave| slave.close # This exception is platform dependent. assert_raise( EOFError, # FreeBSD Errno::EIO # GNU/Linux ) { master.readpartial(10) } } rescue RuntimeError skip $! end def test_getpty_nonexistent bug3672 = '[ruby-dev:41965]' Dir.mktmpdir do |tmpdir| assert_raise(Errno::ENOENT, bug3672) { begin PTY.getpty(File.join(tmpdir, "no-such-command")) rescue RuntimeError skip $! end } end end def test_pty_check_default st1 = st2 = pid = nil `echo` # preset $? PTY.spawn("cat") do |r,w,id| pid = id st1 = PTY.check(pid) w.close r.close begin sleep(0.1) end until st2 = PTY.check(pid) end rescue RuntimeError skip $! else assert_nil(st1) assert_equal(pid, st2.pid) end def test_pty_check_raise bug2642 = '[ruby-dev:44600]' st1 = st2 = pid = nil PTY.spawn("cat") do |r,w,id| pid = id assert_nothing_raised(PTY::ChildExited, bug2642) {st1 = PTY.check(pid, true)} w.close r.close sleep(0.1) st2 = assert_raise(PTY::ChildExited, bug2642) {PTY.check(pid, true)}.status end rescue RuntimeError skip $! else assert_nil(st1) assert_equal(pid, st2.pid) end def test_cloexec PTY.open {|m, s| assert(m.close_on_exec?) assert(s.close_on_exec?) } PTY.spawn(RUBY, '-e', '') {|r, w, pid| begin assert(r.close_on_exec?) assert(w.close_on_exec?) ensure r.close w.close Process.wait(pid) end } rescue RuntimeError skip $! end end if defined? PTY uby/ruby/pull/11761 2024-07-18Refactor RUBY_DESCRIPTION assertions in test_rubyoptionsKevin Newton Notes: Merged: https://github.com/ruby/ruby/pull/11192 2023-12-15Introduce --parser runtime flagHParker Introduce runtime flag for specifying the parser, ``` ruby --parser=prism ``` also update the description: ``` $ ruby --parser=prism --version ruby 3.3.0dev (2023-12-08T04:47:14Z add-parser-runtime.. 0616384c9f) +PRISM [x86_64-darwin23] ``` [Bug #20044] 2023-10-19YJIT: Add RubyVM::YJIT.enable (#8705)Takashi Kokubun 2023-10-17"+MN" in descriptionKoichi Sasada If `RUBY_MN_THREADS=1` is given, this patch shows `+MN` in `RUBY_DESCRIPTION` like: ``` $ RUBY_MN_THREADS=1 ./miniruby --yjit -v ruby 3.3.0dev (2023-10-17T04:10:14Z master 908f8fffa2) +YJIT +MN [x86_64-linux] ``` Before this patch, a warning is displayed if `$VERBOSE` is given. However it can make troubles with tests (with `$VERBOSE`), do not show any warning with a MN threads configuration. 2023-10-16Build `rb_dynamic_description` at runtimeNobuyoshi Nakada To avoid creating literals for all combinations. 2023-08-20Move `MKSTR` markers for fake.rb into comentsNobuyoshi Nakada 2023-03-06s/mjit/rjit/Takashi Kokubun Notes: Merged: https://github.com/ruby/ruby/pull/7462 2023-03-06s/MJIT/RJIT/Takashi Kokubun Notes: Merged: https://github.com/ruby/ruby/pull/7462 2022-11-16YJIT: Show YJIT build option in RUBY_DESCRIPTION (#6738)Takashi Kokubun YJIT: Show YJIT profile in RUBY_DESCRIPTION Notes: Merged-By: k0kubun <takashikkbn@gmail.com> 2022-10-24YJIT: Lazily enable YJIT after prelude (#6597)Takashi Kokubun * YJIT: Lazily enable YJIT after prelude * Update dependencies * Use a bit field for opt->yjit Notes: Merged-By: maximecb <maximecb@ruby-lang.org> 2022-08-31Move macros from version.h to version.cNobuyoshi Nakada Moved the contents of `ruby_description` and `ruby_copyright` which are never used in the other places. 2022-06-20Include JIT information in crash reportsChris Seaton Since enabling YJIT or MJIT drastically changes what could go wrong at runtime, it's good to be front and center about whether they are enabled when dumping a crash report. Previously, `RUBY_DESCRIPTION` and the description printed when crashing can be different when a JIT is on. Introduce a new internal data global, `rb_dynamic_description`, and set it to be the same as `RUBY_DESCRIPTION` during initialization; use it when crashing. * version.c: Init_ruby_description(): Initialize and use `rb_dynamic_description`. * error.c: Change crash reports to use `rb_dynamic_description`. * ruby.c: Call `Init_ruby_description()` earlier. Slightly more work for when we exit right after printing the description but that was deemed acceptable. * include/ruby/version.h: Talk about how JIT info is not in `ruby_description`. * test/-ext-/bug_reporter/test_bug_reporter.rb: Remove handling for crash description being different from `RUBY_DESCRIPTION`. * test/ruby/test_rubyoptions.rb: ditto Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> Co-authored-by: Alan Wu <alanwu@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/5872 2021-12-13Rename --jit to --mjit (#5248)Takashi Kokubun * Rename --jit to --mjit [Feature #18349] * Fix a few more --jit references * Fix MJIT Actions * More s/jit/mjit/ and re-introduce --disable-jit * Update NEWS.md * Fix test_bug_reporter_add Notes: Merged-By: k0kubun <takashikkbn@gmail.com> 2021-10-20Show +YJIT in version string and RUBY_DESCRIPTIONAlan Wu There might be code out there that expect `ruby -v` to print only one line. Since MJIT shows +JIT in `ruby -v` and RUBY_DESCRIPTION, let's show +YJIT. The crash report doesn't show anything about MJIT, so adjust the test. The "test_ruby_version" test was unaware of RUBY_YJIT_ENABLE and so was failing when the variable is set and inherited into the children processes it spawns. Explicitly unset the variable in the test. 2021-10-20Yet Another Ruby JIT!Jose Narvaez Renaming uJIT to YJIT. AKA s/ujit/yjit/g. 2021-10-20Machinery to implement deferred compilationMaxime Chevalier-Boisvert 2021-10-20ujit.h instead in the rest of RubyAlan Wu ujit_iface.h is meant for uJIT internal use only. 2021-10-20Don't increment instr/exit counters if stats not requestedMaxime Chevalier-Boisvert 2021-10-20Fix ujit cc/cme invalidation code for opt_send_without_blockMaxime Chevalier-Boisvert 2021-10-20Refactor uJIT code into more files for readabilityMaxime Chevalier-Boisvert 2021-10-20Don't put MicroJIT status in RUBY_DESCRIPTIONAlan Wu That messes with tests too much. 2021-10-20Show whether MicroJIT is enabled in the version stringAlan Wu 2021-09-10include/ruby/internal/interpreter.h: add doxygen卜部昌平 Must not be a bad idea to improve documents. [ci skip] In fact many functions declared in the header file are already documented more or less. They were just copy & pasted, with applying some style updates. Notes: Merged: https://github.com/ruby/ruby/pull/4815