diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb index 699ea0f3d3f504bc9d1904960375ebd677e6ebbf..0aa6369576c36eb8615915a6cd538bdd670af7fb 100644 --- a/lib/backup/manager.rb +++ b/lib/backup/manager.rb @@ -2,13 +2,15 @@ module Backup class Manager + include ::Gitlab::TaskHelpers + FILE_NAME_SUFFIX = '_gitlab_backup.tar' MANIFEST_NAME = 'backup_information.yml' # Use the content from stdin instead of an actual filepath (used by tar as input or output) USE_STDIN = '-' - attr_reader :progress, :remote_storage, :options + attr_reader :remote_storage, :options, :logger, :progress def initialize(progress, backup_tasks: nil) @progress = progress @@ -16,7 +18,8 @@ def initialize(progress, backup_tasks: nil) @options = Backup::Options.new @metadata = Backup::Metadata.new(manifest_filepath) @options.extract_from_env! # preserve existing behavior - @remote_storage = Backup::RemoteStorage.new(progress: progress, options: options) + @logger = Gitlab::BackupLogger.new(progress) + @remote_storage = Backup::RemoteStorage.new(logger: logger, options: options) end # @return [Boolean] whether all tasks succeeded @@ -27,10 +30,10 @@ def create unpack(previous_backup) if options.incremental? create_all_tasks_result = run_all_create_tasks - puts_time "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \ + logger.warn "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \ "and are not included in this backup. You will need these files to restore a backup.\n" \ - "Please back them up manually.".color(:red) - puts_time "Backup #{backup_id} is done." + "Please back them up manually." + logger.info "Backup #{backup_id} is done." create_all_tasks_result end @@ -40,22 +43,22 @@ def run_create_task(task) build_backup_information unless task.enabled? - puts_time "Dumping #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan) + logger.info "Dumping #{task.human_name} ... " + "[DISABLED]" return true end if options.skip_task?(task.id) - puts_time "Dumping #{task.human_name} ... ".color(:blue) + "[SKIPPED]".color(:cyan) + logger.info "Dumping #{task.human_name} ... " + "[SKIPPED]" return true end - puts_time "Dumping #{task.human_name} ... ".color(:blue) + logger.info "Dumping #{task.human_name} ... " task.backup!(backup_path, backup_id) - puts_time "Dumping #{task.human_name} ... ".color(:blue) + "done".color(:green) + logger.info "Dumping #{task.human_name} ... " + "done" true rescue Backup::DatabaseBackupError, Backup::FileBackupError => e - puts_time "Dumping #{task.human_name} failed: #{e.message}".color(:red) + logger.error "Dumping #{task.human_name} failed: #{e.message}" false end @@ -63,9 +66,9 @@ def restore unpack(options.backup_id) run_all_restore_tasks - puts_time "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \ - "and are not included in this backup. You will need to restore these files manually.".color(:red) - puts_time "Restore task is done." + logger.warn "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \ + "and are not included in this backup. You will need to restore these files manually." + logger.info "Restore task is done." end # @param [Gitlab::Backup::Tasks::Task] task @@ -73,30 +76,30 @@ def run_restore_task(task) read_backup_information unless task.enabled? - puts_time "Restoring #{task.human_name} ... ".color(:blue) + "[DISABLED]".color(:cyan) + logger.info "Restoring #{task.human_name} ... " + "[DISABLED]" return end - puts_time "Restoring #{task.human_name} ... ".color(:blue) + logger.info "Restoring #{task.human_name} ... " warning = task.pre_restore_warning if warning.present? - puts_time warning.color(:red) + logger.warn warning Gitlab::TaskHelpers.ask_to_continue end task.restore!(backup_path, backup_id) - puts_time "Restoring #{task.human_name} ... ".color(:blue) + "done".color(:green) + logger.info "Restoring #{task.human_name} ... done" warning = task.post_restore_warning if warning.present? - puts_time warning.color(:red) + logger.warn warning Gitlab::TaskHelpers.ask_to_continue end - rescue Gitlab::TaskAbortedByUserError - puts_time "Quitting...".color(:red) + rescue ::Gitlab::TaskAbortedByUserError + logger.error "Quitting..." exit 1 end @@ -241,7 +244,7 @@ def backup_information def pack Dir.chdir(backup_path) do # create archive - puts_time "Creating backup archive: #{tar_file} ... ".color(:blue) + logger.info "Creating backup archive: #{tar_file} ... " tar_utils = ::Gitlab::Backup::Cli::Utils::Tar.new tar_command = tar_utils.pack_cmd( @@ -256,9 +259,9 @@ def pack result = tar_command.run_single_pipeline!(output: archive_file) if result.status.success? - puts_time "Creating backup archive: #{tar_file} ... ".color(:blue) + 'done'.color(:green) + logger.info "Creating backup archive: #{tar_file} ... done" else - puts_time "Creating archive #{tar_file} failed".color(:red) + logger.error "Creating archive #{tar_file} failed" raise Backup::Error, 'Backup failed' end end @@ -269,30 +272,30 @@ def upload end def cleanup - puts_time "Deleting tar staging files ... ".color(:blue) + logger.info "Deleting tar staging files ... " remove_backup_path(MANIFEST_NAME) backup_tasks.each_value do |task| remove_backup_path(task.cleanup_path || task.destination_path) end - puts_time "Deleting tar staging files ... ".color(:blue) + 'done'.color(:green) + logger.info "Deleting tar staging files ... done" end def remove_backup_path(path) absolute_path = backup_path.join(path) return unless File.exist?(absolute_path) - puts_time "Cleaning up #{absolute_path}" + logger.info "Cleaning up #{absolute_path}" FileUtils.rm_rf(absolute_path) end def remove_tmp # delete tmp inside backups - puts_time "Deleting backups/tmp ... ".color(:blue) + logger.info "Deleting backups/tmp ... " FileUtils.rm_rf(backup_path.join('tmp')) - puts_time "Deleting backups/tmp ... ".color(:blue) + "done".color(:green) + logger.info "Deleting backups/tmp ... " + "done" end def remove_old @@ -300,11 +303,11 @@ def remove_old keep_time = Gitlab.config.backup.keep_time.to_i if keep_time <= 0 - puts_time "Deleting old backups ... ".color(:blue) + "[SKIPPED]".color(:cyan) + logger.info "Deleting old backups ... [SKIPPED]" return end - puts_time "Deleting old backups ... ".color(:blue) + logger.info "Deleting old backups ... " removed = 0 Dir.chdir(backup_path) do @@ -324,26 +327,26 @@ def remove_old FileUtils.rm(file) removed += 1 rescue StandardError => e - puts_time "Deleting #{file} failed: #{e.message}".color(:red) + logger.error "Deleting #{file} failed: #{e.message}" end end end - puts_time "Deleting old backups ... ".color(:blue) + "done. (#{removed} removed)".color(:green) + logger.info "Deleting old backups ... done. (#{removed} removed)" end def verify_backup_version Dir.chdir(backup_path) do # restoring mismatching backups can lead to unexpected problems if backup_information[:gitlab_version] != Gitlab::VERSION - progress.puts(<<~HEREDOC.color(:red)) + logger.error(<<~HEREDOC) GitLab version mismatch: Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup! Please switch to the following version and try again: version: #{backup_information[:gitlab_version]} HEREDOC - progress.puts - progress.puts "Hint: git checkout v#{backup_information[:gitlab_version]}" + logger.error "" + logger.error "Hint: git checkout v#{backup_information[:gitlab_version]}" exit 1 end end @@ -351,33 +354,33 @@ def verify_backup_version def puts_available_timestamps available_timestamps.each do |available_timestamp| - puts_time " " + available_timestamp + logger.info " " + available_timestamp end end def unpack(source_backup_id) if source_backup_id.blank? && non_tarred_backup? - puts_time "Non tarred backup found in #{backup_path}, using that" + logger.info "Non tarred backup found in #{backup_path}, using that" return end Dir.chdir(backup_path) do # check for existing backups in the backup dir if backup_file_list.empty? - puts_time "No backups found in #{backup_path}" - puts_time "Please make sure that file name ends with #{FILE_NAME_SUFFIX}" + logger.error "No backups found in #{backup_path}" + logger.error "Please make sure that file name ends with #{FILE_NAME_SUFFIX}" exit 1 elsif backup_file_list.many? && source_backup_id.nil? - puts_time 'Found more than one backup:' + logger.warn 'Found more than one backup:' # print list of available backups puts_available_timestamps if options.incremental? - puts_time 'Please specify which one you want to create an incremental backup for:' - puts_time 'rake gitlab:backup:create INCREMENTAL=true PREVIOUS_BACKUP=timestamp_of_backup' + logger.info 'Please specify which one you want to create an incremental backup for:' + logger.info 'rake gitlab:backup:create INCREMENTAL=true PREVIOUS_BACKUP=timestamp_of_backup' else - puts_time 'Please specify which one you want to restore:' - puts_time 'rake gitlab:backup:restore BACKUP=timestamp_of_backup' + logger.info 'Please specify which one you want to restore:' + logger.info 'rake gitlab:backup:restore BACKUP=timestamp_of_backup' end exit 1 @@ -390,16 +393,16 @@ def unpack(source_backup_id) end unless File.exist?(tar_file) - puts_time "The backup file #{tar_file} does not exist!" + logger.error "The backup file #{tar_file} does not exist!" exit 1 end - puts_time 'Unpacking backup ... '.color(:blue) + logger.info 'Unpacking backup ... ' if Kernel.system(*%W[tar -xf #{tar_file}]) - puts_time 'Unpacking backup ... '.color(:blue) + 'done'.color(:green) + logger.info 'Unpacking backup ... ' + 'done' else - puts_time 'Unpacking backup failed'.color(:red) + logger.error 'Unpacking backup failed' exit 1 end end @@ -464,11 +467,6 @@ def backup_id "#{backup_information[:backup_created_at].strftime('%s_%Y_%m_%d_')}#{backup_information[:gitlab_version]}" end end - - def puts_time(msg) - progress.puts "#{Time.current} -- #{msg}" - Gitlab::BackupLogger.info(message: "#{Rainbow.uncolor(msg)}") - end end end diff --git a/lib/backup/remote_storage.rb b/lib/backup/remote_storage.rb index 1d11eee8f47231830519caac70099f49afdc9b1d..cbf3b3322295d8e71767afaa7e133283467245cd 100644 --- a/lib/backup/remote_storage.rb +++ b/lib/backup/remote_storage.rb @@ -2,10 +2,10 @@ module Backup class RemoteStorage - attr_reader :progress, :options, :backup_information + attr_reader :options, :backup_information, :logger - def initialize(progress:, options:) - @progress = progress + def initialize(logger:, options:) + @logger = logger @options = options end @@ -16,26 +16,24 @@ def upload(backup_information:) if connection_settings.blank? || options.skippable_operations.remote_storage || options.skippable_operations.archive - puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) + - "[SKIPPED]".color(:cyan) + logger.info "Uploading backup archive to remote storage #{remote_directory} ... [SKIPPED]" return end - puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) + logger.info "Uploading backup archive to remote storage #{remote_directory} ... " directory = connect_to_remote_directory upload = directory.files.create(create_attributes) if upload if upload.respond_to?(:encryption) && upload.encryption - puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) + - "done (encrypted with #{upload.encryption})".color(:green) + logger.info "Uploading backup archive to remote storage #{remote_directory} ... " \ + "done (encrypted with #{upload.encryption})" else - puts_time "Uploading backup archive to remote storage #{remote_directory} ... ".color(:blue) + - "done".color(:green) + logger.info "Uploading backup archive to remote storage #{remote_directory} ... done" end else - puts_time "Uploading backup to #{remote_directory} failed".color(:red) + logger.error "Uploading backup to #{remote_directory} failed" raise Backup::Error, 'Backup failed' end end @@ -127,13 +125,6 @@ def object_storage_config @object_storage_config ||= ObjectStorage::Config.new(Gitlab.config.backup.upload) end - # TODO: This is a temporary workaround for bad design in Backup::Manager - # Output related code would be moved to a new location - def puts_time(msg) - progress.puts "#{Time.current} -- #{msg}" - Gitlab::BackupLogger.info(message: Rainbow.uncolor(msg)) - end - # TODO: This is a temporary workaround for bad design in Backup::Manager def tar_file @tar_file ||= "#{backup_id}#{Backup::Manager::FILE_NAME_SUFFIX}" diff --git a/lib/backup/targets/database.rb b/lib/backup/targets/database.rb index bb39795f3d0474a2c479797839e8a1247a42c84c..49565c19caa0135b7504e3be1f09f73a4e2017f7 100644 --- a/lib/backup/targets/database.rb +++ b/lib/backup/targets/database.rb @@ -7,7 +7,8 @@ module Targets class Database < Target extend ::Gitlab::Utils::Override include Backup::Helper - attr_reader :force, :errors + + attr_reader :force, :errors, :logger IGNORED_ERRORS = [ # Ignore warnings @@ -24,6 +25,7 @@ def initialize(progress, options:) @errors = [] @force = options.force? + @logger = Gitlab::BackupLogger.new(progress) end override :dump @@ -39,7 +41,7 @@ def dump(destination_dir, _) dump_file_name = file_name(destination_dir, backup_connection.connection_name) FileUtils.rm_f(dump_file_name) - progress.print "Dumping PostgreSQL database #{pg_database_name} ... " + logger.info "Dumping PostgreSQL database #{pg_database_name} ... " schemas = [] @@ -61,8 +63,7 @@ def dump(destination_dir, _) raise DatabaseBackupError.new(active_record_config, dump_file_name) unless success report_success(success) - - progress.flush + logger.flush end ensure if multiple_databases? @@ -96,12 +97,12 @@ def restore(destination_dir, _) unless File.exist?(db_file_name) raise(Backup::Error, "Source database file does not exist #{db_file_name}") if main_database?(database_name) - progress.puts "Source backup for the database #{database_name} doesn't exist. Skipping the task" + logger.info "Source backup for the database #{database_name} doesn't exist. Skipping the task" return false end unless force - progress.puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow) + logger.info 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort' sleep(5) end @@ -119,7 +120,7 @@ def restore(destination_dir, _) status, tracked_errors = case config[:adapter] when "postgresql" then - progress.print "Restoring PostgreSQL database #{database} ... " + logger.info "Restoring PostgreSQL database #{database} ... " execute_and_track_errors(pg_restore_cmd(database), decompress_rd) end decompress_rd.close @@ -129,9 +130,9 @@ def restore(destination_dir, _) end unless tracked_errors.empty? - progress.print "------ BEGIN ERRORS -----\n".color(:yellow) - progress.print tracked_errors.join.color(:yellow) - progress.print "------ END ERRORS -------\n".color(:yellow) + logger.error "------ BEGIN ERRORS -----\n" + logger.error tracked_errors.join + logger.error "------ END ERRORS -------\n" @errors += tracked_errors end @@ -191,17 +192,13 @@ def execute_and_track_errors(cmd, decompress_rd) end def report_success(success) - if success - progress.puts '[DONE]'.color(:green) - else - progress.puts '[FAILED]'.color(:red) - end + success ? logger.info('[DONE]') : logger.error('[FAILED]') end private def drop_tables(database_name) - puts_time 'Cleaning the database ... '.color(:blue) + logger.info 'Cleaning the database ... ' if Rake::Task.task_defined? "gitlab:db:drop_tables:#{database_name}" Rake::Task["gitlab:db:drop_tables:#{database_name}"].invoke @@ -210,7 +207,7 @@ def drop_tables(database_name) Rake::Task["gitlab:db:drop_tables"].invoke end - puts_time 'done'.color(:green) + logger.info 'done' end # @deprecated This will be removed when restore operation is refactored to use extended_env directly diff --git a/lib/backup/targets/repositories.rb b/lib/backup/targets/repositories.rb index 6d4456434fbb75241cb4c24755df8f39b0a05a4a..cfa615f4b3e4a7f119ff90708eab853be326bf5d 100644 --- a/lib/backup/targets/repositories.rb +++ b/lib/backup/targets/repositories.rb @@ -20,6 +20,7 @@ def initialize(progress, strategy:, options:, storages: [], paths: [], skip_path @storages = storages @paths = paths @skip_paths = skip_paths + @logger = Gitlab::BackupLogger.new(progress) end override :dump @@ -49,7 +50,7 @@ def restore(destination_path, backup_id) private - attr_reader :strategy, :storages, :paths, :skip_paths + attr_reader :strategy, :storages, :paths, :skip_paths, :logger def remove_all_repositories return if paths.present? @@ -125,10 +126,10 @@ def skipped_path_relation def restore_object_pools PoolRepository.includes(:source_project).find_each do |pool| - progress.puts " - Object pool #{pool.disk_path}..." + logger.info " - Object pool #{pool.disk_path}..." unless pool.source_project - progress.puts " - Object pool #{pool.disk_path}... " + "[SKIPPED]".color(:cyan) + logger.info " - Object pool #{pool.disk_path}... [SKIPPED]" next end diff --git a/lib/backup/targets/target.rb b/lib/backup/targets/target.rb index 05685659d871b23ef263b43c9a4d5291550b6684..e5cec482bc649abd5f198a533f984d74b99e089b 100644 --- a/lib/backup/targets/target.rb +++ b/lib/backup/targets/target.rb @@ -25,15 +25,6 @@ def dump(path, backup_id) def restore(path, backup_id) raise NotImplementedError end - - private - - attr_reader :progress - - def puts_time(msg) - progress.puts "#{Time.zone.now} -- #{msg}" - Gitlab::BackupLogger.info(message: Rainbow.uncolor(msg).to_s) - end end end end diff --git a/lib/gitlab/backup_logger.rb b/lib/gitlab/backup_logger.rb index ec85c55d4a49f11e2da891b13feea563a431b05a..ee613701f72ea1dd3a2d50ff0a19adb7a5b10ded 100644 --- a/lib/gitlab/backup_logger.rb +++ b/lib/gitlab/backup_logger.rb @@ -4,6 +4,34 @@ module Gitlab class BackupLogger < Gitlab::JsonLogger exclude_context! + attr_reader :progress + + def initialize(progress) + @progress = progress + end + + def warn(message) + progress.puts "#{Time.zone.now} -- #{message}".color(:yellow) + + super + end + + def info(message) + progress.puts "#{Time.zone.now} -- #{message}".color(:cyan) + + super + end + + def error(message) + progress.puts "#{Time.zone.now} -- #{message}".color(:red) + + super + end + + def flush + progress.flush + end + def self.file_name_noext 'backup_json' end diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb index d0f911b90a96fd55e82d0eee6f7d421328f63711..df5027fbcd4d07e764e672ba56815925cef3571e 100644 --- a/spec/lib/backup/manager_spec.rb +++ b/spec/lib/backup/manager_spec.rb @@ -5,7 +5,8 @@ RSpec.describe Backup::Manager, feature_category: :backup_restore do include StubENV - let(:progress) { StringIO.new } + let_it_be(:progress) { StringIO.new } + let(:logger) { subject.logger } let(:backup_tasks) { nil } let(:options) { build(:backup_options, :skip_none) } @@ -18,8 +19,7 @@ allow(File).to receive(:exist?).and_call_original allow(FileUtils).to receive(:rm_rf).and_call_original - allow(progress).to receive(:puts) - allow(progress).to receive(:print) + allow(progress).to receive(:puts).and_call_original end def backup_path @@ -30,7 +30,7 @@ def backup_path describe 'other task' do let(:terraform_state) do Backup::Tasks::TerraformState.new(progress: progress, options: options) - .tap { |state| allow(state).to receive(:target).and_return(target) } + .tap { |state| allow(state).to receive(:target).and_return(target) } end let(:target) { instance_double(Backup::Targets::Target) } @@ -40,8 +40,8 @@ def backup_path it 'runs the provided task' do expect(target).to receive(:dump) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... ') - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... done') + expect(logger).to receive(:info).with('Dumping terraform states ... ') + expect(logger).to receive(:info).with('Dumping terraform states ... done') subject.run_create_task(terraform_state) end @@ -51,7 +51,7 @@ def backup_path allow(terraform_state).to receive(:enabled).and_return(false) expect(target).not_to receive(:dump) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... [DISABLED]') + expect(logger).to receive(:info).with('Dumping terraform states ... [DISABLED]') subject.run_create_task(terraform_state) end @@ -62,7 +62,7 @@ def backup_path stub_env('SKIP', 'terraform_state') expect(target).not_to receive(:dump) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping terraform states ... [SKIPPED]') + expect(logger).to receive(:info).with('Dumping terraform states ... [SKIPPED]') subject.run_create_task(terraform_state) end @@ -73,7 +73,7 @@ def backup_path describe 'database task' do let(:backup_state) do Backup::Tasks::Database.new(progress: progress, options: options) - .tap { |state| allow(state).to receive(:target).and_return(target) } + .tap { |state| allow(state).to receive(:target).and_return(target) } end let(:target) { instance_double(Backup::Targets::Target) } @@ -83,8 +83,8 @@ def backup_path it 'runs the provided task' do expect(target).to receive(:dump) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ') - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... done') + expect(logger).to receive(:info).with('Dumping database ... ') + expect(logger).to receive(:info).with('Dumping database ... done') subject.run_create_task(backup_tasks) end @@ -92,8 +92,8 @@ def backup_path context 'when the task succeeds' do it 'returns true' do expect(target).to receive(:dump) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ') - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... done') + expect(logger).to receive(:info).with('Dumping database ... ') + expect(logger).to receive(:info).with('Dumping database ... done') expect(subject.run_create_task(backup_tasks)).to be_truthy end end @@ -101,9 +101,8 @@ def backup_path context 'when the task fails with a known error' do it 'returns false' do allow(target).to receive(:dump).and_raise(Backup::DatabaseBackupError.new({ host: 'foo', port: 'bar', database: 'baz' }, 'foo')) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ') - expect(Gitlab::BackupLogger).to receive(:info).with(message: match('Dumping database failed: Failed to create compressed file ')) - + expect(logger).to receive(:info).with('Dumping database ... ') + expect(logger).to receive(:error).with(/Dumping database failed: Failed to create compressed file/) expect(subject.run_create_task(backup_tasks)).to be_falsey end end @@ -111,7 +110,7 @@ def backup_path context 'when the task fails with an unknown error' do it 'returns false' do allow(target).to receive(:dump).and_raise(StandardError) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping database ... ') + expect(logger).to receive(:info).with('Dumping database ... ') expect do subject.run_create_task(backup_tasks) @@ -147,18 +146,19 @@ def backup_path it 'runs the provided task' do expect(target).to receive(:restore) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered + + expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered + expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered subject.run_restore_task(terraform_state) end - context 'when disabled' do - it 'does not run the task and informs the user' do + describe 'disabled' do + it 'informs the user' do allow(terraform_state).to receive(:enabled).and_return(false) expect(target).not_to receive(:restore) - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... [DISABLED]').ordered + expect(logger).to receive(:info).with('Restoring terraform states ... [DISABLED]').ordered subject.run_restore_task(terraform_state) end @@ -167,88 +167,52 @@ def backup_path describe 'pre_restore_warning' do let(:pre_restore_warning) { 'Watch out!' } - describe 'skip prompt' do - before do - stub_env('GITLAB_ASSUME_YES', 1) - end - - it 'does not ask to continue' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered - expect(Gitlab::TaskHelpers).not_to receive(:prompt) - expect(target).to receive(:restore) + it 'displays and waits for the user' do + expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered + expect(logger).to receive(:warn).with('Watch out!').ordered + expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered + expect(Gitlab::TaskHelpers).to receive(:ask_to_continue) + expect(target).to receive(:restore) - subject.run_restore_task(terraform_state) - end + subject.run_restore_task(terraform_state) end - describe 'with prompt' do - it 'displays and waits for the user' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered - expect(Gitlab::TaskHelpers).to receive(:ask_to_continue) - expect(target).to receive(:restore) + it 'does not continue when the user quits' do + expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered + expect(logger).to receive(:warn).with('Watch out!').ordered + expect(logger).to receive(:error).with('Quitting...').ordered + expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError) + expect do subject.run_restore_task(terraform_state) - end - - it 'does not continue when the user quits' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered - expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError) - - expect do - subject.run_restore_task(terraform_state) - end.to raise_error(SystemExit) - end + end.to raise_error(SystemExit) end end describe 'post_restore_warning' do let(:post_restore_warning) { 'Watch out!' } - describe 'skip prompt' do - before do - stub_env('GITLAB_ASSUME_YES', 1) - end + it 'displays and waits for the user' do + expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered + expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered + expect(logger).to receive(:warn).with('Watch out!').ordered + expect(Gitlab::TaskHelpers).to receive(:ask_to_continue) + expect(target).to receive(:restore) - it "does not ask to continue" do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::TaskHelpers).not_to receive(:prompt) - expect(target).to receive(:restore) - - subject.run_restore_task(terraform_state) - end + subject.run_restore_task(terraform_state) end - describe "prompt" do - it 'displays and waits for the user' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::TaskHelpers).to receive(:ask_to_continue) - expect(target).to receive(:restore) + it 'does not continue when the user quits' do + expect(logger).to receive(:info).with('Restoring terraform states ... ').ordered + expect(logger).to receive(:info).with('Restoring terraform states ... done').ordered + expect(logger).to receive(:warn).with('Watch out!').ordered + expect(logger).to receive(:error).with('Quitting...').ordered + expect(target).to receive(:restore) + expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError) + expect do subject.run_restore_task(terraform_state) - end - - it 'does not continue when the user quits' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... ').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring terraform states ... done').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered - expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered - expect(target).to receive(:restore) - expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError) - - expect do - subject.run_restore_task(terraform_state) - end.to raise_error(SystemExit) - end + end.to raise_error(SystemExit) end end end @@ -271,7 +235,6 @@ def backup_path before do stub_env('INCREMENTAL', incremental_env) allow(ApplicationRecord.connection).to receive(:reconnect!) - allow(Gitlab::BackupLogger).to receive(:info) end it 'creates a backup tar' do @@ -308,7 +271,7 @@ def backup_path subject.create # rubocop:disable Rails/SaveBang end.to raise_error(Backup::Error, 'Backup failed') - expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed") + expect(progress.string).to include("Creating archive #{pack_tar_file} failed") expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml')) expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp')) end @@ -361,8 +324,6 @@ def backup_path end before do - allow(Gitlab::BackupLogger).to receive(:info) - files.each do |bkp| FileUtils.touch(backup_path.join(bkp)) end @@ -385,7 +346,7 @@ def backup_path end it 'prints a skipped message' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... [SKIPPED]') + expect(progress.string).to include('Deleting old backups ... [SKIPPED]') end end @@ -411,7 +372,7 @@ def backup_path end it 'prints a done message' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (0 removed)') + expect(progress.string).to include('Deleting old backups ... done. (0 removed)') end end @@ -430,7 +391,7 @@ def backup_path end it 'prints a done message' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (0 removed)') + expect(progress.string).to include('Deleting old backups ... done. (0 removed)') end end @@ -471,7 +432,7 @@ def backup_path end it 'prints a done message' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (8 removed)') + expect(progress.string).to include('Deleting old backups ... done. (8 removed)') end end @@ -495,11 +456,11 @@ def backup_path end it 'sets the correct removed count' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Deleting old backups ... done. (7 removed)') + expect(progress.string).to include('Deleting old backups ... done. (7 removed)') end it 'prints the error from file that could not be removed' do - expect(Gitlab::BackupLogger).to have_received(:info).with(message: a_string_matching(message)) + expect(progress.string).to include(message) end end end @@ -509,7 +470,6 @@ def backup_path let(:backup_filename) { File.basename(backup_file.path) } before do - allow(Gitlab::BackupLogger).to receive(:info) allow_next_instance_of(described_class) do |manager| allow(manager).to receive(:tar_file).and_return(backup_filename) allow(manager.remote_storage).to receive(:tar_file).and_return(backup_filename) @@ -550,15 +510,15 @@ def backup_path stub_env('SKIP', 'remote') subject.create # rubocop:disable Rails/SaveBang - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... [SKIPPED]') + expect(progress.string).to include('Uploading backup archive to remote storage directory ... [SKIPPED]') end end context 'target path' do it 'uses the tar filename by default' do expect_any_instance_of(Fog::Collection).to receive(:create) - .with(hash_including(key: backup_filename, public: false)) - .and_call_original + .with(hash_including(key: backup_filename, public: false)) + .and_call_original subject.create # rubocop:disable Rails/SaveBang end @@ -567,8 +527,8 @@ def backup_path stub_env('DIRECTORY', 'daily') expect_any_instance_of(Fog::Collection).to receive(:create) - .with(hash_including(key: "daily/#{backup_filename}", public: false)) - .and_call_original + .with(hash_including(key: "daily/#{backup_filename}", public: false)) + .and_call_original subject.create # rubocop:disable Rails/SaveBang end @@ -606,7 +566,7 @@ def backup_path it 'sets encryption attributes' do subject.create # rubocop:disable Rails/SaveBang - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with AES256)') + expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with AES256)') end end @@ -617,7 +577,7 @@ def backup_path it 'sets encryption attributes' do subject.create # rubocop:disable Rails/SaveBang - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with AES256)') + expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with AES256)') end end @@ -632,7 +592,7 @@ def backup_path it 'sets encryption attributes' do subject.create # rubocop:disable Rails/SaveBang - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Uploading backup archive to remote storage directory ... done (encrypted with aws:kms)') + expect(progress.string).to include('Uploading backup archive to remote storage directory ... done (encrypted with aws:kms)') end end end @@ -660,8 +620,8 @@ def backup_path it 'does not attempt to set ACL' do expect_any_instance_of(Fog::Collection).to receive(:create) - .with(hash_excluding(public: false)) - .and_call_original + .with(hash_excluding(public: false)) + .and_call_original subject.create # rubocop:disable Rails/SaveBang end @@ -747,8 +707,7 @@ def backup_path it 'fails the operation and prints an error' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts) - .with(a_string_matching('No backups found')) + expect(progress.string).to include('No backups found') end end @@ -764,14 +723,14 @@ def backup_path it 'prints the list of available backups' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts).with(a_string_matching('1451606400_2016_01_01_1.2.3')) - expect(progress).to have_received(:puts).with(a_string_matching('1451520000_2015_12_31')) + + expect(progress.string).to include('1451606400_2016_01_01_1.2.3') + expect(progress.string).to include('1451520000_2015_12_31') end it 'fails the operation and prints an error' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts) - .with(a_string_matching('Found more than one backup')) + expect(progress.string).to include('Found more than one backup') end end @@ -790,8 +749,7 @@ def backup_path it 'fails the operation and prints an error' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts) - .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist') end end @@ -799,7 +757,6 @@ def backup_path let(:backup_id) { '1451606400_2016_01_01_1.2.3' } before do - allow(Gitlab::BackupLogger).to receive(:info) allow(Dir).to receive(:glob).and_return( [ '1451606400_2016_01_01_1.2.3_gitlab_backup.tar' @@ -834,7 +791,7 @@ def backup_path subject.create # rubocop:disable Rails/SaveBang end.to raise_error(SystemExit) - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed') + expect(progress.string).to include('Unpacking backup failed') end end @@ -848,7 +805,7 @@ def backup_path subject.create # rubocop:disable Rails/SaveBang end.to raise_error(Backup::Error, 'Backup failed') - expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed") + expect(progress.string).to include("Creating archive #{pack_tar_file} failed") expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml')) expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp')) end @@ -864,8 +821,7 @@ def backup_path it 'stops the process' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts) - .with(a_string_matching('GitLab version mismatch')) + expect(progress.string).to include('GitLab version mismatch') end end end @@ -885,8 +841,7 @@ def backup_path it 'fails the operation and prints an error' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts) - .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist') end end @@ -894,7 +849,6 @@ def backup_path let(:full_backup_id) { 'some_previous_backup' } before do - allow(Gitlab::BackupLogger).to receive(:info) allow(Dir).to receive(:glob).and_return( [ 'some_previous_backup_gitlab_backup.tar' @@ -931,7 +885,7 @@ def backup_path end end.to raise_error(SystemExit) - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed') + expect(progress.string).to include('Unpacking backup failed') end end @@ -949,7 +903,7 @@ def backup_path end end.to raise_error(Backup::Error, 'Backup failed') - expect(Gitlab::BackupLogger).to have_received(:info).with(message: "Creating archive #{pack_tar_file} failed") + expect(progress.string).to include("Creating archive #{pack_tar_file} failed") expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('backup_information.yml')) expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp')) end @@ -965,8 +919,7 @@ def backup_path it 'stops the process' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts) - .with(a_string_matching('GitLab version mismatch')) + expect(progress.string).to include('GitLab version mismatch') end end end @@ -1000,10 +953,8 @@ def backup_path subject.create # rubocop:disable Rails/SaveBang end - expect(progress).to have_received(:puts) - .with(a_string_matching('Non tarred backup found ')) - expect(progress).to have_received(:puts) - .with(a_string_matching("Backup #{backup_id} is done")) + expect(progress.string).to include('Non tarred backup found ') + expect(progress.string).to include("Backup #{backup_id} is done") expect(subject.send(:backup_information).to_h).to include( backup_created_at: backup_time, full_backup_id: full_backup_id, @@ -1021,8 +972,7 @@ def backup_path it 'stops the process' do expect { subject.create }.to raise_error SystemExit # rubocop:disable Rails/SaveBang - expect(progress).to have_received(:puts) - .with(a_string_matching('GitLab version mismatch')) + expect(progress.string).to include('GitLab version mismatch') end end end @@ -1076,7 +1026,6 @@ def backup_path Rake.application.rake_require 'tasks/gitlab/shell' Rake.application.rake_require 'tasks/cache' - allow(Gitlab::BackupLogger).to receive(:info) allow(target1).to receive(:restore).with(backup_path.join('lfs.tar.gz'), backup_id) allow(target2).to receive(:restore).with(backup_path.join('pages.tar.gz'), backup_id) allow_next_instance_of(Backup::Metadata) do |metadata| @@ -1093,8 +1042,7 @@ def backup_path it 'fails the operation and prints an error' do expect { subject.restore }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('No backups found')) + expect(progress.string).to include('No backups found') end end @@ -1110,14 +1058,13 @@ def backup_path it 'prints the list of available backups' do expect { subject.restore }.to raise_error SystemExit - expect(progress).to have_received(:puts).with(a_string_matching('1451606400_2016_01_01_1.2.3')) - expect(progress).to have_received(:puts).with(a_string_matching('1451520000_2015_12_31')) + expect(progress.string).to include('1451606400_2016_01_01_1.2.3') + expect(progress.string).to include('1451520000_2015_12_31') end it 'fails the operation and prints an error' do expect { subject.restore }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('Found more than one backup')) + expect(progress.string).to include('Found more than one backup') end end @@ -1136,8 +1083,7 @@ def backup_path it 'fails the operation and prints an error' do expect { subject.restore }.to raise_error SystemExit expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar') - expect(progress).to have_received(:puts) - .with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist')) + expect(progress.string).to include('The backup file wrong_gitlab_backup.tar does not exist') end end @@ -1146,7 +1092,6 @@ def backup_path let(:backup_id) { "1451606400_2016_01_01_1.2.3" } before do - allow(Gitlab::BackupLogger).to receive(:info) allow(Dir).to receive(:glob).and_return( [ '1451606400_2016_01_01_1.2.3_gitlab_backup.tar' @@ -1198,7 +1143,7 @@ def backup_path subject.restore end.to raise_error(SystemExit) - expect(Gitlab::BackupLogger).to have_received(:info).with(message: 'Unpacking backup failed') + expect(progress.string).to include('Unpacking backup failed') end end @@ -1212,8 +1157,7 @@ def backup_path it 'stops the process' do expect { subject.restore }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('GitLab version mismatch')) + expect(progress.string).to include('GitLab version mismatch') end end end @@ -1233,8 +1177,7 @@ def backup_path subject.restore - expect(progress).to have_received(:puts) - .with(a_string_matching('Non tarred backup found ')) + expect(progress.string).to include('Non tarred backup found ') expect(FileUtils).to have_received(:rm_rf).with(backup_path.join('tmp')) end @@ -1248,8 +1191,7 @@ def backup_path it 'stops the process' do expect { subject.restore }.to raise_error SystemExit - expect(progress).to have_received(:puts) - .with(a_string_matching('GitLab version mismatch')) + expect(progress.string).to include('GitLab version mismatch') end end end diff --git a/spec/lib/backup/targets/database_spec.rb b/spec/lib/backup/targets/database_spec.rb index fe293f80d3153668fcbe52bcdf4343c779d4e16a..26fa769f83a24658ac8058580d4ebc54ecc197f9 100644 --- a/spec/lib/backup/targets/database_spec.rb +++ b/spec/lib/backup/targets/database_spec.rb @@ -9,6 +9,7 @@ let(:one_database_configured?) { base_models_for_backup.one? } let(:force) { true } let(:backup_options) { Backup::Options.new(force: force) } + let(:logger) { subject.logger } let(:timeout_service) do instance_double(Gitlab::Database::TransactionTimeoutSettings, restore_timeouts: nil, disable_timeouts: nil) end diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb index 2ebad71ef8ece83f3c73a486a76afdf920f786d7..88abe2401fdcf112f3d418684da696c8ae3d98f3 100644 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ b/spec/tasks/gitlab/backup_rake_spec.rb @@ -9,6 +9,8 @@ %w[db repo uploads builds artifacts pages lfs terraform_state registry packages ci_secure_files] end + let(:progress) { StringIO.new } + let(:backup_task_ids) do %w[db repositories uploads builds artifacts pages lfs terraform_state registry packages ci_secure_files] end @@ -298,6 +300,9 @@ def reenable_backup_sub_tasks context 'with specific backup tasks' do before do stub_env('SKIP', 'db') + allow_next_instance_of(Gitlab::BackupLogger) do |instance| + allow(instance).to receive(:info).and_call_original + end end it 'prints a progress message to stdout' do @@ -307,27 +312,29 @@ def reenable_backup_sub_tasks end it 'logs the progress to log file' do - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping database ... [SKIPPED]") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping repositories ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping repositories ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping uploads ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping uploads ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping builds ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping builds ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping artifacts ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping artifacts ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping pages ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping pages ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping lfs objects ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping lfs objects ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping terraform states ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping terraform states ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping container registry images ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping container registry images ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping packages ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping packages ... done") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping ci secure files ... ") - expect(Gitlab::BackupLogger).to receive(:info).with(message: "Dumping ci secure files ... done") + expect_logger_to_receive_messages([ + "Dumping database ... [SKIPPED]", + "Dumping repositories ... ", + "Dumping repositories ... done", + "Dumping uploads ... ", + "Dumping uploads ... done", + "Dumping builds ... ", + "Dumping builds ... done", + "Dumping artifacts ... ", + "Dumping artifacts ... done", + "Dumping pages ... ", + "Dumping pages ... done", + "Dumping lfs objects ... ", + "Dumping lfs objects ... done", + "Dumping terraform states ... ", + "Dumping terraform states ... done", + "Dumping container registry images ... ", + "Dumping container registry images ... done", + "Dumping packages ... ", + "Dumping packages ... done", + "Dumping ci secure files ... ", + "Dumping ci secure files ... done" + ]) backup_rake_task_names.each do |task| run_rake_task("gitlab:backup:#{task}:create") @@ -718,5 +725,13 @@ def reenable_backup_sub_tasks expect(backup_tar).to match(/\d+_\d{4}_\d{2}_\d{2}_\d+\.\d+\.\d+.*_gitlab_backup.tar$/) end end + + def expect_logger_to_receive_messages(messages) + expect_any_instance_of(Gitlab::BackupLogger) do |logger| + messages.each do |message| + allow(logger).to receive(:info).with(message).ordered + end + end + end end # gitlab:app namespace