rails/railties/test/application/console_test.rb
Prem Sichanugrist b27105252b Add config.disable_sandbox option to Rails console
A long-running `rails console --sandbox` could cause a database server
to become out-of-memory as it's holding on to changes that happen on the
database.

Given that it's common for Ruby on Rails application with huge
traffic to have separate write database and read database, we should
allow the developers to disable this sandbox option to prevent someone
from accidentally causing the Denial-of-Service on their server.
2019-03-23 19:31:03 +09:00

174 lines
4.0 KiB
Ruby

# frozen_string_literal: true
require "isolation/abstract_unit"
require "console_helpers"
class ConsoleTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
def setup
build_app
end
def teardown
teardown_app
end
def load_environment(sandbox = false)
require "#{rails_root}/config/environment"
Rails.application.sandbox = sandbox
Rails.application.load_console
end
def irb_context
Object.new.extend(Rails::ConsoleMethods)
end
def test_app_method_should_return_integration_session
TestHelpers::Rack.remove_method :app
load_environment
console_session = irb_context.app
assert_instance_of ActionDispatch::Integration::Session, console_session
end
def test_app_can_access_path_helper_method
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get 'foo', to: 'foo#index'
end
RUBY
load_environment
console_session = irb_context.app
assert_equal "/foo", console_session.foo_path
end
def test_new_session_should_return_integration_session
load_environment
session = irb_context.new_session
assert_instance_of ActionDispatch::Integration::Session, session
end
def test_reload_should_fire_preparation_and_cleanup_callbacks
load_environment
a = b = c = nil
# TODO: These should be defined on the initializer
ActiveSupport::Reloader.to_complete { a = b = c = 1 }
ActiveSupport::Reloader.to_complete { b = c = 2 }
ActiveSupport::Reloader.to_prepare { c = 3 }
irb_context.reload!(false)
assert_equal 1, a
assert_equal 2, b
assert_equal 3, c
end
def test_reload_should_reload_constants
app_file "app/models/user.rb", <<-MODEL
class User
attr_accessor :name
end
MODEL
load_environment
assert_respond_to User.new, :name
app_file "app/models/user.rb", <<-MODEL
class User
attr_accessor :name, :age
end
MODEL
assert_not_respond_to User.new, :age
irb_context.reload!(false)
assert_respond_to User.new, :age
end
def test_access_to_helpers
load_environment
helper = irb_context.helper
assert_not_nil helper
assert_instance_of ActionView::Base, helper
assert_equal "Once upon a time in a world...",
helper.truncate("Once upon a time in a world far far away")
end
end
class FullStackConsoleTest < ActiveSupport::TestCase
include ConsoleHelpers
def setup
skip "PTY unavailable" unless available_pty?
build_app
app_file "app/models/post.rb", <<-CODE
class Post < ActiveRecord::Base
end
CODE
system "#{app_path}/bin/rails runner 'Post.connection.create_table :posts'"
@primary, @replica = PTY.open
end
def teardown
teardown_app
end
def write_prompt(command, expected_output = nil)
@primary.puts command
assert_output command, @primary
assert_output expected_output, @primary if expected_output
assert_output "> ", @primary
end
def spawn_console(options, wait_for_prompt: true)
pid = Process.spawn(
"#{app_path}/bin/rails console #{options}",
in: @replica, out: @replica, err: @replica
)
if wait_for_prompt
assert_output "> ", @primary, 30
end
pid
end
def test_sandbox
spawn_console("--sandbox")
write_prompt "Post.count", "=> 0"
write_prompt "Post.create"
write_prompt "Post.count", "=> 1"
@primary.puts "quit"
spawn_console("--sandbox")
write_prompt "Post.count", "=> 0"
write_prompt "Post.transaction { Post.create; raise }"
write_prompt "Post.count", "=> 0"
@primary.puts "quit"
end
def test_sandbox_when_sandbox_is_disabled
add_to_config <<-RUBY
config.disable_sandbox = true
RUBY
output = `#{app_path}/bin/rails console --sandbox`
assert_includes output, "sandbox mode is disabled"
assert_equal 1, $?.exitstatus
end
def test_environment_option_and_irb_option
spawn_console("-e test -- --verbose")
write_prompt "a = 1", "a = 1"
write_prompt "puts Rails.env", "puts Rails.env\r\ntest"
@primary.puts "quit"
end
end