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();
+}