You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2020/07/22 15:57:04 UTC

[trafficserver] 01/03: Restore the MIOBufferWriter unit tests.

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 <wk...@verizonmedia.com>
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();
 }