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 cac9adf88 QUIC: Test basic scenarios around the 
ts.quic.no_activity_timeout_in config. (#9543)
cac9adf88 is described below

commit cac9adf8820edb1ee80472b61e15a86c042772a3
Author: Damian Meden <[email protected]>
AuthorDate: Thu Mar 23 12:11:18 2023 +0000

    QUIC: Test basic scenarios around the ts.quic.no_activity_timeout_in 
config. (#9543)
---
 iocore/net/QUICNetVConnection_quiche.cc            |   5 +-
 .../timeout/gold/quic_no_activity_timeout.gold     |   3 +
 .../timeout/quic_no_activity_timeout.test.py       | 139 +++++++++++++++++++++
 .../replay/quic_no_activity_timeout.replay.yaml    |  91 ++++++++++++++
 tests/gold_tests/timeout/ssl/cert.crt              |  33 +++++
 tests/gold_tests/timeout/ssl/private-key.key       |  52 ++++++++
 6 files changed, 321 insertions(+), 2 deletions(-)

diff --git a/iocore/net/QUICNetVConnection_quiche.cc 
b/iocore/net/QUICNetVConnection_quiche.cc
index 278b3b27a..df0d614b3 100644
--- a/iocore/net/QUICNetVConnection_quiche.cc
+++ b/iocore/net/QUICNetVConnection_quiche.cc
@@ -149,7 +149,7 @@ QUICNetVConnection::state_handshake(int event, Event *data)
     this->closed = 1;
     break;
   default:
-    QUICConDebug("Unhandleed event: %d", event);
+    QUICConDebug("Unhandled event: %d", event);
     break;
   }
 
@@ -180,7 +180,7 @@ QUICNetVConnection::state_established(int event, Event 
*data)
     this->closed = 1;
     break;
   default:
-    QUICConDebug("Unhandleed event: %d", event);
+    QUICConDebug("Unhandled event: %d", event);
     break;
   }
   return EVENT_DONE;
@@ -593,6 +593,7 @@ QUICNetVConnection::_handle_interval()
     this->_ctable->erase(this->_original_quic_connection_id, this);
 
     if (quiche_conn_is_timed_out(this->_quiche_con)) {
+      QUICConDebug("QUIC Idle timeout detected");
       this->thread->schedule_imm(this, VC_EVENT_INACTIVITY_TIMEOUT);
       return;
     }
diff --git a/tests/gold_tests/timeout/gold/quic_no_activity_timeout.gold 
b/tests/gold_tests/timeout/gold/quic_no_activity_timeout.gold
new file mode 100644
index 000000000..c12362405
--- /dev/null
+++ b/tests/gold_tests/timeout/gold/quic_no_activity_timeout.gold
@@ -0,0 +1,3 @@
+``
+``Poll timed out waiting to read HTTP/3 content.
+``
diff --git a/tests/gold_tests/timeout/quic_no_activity_timeout.test.py 
b/tests/gold_tests/timeout/quic_no_activity_timeout.test.py
new file mode 100644
index 000000000..32dadf076
--- /dev/null
+++ b/tests/gold_tests/timeout/quic_no_activity_timeout.test.py
@@ -0,0 +1,139 @@
+#  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.
+
+Test.Summary = 'Basic checks on QUIC max_idle_timeout set by 
ts.quic.no_activity_timeout_in'
+
+
+Test.SkipUnless(
+    Condition.HasATSFeature('TS_HAS_QUICHE'),
+    Condition.HasCurlFeature('http3')
+)
+
+
+class Test_quic_no_activity_timeout:
+    """Configure a test for QUIC no_activity_timeout_in."""
+
+    replay_file = "replay/quic_no_activity_timeout.replay.yaml"
+    client_counter: int = 0
+    ts_counter: int = 0
+    server_counter: int = 0
+
+    def __init__(self, name: str, no_activity_timeout_in=1000, gold_file="", 
replay_keys="", extra_recs=None):
+        """Initialize the test.
+
+        :param name: The name of the test.
+        :param no_activity_timeout_in: Configuration value for 
ts.quic.no_activity_timeout_in
+        :param gold_file: Gold file to be checked.
+        :param replay_keys: Keys to be used by pv
+        :param extra_recs: Any additional records to be set, either a yaml 
string or a dict.
+        """
+        self.name = name
+        self.no_activity_timeout_in = no_activity_timeout_in
+        self.gold_file = gold_file
+        self.replay_keys = replay_keys
+        self.extra_recs = extra_recs
+
+    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_{Test_quic_no_activity_timeout.server_counter}",
+            self.replay_file)
+        Test_quic_no_activity_timeout.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 = 
tr.MakeATSProcess(f"ts-{Test_quic_no_activity_timeout.ts_counter}", 
enable_quic=True, enable_tls=True)
+
+        Test_quic_no_activity_timeout.ts_counter += 1
+        self._ts = ts
+        self._ts.addSSLfile("ssl/cert.crt")
+        self._ts.addSSLfile("ssl/private-key.key")
+        self._ts.Disk.records_config.update({
+            'proxy.config.diags.debug.enabled': 1,
+            'proxy.config.diags.debug.tags': 
'ssl|net|v_quic|quic|http|socket|inactivity_cop',
+            'proxy.config.quic.no_activity_timeout_in': 
self.no_activity_timeout_in,
+            'proxy.config.quic.qlog.file_base': 
f'log/qlog_{Test_quic_no_activity_timeout.server_counter}',
+        })
+
+        if self.extra_recs:
+            self._ts.Disk.records_config.update(self.extra_recs)
+
+        self._ts.Disk.remap_config.AddLine(f'map / 
http://127.0.0.1:{self._server.Variables.http_port}')
+        self._ts.Disk.ssl_multicert_config.AddLine(
+            f'dest_ip=* ssl_cert_name={self._ts.Variables.SSLDir}/cert.crt 
ssl_key_name={self._ts.Variables.SSLDir}/private-key.key'
+        )
+
+    def run(self, check_for_max_idle_timeout=False):
+        """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-{Test_quic_no_activity_timeout.client_counter}',
+            self.replay_file,
+            http3_ports=[self._ts.Variables.ssl_port],
+            keys=self.replay_keys)
+        Test_quic_no_activity_timeout.client_counter += 1
+
+        if check_for_max_idle_timeout:
+            tr.Processes.Default.ReturnCode = 1  # timeout
+            self._ts.Disk.traffic_out.All = Testers.IncludesExpression(
+                "QUIC Idle timeout detected", "We should detect the timeout.")
+        else:
+            tr.Processes.Default.ReturnCode = 0
+
+        if self.gold_file:
+            tr.Processes.Default.Streams.all = self.gold_file
+
+# Tests start.
+
+
+test0 = Test_quic_no_activity_timeout(
+    "Test ts.quic.no_activity_timeout_in(quic max_idle_timeout), no delays",
+    no_activity_timeout_in=0,  # no timeout `max_idle_timeout`
+    replay_keys="nodelays")
+test0.run()
+
+test1 = Test_quic_no_activity_timeout(
+    "Test ts.quic.no_activity_timeout_in(quic max_idle_timeout) with a 5s 
delay",
+    no_activity_timeout_in=3000,  # 3s `max_idle_timeout`
+    replay_keys="delay5s",
+    gold_file="gold/quic_no_activity_timeout.gold")
+test1.run(check_for_max_idle_timeout=True)
+
+##
+# The following tests is commented out as if we have a smaller 
default_inactivity_timeout
+# happening before the configured max_idle_timeout in quiche we will end up 
crashing.
+# The following should be uncommented once the bug is fixed.
+#
+
+# test2 = Test_quic_no_activity_timeout(
+#     "Test quic ts.quic.no_activity_timeout_in(max_idle_timeout_, 
default_inactivity_timeout should kick in first.",
+#     replay_keys="delay5s",
+#     no_activity_timeout_in=6800,
+#     extra_recs={'proxy.config.net.default_inactivity_timeout': 1})
+# test2.run()
diff --git 
a/tests/gold_tests/timeout/replay/quic_no_activity_timeout.replay.yaml 
b/tests/gold_tests/timeout/replay/quic_no_activity_timeout.replay.yaml
new file mode 100644
index 000000000..1937e6e68
--- /dev/null
+++ b/tests/gold_tests/timeout/replay/quic_no_activity_timeout.replay.yaml
@@ -0,0 +1,91 @@
+#  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, nodelays ]
+    server-response:
+      status: 200
+      reason: "OK"
+      headers:
+        fields:
+        - [ Content-Length, 20 ]
+
+    proxy-response:
+      status: 200
+
+  - client-request:
+      delay: 5s
+      version: "3"
+      headers:
+        fields:
+        - [ Content-Length, 0 ]
+        - [:method, GET]
+        - [:scheme, https]
+        - [:authority, example.com]
+        - [:path, /path/test2]
+        - [ uuid, delay5s ]
+    server-response:
+      status: 200
+      reason: "OK"
+      headers:
+        fields:
+        - [ Content-Length, 20 ]
+
+    proxy-response:
+      status: 200
+
+  - client-request:
+      delay: 1500ms
+      version: "3"
+      headers:
+        fields:
+        - [ Content-Length, 0 ]
+        - [:method, GET]
+        - [:scheme, https]
+        - [:authority, example.com]
+        - [:path, /path/test3]
+        - [ uuid, delay1500ms ]
+    server-response:
+      status: 200
+      reason: "OK"
+      headers:
+        fields:
+        - [ Content-Length, 20 ]
+
+    proxy-response:
+      status: 200
+
+
+
diff --git a/tests/gold_tests/timeout/ssl/cert.crt 
b/tests/gold_tests/timeout/ssl/cert.crt
new file mode 100644
index 000000000..8dedfa250
--- /dev/null
+++ b/tests/gold_tests/timeout/ssl/cert.crt
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFoDCCA4igAwIBAgIUPWkE7mLk4qWFS6dxtSaFDRdjAm4wDQYJKoZIhvcNAQEL
+BQAwZzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFp
+biBWaWV3MRcwFQYDVQQKDA5UcmFmZmljIFNlcnZlcjEaMBgGA1UEAwwRdHJhZmZp
+Y3NlcnZlci5vcmcwHhcNMjMwMjE3MTIyMzI2WhcNMjUwMjE2MTIyMzI2WjBnMQsw
+CQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcx
+FzAVBgNVBAoMDlRyYWZmaWMgU2VydmVyMRowGAYDVQQDDBF0cmFmZmljc2VydmVy
+Lm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANyUH2QdsM3FuEGS
+bZv/GZF4JT2e5zIdlj0AlobvpDntGAuGeAQpRBLrAyWxobCBbEqYvqXo1QXTDdee
+Bx9fRiOhHkBC1OMMP5cJ9zdzo1/jXZ5A4WXATaxcX6VdmynxuoHLpyQZg504jFgB
+HkpkYD0PCoB2aQ2uhE2O8oSQVVkI0ExyJLyq7mfdqbl/0wKc8XLPh9XtBTSbmELm
+wAuCyFutsYGcv/4hMPZC6cbAjCWLQyokkH2mdNXdi4d95KDoL7wyh5inGaymCJbj
+ObrqJ6Jj17GkBltqVV9LdBqLcqFQPbvdQycizWgeWmYJvBApgHxpp8aET4r0v+SL
+fnXJx6M1ugohv6E832isemM0+yuWD6z9ZH/jBRHAQukLB4fqojFS8qIgEnXzH+vD
+jk0mm6gm3hIZ+Xk/f/DGCX/fv8Un+MlZotJqaAEbWH1OxSJ2HpTMoOCIKPvmWZjk
+qv9A5rJckXx9rzNukQt3ZU85LyHrDVOp+VQoyzyqGqhKPBC1gkQ/KenweAufMGU2
+9WFP6Oc5J807R3NR4q95DRg14yLB5fLF2R1yXkrxv3/qpRp+LGeYTL9AqOtJWIlf
+pm50qbb9G/akxsl050AyXHDqzjTddHtlf0aOI97/DI8+KyfbzlTKPPllUoYcj8S4
+kRnlIvQyFGjZWZNFdksCXJzcG5/JAgMBAAGjRDBCMAsGA1UdDwQEAwIF4DATBgNV
+HSUEDDAKBggrBgEFBQcDATAeBgNVHREEFzAVghMqLnRyYWZmaWNzZXJ2ZXIub3Jn
+MA0GCSqGSIb3DQEBCwUAA4ICAQAzik7Hq+tjIeFHlFdeIHTlrVcuu+12XQ05bpwS
+X2RdVSMj2FzjuOB1OTAMBpFl8hrLN1p5vTpIJ0x/Zx5Ks2YaR/KmF5In8/vPNbIr
+ZHVfnLSgg/X+1dtN1LVnue+kQbuc7OlzJpwfmQjA4BYzAb0fbf+IM7E6MfEzT/kB
+AChW3WF9eviyklOV0qZlRLDwrQLIT+oLsJNkX7OWFpVrpXrOLj4hYf2N7zxGHxYJ
+g9NkmZOTJ4maXEpzNZaewpuIW4ldZccGchwhSX0daaoVmqYSVXjfRaCpRcb0mrPR
+oj9x0Jj17v4G3FoyaOoW1DEAZwjFj8r7WaauGagQqBq0kflItrIRjzI+MlJkX3QS
+0AKedEllbCpSe5VJcHlaR7K3y9w3hQTKlN4Im6M8eDJ+qxYURbDLE2cHBuaYkI9Q
+aZcojBYSRA++fmmS5805CqKrhCCZbORI5zqBoB6iFUG1z+dwdpygDMpuH0bbXwQ1
+mp4S8GRKtTeJ2y2aFw/i/Wi/Qs8nAbQlSc6ei+oWT9ywdvkCFfdcsP+2LrWVVN3w
+wAl26S08x9pZPI5kAvIG0DllSXYf65V3YXdzPoZ78igobWzfszAZ6OxfDQgkewfp
+h4OSYKHBl3Jfe/Q9B8PcmgW0ikKGcquxFg3hvlMc0GZ/fVqUu++X+9Vb+QtMgyjJ
+y4ybug==
+-----END CERTIFICATE-----
diff --git a/tests/gold_tests/timeout/ssl/private-key.key 
b/tests/gold_tests/timeout/ssl/private-key.key
new file mode 100644
index 000000000..f4350d6b2
--- /dev/null
+++ b/tests/gold_tests/timeout/ssl/private-key.key
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+o6MNJBWDIgSRGCjUC0jfnjes9h8Lf9Q=
+-----END PRIVATE KEY-----

Reply via email to