This is an automated email from the ASF dual-hosted git repository. bcall pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 8c75900595121a06fe09b93323b29cf8e069c722 Author: Walter Karas <[email protected]> AuthorDate: Thu Oct 17 14:56:36 2019 -0500 Restore the MIOBufferWriter unit tests. (cherry picked from commit d52c64ab93afa2df92caff0781f239d0f994b452) --- iocore/eventsystem/IOBuffer.cc | 76 --------- iocore/eventsystem/MIOBufferWriter.cc | 124 ++++++++++++++ iocore/eventsystem/Makefile.am | 2 +- .../eventsystem/unit_tests/test_MIOBufferWriter.cc | 179 ++++++++++++++++++--- 4 files changed, 283 insertions(+), 98 deletions(-) diff --git a/iocore/eventsystem/IOBuffer.cc b/iocore/eventsystem/IOBuffer.cc index d88f332..61f71f5 100644 --- a/iocore/eventsystem/IOBuffer.cc +++ b/iocore/eventsystem/IOBuffer.cc @@ -26,7 +26,6 @@ **************************************************************************/ #include "tscore/ink_defs.h" -#include "I_MIOBufferWriter.h" #include "P_EventSystem.h" // @@ -335,78 +334,3 @@ IOBufferChain::consume(int64_t size) } return zret; } - -// -// MIOBufferWriter -// -MIOBufferWriter & -MIOBufferWriter::write(const void *data_, size_t length) -{ - const char *data = static_cast<const char *>(data_); - - while (length) { - IOBufferBlock *iobbPtr = _miob->first_write_block(); - - if (!iobbPtr) { - addBlock(); - - iobbPtr = _miob->first_write_block(); - - ink_assert(iobbPtr); - } - - size_t writeSize = iobbPtr->write_avail(); - - if (length < writeSize) { - writeSize = length; - } - - std::memcpy(iobbPtr->end(), data, writeSize); - iobbPtr->fill(writeSize); - - data += writeSize; - length -= writeSize; - - _numWritten += writeSize; - } - - return *this; -} - -std::ostream & -MIOBufferWriter::operator>>(std::ostream &stream) const -{ - IOBufferReader *r = _miob->alloc_reader(); - if (r) { - IOBufferBlock *b; - while (nullptr != (b = r->get_current_block())) { - auto n = b->read_avail(); - stream.write(b->start(), n); - r->consume(n); - } - _miob->dealloc_reader(r); - } - return stream; -} - -ssize_t -MIOBufferWriter::operator>>(int fd) const -{ - ssize_t zret = 0; - IOBufferReader *reader = _miob->alloc_reader(); - if (reader) { - IOBufferBlock *b; - while (nullptr != (b = reader->get_current_block())) { - auto n = b->read_avail(); - auto r = ::write(fd, b->start(), n); - if (r <= 0) { - break; - } else { - reader->consume(r); - zret += r; - } - } - _miob->dealloc_reader(reader); - } - return zret; -} diff --git a/iocore/eventsystem/MIOBufferWriter.cc b/iocore/eventsystem/MIOBufferWriter.cc new file mode 100644 index 0000000..67f6108 --- /dev/null +++ b/iocore/eventsystem/MIOBufferWriter.cc @@ -0,0 +1,124 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +/************************************************************************** + MIOBufferWriter.cc + +**************************************************************************/ + +#include "I_MIOBufferWriter.h" + +// +// MIOBufferWriter +// +MIOBufferWriter & +MIOBufferWriter::write(const void *data_, size_t length) +{ + const char *data = static_cast<const char *>(data_); + + while (length) { + IOBufferBlock *iobbPtr = _miob->first_write_block(); + + if (!iobbPtr) { + addBlock(); + + iobbPtr = _miob->first_write_block(); + + ink_assert(iobbPtr); + } + + size_t writeSize = iobbPtr->write_avail(); + + if (length < writeSize) { + writeSize = length; + } + + std::memcpy(iobbPtr->end(), data, writeSize); + iobbPtr->fill(writeSize); + + data += writeSize; + length -= writeSize; + + _numWritten += writeSize; + } + + return *this; +} + +#if defined(UNIT_TEST_BUFFER_WRITER) + +// Dummys just for linkage (never called). + +std::ostream & +MIOBufferWriter::operator>>(std::ostream &stream) const +{ + return stream; +} + +ssize_t +MIOBufferWriter::operator>>(int fd) const +{ + return 0; +} + +#else + +std::ostream & +MIOBufferWriter::operator>>(std::ostream &stream) const +{ + IOBufferReader *r = _miob->alloc_reader(); + if (r) { + IOBufferBlock *b; + while (nullptr != (b = r->get_current_block())) { + auto n = b->read_avail(); + stream.write(b->start(), n); + r->consume(n); + } + _miob->dealloc_reader(r); + } + return stream; +} + +ssize_t +MIOBufferWriter::operator>>(int fd) const +{ + ssize_t zret = 0; + IOBufferReader *reader = _miob->alloc_reader(); + if (reader) { + IOBufferBlock *b; + while (nullptr != (b = reader->get_current_block())) { + auto n = b->read_avail(); + auto r = ::write(fd, b->start(), n); + if (r <= 0) { + break; + } else { + reader->consume(r); + zret += r; + } + } + _miob->dealloc_reader(reader); + } + return zret; +} + +#endif // defined(UNIT_TEST_BUFFER_WRITER) diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am index 970d0ba..3421eb4 100644 --- a/iocore/eventsystem/Makefile.am +++ b/iocore/eventsystem/Makefile.am @@ -47,6 +47,7 @@ libinkevent_a_SOURCES = \ I_VIO.h \ Inline.cc \ Lock.cc \ + MIOBufferWriter.cc \ PQ-List.cc \ P_EventSystem.h \ P_Freer.h \ @@ -112,7 +113,6 @@ test_IOBuffer_LDADD = $(test_LD_ADD) test_MIOBufferWriter_SOURCES = unit_tests/test_MIOBufferWriter.cc test_MIOBufferWriter_CPPFLAGS = $(test_CPP_FLAGS) test_MIOBufferWriter_LDFLAGS = $(test_LD_FLAGS) -test_MIOBufferWriter_LDADD = $(test_LD_ADD) include $(top_srcdir)/build/tidy.mk diff --git a/iocore/eventsystem/unit_tests/test_MIOBufferWriter.cc b/iocore/eventsystem/unit_tests/test_MIOBufferWriter.cc index c75d59e..429bff2 100644 --- a/iocore/eventsystem/unit_tests/test_MIOBufferWriter.cc +++ b/iocore/eventsystem/unit_tests/test_MIOBufferWriter.cc @@ -21,38 +21,94 @@ limitations under the License. */ -#define CATCH_CONFIG_RUNNER +#define CATCH_CONFIG_MAIN #include "catch.hpp" #include <cstdint> -#include <cstdlib> -#include "I_EventSystem.h" -#include "tscore/I_Layout.h" +struct IOBufferBlock { + std::int64_t write_avail(); -#include "diags.i" + char *end(); + + void fill(int64_t); +}; + +struct MIOBuffer { + IOBufferBlock *first_write_block(); + + void add_block(); +}; + +#define UNIT_TEST_BUFFER_WRITER #include "I_MIOBufferWriter.h" +#include "MIOBufferWriter.cc" + +IOBufferBlock iobb[1]; +int iobbIdx{0}; + +const int BlockSize = 11 * 11; +char block[BlockSize]; +int blockUsed{0}; + +std::int64_t +IOBufferBlock::write_avail() +{ + REQUIRE(this == (iobb + iobbIdx)); + return BlockSize - blockUsed; +} + +char * +IOBufferBlock::end() +{ + REQUIRE(this == (iobb + iobbIdx)); + return block + blockUsed; +} -int -main(int argc, char *argv[]) +void +IOBufferBlock::fill(int64_t len) { - // global setup... - Layout::create(); - init_diags("", nullptr); - RecProcessInit(RECM_STAND_ALONE); + static std::uint8_t dataCheck; + + REQUIRE(this == (iobb + iobbIdx)); + + while (len-- and (blockUsed < BlockSize)) { + REQUIRE(block[blockUsed] == static_cast<char>(dataCheck)); + + ++blockUsed; + + dataCheck += 7; + } + + REQUIRE(len == -1); +} + +MIOBuffer theMIOBuffer; + +IOBufferBlock * +MIOBuffer::first_write_block() +{ + REQUIRE(this == &theMIOBuffer); + + REQUIRE(blockUsed <= BlockSize); + + if (blockUsed == BlockSize) { + return nullptr; + } - ink_event_system_init(EVENT_SYSTEM_MODULE_PUBLIC_VERSION); - eventProcessor.start(2); + return iobb + iobbIdx; +} - Thread *main_thread = new EThread; - main_thread->set_specific(); +void +MIOBuffer::add_block() +{ + REQUIRE(this == &theMIOBuffer); - std::cout << "Pre-Catch" << std::endl; - int result = Catch::Session().run(argc, argv); + REQUIRE(blockUsed == BlockSize); - // global clean-up... + blockUsed = 0; - exit(result); + ++iobbIdx; } std::string @@ -70,12 +126,93 @@ genData(int numBytes) return s; } +void +writeOnce(MIOBufferWriter &bw, std::size_t len) +{ + static bool toggle; + + std::string s{genData(len)}; + + if (len == 1) { + bw.write(s[0]); + + } else if (toggle) { + std::size_t cap{bw.auxBufferCapacity()}; + + if (cap >= len) { + memcpy(bw.auxBuffer(), s.data(), len); + bw.fill(len); + + } else { + memcpy(bw.auxBuffer(), s.data(), cap); + bw.fill(cap); + bw.write(s.data() + cap, len - cap); + } + } else { + bw.write(s.data(), len); + } + + toggle = !toggle; + + REQUIRE(bw.auxBufferCapacity() <= BlockSize); +} + class InkAssertExcept { }; TEST_CASE("MIOBufferWriter", "[MIOBW]") { - MIOBuffer *theMIOBuffer = new_MIOBuffer(default_large_iobuffer_size); - MIOBufferWriter bw(theMIOBuffer); + MIOBufferWriter bw(&theMIOBuffer); + + REQUIRE(bw.auxBufferCapacity() == BlockSize); + + writeOnce(bw, 0); + writeOnce(bw, 1); + writeOnce(bw, 1); + writeOnce(bw, 1); + writeOnce(bw, 10); + writeOnce(bw, 1000); + writeOnce(bw, 1); + writeOnce(bw, 0); + writeOnce(bw, 1); + writeOnce(bw, 2000); + writeOnce(bw, 69); + writeOnce(bw, 666); + + for (int i = 0; i < 3000; i += 13) { + writeOnce(bw, i); + } + + writeOnce(bw, 0); + writeOnce(bw, 1); + + REQUIRE(bw.extent() == ((iobbIdx * BlockSize) + blockUsed)); + +// These tests don't work properly with clang for some reason. +#if !defined(__clang__) + + try { + bw.fill(bw.auxBufferCapacity() + 1); + REQUIRE(false); + + } catch (InkAssertExcept) { + REQUIRE(true); + } + + try { + bw.data(); + REQUIRE(false); + + } catch (InkAssertExcept) { + REQUIRE(true); + } + +#endif +} + +void +_ink_assert(const char *a, const char *f, int l) +{ + throw InkAssertExcept(); }
