2017-01-19 00:28:16 +08:00
|
|
|
require 'test_helper'
|
|
|
|
|
|
|
|
class CompileCacheTest < Minitest::Test
|
|
|
|
include TmpdirHelper
|
|
|
|
|
2017-05-24 12:06:48 +08:00
|
|
|
def test_no_write_permission_to_cache
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
2017-06-04 10:20:11 +08:00
|
|
|
folder = File.dirname(Help.cache_path(@tmp_dir, path))
|
|
|
|
FileUtils.mkdir_p(folder)
|
|
|
|
FileUtils.chmod(0400, folder)
|
2017-05-24 12:06:48 +08:00
|
|
|
assert_raises(Errno::EACCES) { load(path) }
|
2017-01-19 00:28:16 +08:00
|
|
|
end
|
|
|
|
|
2017-06-04 10:20:11 +08:00
|
|
|
def test_can_open_read_only_cache
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
|
|
|
# Load once to create the cache file
|
|
|
|
load(path)
|
|
|
|
FileUtils.chmod(0400, path)
|
|
|
|
# Loading again after the file is marked read-only should still succeed
|
|
|
|
load(path)
|
|
|
|
end
|
|
|
|
|
2017-01-19 00:28:16 +08:00
|
|
|
def test_file_is_only_read_once
|
2017-05-24 12:06:48 +08:00
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
storage = RubyVM::InstructionSequence.compile_file(path).to_binary
|
|
|
|
output = RubyVM::InstructionSequence.load_from_binary(storage)
|
|
|
|
# This doesn't really *prove* the file is only read once, but
|
|
|
|
# it at least asserts the input is only cached once.
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:input_to_storage).times(1).returns(storage)
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:storage_to_output).times(2).returns(output)
|
|
|
|
load(path)
|
|
|
|
load(path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def test_raises_syntax_error
|
2017-05-24 12:06:48 +08:00
|
|
|
path = Help.set_file('a.rb', 'a = (3', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
assert_raises(SyntaxError) do
|
|
|
|
# SyntaxError emits directly to stderr in addition to raising, it seems.
|
2017-05-24 12:06:48 +08:00
|
|
|
capture_io { load(path) }
|
2017-01-19 00:28:16 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-05-24 12:06:48 +08:00
|
|
|
def test_no_recache_when_mtime_and_size_same
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
storage = RubyVM::InstructionSequence.compile_file(path).to_binary
|
|
|
|
output = RubyVM::InstructionSequence.load_from_binary(storage)
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:input_to_storage).times(1).returns(storage)
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:storage_to_output).times(2).returns(output)
|
|
|
|
|
|
|
|
load(path)
|
2017-05-24 12:06:48 +08:00
|
|
|
Help.set_file(path, 'a = 4', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
load(path)
|
|
|
|
end
|
|
|
|
|
2017-05-24 12:06:48 +08:00
|
|
|
def test_recache_when_mtime_different
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
storage = RubyVM::InstructionSequence.compile_file(path).to_binary
|
|
|
|
output = RubyVM::InstructionSequence.load_from_binary(storage)
|
|
|
|
# Totally lies the second time but that's not the point.
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:input_to_storage).times(2).returns(storage)
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:storage_to_output).times(2).returns(output)
|
|
|
|
|
|
|
|
load(path)
|
2017-05-24 12:06:48 +08:00
|
|
|
Help.set_file(path, 'a = 2', 101)
|
2017-01-19 00:28:16 +08:00
|
|
|
load(path)
|
|
|
|
end
|
|
|
|
|
2017-05-24 12:06:48 +08:00
|
|
|
def test_recache_when_size_different
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
storage = RubyVM::InstructionSequence.compile_file(path).to_binary
|
|
|
|
output = RubyVM::InstructionSequence.load_from_binary(storage)
|
2017-05-24 12:06:48 +08:00
|
|
|
# Totally lies the second time but that's not the point.
|
2017-01-19 00:28:16 +08:00
|
|
|
Bootsnap::CompileCache::ISeq.expects(:input_to_storage).times(2).returns(storage)
|
|
|
|
Bootsnap::CompileCache::ISeq.expects(:storage_to_output).times(2).returns(output)
|
2017-05-24 12:06:48 +08:00
|
|
|
|
2017-01-19 00:28:16 +08:00
|
|
|
load(path)
|
2017-05-24 12:06:48 +08:00
|
|
|
Help.set_file(path, 'a = 33', 100)
|
2017-01-19 00:28:16 +08:00
|
|
|
load(path)
|
|
|
|
end
|
|
|
|
|
2017-05-24 12:06:48 +08:00
|
|
|
def test_invalid_cache_file
|
|
|
|
path = Help.set_file('a.rb', 'a = 3', 100)
|
|
|
|
cp = Help.cache_path(@tmp_dir, path)
|
|
|
|
FileUtils.mkdir_p(File.dirname(cp))
|
|
|
|
File.write(cp, 'nope')
|
|
|
|
load(path)
|
|
|
|
assert(File.size(cp) > 32) # cache was overwritten
|
2017-01-19 00:28:16 +08:00
|
|
|
end
|
|
|
|
end
|