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
+
+
+
+

Reply via email to