diff --git a/.gitignore b/.gitignore index 8ed12078c3b..04cc025bdc6 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ proxy/http/remap/test_PluginFactory proxy/http/remap/test_RemapPluginInfo proxy/http/test_proxy_http proxy/http/remap/test_* +proxy/http2/test_libhttp2 proxy/http2/test_Http2DependencyTree proxy/http2/test_Http2FrequencyCounter proxy/http2/test_HPACK diff --git a/proxy/http2/HTTP2.h b/proxy/http2/HTTP2.h index 41518871c0b..7bcc75f1ddc 100644 --- a/proxy/http2/HTTP2.h +++ b/proxy/http2/HTTP2.h @@ -302,7 +302,6 @@ struct Http2RstStream { // [RFC 7540] 6.6 PUSH_PROMISE Format struct Http2PushPromise { - Http2PushPromise() {} uint8_t pad_length = 0; Http2StreamId promised_streamid = 0; }; diff --git a/proxy/http2/Http2Frame.h b/proxy/http2/Http2Frame.h index dd68b8c105c..b0bcd35d022 100644 --- a/proxy/http2/Http2Frame.h +++ b/proxy/http2/Http2Frame.h @@ -169,7 +169,10 @@ class Http2PushPromiseFrame : public Http2TxFrame { public: Http2PushPromiseFrame(Http2StreamId stream_id, uint8_t flags, Http2PushPromise p, uint8_t *h, uint32_t l) - : Http2TxFrame({l, HTTP2_FRAME_TYPE_PUSH_PROMISE, flags, stream_id}), _params(p), _hdr_block(h), _hdr_block_len(l) + : Http2TxFrame({l + static_cast(sizeof(Http2StreamId)), HTTP2_FRAME_TYPE_PUSH_PROMISE, flags, stream_id}), + _params(p), + _hdr_block(h), + _hdr_block_len(l) { } diff --git a/proxy/http2/Makefile.am b/proxy/http2/Makefile.am index 6ca54fe9bf9..0952eef8852 100644 --- a/proxy/http2/Makefile.am +++ b/proxy/http2/Makefile.am @@ -60,14 +60,30 @@ libhttp2_a_SOURCES += \ endif check_PROGRAMS = \ + test_libhttp2 \ test_Http2DependencyTree \ test_Http2FrequencyCounter \ test_HPACK -TESTS = \ - test_Http2DependencyTree \ - test_Http2FrequencyCounter \ - test_HPACK +TESTS = $(check_PROGRAMS) + +test_libhttp2_LDADD = \ + libhttp2.a \ + $(top_builddir)/proxy/hdrs/libhdrs.a \ + $(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@ + +test_libhttp2_CPPFLAGS = $(AM_CPPFLAGS)\ + -I$(abs_top_srcdir)/tests/include + +test_libhttp2_SOURCES = \ + unit_tests/test_Http2Frame.cc \ + unit_tests/main.cc test_Http2DependencyTree_LDADD = \ $(top_builddir)/src/tscore/libtscore.la \ diff --git a/proxy/http2/unit_tests/main.cc b/proxy/http2/unit_tests/main.cc new file mode 100644 index 00000000000..aa19e099b95 --- /dev/null +++ b/proxy/http2/unit_tests/main.cc @@ -0,0 +1,55 @@ +/** @file + + The main file for test_libhttp2 + + @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. +*/ + +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#include "tscore/I_Layout.h" + +#include "I_EventSystem.h" +#include "RecordsConfig.h" + +#include "diags.i" + +#define TEST_THREADS 1 + +struct EventProcessorListener : Catch::TestEventListenerBase { + using TestEventListenerBase::TestEventListenerBase; + + void + testRunStarting(Catch::TestRunInfo const &testRunInfo) override + { + Layout::create(); + init_diags("", nullptr); + RecProcessInit(RECM_STAND_ALONE); + LibRecordsConfigInit(); + + ink_event_system_init(EVENT_SYSTEM_MODULE_PUBLIC_VERSION); + eventProcessor.start(TEST_THREADS); + + EThread *main_thread = new EThread; + main_thread->set_specific(); + } +}; + +CATCH_REGISTER_LISTENER(EventProcessorListener); diff --git a/proxy/http2/unit_tests/test_Http2Frame.cc b/proxy/http2/unit_tests/test_Http2Frame.cc new file mode 100644 index 00000000000..d1e695e4fe0 --- /dev/null +++ b/proxy/http2/unit_tests/test_Http2Frame.cc @@ -0,0 +1,64 @@ +/** @file + + Unit tests for Http2Frame + + @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 "Http2Frame.h" + +TEST_CASE("Http2Frame", "[http2][Http2Frame]") +{ + MIOBuffer *miob = new_MIOBuffer(); + IOBufferReader *miob_r = miob->alloc_reader(); + + SECTION("PUSH_PROMISE") + { + Http2StreamId id = 1; + uint8_t flags = HTTP2_FLAGS_PUSH_PROMISE_END_HEADERS; + Http2PushPromise pp{0, 2}; + uint8_t hdr_block[] = {0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef}; + uint8_t hdr_block_len = sizeof(hdr_block); + + Http2PushPromiseFrame frame(id, flags, pp, hdr_block, hdr_block_len); + uint64_t written = frame.write_to(miob); + + CHECK(written == HTTP2_FRAME_HEADER_LEN + sizeof(Http2StreamId) + hdr_block_len); + CHECK(written == miob_r->read_avail()); + + uint8_t buf[32] = {0}; + uint64_t read = miob_r->read(buf, written); + CHECK(read == written); + + uint8_t expected[] = { + 0x00, 0x00, 0x0e, ///< Length + 0x05, ///< Type + 0x04, ///< Flags + 0x00, 0x00, 0x00, 0x01, ///< Stream Identifier (31) + 0x00, 0x00, 0x00, 0x02, ///< Promised Stream ID + 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef ///< Header Block Fragment + }; + + CHECK(memcmp(buf, expected, written) == 0); + } + + free_MIOBuffer(miob); +}