You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2019/06/27 22:51:32 UTC

[trafficserver] branch master updated: Convert HdrHeap regression test into unit test using Catch

This is an automated email from the ASF dual-hosted git repository.

masaori pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new e3d5bcd  Convert HdrHeap regression test into unit test using Catch
e3d5bcd is described below

commit e3d5bcd92322c9d53e27840b1a0ed027201fe526
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Sat Jun 22 21:17:37 2019 +0900

    Convert HdrHeap regression test into unit test using Catch
---
 .gitignore                            |   1 +
 proxy/hdrs/HdrHeap.cc                 | 100 --------------------------
 proxy/hdrs/Makefile.am                |  27 +++++--
 proxy/hdrs/unit_tests/test_HdrHeap.cc | 132 ++++++++++++++++++++++++++++++++++
 4 files changed, 156 insertions(+), 104 deletions(-)

diff --git a/.gitignore b/.gitignore
index 89b2b22..b57dbe2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -100,6 +100,7 @@ iocore/hostdb/test_RefCountCache
 
 proxy/hdrs/test_mime
 proxy/hdrs/test_proxy_hdrs
+proxy/hdrs/test_hdr_heap
 proxy/http/test_proxy_http
 proxy/http2/test_Huffmancode
 proxy/http2/test_Http2DependencyTree
diff --git a/proxy/hdrs/HdrHeap.cc b/proxy/hdrs/HdrHeap.cc
index 2f1fc0e..5333de6 100644
--- a/proxy/hdrs/HdrHeap.cc
+++ b/proxy/hdrs/HdrHeap.cc
@@ -1161,103 +1161,3 @@ HdrStrHeap::expand(char *ptr, int old_size, int new_size)
     return nullptr;
   }
 }
-
-#if TS_HAS_TESTS
-#include "tscore/TestBox.h"
-REGRESSION_TEST(HdrHeap_Coalesce)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus)
-{
-  *pstatus = REGRESSION_TEST_PASSED;
-  /*
-   * This test is designed to test numerous pieces of the HdrHeaps including allocations,
-   * demotion of rw heaps to ronly heaps, and finally the coalesce and evacuate behaviours.
-   */
-
-  // The amount of space we will need to overflow the StrHdrHeap is HdrStrHeap::DEFAULT_SIZE - sizeof(HdrStrHeap)
-  size_t next_rw_heap_size           = HdrStrHeap::DEFAULT_SIZE;
-  size_t next_required_overflow_size = next_rw_heap_size - sizeof(HdrStrHeap);
-  char buf[next_required_overflow_size];
-  for (unsigned int i = 0; i < sizeof(buf); ++i) {
-    buf[i] = ('a' + (i % 26));
-  }
-
-  TestBox tb(t, pstatus);
-  HdrHeap *heap = new_HdrHeap();
-  URLImpl *url  = url_create(heap);
-
-  tb.check(heap->m_read_write_heap.get() == nullptr, "Checking that we have no rw heap.");
-  url_path_set(heap, url, buf, next_required_overflow_size, true);
-  tb.check(heap->m_read_write_heap->m_free_size == 0, "Checking that we've completely consumed the rw heap");
-  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
-    tb.check(heap->m_ronly_heap[i].m_heap_start == (char *)nullptr, "Checking ronly_heap[%d] is NULL", i);
-  }
-
-  // Now we have no ronly heaps in use and a completely full rwheap, so we will test that
-  // we demote to ronly heaps HDR_BUF_RONLY_HEAPS times.
-  for (unsigned ronly_heap = 0; ronly_heap < HDR_BUF_RONLY_HEAPS; ++ronly_heap) {
-    next_rw_heap_size           = 2 * heap->m_read_write_heap->m_heap_size;
-    next_required_overflow_size = next_rw_heap_size - sizeof(HdrStrHeap);
-    char buf2[next_required_overflow_size];
-    for (unsigned int i = 0; i < sizeof(buf2); ++i) {
-      buf2[i] = ('a' + (i % 26));
-    }
-
-    URLImpl *url2 = url_create(heap);
-    url_path_set(heap, url2, buf2, next_required_overflow_size, true);
-
-    tb.check(heap->m_read_write_heap->m_heap_size == (uint32_t)next_rw_heap_size, "Checking the current rw heap is %d bytes",
-             (int)next_rw_heap_size);
-    tb.check(heap->m_read_write_heap->m_free_size == 0, "Checking that we've completely consumed the rw heap");
-    tb.check(heap->m_ronly_heap[ronly_heap].m_heap_start != nullptr, "Checking that we properly demoted the previous rw heap");
-    for (unsigned i = ronly_heap + 1; i < HDR_BUF_RONLY_HEAPS; ++i) {
-      tb.check(heap->m_ronly_heap[i].m_heap_start == nullptr, "Checking ronly_heap[%d] is NULL", i);
-    }
-  }
-
-  // We will rerun these checks after we introduce a non-copied string to make sure we didn't already coalesce
-  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
-    tb.check(heap->m_ronly_heap[i].m_heap_start != (char *)nullptr, "Pre non-copied string: Checking ronly_heap[%d] is NOT NULL",
-             i);
-  }
-
-  // Now if we add a url object that contains only non-copied strings it shouldn't affect the size of the rwheap
-  // since it doesn't require allocating any storage on this heap.
-  char buf3[next_required_overflow_size];
-  for (unsigned int i = 0; i < sizeof(buf3); ++i) {
-    buf3[i] = ('a' + (i % 26));
-  }
-
-  URLImpl *aliased_str_url = url_create(heap);
-  url_path_set(heap, aliased_str_url, buf3, next_required_overflow_size, false); // don't copy this string
-  tb.check(aliased_str_url->m_len_path == next_required_overflow_size,
-           "Checking that the aliased string shows having proper length");
-  tb.check(aliased_str_url->m_ptr_path == buf3, "Checking that the aliased string is correctly pointing at buf");
-
-  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
-    tb.check(heap->m_ronly_heap[i].m_heap_start != (char *)nullptr, "Post non-copied string: Checking ronly_heap[%d] is NOT NULL",
-             i);
-  }
-  tb.check(heap->m_read_write_heap->m_free_size == 0, "Checking that we've completely consumed the rw heap");
-  tb.check(heap->m_next == nullptr, "Checking that we dont have any chained heaps");
-
-  // Now at this point we have a completely full rw_heap and no ronly heap slots, so any allocation would have to result
-  // in a coalesce, and to validate that we don't reintroduce TS-2766 we have an aliased string, so when it tries to
-  // coalesce it used to sum up the size of the ronly heaps and the rw heap which is incorrect because we never
-  // copied the above string onto the heap. The new behaviour fixed in TS-2766 will make sure that this non copied
-  // string is accounted for, in the old implementation it would result in an allocation failure.
-
-  char *str = heap->allocate_str(1); // this will force a coalesce.
-  tb.check(str != nullptr, "Checking that 1 byte allocated string is not NULL");
-
-  // Now we need to validate that aliased_str_url has a path that isn't NULL, if it's NULL then the
-  // coalesce is broken and didn't properly determine the size, if it's not null then everything worked as expected.
-  tb.check(aliased_str_url->m_len_path == next_required_overflow_size,
-           "Checking that the aliased string shows having proper length");
-  tb.check(aliased_str_url->m_ptr_path != nullptr,
-           "Checking that the aliased string was properly moved during coalsece and evacuation");
-  tb.check(aliased_str_url->m_ptr_path != buf3,
-           "Checking that the aliased string was properly moved during coalsece and evacuation (not pointing at buf3)");
-
-  // Clean up
-  heap->destroy();
-}
-#endif
diff --git a/proxy/hdrs/Makefile.am b/proxy/hdrs/Makefile.am
index 75c3386..0542a57 100644
--- a/proxy/hdrs/Makefile.am
+++ b/proxy/hdrs/Makefile.am
@@ -61,7 +61,7 @@ load_http_hdr_LDADD = -L. -lhdrs \
 	$(top_builddir)/src/tscore/libtscore.la \
 	$(top_builddir)/src/tscpp/util/libtscpputil.la
 
-check_PROGRAMS = test_mime test_proxy_hdrs
+check_PROGRAMS = test_mime test_proxy_hdrs test_hdr_heap
 
 TESTS = $(check_PROGRAMS)
 
@@ -77,8 +77,8 @@ test_mime_LDADD = -L. -lhdrs \
 
 test_mime_SOURCES = test_mime.cc
 
-test_proxy_hdrs_CPPFLAGS = $(AM_CPPFLAGS)\
-        -I$(abs_top_srcdir)/tests/include
+test_proxy_hdrs_CPPFLAGS = $(AM_CPPFLAGS) \
+	-I$(abs_top_srcdir)/tests/include
 
 test_proxy_hdrs_SOURCES = \
 	unit_tests/unit_test_main.cc \
@@ -87,7 +87,26 @@ test_proxy_hdrs_SOURCES = \
 
 test_proxy_hdrs_LDADD = \
 	$(top_builddir)/src/tscore/libtscore.la \
-    -L. -lhdrs \
+	-L. -lhdrs \
+	$(top_builddir)/src/tscore/libtscore.la \
+	$(top_builddir)/src/tscpp/util/libtscpputil.la \
+	$(top_builddir)/iocore/eventsystem/libinkevent.a \
+	$(top_builddir)/lib/records/librecords_p.a \
+	$(top_builddir)/mgmt/libmgmt_p.la \
+	$(top_builddir)/proxy/shared/libUglyLogStubs.a \
+	@HWLOC_LIBS@ \
+	@LIBCAP@
+
+test_hdr_heap_CPPFLAGS = $(AM_CPPFLAGS) \
+	-I$(abs_top_srcdir)/tests/include
+
+test_hdr_heap_SOURCES = \
+	unit_tests/unit_test_main.cc \
+	unit_tests/test_HdrHeap.cc
+
+test_hdr_heap_LDADD = -L. -lhdrs \
+	$(top_builddir)/src/tscore/libtscore.la \
+	-L. -lhdrs \
 	$(top_builddir)/src/tscore/libtscore.la \
 	$(top_builddir)/src/tscpp/util/libtscpputil.la \
 	$(top_builddir)/iocore/eventsystem/libinkevent.a \
diff --git a/proxy/hdrs/unit_tests/test_HdrHeap.cc b/proxy/hdrs/unit_tests/test_HdrHeap.cc
new file mode 100644
index 0000000..5893395
--- /dev/null
+++ b/proxy/hdrs/unit_tests/test_HdrHeap.cc
@@ -0,0 +1,132 @@
+/** @file
+
+   Catch-based unit tests for HdrHeap
+
+   @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.
+ */
+
+#include "catch.hpp"
+
+#include "HdrHeap.h"
+#include "URL.h"
+
+/**
+  This test is designed to test numerous pieces of the HdrHeaps including allocations,
+  demotion of rw heaps to ronly heaps, and finally the coalesce and evacuate behaviours.
+ */
+TEST_CASE("HdrHeap", "[proxy][hdrheap]")
+{
+  // The amount of space we will need to overflow the StrHdrHeap is HdrStrHeap::DEFAULT_SIZE - sizeof(HdrStrHeap)
+  size_t next_rw_heap_size           = HdrStrHeap::DEFAULT_SIZE;
+  size_t next_required_overflow_size = next_rw_heap_size - sizeof(HdrStrHeap);
+  char buf[next_required_overflow_size];
+  for (unsigned int i = 0; i < sizeof(buf); ++i) {
+    buf[i] = ('a' + (i % 26));
+  }
+
+  HdrHeap *heap = new_HdrHeap();
+  URLImpl *url  = url_create(heap);
+
+  // Checking that we have no rw heap
+  CHECK(heap->m_read_write_heap.get() == nullptr);
+  url_path_set(heap, url, buf, next_required_overflow_size, true);
+
+  // Checking that we've completely consumed the rw heap
+  CHECK(heap->m_read_write_heap->m_free_size == 0);
+
+  // Checking ronly_heaps are empty
+  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
+    CHECK(heap->m_ronly_heap[i].m_heap_start == nullptr);
+  }
+
+  // Now we have no ronly heaps in use and a completely full rwheap, so we will test that
+  // we demote to ronly heaps HDR_BUF_RONLY_HEAPS times.
+  for (unsigned ronly_heap = 0; ronly_heap < HDR_BUF_RONLY_HEAPS; ++ronly_heap) {
+    next_rw_heap_size           = 2 * heap->m_read_write_heap->m_heap_size;
+    next_required_overflow_size = next_rw_heap_size - sizeof(HdrStrHeap);
+    char buf2[next_required_overflow_size];
+    for (unsigned int i = 0; i < sizeof(buf2); ++i) {
+      buf2[i] = ('a' + (i % 26));
+    }
+
+    URLImpl *url2 = url_create(heap);
+    url_path_set(heap, url2, buf2, next_required_overflow_size, true);
+
+    // Checking the current rw heap is next_rw_heap_size bytes
+    CHECK(heap->m_read_write_heap->m_heap_size == (uint32_t)next_rw_heap_size);
+    // Checking that we've completely consumed the rw heap
+    CHECK(heap->m_read_write_heap->m_free_size == 0);
+    // Checking that we properly demoted the previous rw heap
+    CHECK(heap->m_ronly_heap[ronly_heap].m_heap_start != nullptr);
+
+    for (unsigned i = ronly_heap + 1; i < HDR_BUF_RONLY_HEAPS; ++i) {
+      // Checking ronly_heap[i] is empty
+      CHECK(heap->m_ronly_heap[i].m_heap_start == nullptr);
+    }
+  }
+
+  // We will rerun these checks after we introduce a non-copied string to make sure we didn't already coalesce
+  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
+    // Pre non-copied string: Checking ronly_heaps[i] is NOT empty
+    CHECK(heap->m_ronly_heap[i].m_heap_start != nullptr);
+  }
+
+  // Now if we add a url object that contains only non-copied strings it shouldn't affect the size of the rwheap
+  // since it doesn't require allocating any storage on this heap.
+  char buf3[next_required_overflow_size];
+  for (unsigned int i = 0; i < sizeof(buf3); ++i) {
+    buf3[i] = ('a' + (i % 26));
+  }
+
+  URLImpl *aliased_str_url = url_create(heap);
+  url_path_set(heap, aliased_str_url, buf3, next_required_overflow_size, false); // don't copy this string
+  // Checking that the aliased string shows having proper length
+  CHECK(aliased_str_url->m_len_path == next_required_overflow_size);
+  // Checking that the aliased string is correctly pointing at buf
+  CHECK(aliased_str_url->m_ptr_path == &buf3[0]);
+
+  // Post non-copied string: Checking ronly_heaps are NOT empty
+  for (unsigned i = 0; i < HDR_BUF_RONLY_HEAPS; ++i) {
+    CHECK(heap->m_ronly_heap[i].m_heap_start != nullptr);
+  }
+  // Checking that we've completely consumed the rw heap
+  CHECK(heap->m_read_write_heap->m_free_size == 0);
+  // Checking that we dont have any chained heaps
+  CHECK(heap->m_next == nullptr);
+
+  // Now at this point we have a completely full rw_heap and no ronly heap slots, so any allocation would have to result
+  // in a coalesce, and to validate that we don't reintroduce TS-2766 we have an aliased string, so when it tries to
+  // coalesce it used to sum up the size of the ronly heaps and the rw heap which is incorrect because we never
+  // copied the above string onto the heap. The new behaviour fixed in TS-2766 will make sure that this non copied
+  // string is accounted for, in the old implementation it would result in an allocation failure.
+
+  char *str = heap->allocate_str(1); // this will force a coalesce.
+  // Checking that 1 byte allocated string is not nullptr
+  CHECK(str != nullptr);
+
+  // Now we need to validate that aliased_str_url has a path that isn't nullptr, if it's nullptr then the
+  // coalesce is broken and didn't properly determine the size, if it's not nullptr then everything worked as expected.
+
+  // Checking that the aliased string shows having proper length
+  CHECK(aliased_str_url->m_len_path == next_required_overflow_size);
+  // Checking that the aliased string was properly moved during coalesce and evacuation
+  CHECK(aliased_str_url->m_ptr_path != nullptr);
+  // Checking that the aliased string was properly moved during coalesce and evacuation (not pointing at buf3)
+  CHECK(aliased_str_url->m_ptr_path != &buf3[0]);
+
+  // Clean up
+  heap->destroy();
+}