From 030d8a5aa0c227d352c0cca6633f15f8ff00139a Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Wed, 6 Nov 2024 15:58:20 +0100 Subject: [PATCH] [TEST] Add testcase --- test/unit/io/sam_file/format_bam_test.cpp | 25 ++++++++++ test/unit/io/sam_file/format_sam_test.cpp | 18 +++++-- .../sam_file_format_test_template.hpp | 50 ++++++++++++++++++- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/test/unit/io/sam_file/format_bam_test.cpp b/test/unit/io/sam_file/format_bam_test.cpp index e3d436efe3..8868cbd1dd 100644 --- a/test/unit/io/sam_file/format_bam_test.cpp +++ b/test/unit/io/sam_file/format_bam_test.cpp @@ -393,6 +393,31 @@ struct sam_file_read : public sam_file_data '\x14', '\x00', '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x12', '\x00', '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x11', '\x00', '\x00', '\x00', '\x12', '\x48', '\x00', '\x02', '\x02', '\x03', '\x62', '\x48', '\x48', '\x31', '\x41', '\x45', '\x33', '\x30', '\x00'}; + + std::string issue3299_output{ + '\x42', '\x41', '\x4d', '\x01', '\x41', '\x00', '\x00', '\x00', '\x40', '\x48', '\x44', '\x09', '\x56', '\x4e', + '\x3a', '\x31', '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x68', '\x65', + '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x31', + '\x30', '\x30', '\x32', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x77', '\x6f', '\x72', + '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x32', '\x30', + '\x30', '\x32', '\x0a', '\x02', '\x00', '\x00', '\x00', '\x0c', '\x00', '\x00', '\x00', '\x68', '\x65', '\x6c', + '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', '\x00', '\xea', '\x03', '\x00', '\x00', '\x0c', + '\x00', '\x00', '\x00', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x66', '\x6f', '\x6f', + '\x00', '\xd2', '\x07', '\x00', '\x00', '\x42', '\x41', '\x4d', '\x01', '\x3b', '\x00', '\x00', '\x00', '\x40', + '\x48', '\x44', '\x09', '\x56', '\x4e', '\x3a', '\x31', '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', + '\x53', '\x4e', '\x3a', '\x68', '\x65', '\x6c', '\x6c', '\x6f', '\x66', '\x6f', '\x6f', '\x09', '\x4c', '\x4e', + '\x3a', '\x31', '\x30', '\x30', '\x31', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x77', + '\x6f', '\x72', '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x32', '\x30', '\x30', + '\x31', '\x0a', '\x02', '\x00', '\x00', '\x00', '\x09', '\x00', '\x00', '\x00', '\x68', '\x65', '\x6c', '\x6c', + '\x6f', '\x66', '\x6f', '\x6f', '\x00', '\xe9', '\x03', '\x00', '\x00', '\x09', '\x00', '\x00', '\x00', '\x77', + '\x6f', '\x72', '\x6c', '\x64', '\x66', '\x6f', '\x6f', '\x00', '\xd1', '\x07', '\x00', '\x00', '\x42', '\x41', + '\x4d', '\x01', '\x35', '\x00', '\x00', '\x00', '\x40', '\x48', '\x44', '\x09', '\x56', '\x4e', '\x3a', '\x31', + '\x2e', '\x36', '\x0a', '\x40', '\x53', '\x51', '\x09', '\x53', '\x4e', '\x3a', '\x68', '\x65', '\x6c', '\x6c', + '\x6f', '\x09', '\x4c', '\x4e', '\x3a', '\x31', '\x30', '\x30', '\x30', '\x0a', '\x40', '\x53', '\x51', '\x09', + '\x53', '\x4e', '\x3a', '\x77', '\x6f', '\x72', '\x6c', '\x64', '\x09', '\x4c', '\x4e', '\x3a', '\x32', '\x30', + '\x30', '\x30', '\x0a', '\x02', '\x00', '\x00', '\x00', '\x06', '\x00', '\x00', '\x00', '\x68', '\x65', '\x6c', + '\x6c', '\x6f', '\x00', '\xe8', '\x03', '\x00', '\x00', '\x06', '\x00', '\x00', '\x00', '\x77', '\x6f', '\x72', + '\x6c', '\x64', '\x00', '\xd0', '\x07', '\x00', '\x00'}; }; // --------------------------------------------------------------------------------------------------------------------- diff --git a/test/unit/io/sam_file/format_sam_test.cpp b/test/unit/io/sam_file/format_sam_test.cpp index f69cca440e..de4fb4ed58 100644 --- a/test/unit/io/sam_file/format_sam_test.cpp +++ b/test/unit/io/sam_file/format_sam_test.cpp @@ -107,6 +107,18 @@ read1 41 * 1 61 1S1M1D1M1I * 0 0 ACGT !##$ std::string wrong_hexadecimal_tag{ R"(@SQ SN:ref LN:150 read1 41 ref 1 61 1S1M1D1M1I = 10 300 ACGT !##$ bH:H:1AE30 +)"}; + + std::string issue3299_output{ + R"(@HD VN:1.6 +@SQ SN:hellofoofoo LN:1002 +@SQ SN:worldfoofoo LN:2002 +@HD VN:1.6 +@SQ SN:hellofoo LN:1001 +@SQ SN:worldfoo LN:2001 +@HD VN:1.6 +@SQ SN:hello LN:1000 +@SQ SN:world LN:2000 )"}; }; @@ -384,9 +396,9 @@ TEST_F(sam_format, write_different_header) write_header(); ostream.flush(); - EXPECT_EQ( - ostream.str(), - "@HD\tVN:1.6\tSO:coordinate\tSS:query\tGO:reference\n@SQ\tSN:ref\tLN:34\n*\t0\tref\t1\t0\t*\t*\t0\t0\t*\t*\n"); + EXPECT_EQ(ostream.str(), + "@HD\tVN:1.6\tSO:coordinate\tSS:query\tGO:reference\n@SQ\tSN:ref\tLN:34\n*\t0\tref\t1\t0\t*\t*" + "\t0\t0\t*\t*\n"); } TEST_F(sam_format, issue2195) diff --git a/test/unit/io/sam_file/sam_file_format_test_template.hpp b/test/unit/io/sam_file/sam_file_format_test_template.hpp index 6f9b3bc01a..8ce309e225 100644 --- a/test/unit/io/sam_file/sam_file_format_test_template.hpp +++ b/test/unit/io/sam_file/sam_file_format_test_template.hpp @@ -705,6 +705,53 @@ TYPED_TEST_P(sam_file_write, format_errors) seqan3::format_error); } +TYPED_TEST_P(sam_file_write, issue3299) +{ + using sam_file_output_t = seqan3::sam_file_output::selected_field_ids, + seqan3::type_list, + std::vector>; + std::vector seq_names{"hello", "world"}; + std::vector seq_lengths{1000, 2000}; + + // Issue: Moved-from sam_file_output would try to write header on destruction + { + sam_file_output_t fout1{std::ostringstream{}, seq_names, seq_lengths, TypeParam{}}; + sam_file_output_t fout2{std::move(fout1)}; + } + + // Issue: Header does not own ref_ids: ref_ids outlives sam_file_output + { + std::vector alignment_streams; + auto seq_names_copy = seq_names; + alignment_streams.emplace_back(std::ostringstream{}, seq_names_copy, seq_lengths, TypeParam{}); + // Destructor calls: + // 1) seq_names_copy + // 2) alignment_streams, starting with the one element it holds + } + + // Issue: Header does not own ref_ids: ref_ids may change + { + std::vector alignment_streams; + for (size_t i = 0; i < 3; ++i) + { + alignment_streams.emplace_back(this->ostream, seq_names, seq_lengths, TypeParam{}); + + std::ranges::for_each(seq_names, + [](std::string & str) + { + str += "foo"; + }); + std::ranges::for_each(seq_lengths, + [](size_t & len) + { + ++len; + }); + } + } + this->ostream.flush(); + EXPECT_EQ(this->ostream.str(), this->issue3299_output); +} + REGISTER_TYPED_TEST_SUITE_P(sam_file_read, input_concept, header_sucess, @@ -729,4 +776,5 @@ REGISTER_TYPED_TEST_SUITE_P(sam_file_write, with_header, cigar_vector, special_cases, - format_errors); + format_errors, + issue3299);