1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
# frozen_string_literal: true
require "test_helper"
require "tmpdir"
require "fileutils"
module Bootsnap
module LoadPathCache
class StoreTest < Minitest::Test
include LoadPathCacheHelper
def setup
super
@dir = Dir.mktmpdir
@path = "#{@dir}/store"
@store = Store.new(@path)
end
def teardown
FileUtils.rm_rf(@dir)
end
attr_reader(:store)
def test_persistence
store.transaction { store.set("a", "b") }
store2 = Store.new(@path)
assert_equal("b", store2.get("a"))
end
def test_modification
store.transaction { store.set("a", "b") }
store2 = Store.new(@path)
assert_equal("b", store2.get("a"))
store.transaction { store.set("a", "c") }
store3 = Store.new(@path)
assert_equal("c", store3.get("a"))
end
def test_modification_of_loaded_store
store.transaction { store.set("a", "b") }
store = Store.new(@path)
store.transaction { store.set("c", "d") }
end
def test_stores_arrays
store.transaction { store.set("a", [1234, %w(a b)]) }
store2 = Store.new(@path)
assert_equal([1234, %w(a b)], store2.get("a"))
end
def test_transaction_required_to_set
assert_raises(Store::SetOutsideTransactionNotAllowed) do
store.set("a", "b")
end
assert_raises(Store::SetOutsideTransactionNotAllowed) do
store.fetch("a") { 1 + 1 }
end
end
def test_nested_transaction_fails
assert_raises(Store::NestedTransactionError) do
store.transaction { store.transaction }
end
end
def test_no_commit_unless_dirty
store.transaction { store.set("a", nil) }
refute(File.exist?(@path))
store.transaction { store.set("a", 1) }
assert(File.exist?(@path))
end
def test_retry_on_collision
retries = sequence("retries")
MessagePack.expects(:dump).in_sequence(retries).raises(Errno::EEXIST.new("File exists @ rb_sysopen"))
MessagePack.expects(:dump).in_sequence(retries).returns(1)
File.expects(:rename).in_sequence(retries)
store.transaction { store.set("a", 1) }
end
def test_with_broken_symlink
FileUtils.ln_s(@path, "#{@dir}/store_broken")
store = Store.new("#{@dir}/store_broken/store")
store.transaction { store.set("a", "b") }
end
def test_ignore_read_only_filesystem
MessagePack.expects(:dump).raises(Errno::EROFS.new("Read-only file system @ rb_sysopen"))
store.transaction { store.set("a", 1) }
refute(File.exist?(@path))
end
def test_bust_cache_on_ruby_change
store.transaction { store.set("a", "b") }
assert_equal "b", Store.new(@path).get("a")
stub_const(Store, :CURRENT_VERSION, "foobar") do
assert_nil Store.new(@path).get("a")
end
end
private
def stub_const(owner, const_name, stub_value)
original_value = owner.const_get(const_name)
owner.send(:remove_const, const_name)
owner.const_set(const_name, stub_value)
begin
yield
ensure
owner.send(:remove_const, const_name)
owner.const_set(const_name, original_value)
end
end
end
end
end
|