-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
quiche: fix QuicMemSliceStorageImplTest and add quiche tests into CIs #10287
Conversation
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
neither of for, platform, impl, change can be assigned to this issue. |
🙀 Error while processing event:
|
/retest |
🔨 rebuilding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
basically looks good but I was hoping @antoniovicente could take a look as I think he's been thinking more about the buffers code.
if (buffer_ != nullptr) { | ||
return buffer_->length(); | ||
} else { | ||
size_t len = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we are returning a QuicByteCount rather than size_t should we use that for the accumulation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point!
|
||
private: | ||
// Either |buffer_| or |span_| is used to point to the mem slices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line 69 above assumes that they can't both be populated, but it's a little ambiguous from this comment. Can you clarify in this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
ci/do_ci.sh
Outdated
@@ -92,7 +92,7 @@ if [[ $# -gt 1 ]]; then | |||
shift | |||
TEST_TARGETS=$* | |||
else | |||
TEST_TARGETS=//test/... | |||
TEST_TARGETS="//test/... $(bazel query ${BAZEL_QUERY_OPTIONS} "attr('size', 'small', '@com_googlesource_quiche//:all')" | grep "^@com_googlesource_quiche")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only run small quiche tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed to check a new tag 'test_included'. We want to run QUICHE tests selectively because we may add a test target quic_end_to_end_test which is can be ran manually in case of need.
if (buffer_ != nullptr) { | ||
uint64_t num_slices = buffer_->getRawSlices(nullptr, 0); | ||
ASSERT(num_slices > index); | ||
absl::FixedArray<Envoy::Buffer::RawSlice> slices(num_slices); | ||
buffer_->getRawSlices(slices.begin(), num_slices); | ||
return {reinterpret_cast<char*>(slices[index].mem_), slices[index].len_}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we store a absl::FixedArray<Envoy::Buffer::RawSlice>
as a member variable, and convert the slices in Envoy::Buffer::Instance
and absl::Span<QuicMemSliceImpl>
to the FixedArray? It seems to me that QuicMemSliceSpanImpl never owns a buffer, so making that change will result in a much smaller implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have a way to convert a RawSlice to QuicMemSliceImpl which is used in ConsumeFunction. RawSlice have no control over the memory but QuicMemSliceImpl does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, I think in ConsumeAll
, we are already converting a RawSlice to a QuicMemSlice?
absl::FixedArray<Envoy::Buffer::RawSlice> slices(num_slices);
buffer_->getRawSlices(slices.begin(), num_slices);
for (auto& slice : slices) {
if (slice.len_ == 0) {
continue;
}
// Move each slice into a stand-alone buffer.
// TODO(danzh): investigate the cost of allocating one buffer per slice.
// If it turns out to be expensive, add a new function to free data in the middle in buffer
// interface and re-design QuicMemSliceImpl.
consume(QuicMemSlice(QuicMemSliceImpl(*buffer_, slice.len_)));
saved_length += slice.len_;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can transfer the ownership of memory from Envoy Buffer to QuicMemSlice, but not from RawSlice to QuicMemSlice. My understanding is that QuicMemSliceSpan needs to have a handle to the owner of the memory.
for (auto& mem_slice : other.mem_slices_) { | ||
Envoy::Buffer::OwnedImpl buffer; | ||
buffer.add(mem_slice.data(), mem_slice.length()); | ||
mem_slices_.emplace_back(buffer, mem_slice.length()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think making copies is fine since it is only needed in tests, but worth adding a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copy assignment, making copy is expected. And yes, this is only used in QUICHE tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough.
quic::QuicUniqueBufferPtr buffer = quic::MakeUniqueBuffer(allocator, slice_len); | ||
QuicUtils::CopyToBuffer(iov, iov_count, io_offset, slice_len, buffer.get()); | ||
mem_slices_.emplace_back(std::move(buffer), slice_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks much better than before. Thanks!
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
Signed-off-by: Dan Zhang <danzh@google.com>
ping? |
Discussed with @wu-bin offline. The current QuicMemSlice API is not very straight forward for user. And there might be better API for it together with QuicMemSliceSpan and QuicMemSliceStorage. We want to try the upstream improvement first before fixing this failure. So I will close this PR for now and resurrect it once we get some conclusion about the best approach. |
QuicMemSliceStorageImpl is implemented with Envoy::Buffer::OwnedImpl which has a recent change in its move() implementation. The changed behavior is that move() will merge small slices into the last slice to avoid a lot of fragments. This breaks our assumption that move() between 2 buffers should keep the slices in their original form. As a result, it fails our QUICHE test QuicMemSliceStorageImplTest.MultipleIovInMultipleSlice in which we test building a QuicMemSliceStorage with max slice length 4 bytes.
[ RUN ] QuicMemSliceStorageImplTest.MultipleIovInMultipleSlice
bazel-out/k8-fastbuild/bin/external/com_googlesource_quiche/quiche/quic/platform/api/quic_mem_slice_storage_test.cc:56: Failure
Expected equality of these values:
"aaaa"
Which is: 0x3fd160
span.GetData(0)
Which is: "aaaabbbb"
Because the max slices length for this test is small enough for the Envoy buffer to merge them, QuicMemSliceStorage ends up doesn't honor the max_slice_len passed to its constructor. This could lead the slices in QuicStreamSendBuffer to become larger than QUIC expects.
This PR changes the implementation of QuicMemSliceStorageImpl and QuicMemSliceSpanImpl to work with this new Envoy Buffer behavior:
QuicMemSliceStorageImpl is changes to keep a vector of QuicMemSliceImpl instead of a Envoy buffer.
QuicMemSliceSpanImpl has a handle to a Envoy Buffer as before and the other handle to Span of QuicMemSliceImpl to work with the new implementation of QuicMemSliceStorageImpl.
Risk Level: low
Testing: existing tests pass