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

jbonofre pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/karaf.git


The following commit(s) were added to refs/heads/main by this push:
     new a8ff4fb93f [itests] Fix flaky LogTest (#3006)
a8ff4fb93f is described below

commit a8ff4fb93f6caa5e32db60246e88a50af2f85c6b
Author: JB Onofré <[email protected]>
AuthorDate: Fri Oct 16 04:57:54 2026 +0100

    [itests] Fix flaky LogTest (#3006)
    
    log:set updates the pax-logging configuration asynchronously, so reading it 
right after can fail with 'Unrecognized configuration' or return the previous 
level. Wait for the new level to be applied instead of failing right away.
    
    log:list and ld are aliases, not command services: don't wait 30 seconds 
for a service that is never registered on each call.
---
 .../test/java/org/apache/karaf/itests/LogTest.java | 40 +++++++++++++++++++---
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/itests/test/src/test/java/org/apache/karaf/itests/LogTest.java 
b/itests/test/src/test/java/org/apache/karaf/itests/LogTest.java
index 877bf47d3e..ee9e9aa6d4 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/LogTest.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/LogTest.java
@@ -29,6 +29,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.management.ManagementFactory;
+import java.util.function.Supplier;
 
 @RunWith(PaxExam.class)
 @ExamReactorStrategy(PerClass.class)
@@ -36,6 +37,12 @@ public class LogTest extends BaseTest {
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(LogTest.class);
 
+    private static final long LEVEL_APPLIED_TIMEOUT = 30000L;
+    private static final long ALIAS_COMMAND_TIMEOUT = 360000L;
+    // log:list and ld are aliases defined in shell.init.script, not command 
services: don't wait for a service
+    // that is never registered (the default would block 30 seconds on every 
call)
+    private static final long NO_WAIT = 0L;
+
     @Test
     public void setDebugAndDisplay() throws Exception {
         assertSetLevel("DEBUG");
@@ -47,7 +54,7 @@ public class LogTest extends BaseTest {
     public void setDebugAndDisplayAlias() throws Exception {
         assertSetLevel("DEBUG");
         LOGGER.debug("Making sure there is DEBUG level output");
-        assertContains("DEBUG", executeAlias("ld -n 200"));
+        assertContains("DEBUG", executeAlias("ld -n 200", 
ALIAS_COMMAND_TIMEOUT, NO_WAIT, false));
     }
 
     @Test
@@ -75,15 +82,38 @@ public class LogTest extends BaseTest {
         assertSetLevel("DEBUG");
         assertSetLevel("INFO");
         System.out.println(executeCommand("log:clear"));
-        String displayOutput = executeAlias("ld").trim();
+        String displayOutput = executeAlias("ld", ALIAS_COMMAND_TIMEOUT, 
NO_WAIT, false).trim();
         assertTrue("Should be empty but was: " + displayOutput, 
displayOutput.trim().isEmpty());
     }
     
     public void assertSetLevel(String level) throws InterruptedException {
         System.out.println(executeCommand("log:set " + level));
-        assertContains(level, executeCommand("log:get"));
-        assertContains(level, executeAlias("log:list"));
-        Thread.sleep(100);
+        // log:set updates the pax-logging configuration asynchronously 
(ConfigAdmin update, then pax-logging
+        // reconfiguration): until it is applied, the configuration can be 
transiently unreadable ("Unrecognized
+        // configuration") or still hold the previous level. Wait for the new 
level instead of failing right away.
+        assertEventuallyContains(level, () -> executeCommand("log:get"));
+        assertEventuallyContains(level, () -> executeAlias("log:list", 
ALIAS_COMMAND_TIMEOUT, NO_WAIT, false));
+    }
+
+    private void assertEventuallyContains(String expected, Supplier<String> 
command) throws InterruptedException {
+        long deadline = System.currentTimeMillis() + LEVEL_APPLIED_TIMEOUT;
+        String last;
+        while (true) {
+            try {
+                last = command.get();
+                if (last.contains(expected)) {
+                    return;
+                }
+            } catch (RuntimeException e) {
+                // transient configuration state while pax-logging reconfigures
+                last = "Exception: " + e.getMessage();
+            }
+            if (System.currentTimeMillis() > deadline) {
+                break;
+            }
+            Thread.sleep(100);
+        }
+        assertContains(expected, last);
     }
 
 }

Reply via email to