diff --git a/lib/syskit/cli/log_runtime_archive.rb b/lib/syskit/cli/log_runtime_archive.rb index 7d6f1cf76..7fabdd0c9 100644 --- a/lib/syskit/cli/log_runtime_archive.rb +++ b/lib/syskit/cli/log_runtime_archive.rb @@ -371,13 +371,27 @@ def self.find_all_dataset_folders(root_dir) # # @return [Boolean] true if the file was added successfully, false otherwise def self.add_to_archive(archive_io, child_path, logger: null_logger) - logger.info "adding #{child_path}" - stat = child_path.stat + child_path.open("r") do |child_input_stream| + logger.info "adding #{child_path}" + compress_and_add_to_archive(archive_io, child_path, + child_input_stream, logger) + end + rescue ::Exception => e # rubocop:disable Lint/RescueException + logger.warn( + "#{child_path.basename} not added to archive. Error: #{e}" + ) + else + child_path.unlink + end + def self.compress_and_add_to_archive(archive_io, child_path, child_in_stream, + logger) + stat = child_path.stat start_pos = archive_io.tell + write_initial_header(archive_io, child_path, stat) data_pos = archive_io.tell - exit_status = write_compressed_data(child_path, archive_io) + exit_status = write_compressed_data(child_in_stream, archive_io) unless exit_status.success? raise CompressionFailed, "compression failed for #{child_path}" @@ -386,7 +400,6 @@ def self.add_to_archive(archive_io, child_path, logger: null_logger) add_to_archive_commit( archive_io, child_path, start_pos, data_pos, stat ) - child_path.unlink rescue Exception => e # rubocop:disable Lint/RescueException Roby.display_exception($stdout, e) if start_pos @@ -436,14 +449,13 @@ def self.write_final_header(archive_io, child_path, stat, size) end # Compress data and append it to the archive - def self.write_compressed_data(child_path, archive_io) - _, exit_status = child_path.open("r") do |io| - zstd_transfer_r, zstd_transfer_w = IO.pipe - pid = Process.spawn("zstd", "--stdout", in: io, out: zstd_transfer_w) - zstd_transfer_w.close - IO.copy_stream(zstd_transfer_r, archive_io) - Process.waitpid2(pid) - end + def self.write_compressed_data(child_in_stream, archive_io) + zstd_transfer_r, zstd_transfer_w = IO.pipe + pid = Process.spawn("zstd", "--stdout", + in: child_in_stream, out: zstd_transfer_w) + zstd_transfer_w.close + IO.copy_stream(zstd_transfer_r, archive_io) + _, exit_status = Process.waitpid2(pid) exit_status end diff --git a/test/cli/test_log_runtime_archive.rb b/test/cli/test_log_runtime_archive.rb index eff6033f1..c442e14a8 100644 --- a/test/cli/test_log_runtime_archive.rb +++ b/test/cli/test_log_runtime_archive.rb @@ -100,9 +100,7 @@ module CLI .and_return([10, flexmock(success?: false)]) flexmock(Roby).should_receive(:display_exception).once - assert_raises(CompressionFailed) do - LogRuntimeArchive.add_to_archive(archive_io, blo) - end + LogRuntimeArchive.add_to_archive(archive_io, blo) end assert LogRuntimeArchive.add_to_archive(archive_io, bli) end @@ -129,9 +127,7 @@ module CLI mock.should_receive(:waitpid2).once .and_raise(exception_m.new) flexmock(Roby).should_receive(:display_exception).once - assert_raises(exception_m) do - LogRuntimeArchive.add_to_archive(archive_io, blo) - end + LogRuntimeArchive.add_to_archive(archive_io, blo) end assert LogRuntimeArchive.add_to_archive(archive_io, bli) end @@ -144,6 +140,33 @@ module CLI assert blo.exist? refute bli.exist? end + + it "restores the file as it was and does not raise if file access " \ + "fails" do + bla = make_in_file "bla.txt", "bla" + blo = make_in_file "blo.txt", "blo" + bli = make_in_file "bli.txt", "bli" + + @archive_path.open("w") do |archive_io| + assert LogRuntimeArchive.add_to_archive(archive_io, bla) + + flexmock(blo) + .should_receive(:open) + .with("r").with_block.once + .and_raise(::Exception.new) + LogRuntimeArchive.add_to_archive(archive_io, blo) + + assert LogRuntimeArchive.add_to_archive(archive_io, bli) + end + + entries = read_archive + assert_equal 2, entries.size + assert_entry_matches(*entries[0], name: "bla.txt.zst", content: "bla") + assert_entry_matches(*entries[1], name: "bli.txt.zst", content: "bli") + refute bla.exist? + assert blo.exist? + refute bli.exist? + end end describe ".archive_dataset" do