This is an automated email from the ASF dual-hosted git repository.

bneradt 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 f063c0eb9a Make log pipe test tolerate restricted kernels (#13431)
f063c0eb9a is described below

commit f063c0eb9a60b400bf0d5be8a494f808f286dfe8
Author: Brian Neradt <[email protected]>
AuthorDate: Fri Jul 31 17:05:27 2026 -0500

    Make log pipe test tolerate restricted kernels (#13431)
    
    Some CI environments do not permit unprivileged processes to increase
    FIFO buffer sizes, even when the requested size is below the system
    maximum. The log_pipe AuTest treats this kernel policy as a product
    failure and cannot run in those environments.
    
    This makes the test accept only the corresponding `Operation not
    permitted` diagnostic when the FIFO remains unchanged, while continuing
    to reject other errors and fatal diagnostics. It also waits briefly for
    asynchronous diagnostic output before deciding whether the size check
    failed.
---
 tests/gold_tests/logging/log_pipe.test.py          | 18 +++++++++++----
 .../logging/pipe_buffer_is_larger_than.py          | 26 +++++++++++++++++-----
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/tests/gold_tests/logging/log_pipe.test.py 
b/tests/gold_tests/logging/log_pipe.test.py
index e550b75b5e..fbfcc67b6f 100644
--- a/tests/gold_tests/logging/log_pipe.test.py
+++ b/tests/gold_tests/logging/log_pipe.test.py
@@ -27,12 +27,16 @@ 
Test.SkipUnless(Condition.HasATSFeature('TS_HAS_PIPE_BUFFER_SIZE_CONFIG'))
 ts_counter = 1
 
 
-def get_ts(logging_config):
+def get_ts(logging_config, disable_log_checks=False):
     """
     Create a Traffic Server process.
+
+    :param disable_log_checks: Whether to disable the default diagnostics log
+        checks on systems where the kernel may reject increasing the pipe
+        buffer size for an unprivileged Traffic Server process.
     """
     global ts_counter
-    ts = Test.MakeATSProcess("ts{}".format(ts_counter))
+    ts = Test.MakeATSProcess("ts{}".format(ts_counter), 
disable_log_checks=disable_log_checks)
     ts_counter += 1
 
     ts.Disk.records_config.update(
@@ -122,10 +126,15 @@ logging:
       mode: ascii_pipe
       format: custom
       pipe_buffer_size: {}
-      '''.format(pipe_name, pipe_size).split("\n"))
+      '''.format(pipe_name, pipe_size).split("\n"),
+    disable_log_checks=True)
 
 pipe_path = os.path.join(ts.Variables.LOGDIR, pipe_name)
 
+ts.Disk.diags_log.Content += Testers.ExcludesExpression(
+    r"ERROR:(?! Set pipe size failed for pipe .*: Operation not permitted)", 
"The diagnostics should contain no unexpected errors.")
+ts.Disk.diags_log.Content += Testers.ExcludesExpression("FATAL:", "The 
diagnostics should contain no fatal errors.")
+
 ts.Disk.traffic_out.Content += Testers.ContainsExpression(
     "Created named pipe .*{}".format(pipe_name), "Verify that the named pipe 
was created")
 
@@ -147,7 +156,8 @@ ts.Disk.traffic_out.Content += Testers.ContainsExpression(
     "New buffer size for pipe.*{}".format(pipe_name), "Verify that the named 
pipe's size was adjusted")
 buffer_verifier = "pipe_buffer_is_larger_than.py"
 tr.Setup.Copy(buffer_verifier)
-verify_buffer_size = tr.Processes.Process("verify_buffer_size", 
f"{sys.executable} {buffer_verifier} {pipe_path} {pipe_size}")
+verify_buffer_size = tr.Processes.Process(
+    "verify_buffer_size", f"{sys.executable} {buffer_verifier} {pipe_path} 
{pipe_size} {ts.Disk.diags_log.AbsPath}")
 verify_buffer_size.Return = 0
 verify_buffer_size.Streams.All += Testers.ContainsExpression("Success", "The 
buffer size verifier should report success.")
 
diff --git a/tests/gold_tests/logging/pipe_buffer_is_larger_than.py 
b/tests/gold_tests/logging/pipe_buffer_is_larger_than.py
index 194dbfa174..00fa7db43d 100644
--- a/tests/gold_tests/logging/pipe_buffer_is_larger_than.py
+++ b/tests/gold_tests/logging/pipe_buffer_is_larger_than.py
@@ -19,7 +19,9 @@
 
 import argparse
 import fcntl
+import os
 import sys
+import time
 
 F_SETPIPE_SZ = 1031  # Linux 2.6.35+
 F_GETPIPE_SZ = 1032  # Linux 2.6.35+
@@ -32,10 +34,12 @@ def parse_args():
 
     parser.add_argument('minimum_buffer_size', help='The minimu buffer size 
for the pipe to expect.')
 
+    parser.add_argument('diags_log', help='The diagnostics log in which a 
kernel permission error may be reported.')
+
     return parser.parse_args()
 
 
-def test_fifo(fifo, minimum_buffer_size):
+def test_fifo(fifo, minimum_buffer_size, diags_log):
     try:
         fifo_fd = open(fifo, "rb+", buffering=0)
         buffer_size = fcntl.fcntl(fifo_fd, F_GETPIPE_SZ)
@@ -43,9 +47,21 @@ def test_fifo(fifo, minimum_buffer_size):
         if buffer_size >= int(minimum_buffer_size):
             print("Success. Size is: {} which is larger than: 
{}".format(buffer_size, minimum_buffer_size))
             return 0
-        else:
-            print("Fail. Size is: {} which is smaller than: 
{}".format(buffer_size, minimum_buffer_size))
-            return 1
+
+        # Diagnostic writes are asynchronous, so briefly wait for the
+        # explicit permission error before treating an unchanged size as a
+        # failure.
+        for _ in range(50):
+            if os.path.exists(diags_log):
+                with open(diags_log, encoding='utf-8') as diags:
+                    diagnostics = diags.read()
+                    if "Set pipe size failed" in diagnostics and "Operation 
not permitted" in diagnostics:
+                        print("Success. The kernel denied increasing the pipe 
buffer for the unprivileged ATS user.")
+                        return 0
+            time.sleep(0.1)
+
+        print("Fail. Size is: {} which is smaller than: 
{}".format(buffer_size, minimum_buffer_size))
+        return 1
     except Exception as e:
         print("Unable to open fifo, error: {}".format(str(e)))
         return 2
@@ -53,7 +69,7 @@ def test_fifo(fifo, minimum_buffer_size):
 
 def main():
     args = parse_args()
-    return test_fifo(args.pipe_name, args.minimum_buffer_size)
+    return test_fifo(args.pipe_name, args.minimum_buffer_size, args.diags_log)
 
 
 if __name__ == '__main__':

Reply via email to