void test_insert_one_then_split_gap() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(17); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); TEST_ASSERT(!tr.reassemble(1, true, data.sample)); // 1 TEST_ASSERT(!tr.reassemble(6, true, data.sample)); // 1,6 CORBA::ULong base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(2 == base); // Gap from 2-5 TEST_ASSERT(4 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(gaps.check_gap(3)); // Gap TEST_ASSERT(gaps.check_gap(4)); // Gap TEST_ASSERT(gaps.check_gap(5)); // Gap TEST_ASSERT(!gaps.check_gap(6)); // No gap TEST_ASSERT(!tr.reassemble(4, true, data.sample)); // 1,4,6 TEST_ASSERT(!tr.reassemble(3, true, data.sample)); // 1,3-4,6 base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(2 == base); // Gap at 2 and 5 TEST_ASSERT(4 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(!gaps.check_gap(3)); // No gap TEST_ASSERT(!gaps.check_gap(4)); // No gap TEST_ASSERT(gaps.check_gap(5)); // Gap TEST_ASSERT(!gaps.check_gap(6)); // No gap }
void test_empty() { TransportReassembly tr; Gaps gaps; SequenceNumber seq(1); RepoId pub_id = create_pub_id(); TEST_ASSERT(!tr.has_frags(seq, pub_id)); TEST_ASSERT(0 == gaps.get(tr, seq, pub_id)); }
void test_insert_has_frag() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(4); SequenceNumber frag_seq(1); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); tr.reassemble(frag_seq, true, data.sample); TEST_ASSERT(tr.has_frags(msg_seq, pub_id)); }
void test_first_insert_has_no_gaps() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(18); SequenceNumber frag_seq(1); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); TEST_ASSERT(!tr.reassemble(frag_seq, true, data.sample)); CORBA::ULong base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(tr.has_frags(msg_seq, pub_id)); TEST_ASSERT(2 == base); // Now expecting 2 TEST_ASSERT(1 == gaps.result_bits); // Only one bit TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(!gaps.check_gap(3)); // No gap }
void test_insert_gaps() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(9); SequenceNumber frag_seq(4); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); tr.reassemble(frag_seq, true, data.sample); CORBA::ULong base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(1 == base); // Gap from 1-3 TEST_ASSERT(3 == gaps.result_bits); // Only one bit TEST_ASSERT(gaps.check_gap(1)); // Gap TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(gaps.check_gap(3)); // Gap TEST_ASSERT(!gaps.check_gap(4)); // No gap }
void test_fill_rtol() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(17); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); TEST_ASSERT(!tr.reassemble(1, true, data.sample)); // 1 TEST_ASSERT(!tr.reassemble(6, true, data.sample)); // 1,6 CORBA::ULong base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(2 == base); // Gap from 2-5 TEST_ASSERT(4 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(gaps.check_gap(3)); // Gap TEST_ASSERT(gaps.check_gap(4)); // Gap TEST_ASSERT(gaps.check_gap(5)); // Gap TEST_ASSERT(!gaps.check_gap(6)); // No gap TEST_ASSERT(!tr.reassemble(5, true, data.sample)); // 1,5-6 TEST_ASSERT(!tr.reassemble(4, true, data.sample)); // 1,4-6 base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(2 == base); // Gap from 2-3 TEST_ASSERT(2 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(gaps.check_gap(3)); // Gap TEST_ASSERT(!gaps.check_gap(4)); // No gap TEST_ASSERT(!gaps.check_gap(5)); // No gap TEST_ASSERT(!gaps.check_gap(6)); // No gap TEST_ASSERT(!tr.reassemble(3, true, data.sample)); // 1,3-6 TEST_ASSERT(!tr.reassemble(2, true, data.sample)); // 1-6 base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(7 == base); // Gap from 2-3 TEST_ASSERT(1 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(7)); // Gap TEST_ASSERT(!gaps.check_gap(8)); // No gap }
void test_insert_one_then_gap() { TransportReassembly tr; Gaps gaps; SequenceNumber msg_seq(17); SequenceNumber frag_seq1(1); SequenceNumber frag_seq2(6); RepoId pub_id = create_pub_id(); Sample data(pub_id, msg_seq); tr.reassemble(frag_seq1, true, data.sample); tr.reassemble(frag_seq2, true, data.sample); CORBA::ULong base = gaps.get(tr, msg_seq, pub_id); TEST_ASSERT(2 == base); // Gap from 2-5 TEST_ASSERT(4 == gaps.result_bits); // Number of bits TEST_ASSERT(gaps.check_gap(2)); // Gap TEST_ASSERT(gaps.check_gap(3)); // Gap TEST_ASSERT(gaps.check_gap(4)); // Gap TEST_ASSERT(gaps.check_gap(5)); // Gap TEST_ASSERT(!gaps.check_gap(6)); // No gap }
int ACE_TMAIN(int, ACE_TCHAR*[]) { try { DataSampleHeader dsh; const size_t N = 300; dsh.message_length_ = N; ACE_Message_Block header_mb(DataSampleHeader::max_marshaled_size()); header_mb << dsh; { // simple case: no content-filter, data in a single messageblock ACE_Message_Block data(N); data.wr_ptr(N); header_mb.cont(&data); Fragments f; DataSampleHeader::split(header_mb, N / 2 + header_mb.length(), f.head_, f.tail_); DataSampleHeader header1(*f.head_); TEST_CHECK(header1.more_fragments_); TEST_CHECK(header1.message_length_ == N / 2); TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == N / 2); TEST_CHECK(!f.head_->cont()->cont()); DataSampleHeader header2(*f.tail_); TEST_CHECK(!header2.more_fragments_); TEST_CHECK(header2.message_length_ == N / 2); TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == N / 2); TEST_CHECK(!f.tail_->cont()->cont()); DataSampleHeader reassembled; TEST_CHECK(DataSampleHeader::join(header1, header2, reassembled)); TEST_CHECK(reassembled.sequence_ == header1.sequence_); TEST_CHECK(reassembled.sequence_ == header2.sequence_); TEST_CHECK(!reassembled.more_fragments_); TEST_CHECK(reassembled.message_length_ == N); ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2; TransportReassembly tr; TEST_CHECK(!tr.reassemble(4, true, rds1)); TEST_CHECK(tr.reassemble(5, false, rds2)); TEST_CHECK(rds2.sample_ && rds2.sample_->total_length() == N); ReceivedDataSample rds1b(f.head_->cont()->duplicate()), rds2b(f.tail_->cont()->duplicate()); rds1b.header_ = header1; rds2b.header_ = header2; TransportReassembly tr2; TEST_CHECK(!tr2.reassemble(5, false, rds2b)); TEST_CHECK(tr2.reassemble(4, true, rds1b)); TEST_CHECK(rds1b.sample_ && rds1b.sample_->total_length() == N); } { // data split into 3 messageblocks, fragment in the middle of block #2 ACE_Message_Block data1(N / 3), data2(N / 3), data3(N / 3); data1.wr_ptr(N / 3); data2.wr_ptr(N / 3); data3.wr_ptr(N / 3); header_mb.cont(&data1); data1.cont(&data2); data2.cont(&data3); Fragments f; DataSampleHeader::split(header_mb, N / 2 + header_mb.length(), f.head_, f.tail_); DataSampleHeader header(*f.head_); TEST_CHECK(header.more_fragments_); TEST_CHECK(header.message_length_ == N / 2); TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == N / 3); TEST_CHECK(f.head_->cont()->cont()->length() == N / 6); TEST_CHECK(!f.head_->cont()->cont()->cont()); header = *f.tail_; TEST_CHECK(!header.more_fragments_); TEST_CHECK(header.message_length_ == N / 2); TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == N / 6); TEST_CHECK(f.tail_->cont()->cont()->length() == N / 3); TEST_CHECK(!f.tail_->cont()->cont()->cont()); } { // data split into 4 messageblocks, fragment at the block division ACE_Message_Block data1(N / 4), data2(N / 4), data3(N / 4), data4(N / 4); data1.wr_ptr(N / 4); data2.wr_ptr(N / 4); data3.wr_ptr(N / 4); data4.wr_ptr(N / 4); header_mb.cont(&data1); data1.cont(&data2); data2.cont(&data3); data3.cont(&data4); Fragments f; DataSampleHeader::split(header_mb, N / 2 + header_mb.length(), f.head_, f.tail_); DataSampleHeader header(*f.head_); TEST_CHECK(header.more_fragments_); TEST_CHECK(header.message_length_ == N / 2); TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == N / 4); TEST_CHECK(f.head_->cont()->cont()->length() == N / 4); TEST_CHECK(!f.head_->cont()->cont()->cont()); header = *f.tail_; TEST_CHECK(!header.more_fragments_); TEST_CHECK(header.message_length_ == N / 2); TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == N / 4); TEST_CHECK(f.tail_->cont()->cont()->length() == N / 4); TEST_CHECK(!f.tail_->cont()->cont()->cont()); } { // 3 fragments needed: first split into 2 and then split the 2nd ACE_Message_Block data(N); data.wr_ptr(N); header_mb.cont(&data); Fragments f; DataSampleHeader::split(header_mb, N / 3 + header_mb.length(), f.head_, f.tail_); DataSampleHeader header1(*f.head_); TEST_CHECK(header1.more_fragments_); TEST_CHECK(header1.message_length_ == N / 3); TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == N / 3); TEST_CHECK(!f.head_->cont()->cont()); DataSampleHeader header2(*f.tail_); TEST_CHECK(!header2.more_fragments_); TEST_CHECK(header2.message_length_ == 2 * N / 3); TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == 2 * N / 3); TEST_CHECK(!f.tail_->cont()->cont()); Fragments f2; f.tail_->rd_ptr(f.tail_->base()); DataSampleHeader::split(*f.tail_, N / 3 + header_mb.length(), f2.head_, f2.tail_); DataSampleHeader header2a(*f2.head_); TEST_CHECK(header2a.more_fragments_); TEST_CHECK(header2a.message_length_ == N / 3); TEST_CHECK(f2.head_->cont()); TEST_CHECK(f2.head_->cont()->length() == N / 3); TEST_CHECK(!f2.head_->cont()->cont()); DataSampleHeader header2b(*f2.tail_); TEST_CHECK(!header2b.more_fragments_); TEST_CHECK(header2b.message_length_ == N / 3); TEST_CHECK(f2.tail_->cont()); TEST_CHECK(f2.tail_->cont()->length() == N / 3); TEST_CHECK(!f2.tail_->cont()->cont()); // Test all permutations of order of reception of the 3 fragments { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(1, true, rds1)); TEST_CHECK(!tr.reassemble(2, false, rds2)); TEST_CHECK(tr.reassemble(3, false, rds3)); TEST_CHECK(rds3.sample_ && rds3.sample_->total_length() == N); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(1, true, rds1)); TEST_CHECK(!tr.reassemble(3, false, rds3)); TEST_CHECK(tr.reassemble(2, false, rds2)); TEST_CHECK(rds2.sample_ && rds2.sample_->total_length() == N); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(2, false, rds2)); TEST_CHECK(!tr.reassemble(1, true, rds1)); TEST_CHECK(tr.reassemble(3, false, rds3)); TEST_CHECK(rds3.sample_ && rds3.sample_->total_length() == N); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(2, false, rds2)); TEST_CHECK(!tr.reassemble(3, false, rds3)); TEST_CHECK(tr.reassemble(1, true, rds1)); TEST_CHECK(rds1.sample_ && rds1.sample_->total_length() == N); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(3, false, rds3)); TEST_CHECK(!tr.reassemble(1, true, rds1)); TEST_CHECK(tr.reassemble(2, false, rds2)); TEST_CHECK(rds2.sample_ && rds2.sample_->total_length() == N); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(3, false, rds3)); TEST_CHECK(!tr.reassemble(2, false, rds2)); TEST_CHECK(tr.reassemble(1, true, rds1)); TEST_CHECK(rds1.sample_ && rds1.sample_->total_length() == N); } // Test data_unavailable() scenarios { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(1, true, rds1)); tr.data_unavailable(SequenceRange(2, 2)); TEST_CHECK(!tr.reassemble(3, false, rds3)); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds3(f2.tail_->cont()->duplicate()); rds1.header_ = header1; rds3.header_ = header2b; TransportReassembly tr; TEST_CHECK(!tr.reassemble(3, false, rds3)); tr.data_unavailable(SequenceRange(2, 2)); TEST_CHECK(!tr.reassemble(1, true, rds1)); } { ReceivedDataSample rds1(f.head_->cont()->duplicate()), rds2(f2.head_->cont()->duplicate()); rds1.header_ = header1; rds2.header_ = header2a; TransportReassembly tr; TEST_CHECK(!tr.reassemble(2, false, rds2)); tr.data_unavailable(SequenceRange(3, 3)); TEST_CHECK(!tr.reassemble(1, true, rds1)); } } { // content filtering flag with no "entries" (adds another MB to the chain) ACE_Message_Block data(N); data.wr_ptr(N); header_mb.cont(&data); DataSampleHeader::set_flag(CONTENT_FILTER_FLAG, &header_mb); DataSampleHeader::add_cfentries(0, &header_mb); Fragments f; const size_t FRAG = 100; // arbitrary split at 100 bytes DataSampleHeader::split(header_mb, FRAG, f.head_, f.tail_); DataSampleHeader header1(*f.head_); TEST_CHECK(header1.more_fragments_); TEST_CHECK(header1.content_filter_); TEST_CHECK(header1.content_filter_entries_.length() == 0); const size_t hdr_len = header_mb.length() + header_mb.cont()->length(); release_cfentries(header_mb); TEST_CHECK(header1.message_length_ == FRAG - hdr_len); TEST_CHECK(f.head_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.head_->cont()->cont()); TEST_CHECK(f.head_->cont()->cont()->length() == header1.message_length_); TEST_CHECK(!f.head_->cont()->cont()->cont()); DataSampleHeader header2(*f.tail_); TEST_CHECK(!header2.more_fragments_); TEST_CHECK(!header2.content_filter_); TEST_CHECK(header2.message_length_ == N - (FRAG - hdr_len)); TEST_CHECK(f.tail_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == header2.message_length_); TEST_CHECK(!f.tail_->cont()->cont()); DataSampleHeader reassembled; TEST_CHECK(DataSampleHeader::join(header1, header2, reassembled)); TEST_CHECK(reassembled.sequence_ == header1.sequence_); TEST_CHECK(reassembled.sequence_ == header2.sequence_); TEST_CHECK(!reassembled.more_fragments_); TEST_CHECK(reassembled.message_length_ == N); TEST_CHECK(reassembled.content_filter_); } { // content filtering with some "entries" that all fit in the fragment ACE_Message_Block data(N); data.wr_ptr(N); header_mb.cont(&data); DataSampleHeader::set_flag(CONTENT_FILTER_FLAG, &header_mb); const size_t CF_ENTRIES = 6; // serializes to 100 bytes GUIDSeq entries(CF_ENTRIES); entries.length(CF_ENTRIES); DataSampleHeader::add_cfentries(&entries, &header_mb); Fragments f; const size_t FRAG = 200; DataSampleHeader::split(header_mb, FRAG, f.head_, f.tail_); release_cfentries(header_mb); DataSampleHeader header1(*f.head_); TEST_CHECK(header1.more_fragments_); TEST_CHECK(header1.content_filter_); TEST_CHECK(header1.content_filter_entries_.length() == CF_ENTRIES); TEST_CHECK(header1.message_length_ > 0); TEST_CHECK(f.head_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.head_->cont()->cont()); const size_t frag_payload = f.head_->cont()->cont()->length(); TEST_CHECK(frag_payload > 0); TEST_CHECK(!f.head_->cont()->cont()->cont()); DataSampleHeader header2(*f.tail_); TEST_CHECK(!header2.more_fragments_); TEST_CHECK(!header2.content_filter_); TEST_CHECK(header2.message_length_ + frag_payload == N); TEST_CHECK(f.tail_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == header2.message_length_); TEST_CHECK(!f.tail_->cont()->cont()); DataSampleHeader reassembled; TEST_CHECK(DataSampleHeader::join(header1, header2, reassembled)); TEST_CHECK(reassembled.sequence_ == header1.sequence_); TEST_CHECK(reassembled.sequence_ == header2.sequence_); TEST_CHECK(!reassembled.more_fragments_); TEST_CHECK(reassembled.message_length_ == N); TEST_CHECK(reassembled.content_filter_); TEST_CHECK(reassembled.content_filter_entries_.length() == CF_ENTRIES); } { // content filtering with some "entries", split inside the entires ACE_Message_Block data(N); data.wr_ptr(N); header_mb.cont(&data); DataSampleHeader::set_flag(CONTENT_FILTER_FLAG, &header_mb); const size_t CF_ENTRIES = 6; // serializes to 100 bytes GUIDSeq entries(CF_ENTRIES); entries.length(CF_ENTRIES); DataSampleHeader::add_cfentries(&entries, &header_mb); Fragments f; const size_t FRAG = 68; DataSampleHeader::split(header_mb, FRAG, f.head_, f.tail_); release_cfentries(header_mb); DataSampleHeader header1(*f.head_); TEST_CHECK(header1.more_fragments_); TEST_CHECK(header1.content_filter_); const size_t entries_in_header = header1.content_filter_entries_.length(); TEST_CHECK(entries_in_header > 0); TEST_CHECK(header1.message_length_ == 0); TEST_CHECK(f.head_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.head_->cont()); TEST_CHECK(f.head_->cont()->length() == 0); // consumed by DataSampleHeader TEST_CHECK(!f.head_->cont()->cont()); DataSampleHeader header2(*f.tail_); TEST_CHECK(!header2.more_fragments_); TEST_CHECK(header2.content_filter_); TEST_CHECK(header2.content_filter_entries_.length() + entries_in_header == CF_ENTRIES); TEST_CHECK(header2.message_length_ == N); TEST_CHECK(f.tail_->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.tail_->cont()); TEST_CHECK(f.tail_->cont()->length() == 0); // consumed by DataSampleHeader TEST_CHECK(f.tail_->cont()->cont()); TEST_CHECK(f.tail_->cont()->cont()->length() == N); TEST_CHECK(!f.tail_->cont()->cont()->cont()); DataSampleHeader reassembled; TEST_CHECK(DataSampleHeader::join(header1, header2, reassembled)); TEST_CHECK(reassembled.sequence_ == header1.sequence_); TEST_CHECK(reassembled.sequence_ == header2.sequence_); TEST_CHECK(!reassembled.more_fragments_); TEST_CHECK(reassembled.message_length_ == N); TEST_CHECK(reassembled.content_filter_); TEST_CHECK(reassembled.content_filter_entries_.length() == CF_ENTRIES); } } catch (const CORBA::BAD_PARAM& ex) { ex._tao_print_exception("Exception caught in Fragmentation.cpp:"); return 1; } return 0; }