This is an automated email from the ASF dual-hosted git repository.
dmeden 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 61dc33447 QUIC: Add a unit tests to validate that the qlog file is
generated (and no crashes) (#9668)
61dc33447 is described below
commit 61dc33447465be8f45ae555b668c47bc19ab0787
Author: Damian Meden <[email protected]>
AuthorDate: Fri May 12 16:24:13 2023 +0100
QUIC: Add a unit tests to validate that the qlog file is generated (and no
crashes) (#9668)
* QUIC: Add a unit tests to validate that the qlog file is generated(if
configured).
This also uses buffer writter to build up the qlog name(instead of
snprintf).
---
iocore/net/QUICPacketHandler_quiche.cc | 15 ++-
tests/gold_tests/logging/qlog_quiche.test.py | 130 +++++++++++++++++++++
tests/gold_tests/logging/rename_qlog.sh | 35 ++++++
tests/gold_tests/logging/replay/basic1.replay.yaml | 50 ++++++++
4 files changed, 224 insertions(+), 6 deletions(-)
diff --git a/iocore/net/QUICPacketHandler_quiche.cc
b/iocore/net/QUICPacketHandler_quiche.cc
index d256445c1..bad50d651 100644
--- a/iocore/net/QUICPacketHandler_quiche.cc
+++ b/iocore/net/QUICPacketHandler_quiche.cc
@@ -32,6 +32,8 @@
#include "QUICMultiCertConfigLoader.h"
#include <quiche.h>
+#include "swoc/BufferWriter.h"
+
static constexpr char debug_tag[] = "quic_sec";
static constexpr char v_debug_tag[] = "v_quic_sec";
@@ -285,14 +287,15 @@ QUICPacketHandlerIn::_recv_packet(int event, UDPPacket
*udp_packet)
udp_packet->from.isIp4() ? sizeof(udp_packet->from.sin) :
sizeof(udp_packet->from.sin6), &this->_quiche_config, ssl, true);
if (params->get_qlog_file_base_name() != nullptr) {
- char qlog_filepath[PATH_MAX];
+ swoc::LocalBufferWriter<PATH_MAX> w;
const uint8_t *quic_trace_id;
- size_t quic_trace_id_len = 0;
+ size_t quic_trace_id_len{0};
quiche_conn_trace_id(quiche_con, &quic_trace_id, &quic_trace_id_len);
- snprintf(qlog_filepath, PATH_MAX, "%s-%.*s.sqlog",
Layout::get()->relative(params->get_qlog_file_base_name()).c_str(),
- static_cast<int>(quic_trace_id_len), quic_trace_id);
- if (auto success = quiche_conn_set_qlog_path(quiche_con, qlog_filepath,
"Apache Traffic Server", "qlog"); !success) {
- QUICDebug("quiche_conn_set_qlog_path failed to use %s", qlog_filepath);
+
+ w.print("{}-{}.sqlog\0",
Layout::get()->relative(params->get_qlog_file_base_name()),
+ std::string_view{reinterpret_cast<const char *>(quic_trace_id),
quic_trace_id_len});
+ if (auto success = quiche_conn_set_qlog_path(quiche_con, w.data(),
"Apache Traffic Server", "qlog"); !success) {
+ QUICDebug("quiche_conn_set_qlog_path failed to use %s", w.data());
}
}
diff --git a/tests/gold_tests/logging/qlog_quiche.test.py
b/tests/gold_tests/logging/qlog_quiche.test.py
new file mode 100644
index 000000000..e6265f4e2
--- /dev/null
+++ b/tests/gold_tests/logging/qlog_quiche.test.py
@@ -0,0 +1,130 @@
+'''
+'''
+# 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.
+
+import os
+
+Test.Summary = '''
+Basic test for qlog using quiche library.
+'''
+
+Test.SkipUnless(
+ Condition.HasATSFeature('TS_HAS_QUICHE')
+)
+
+Generate_Qlog = True
+No_Qlog = False
+
+
+class quiche_qlog_Test:
+ replay_file = "replay/basic1.replay.yaml"
+ client_counter: int = 0
+ ts_counter: int = 0
+ server_counter: int = 0
+
+ def __init__(self, name: str):
+ """Initialize the test.
+ :param name: The name of the test.
+ """
+ self._name = name
+ self._generate_qlog = False
+
+ def with_qlogs(self):
+ self._generate_qlog = True
+ return self
+
+ def without_qlogs(self):
+ self._generate_qlog = False
+ return self
+
+ def _configure_server(self, tr: 'TestRun'):
+ """Configure the server.
+
+ :param tr: The TestRun object to associate the server process with.
+ """
+ server =
tr.AddVerifierServerProcess(f"server_{quiche_qlog_Test.server_counter}",
self.replay_file)
+ quiche_qlog_Test.server_counter += 1
+ self._server = server
+
+ def _configure_traffic_server(self, tr: 'TestRun'):
+ """Configure Traffic Server.
+
+ :param tr: The TestRun object to associate the ts process with.
+ """
+ ts = Test.MakeATSProcess(f"ts-{quiche_qlog_Test.ts_counter}",
enable_quic=True, enable_tls=True)
+ self._ts = ts
+ quiche_qlog_Test.ts_counter += 1
+ self._ts.addDefaultSSLFiles()
+ self._ts.Disk.records_config.update(
+ '''
+ diags:
+ debug:
+ enabled: 1
+ tags: vv_quic|v_quic
+ quic:
+ no_activity_timeout_in: 3000
+ ''')
+ if self._generate_qlog:
+ self._ts.Disk.records_config.update(
+ '''
+ quic:
+ qlog:
+ file_base: log/test_qlog # we expect to have
log/test_qlog-<TRACE ID>.sqlog
+ '''
+ )
+ self._ts.Disk.ssl_multicert_config.AddLine(
+ f'dest_ip=* ssl_cert_name={ts.Variables.SSLDir}/server.pem
ssl_key_name={ts.Variables.SSLDir}/server.key'
+ )
+
+ self._ts.Disk.remap_config.AddLine(f'map /
http://127.0.0.1:{self._server.Variables.http_port}')
+
+ def test(self):
+ """Run the test."""
+ tr = Test.AddTestRun(self._name)
+ self._configure_server(tr)
+ self._configure_traffic_server(tr)
+
+ tr.Processes.Default.StartBefore(self._server)
+ tr.Processes.Default.StartBefore(self._ts)
+ tr.AddVerifierClientProcess(
+ f"client-{quiche_qlog_Test.client_counter}",
+ self.replay_file,
+ http3_ports=[
+ self._ts.Variables.ssl_port])
+ quiche_qlog_Test.client_counter += 1
+ tr.Processes.Default.ReturnCode = 0
+
+ # If requested we will copy the file to a known name as the runtime
name is not know
+ # by the test. So we will rename them all and grab the first one for
validation.
+ test_run = Test.AddTestRun(f"{self._name} : check qlog files")
+ qlog_base_name = "test_qlog"
+ rename_script = os.path.join(Test.TestDirectory, 'rename_qlog.sh')
+ test_run.Processes.Default.Command = f'sleep 5; bash {rename_script}
{self._ts.Variables.LOGDIR} {qlog_base_name}'
+ test_run.Processes.Default.ReturnCode = 0 if self._generate_qlog else
2 # exit 2 is what we want if no qlog was generated.
+
+ # Basic valdation
+ if self._generate_qlog:
+ tr = Test.AddTestRun("Check qlog content")
+ file = os.path.join(self._ts.Variables.LOGDIR, "1.sqlog")
+ f = tr.Disk.File(file)
+ tr.Processes.Default.Command = "echo 0"
+ tr.Processes.Default.ReturnCode = 0
+ f.Content = Testers.IncludesExpression('"title":"Apache Traffic
Server"', 'Should include this basic text')
+
+
+quiche_qlog_Test("Generate qlog test").with_qlogs().test()
+quiche_qlog_Test("Do not generate qlog").without_qlogs().test()
diff --git a/tests/gold_tests/logging/rename_qlog.sh
b/tests/gold_tests/logging/rename_qlog.sh
new file mode 100755
index 000000000..4fcb8b273
--- /dev/null
+++ b/tests/gold_tests/logging/rename_qlog.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# 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.
+
+# Rename qlog files base on a folder and a file name basename
+
+x=0
+
+for i in `find $1 -name $2*`; do
+ ((x+=1))
+ mv -- "$i" "$1/$x.sqlog"
+ echo "renamed $i with $1/$x.sqlog"
+done
+
+if [ $x -gt 0 ]; then
+ echo "exit with 0"
+ exit 0
+else
+ echo "exit with 2"
+ exit 2
+fi
diff --git a/tests/gold_tests/logging/replay/basic1.replay.yaml
b/tests/gold_tests/logging/replay/basic1.replay.yaml
new file mode 100644
index 000000000..4de3719c2
--- /dev/null
+++ b/tests/gold_tests/logging/replay/basic1.replay.yaml
@@ -0,0 +1,50 @@
+# 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.
+
+meta:
+ version: "1.0"
+
+sessions:
+- protocol:
+ - name: http
+ version: 3
+ - name: tls
+ sni: test_sni
+ transactions:
+
+ - client-request:
+ version: "3"
+ headers:
+ fields:
+ - [ Content-Length, 0 ]
+ - [:method, GET]
+ - [:scheme, https]
+ - [:authority, example.com]
+ - [:path, /path/test1]
+ - [ uuid, generate_qlog1 ]
+ server-response:
+ status: 200
+ reason: "OK"
+ headers:
+ fields:
+ - [ Content-Length, 20 ]
+
+ proxy-response:
+ status: 200
+
+
+
+