mirror of
https://github.com/discourse/discourse.git
synced 2025-02-22 08:00:53 +08:00
DEV: Isolate multisite specs (#13634)
Mixing multisite and standard specs can lead to issues (e.g. when using `fab!`) Disabled the (upcoming https://github.com/discourse/rubocop-discourse/pull/11) rubocop rule for two files that have thoroughly tangled both types of specs.
This commit is contained in:
parent
14a13dc192
commit
48b92d8897
29
spec/components/s3_inventory_multisite_spec.rb
Normal file
29
spec/components/s3_inventory_multisite_spec.rb
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require "s3_helper"
|
||||||
|
require "s3_inventory"
|
||||||
|
require "file_store/s3_store"
|
||||||
|
|
||||||
|
describe "S3Inventory", type: :multisite do
|
||||||
|
let(:client) { Aws::S3::Client.new(stub_responses: true) }
|
||||||
|
let(:helper) { S3Helper.new(SiteSetting.Upload.s3_upload_bucket.downcase, "", client: client) }
|
||||||
|
let(:inventory) { S3Inventory.new(helper, :upload) }
|
||||||
|
let(:csv_filename) { "#{Rails.root}/spec/fixtures/csv/s3_inventory.csv" }
|
||||||
|
|
||||||
|
it "can create per-site files" do
|
||||||
|
freeze_time
|
||||||
|
setup_s3
|
||||||
|
SiteSetting.enable_s3_inventory = true
|
||||||
|
inventory.stubs(:files).returns([{ key: "Key", filename: "#{csv_filename}.gz" }])
|
||||||
|
inventory.stubs(:cleanup!)
|
||||||
|
|
||||||
|
files = inventory.prepare_for_all_sites
|
||||||
|
db1 = files["default"].read
|
||||||
|
db2 = files["second"].read
|
||||||
|
|
||||||
|
expect(db1.lines.count).to eq(3)
|
||||||
|
expect(db2.lines.count).to eq(1)
|
||||||
|
files.values.each { |f| f.close; f.unlink }
|
||||||
|
end
|
||||||
|
end
|
@ -175,19 +175,6 @@ describe "S3Inventory" do
|
|||||||
expect(Discourse.stats.get("missing_s3_uploads")).to eq(2)
|
expect(Discourse.stats.get("missing_s3_uploads")).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can create per-site files", type: :multisite do
|
|
||||||
freeze_time
|
|
||||||
|
|
||||||
inventory.stubs(:files).returns([{ key: "Key", filename: "#{csv_filename}.gz" }])
|
|
||||||
|
|
||||||
files = inventory.prepare_for_all_sites
|
|
||||||
db1 = files["default"].read
|
|
||||||
db2 = files["second"].read
|
|
||||||
expect(db1.lines.count).to eq(3)
|
|
||||||
expect(db2.lines.count).to eq(1)
|
|
||||||
files.values.each { |f| f.close; f.unlink }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "s3 inventory configuration" do
|
context "s3 inventory configuration" do
|
||||||
let(:bucket_name) { "s3-upload-bucket" }
|
let(:bucket_name) { "s3-upload-bucket" }
|
||||||
let(:subfolder_path) { "subfolder" }
|
let(:subfolder_path) { "subfolder" }
|
||||||
|
30
spec/components/site_setting_extension_multisite_spec.rb
Normal file
30
spec/components/site_setting_extension_multisite_spec.rb
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe SiteSettingExtension, type: :multisite do
|
||||||
|
before do
|
||||||
|
MessageBus.off
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
MessageBus.on
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:provider_local) do
|
||||||
|
SiteSettings::LocalProcessProvider.new
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:settings) do
|
||||||
|
new_settings(provider_local)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has no db cross talk" do
|
||||||
|
settings.setting(:hello, 1)
|
||||||
|
settings.hello = 100
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
expect(settings.hello).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -162,17 +162,6 @@ describe SiteSettingExtension do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "multisite" do
|
|
||||||
it "has no db cross talk", type: :multisite do
|
|
||||||
settings.setting(:hello, 1)
|
|
||||||
settings.hello = 100
|
|
||||||
|
|
||||||
test_multisite_connection("second") do
|
|
||||||
expect(settings.hello).to eq(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "DiscourseEvent" do
|
describe "DiscourseEvent" do
|
||||||
before do
|
before do
|
||||||
settings.setting(:test_setting, 1)
|
settings.setting(:test_setting, 1)
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe SiteSettings::LocalProcessProvider, type: :multisite do
|
||||||
|
def expect_same_setting(actual, expected)
|
||||||
|
expect(actual.name).to eq(expected.name)
|
||||||
|
expect(actual.value).to eq(expected.value)
|
||||||
|
expect(actual.data_type).to eq(expected.data_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:provider) { described_class.new }
|
||||||
|
|
||||||
|
def setting(name, value, data_type)
|
||||||
|
described_class::Setting.new(name, data_type).tap { |s| s.value = value }
|
||||||
|
end
|
||||||
|
|
||||||
|
it "loads the correct settings" do
|
||||||
|
test_multisite_connection("default") { provider.save("test", "bla-default", 2) }
|
||||||
|
test_multisite_connection("second") { provider.save("test", "bla-second", 2) }
|
||||||
|
|
||||||
|
test_multisite_connection("default") do
|
||||||
|
expect_same_setting(provider.find("test"), setting("test", "bla-default", 2))
|
||||||
|
end
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
expect_same_setting(provider.find("test"), setting("test", "bla-second", 2))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the correct site name" do
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
expect(provider.current_site).to eq("second")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -61,25 +61,4 @@ describe SiteSettings::LocalProcessProvider do
|
|||||||
it "returns the correct site name" do
|
it "returns the correct site name" do
|
||||||
expect(provider.current_site).to eq("default")
|
expect(provider.current_site).to eq("default")
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "multisite", type: :multisite do
|
|
||||||
it "loads the correct settings" do
|
|
||||||
test_multisite_connection("default") { provider.save("test", "bla-default", 2) }
|
|
||||||
test_multisite_connection("second") { provider.save("test", "bla-second", 2) }
|
|
||||||
|
|
||||||
test_multisite_connection("default") do
|
|
||||||
expect_same_setting(provider.find("test"), setting("test", "bla-default", 2))
|
|
||||||
end
|
|
||||||
|
|
||||||
test_multisite_connection("second") do
|
|
||||||
expect_same_setting(provider.find("test"), setting("test", "bla-second", 2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns the correct site name" do
|
|
||||||
test_multisite_connection("second") do
|
|
||||||
expect(provider.current_site).to eq("second")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -49,7 +49,6 @@ describe 'multisite', type: :multisite do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should hit correct site elsewise" do
|
it "should hit correct site elsewise" do
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"HTTP_HOST" => "test2.localhost",
|
"HTTP_HOST" => "test2.localhost",
|
||||||
"REQUEST_METHOD" => "GET",
|
"REQUEST_METHOD" => "GET",
|
||||||
@ -61,5 +60,4 @@ describe 'multisite', type: :multisite do
|
|||||||
expect(code).to eq(200)
|
expect(code).to eq(200)
|
||||||
expect(body.join).to eq("test2.localhost")
|
expect(body.join).to eq("test2.localhost")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
|
describe BackupRestore::BackupFileHandler, type: :multisite do
|
||||||
|
include_context "shared stuff"
|
||||||
|
|
||||||
|
it "works with old backup file format" do
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
expect_decompress_and_clean_up_to_work(
|
||||||
|
backup_filename: "backup_till_v1.5.tar.gz",
|
||||||
|
require_metadata_file: true,
|
||||||
|
require_uploads: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -6,68 +6,6 @@ require_relative 'shared_context_for_backup_restore'
|
|||||||
describe BackupRestore::BackupFileHandler do
|
describe BackupRestore::BackupFileHandler do
|
||||||
include_context "shared stuff"
|
include_context "shared stuff"
|
||||||
|
|
||||||
def expect_decompress_and_clean_up_to_work(backup_filename:, expected_dump_filename: "dump.sql",
|
|
||||||
require_metadata_file:, require_uploads:, expected_upload_paths: nil,
|
|
||||||
location: nil)
|
|
||||||
|
|
||||||
freeze_time(DateTime.parse('2019-12-24 14:31:48'))
|
|
||||||
|
|
||||||
source_file = File.join(Rails.root, "spec/fixtures/backups", backup_filename)
|
|
||||||
target_directory = BackupRestore::LocalBackupStore.base_directory
|
|
||||||
target_file = File.join(target_directory, backup_filename)
|
|
||||||
FileUtils.copy_file(source_file, target_file)
|
|
||||||
|
|
||||||
Dir.mktmpdir do |root_directory|
|
|
||||||
current_db = RailsMultisite::ConnectionManagement.current_db
|
|
||||||
file_handler = BackupRestore::BackupFileHandler.new(
|
|
||||||
logger, backup_filename, current_db,
|
|
||||||
root_tmp_directory: root_directory,
|
|
||||||
location: location
|
|
||||||
)
|
|
||||||
tmp_directory, db_dump_path = file_handler.decompress
|
|
||||||
|
|
||||||
expected_tmp_path = File.join(root_directory, "tmp/restores", current_db, "2019-12-24-143148")
|
|
||||||
expect(tmp_directory).to eq(expected_tmp_path)
|
|
||||||
expect(db_dump_path).to eq(File.join(expected_tmp_path, expected_dump_filename))
|
|
||||||
|
|
||||||
expect(Dir.exist?(tmp_directory)).to eq(true)
|
|
||||||
expect(File.exist?(db_dump_path)).to eq(true)
|
|
||||||
|
|
||||||
expect(File.exist?(File.join(tmp_directory, "meta.json"))).to eq(require_metadata_file)
|
|
||||||
|
|
||||||
if require_uploads
|
|
||||||
expected_upload_paths ||= ["uploads/default/original/3X/b/d/bd269860bb508aebcb6f08fe7289d5f117830383.png"]
|
|
||||||
|
|
||||||
expected_upload_paths.each do |upload_path|
|
|
||||||
absolute_upload_path = File.join(tmp_directory, upload_path)
|
|
||||||
expect(File.exist?(absolute_upload_path)).to eq(true), "expected file #{upload_path} does not exist"
|
|
||||||
yield(absolute_upload_path) if block_given?
|
|
||||||
end
|
|
||||||
else
|
|
||||||
expect(Dir.exist?(File.join(tmp_directory, "uploads"))).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
file_handler.clean_up
|
|
||||||
expect(Dir.exist?(tmp_directory)).to eq(false)
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
FileUtils.rm(target_file)
|
|
||||||
|
|
||||||
# We don't want to delete the directory unless it is empty, otherwise this could be annoying
|
|
||||||
# when tests run for the "default" database in a development environment.
|
|
||||||
FileUtils.rmdir(target_directory) rescue nil
|
|
||||||
end
|
|
||||||
|
|
||||||
it "works with old backup file format", type: :multisite do
|
|
||||||
test_multisite_connection("second") do
|
|
||||||
expect_decompress_and_clean_up_to_work(
|
|
||||||
backup_filename: "backup_till_v1.5.tar.gz",
|
|
||||||
require_metadata_file: true,
|
|
||||||
require_uploads: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "works with current backup file format" do
|
it "works with current backup file format" do
|
||||||
expect_decompress_and_clean_up_to_work(
|
expect_decompress_and_clean_up_to_work(
|
||||||
backup_filename: "backup_since_v1.6.tar.gz",
|
backup_filename: "backup_since_v1.6.tar.gz",
|
||||||
|
22
spec/lib/backup_restore/database_restorer_multisite_spec.rb
Normal file
22
spec/lib/backup_restore/database_restorer_multisite_spec.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
|
describe BackupRestore::DatabaseRestorer, type: :multisite do
|
||||||
|
include_context "shared stuff"
|
||||||
|
|
||||||
|
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
||||||
|
|
||||||
|
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
||||||
|
|
||||||
|
describe "#restore" do
|
||||||
|
context "database connection" do
|
||||||
|
it "reconnects to the correct database" do
|
||||||
|
RailsMultisite::ConnectionManagement.establish_connection(db: "second")
|
||||||
|
execute_stubbed_restore
|
||||||
|
expect(RailsMultisite::ConnectionManagement.current_db).to eq("second")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -7,56 +7,9 @@ describe BackupRestore::DatabaseRestorer do
|
|||||||
include_context "shared stuff"
|
include_context "shared stuff"
|
||||||
|
|
||||||
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
let(:current_db) { RailsMultisite::ConnectionManagement.current_db }
|
||||||
|
|
||||||
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
subject { BackupRestore::DatabaseRestorer.new(logger, current_db) }
|
||||||
|
|
||||||
def expect_create_readonly_functions
|
|
||||||
Migration::BaseDropper.expects(:create_readonly_function).at_least_once
|
|
||||||
end
|
|
||||||
|
|
||||||
def expect_table_move
|
|
||||||
BackupRestore.expects(:move_tables_between_schemas).with("public", "backup").once
|
|
||||||
end
|
|
||||||
|
|
||||||
def expect_psql(output_lines: ["output from psql"], exit_status: 0, stub_thread: false)
|
|
||||||
status = mock("psql status")
|
|
||||||
status.expects(:exitstatus).returns(exit_status).once
|
|
||||||
Process.expects(:last_status).returns(status).once
|
|
||||||
|
|
||||||
if stub_thread
|
|
||||||
thread = mock("thread")
|
|
||||||
thread.stubs(:join)
|
|
||||||
Thread.stubs(:new).returns(thread)
|
|
||||||
end
|
|
||||||
|
|
||||||
output_lines << nil
|
|
||||||
psql_io = mock("psql")
|
|
||||||
psql_io.expects(:readline).returns(*output_lines).times(output_lines.size)
|
|
||||||
IO.expects(:popen).yields(psql_io).once
|
|
||||||
end
|
|
||||||
|
|
||||||
def expect_db_migrate
|
|
||||||
Discourse::Utils.expects(:execute_command).with do |env, *command, **options|
|
|
||||||
env["SKIP_POST_DEPLOYMENT_MIGRATIONS"] == "0" &&
|
|
||||||
env["SKIP_OPTIMIZE_ICONS"] == "1" &&
|
|
||||||
env["DISABLE_TRANSLATION_OVERRIDES"] == "1" &&
|
|
||||||
command == ["rake", "db:migrate"] &&
|
|
||||||
options[:chdir] == Rails.root
|
|
||||||
end.once
|
|
||||||
end
|
|
||||||
|
|
||||||
def expect_db_reconnect
|
|
||||||
RailsMultisite::ConnectionManagement.expects(:establish_connection).once
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute_stubbed_restore(stub_readonly_functions: true, stub_psql: true, stub_migrate: true,
|
|
||||||
dump_file_path: "foo.sql")
|
|
||||||
expect_table_move
|
|
||||||
expect_create_readonly_functions if stub_readonly_functions
|
|
||||||
expect_psql if stub_psql
|
|
||||||
expect_db_migrate if stub_migrate
|
|
||||||
subject.restore(dump_file_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#restore" do
|
describe "#restore" do
|
||||||
it "executes everything in the correct order" do
|
it "executes everything in the correct order" do
|
||||||
restore = sequence("restore")
|
restore = sequence("restore")
|
||||||
@ -173,12 +126,6 @@ describe BackupRestore::DatabaseRestorer do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "database connection" do
|
context "database connection" do
|
||||||
it 'reconnects to the correct database', type: :multisite do
|
|
||||||
RailsMultisite::ConnectionManagement.establish_connection(db: 'second')
|
|
||||||
execute_stubbed_restore
|
|
||||||
expect(RailsMultisite::ConnectionManagement.current_db).to eq('second')
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'it is not erroring for non-multisite' do
|
it 'it is not erroring for non-multisite' do
|
||||||
expect { execute_stubbed_restore }.not_to raise_error
|
expect { execute_stubbed_restore }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
@ -1,9 +1,117 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
#
|
|
||||||
shared_context "shared stuff" do
|
shared_context "shared stuff" do
|
||||||
let!(:logger) do
|
let!(:logger) do
|
||||||
Class.new do
|
Class.new do
|
||||||
def log(message, ex = nil); end
|
def log(message, ex = nil); end
|
||||||
end.new
|
end.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expect_create_readonly_functions
|
||||||
|
Migration::BaseDropper.expects(:create_readonly_function).at_least_once
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_table_move
|
||||||
|
BackupRestore.expects(:move_tables_between_schemas).with("public", "backup").once
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_psql(output_lines: ["output from psql"], exit_status: 0, stub_thread: false)
|
||||||
|
status = mock("psql status")
|
||||||
|
status.expects(:exitstatus).returns(exit_status).once
|
||||||
|
Process.expects(:last_status).returns(status).once
|
||||||
|
|
||||||
|
if stub_thread
|
||||||
|
thread = mock("thread")
|
||||||
|
thread.stubs(:join)
|
||||||
|
Thread.stubs(:new).returns(thread)
|
||||||
|
end
|
||||||
|
|
||||||
|
output_lines << nil
|
||||||
|
psql_io = mock("psql")
|
||||||
|
psql_io.expects(:readline).returns(*output_lines).times(output_lines.size)
|
||||||
|
IO.expects(:popen).yields(psql_io).once
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_db_migrate
|
||||||
|
Discourse::Utils.expects(:execute_command).with do |env, *command, **options|
|
||||||
|
env["SKIP_POST_DEPLOYMENT_MIGRATIONS"] == "0" &&
|
||||||
|
env["SKIP_OPTIMIZE_ICONS"] == "1" &&
|
||||||
|
env["DISABLE_TRANSLATION_OVERRIDES"] == "1" &&
|
||||||
|
command == ["rake", "db:migrate"] &&
|
||||||
|
options[:chdir] == Rails.root
|
||||||
|
end.once
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_db_reconnect
|
||||||
|
RailsMultisite::ConnectionManagement.expects(:establish_connection).once
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_stubbed_restore(
|
||||||
|
stub_readonly_functions: true,
|
||||||
|
stub_psql: true,
|
||||||
|
stub_migrate: true,
|
||||||
|
dump_file_path: "foo.sql"
|
||||||
|
)
|
||||||
|
expect_table_move
|
||||||
|
expect_create_readonly_functions if stub_readonly_functions
|
||||||
|
expect_psql if stub_psql
|
||||||
|
expect_db_migrate if stub_migrate
|
||||||
|
subject.restore(dump_file_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_decompress_and_clean_up_to_work(
|
||||||
|
backup_filename:,
|
||||||
|
expected_dump_filename: "dump.sql",
|
||||||
|
require_metadata_file:,
|
||||||
|
require_uploads:,
|
||||||
|
expected_upload_paths: nil,
|
||||||
|
location: nil
|
||||||
|
)
|
||||||
|
freeze_time(DateTime.parse("2019-12-24 14:31:48"))
|
||||||
|
|
||||||
|
source_file = File.join(Rails.root, "spec/fixtures/backups", backup_filename)
|
||||||
|
target_directory = BackupRestore::LocalBackupStore.base_directory
|
||||||
|
target_file = File.join(target_directory, backup_filename)
|
||||||
|
FileUtils.copy_file(source_file, target_file)
|
||||||
|
|
||||||
|
Dir.mktmpdir do |root_directory|
|
||||||
|
current_db = RailsMultisite::ConnectionManagement.current_db
|
||||||
|
file_handler = BackupRestore::BackupFileHandler.new(
|
||||||
|
logger, backup_filename, current_db,
|
||||||
|
root_tmp_directory: root_directory,
|
||||||
|
location: location
|
||||||
|
)
|
||||||
|
tmp_directory, db_dump_path = file_handler.decompress
|
||||||
|
|
||||||
|
expected_tmp_path = File.join(root_directory, "tmp/restores", current_db, "2019-12-24-143148")
|
||||||
|
expect(tmp_directory).to eq(expected_tmp_path)
|
||||||
|
expect(db_dump_path).to eq(File.join(expected_tmp_path, expected_dump_filename))
|
||||||
|
|
||||||
|
expect(Dir.exist?(tmp_directory)).to eq(true)
|
||||||
|
expect(File.exist?(db_dump_path)).to eq(true)
|
||||||
|
|
||||||
|
expect(File.exist?(File.join(tmp_directory, "meta.json"))).to eq(require_metadata_file)
|
||||||
|
|
||||||
|
if require_uploads
|
||||||
|
expected_upload_paths ||= ["uploads/default/original/3X/b/d/bd269860bb508aebcb6f08fe7289d5f117830383.png"]
|
||||||
|
|
||||||
|
expected_upload_paths.each do |upload_path|
|
||||||
|
absolute_upload_path = File.join(tmp_directory, upload_path)
|
||||||
|
expect(File.exist?(absolute_upload_path)).to eq(true), "expected file #{upload_path} does not exist"
|
||||||
|
yield(absolute_upload_path) if block_given?
|
||||||
|
end
|
||||||
|
else
|
||||||
|
expect(Dir.exist?(File.join(tmp_directory, "uploads"))).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
file_handler.clean_up
|
||||||
|
expect(Dir.exist?(tmp_directory)).to eq(false)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
FileUtils.rm(target_file)
|
||||||
|
|
||||||
|
# We don't want to delete the directory unless it is empty, otherwise this could be annoying
|
||||||
|
# when tests run for the "default" database in a development environment.
|
||||||
|
FileUtils.rmdir(target_directory) rescue nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
# rubocop:disable Discourse/OnlyTopLevelMultisiteSpecs
|
||||||
|
|
||||||
shared_context "backups" do
|
shared_context "backups" do
|
||||||
before { create_backups }
|
before { create_backups }
|
||||||
|
40
spec/lib/backup_restore/system_interface_multisite_spec.rb
Normal file
40
spec/lib/backup_restore/system_interface_multisite_spec.rb
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require_relative "shared_context_for_backup_restore"
|
||||||
|
|
||||||
|
describe BackupRestore::SystemInterface, type: :multisite do
|
||||||
|
include_context "shared stuff"
|
||||||
|
|
||||||
|
subject { BackupRestore::SystemInterface.new(logger) }
|
||||||
|
|
||||||
|
describe "#flush_redis" do
|
||||||
|
it "removes only keys from the current site in a multisite" do
|
||||||
|
test_multisite_connection("default") do
|
||||||
|
Discourse.redis.set("foo", "default-foo")
|
||||||
|
Discourse.redis.set("bar", "default-bar")
|
||||||
|
|
||||||
|
expect(Discourse.redis.get("foo")).to eq("default-foo")
|
||||||
|
expect(Discourse.redis.get("bar")).to eq("default-bar")
|
||||||
|
end
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
Discourse.redis.set("foo", "second-foo")
|
||||||
|
Discourse.redis.set("bar", "second-bar")
|
||||||
|
|
||||||
|
expect(Discourse.redis.get("foo")).to eq("second-foo")
|
||||||
|
expect(Discourse.redis.get("bar")).to eq("second-bar")
|
||||||
|
|
||||||
|
subject.flush_redis
|
||||||
|
|
||||||
|
expect(Discourse.redis.get("foo")).to be_nil
|
||||||
|
expect(Discourse.redis.get("bar")).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
test_multisite_connection("default") do
|
||||||
|
expect(Discourse.redis.get("foo")).to eq("default-foo")
|
||||||
|
expect(Discourse.redis.get("bar")).to eq("default-bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -168,45 +168,17 @@ describe BackupRestore::SystemInterface do
|
|||||||
subject.wait_for_sidekiq
|
subject.wait_for_sidekiq
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "flush_redis" do
|
describe "#flush_redis" do
|
||||||
context "Sidekiq" do
|
context "Sidekiq" do
|
||||||
after { Sidekiq.unpause! }
|
after { Sidekiq.unpause! }
|
||||||
|
|
||||||
it "doesn't unpause Sidekiq" do
|
it "doesn't unpause Sidekiq" do
|
||||||
Sidekiq.pause!
|
Sidekiq.pause!
|
||||||
subject.flush_redis
|
subject.flush_redis
|
||||||
|
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "removes only keys from the current site in a multisite", type: :multisite do
|
|
||||||
test_multisite_connection("default") do
|
|
||||||
Discourse.redis.set("foo", "default-foo")
|
|
||||||
Discourse.redis.set("bar", "default-bar")
|
|
||||||
|
|
||||||
expect(Discourse.redis.get("foo")).to eq("default-foo")
|
|
||||||
expect(Discourse.redis.get("bar")).to eq("default-bar")
|
|
||||||
end
|
|
||||||
|
|
||||||
test_multisite_connection("second") do
|
|
||||||
Discourse.redis.set("foo", "second-foo")
|
|
||||||
Discourse.redis.set("bar", "second-bar")
|
|
||||||
|
|
||||||
expect(Discourse.redis.get("foo")).to eq("second-foo")
|
|
||||||
expect(Discourse.redis.get("bar")).to eq("second-bar")
|
|
||||||
|
|
||||||
subject.flush_redis
|
|
||||||
|
|
||||||
expect(Discourse.redis.get("foo")).to be_nil
|
|
||||||
expect(Discourse.redis.get("bar")).to be_nil
|
|
||||||
end
|
|
||||||
|
|
||||||
test_multisite_connection("default") do
|
|
||||||
expect(Discourse.redis.get("foo")).to eq("default-foo")
|
|
||||||
expect(Discourse.redis.get("bar")).to eq("default-bar")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
# rubocop:disable Discourse/OnlyTopLevelMultisiteSpecs
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
require_relative 'shared_context_for_backup_restore'
|
require_relative 'shared_context_for_backup_restore'
|
||||||
|
77
spec/multisite/pausable_multisite_spec.rb
Normal file
77
spec/multisite/pausable_multisite_spec.rb
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe "Pausing/Unpausing Sidekiq", type: :multisite do
|
||||||
|
describe "#pause!, #unpause! and #paused?" do
|
||||||
|
it "can pause and unpause" do
|
||||||
|
Sidekiq.pause!
|
||||||
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
expect(Sidekiq.paused?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
Sidekiq.unpause!
|
||||||
|
|
||||||
|
expect(Sidekiq.paused?).to eq(false)
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
Sidekiq.pause!("test")
|
||||||
|
expect(Sidekiq.paused?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(Sidekiq.paused_dbs).to eq(["second"])
|
||||||
|
|
||||||
|
Sidekiq.unpause_all!
|
||||||
|
|
||||||
|
RailsMultisite::ConnectionManagement.each_connection do
|
||||||
|
expect(Sidekiq.paused?).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.describe Sidekiq::Pausable, type: :multisite do
|
||||||
|
after do
|
||||||
|
Sidekiq.unpause_all!
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "when sidekiq is paused" do
|
||||||
|
let(:middleware) { Sidekiq::Pausable.new }
|
||||||
|
|
||||||
|
def call_middleware(db = RailsMultisite::ConnectionManagement::DEFAULT)
|
||||||
|
middleware.call(Jobs::PostAlert.new, {
|
||||||
|
"args" => [{ "current_site_id" => db }]
|
||||||
|
}, "critical") do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should delay the job" do
|
||||||
|
Sidekiq.pause!
|
||||||
|
|
||||||
|
called = false
|
||||||
|
called2 = false
|
||||||
|
call_middleware { called = true }
|
||||||
|
|
||||||
|
expect(called).to eq(false)
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
call_middleware("second") { called2 = true }
|
||||||
|
expect(called2).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
Sidekiq.unpause!
|
||||||
|
call_middleware { called = true }
|
||||||
|
|
||||||
|
expect(called).to eq(true)
|
||||||
|
|
||||||
|
test_multisite_connection("second") do
|
||||||
|
Sidekiq.pause!
|
||||||
|
call_middleware("second") { called2 = false }
|
||||||
|
expect(called2).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,37 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require "rails_helper"
|
||||||
|
|
||||||
RSpec.describe "Pausing/Unpausing Sidekiq", type: :multisite do
|
|
||||||
|
|
||||||
describe '#pause!, #unpause! and #paused?' do
|
|
||||||
it "can pause and unpause" do
|
|
||||||
Sidekiq.pause!
|
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
|
||||||
|
|
||||||
test_multisite_connection('second') do
|
|
||||||
expect(Sidekiq.paused?).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
Sidekiq.unpause!
|
|
||||||
|
|
||||||
expect(Sidekiq.paused?).to eq(false)
|
|
||||||
|
|
||||||
test_multisite_connection('second') do
|
|
||||||
Sidekiq.pause!("test")
|
|
||||||
expect(Sidekiq.paused?).to eq(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(Sidekiq.paused_dbs).to eq(["second"])
|
|
||||||
|
|
||||||
Sidekiq.unpause_all!
|
|
||||||
|
|
||||||
RailsMultisite::ConnectionManagement.each_connection do
|
|
||||||
expect(Sidekiq.paused?).to eq(false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
RSpec.describe Sidekiq::Pausable do
|
RSpec.describe Sidekiq::Pausable do
|
||||||
after do
|
after do
|
||||||
@ -54,42 +23,4 @@ RSpec.describe Sidekiq::Pausable do
|
|||||||
jobs = Sidekiq::ScheduledSet.new
|
jobs = Sidekiq::ScheduledSet.new
|
||||||
expect(jobs.size).to eq(0)
|
expect(jobs.size).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'when sidekiq is paused', type: :multisite do
|
|
||||||
let(:middleware) { Sidekiq::Pausable.new }
|
|
||||||
|
|
||||||
def call_middleware(db = RailsMultisite::ConnectionManagement::DEFAULT)
|
|
||||||
middleware.call(Jobs::PostAlert.new, {
|
|
||||||
"args" => [{ "current_site_id" => db }]
|
|
||||||
}, "critical") do
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'should delay the job' do
|
|
||||||
Sidekiq.pause!
|
|
||||||
|
|
||||||
called = false
|
|
||||||
called2 = false
|
|
||||||
call_middleware { called = true }
|
|
||||||
|
|
||||||
expect(called).to eq(false)
|
|
||||||
|
|
||||||
test_multisite_connection('second') do
|
|
||||||
call_middleware('second') { called2 = true }
|
|
||||||
expect(called2).to eq(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
Sidekiq.unpause!
|
|
||||||
call_middleware { called = true }
|
|
||||||
|
|
||||||
expect(called).to eq(true)
|
|
||||||
|
|
||||||
test_multisite_connection('second') do
|
|
||||||
Sidekiq.pause!
|
|
||||||
call_middleware('second') { called2 = false }
|
|
||||||
expect(called2).to eq(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -1,33 +1,22 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require "rails_helper"
|
||||||
|
|
||||||
describe UploadsController do
|
describe UploadsController, type: [:multisite, :request] do
|
||||||
let!(:user) { Fabricate(:user) }
|
let!(:user) { Fabricate(:user) }
|
||||||
|
let(:upload) { Fabricate(:upload_s3) }
|
||||||
|
|
||||||
describe "#show_short" do
|
before do
|
||||||
describe "s3 store" do
|
setup_s3
|
||||||
let(:upload) { Fabricate(:upload_s3) }
|
SiteSetting.secure_media = true
|
||||||
|
upload.update(secure: true)
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
it "redirects to the signed_url_for_path with the multisite DB name in the url" do
|
||||||
setup_s3
|
sign_in(user)
|
||||||
end
|
freeze_time
|
||||||
|
get upload.short_path
|
||||||
|
|
||||||
context "when upload is secure and secure media enabled" do
|
expect(response.body).to include(RailsMultisite::ConnectionManagement.current_db)
|
||||||
before do
|
|
||||||
SiteSetting.secure_media = true
|
|
||||||
upload.update(secure: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when running on a multisite connection", type: :multisite do
|
|
||||||
it "redirects to the signed_url_for_path with the multisite DB name in the url" do
|
|
||||||
sign_in(user)
|
|
||||||
freeze_time
|
|
||||||
get upload.short_path
|
|
||||||
expect(response.body).to include(RailsMultisite::ConnectionManagement.current_db)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
43
spec/services/inline_uploads_multisite_spec.rb
Normal file
43
spec/services/inline_uploads_multisite_spec.rb
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe InlineUploads, type: :multisite do
|
||||||
|
before do
|
||||||
|
set_cdn_url "https://awesome.com"
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".process" do
|
||||||
|
describe "s3 uploads" do
|
||||||
|
let(:upload) { Fabricate(:upload_s3) }
|
||||||
|
let(:upload2) { Fabricate(:upload_s3) }
|
||||||
|
let(:upload3) { Fabricate(:upload) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
upload3
|
||||||
|
setup_s3
|
||||||
|
SiteSetting.s3_cdn_url = "https://s3.cdn.com"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should correct image URLs in multisite" do
|
||||||
|
md = <<~MD
|
||||||
|
https:#{upload2.url} https:#{upload2.url}
|
||||||
|
#{URI.join(SiteSetting.s3_cdn_url, URI.parse(upload2.url).path).to_s}
|
||||||
|
|
||||||
|
<img src="#{upload.url}" alt="some image">
|
||||||
|
<img src="#{URI.join(SiteSetting.s3_cdn_url, URI.parse(upload2.url).path).to_s}" alt="some image">
|
||||||
|
<img src="#{upload3.url}">
|
||||||
|
MD
|
||||||
|
|
||||||
|
expect(InlineUploads.process(md)).to eq(<<~MD)
|
||||||
|
#{Discourse.base_url}#{upload2.short_path} #{Discourse.base_url}#{upload2.short_path}
|
||||||
|
#{Discourse.base_url}#{upload2.short_path}
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
MD
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -692,26 +692,6 @@ RSpec.describe InlineUploads do
|
|||||||
[some reference]: #{Discourse.base_url}#{upload.short_path}
|
[some reference]: #{Discourse.base_url}#{upload.short_path}
|
||||||
MD
|
MD
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should correct image URLs in multisite", type: :multisite do
|
|
||||||
md = <<~MD
|
|
||||||
https:#{upload2.url} https:#{upload2.url}
|
|
||||||
#{URI.join(SiteSetting.s3_cdn_url, URI.parse(upload2.url).path).to_s}
|
|
||||||
|
|
||||||
<img src="#{upload.url}" alt="some image">
|
|
||||||
<img src="#{URI.join(SiteSetting.s3_cdn_url, URI.parse(upload2.url).path).to_s}" alt="some image">
|
|
||||||
<img src="#{upload3.url}">
|
|
||||||
MD
|
|
||||||
|
|
||||||
expect(InlineUploads.process(md)).to eq(<<~MD)
|
|
||||||
#{Discourse.base_url}#{upload2.short_path} #{Discourse.base_url}#{upload2.short_path}
|
|
||||||
#{Discourse.base_url}#{upload2.short_path}
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
MD
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user