Files
danbooru/test/unit/storage_manager_test.rb
evazion e935f01358 uploads: fix temp files not being cleaned up quickly enough.
Fix temp files generated during the upload process not being cleaned up quickly enough. This included
downloaded files, generated preview images, and Ugoira video conversions.

Before we relied on `Tempfile` cleaning up files automatically. But this only happened when the
Tempfile object was garbage collected, which could take a long time. In the meantime we could have
hundreds of megabytes of temp files hanging around.

The fix is to explicitly close temp files when we're done with them. But the standard `Tempfile`
class doesn't immediately delete the file when it's closed. So we also have to introduce a
Danbooru::Tempfile wrapper that deletes the tempfile as soon as it's closed.
2022-11-15 18:50:50 -06:00

89 lines
2.5 KiB
Ruby

require 'test_helper'
class StorageManagerTest < ActiveSupport::TestCase
def tempfile(data)
file = Danbooru::Tempfile.new
file.write(data)
file.flush
file
end
context "StorageManager::Local" do
setup do
@storage_manager = StorageManager::Local.new(base_dir: @temp_dir, base_url: "/data")
end
context "#store method" do
should "store the file" do
@storage_manager.store(tempfile("data"), "test.txt")
assert_equal("data", File.read("#{@temp_dir}/test.txt"))
end
should "overwrite the file if it already exists" do
@storage_manager.store(tempfile("foo"), "test.txt")
@storage_manager.store(tempfile("bar"), "test.txt")
assert_equal("bar", File.read("#{@temp_dir}/test.txt"))
end
end
context "#delete method" do
should "delete the file" do
@storage_manager.store(tempfile("data"), "test.txt")
@storage_manager.delete("test.txt")
assert_not(File.exist?("#{@temp_dir}/test.txt"))
end
should "not fail if the file doesn't exist" do
assert_nothing_raised { @storage_manager.delete("dne.txt") }
end
end
end
context "StorageManager::Mirror" do
setup do
@temp_dir1 = Dir.mktmpdir("danbooru-temp1-")
@temp_dir2 = Dir.mktmpdir("danbooru-temp2-")
@storage_manager = StorageManager::Mirror.new([
StorageManager::Local.new(base_dir: @temp_dir1, base_url: "/data"),
StorageManager::Local.new(base_dir: @temp_dir2, base_url: "/data")
])
end
teardown do
FileUtils.rm_rf(@temp_dir1)
FileUtils.rm_rf(@temp_dir2)
end
context "#store method" do
should "store the file on both backends" do
@storage_manager.store(tempfile("data"), "test.txt")
assert_equal("data", File.read("#{@temp_dir1}/test.txt"))
assert_equal("data", File.read("#{@temp_dir2}/test.txt"))
end
end
context "#delete method" do
should "delete the file from both backends" do
@storage_manager.store(tempfile("data"), "test.txt")
@storage_manager.delete("test.txt")
assert_not(File.exist?("#{@temp_dir1}/test.txt"))
assert_not(File.exist?("#{@temp_dir2}/test.txt"))
end
end
context "#open method" do
should "open the file from the first backend" do
@storage_manager.store(tempfile("data"), "test.txt")
assert_equal("data", @storage_manager.open("test.txt").read)
end
end
end
end