Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package openQA for openSUSE:Factory checked 
in at 2026-07-02 20:10:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/openQA (Old)
 and      /work/SRC/openSUSE:Factory/.openQA.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "openQA"

Thu Jul  2 20:10:09 2026 rev:861 rq:1363541 version:5.1782995932.ffeb09be

Changes:
--------
--- /work/SRC/openSUSE:Factory/openQA/openQA.changes    2026-07-01 
16:38:01.207947325 +0200
+++ /work/SRC/openSUSE:Factory/.openQA.new.1982/openQA.changes  2026-07-02 
20:13:23.353567159 +0200
@@ -1,0 +2,32 @@
+Thu Jul  2 16:07:45 UTC 2026 - Marius Kittler <[email protected]>
+
+- Clarify resolution of three CVEs
+  * The following CVEs have been fixed (see previous changelog
+    entries that mentioned only the according Bugzilla tickets):
+    - bsc#1259005 - CVE-2026-27904
+    - bsc#1264376 - CVE-2026-6321
+    - bsc#1258632 - CVE-2026-26996 
+
+-------------------------------------------------------------------
+Thu Jul 02 12:38:59 UTC 2026 - [email protected]
+
+- Update to version 5.1782995932.ffeb09be:
+  * feat: throw 404 for nonexistent groups in overview
+  * feat: Avoid logwarn notifications for non-critical auth error
+  * chore(deps): Dependency cron 2026-07-02
+  * git subrepo pull (merge) external/os-autoinst-common
+  * fix: Check also hidden files in checklist plugin
+  * test: Enable faster re-connects in full scheduler test consistently
+  * test: Avoid silent daemons in verbose mode
+  * test: Allow running `t/43-…-scalability.t` in parallel
+  * test: Allow running `t/05-scheduler-full.t` in parallel
+  * test: Avoid race condition when generating ports in `25-cache.t`
+  * test: Avoid wasting seconds in `40-script_load_dump_templates.t`
+  * refactor: Remove disabled code in `openqa-load-templates`
+  * test: Avoid race condition when generating ports in many tests
+  * chore(deps): Dependency cron 2026-07-01
+  * fix(ci): format inline comments in workflows to pass yamllint
+  * test: Avoid running into "Address already in use" in fullstack test
+  * feat(ci): pin GitHub Actions by commit hash
+
+-------------------------------------------------------------------

Old:
----
  openQA-5.1782822561.fa3defef.obscpio

New:
----
  openQA-5.1782995932.ffeb09be.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ openQA-client-test.spec ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:24.737615060 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:24.749615473 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-client
 Name:           %{short_name}-test
-Version:        5.1782822561.fa3defef
+Version:        5.1782995932.ffeb09be
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-devel-test.spec ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:24.781616577 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:24.785616716 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-devel
 Name:           %{short_name}-test
-Version:        5.1782822561.fa3defef
+Version:        5.1782995932.ffeb09be
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA-test.spec ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:24.825618095 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:24.829618234 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA
 Name:           %{short_name}-test
-Version:        5.1782822561.fa3defef
+Version:        5.1782995932.ffeb09be
 Release:        0
 Summary:        Test package for openQA
 License:        GPL-2.0-or-later

++++++ openQA-worker-test.spec ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:24.889620303 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:24.889620303 +0200
@@ -18,7 +18,7 @@
 
 %define         short_name openQA-worker
 Name:           %{short_name}-test
-Version:        5.1782822561.fa3defef
+Version:        5.1782995932.ffeb09be
 Release:        0
 Summary:        Test package for %{short_name}
 License:        GPL-2.0-or-later

++++++ openQA.spec ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:24.945622235 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:24.949622372 +0200
@@ -104,7 +104,7 @@
 %define devel_requires %devel_no_selenium_requires chromedriver
 
 Name:           openQA
-Version:        5.1782822561.fa3defef
+Version:        5.1782995932.ffeb09be
 Release:        0
 Summary:        Framework for automated system-level testing (web-frontend, 
scheduler and tools)
 Group:          Development/Tools/Other

++++++ openQA-5.1782822561.fa3defef.obscpio -> 
openQA-5.1782995932.ffeb09be.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/.github/dependabot.yml 
new/openQA-5.1782995932.ffeb09be/.github/dependabot.yml
--- old/openQA-5.1782822561.fa3defef/.github/dependabot.yml     2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/dependabot.yml     2026-07-02 
14:38:52.000000000 +0200
@@ -2,6 +2,18 @@
 
 version: 2
 updates:
+  - package-ecosystem: 'github-actions'
+    directory: '/'
+    schedule:
+      interval: 'weekly'
+      day: 'monday'
+    cooldown:
+      default-days: 7
+    open-pull-requests-limit: 5
+    groups:
+      all-actions:
+        patterns:
+          - "*"
   - package-ecosystem: npm
     directory: /
     schedule:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/check-containers.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/check-containers.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/check-containers.yml     
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/check-containers.yml     
2026-07-02 14:38:52.000000000 +0200
@@ -8,6 +8,6 @@
       contents: read
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: Test our container definitions
         run: make test-check-containers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/check-helm-chart.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/check-helm-chart.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/check-helm-chart.yml     
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/check-helm-chart.yml     
2026-07-02 14:38:52.000000000 +0200
@@ -9,20 +9,20 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v6
+        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
 
       - name: Install Helm
-        uses: azure/setup-helm@v4
+        uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4  # v4
         with:
           version: v3.8.1
 
       - name: Install Python
-        uses: actions/setup-python@v5
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065  # 
v5
         with:
           python-version: 3.13
 
       - name: Set up chart-testing
-        uses: helm/chart-testing-action@v2
+        uses: 
helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f  # v2
 
       - name: Run chart-testing
         run: make test-helm-lint
@@ -35,15 +35,15 @@
       REGISTRY_PATH: registry.opensuse.org/devel/openqa/containers16.0
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v6
+        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
 
       - name: Install Helm
-        uses: azure/setup-helm@v4
+        uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4  # v4
         with:
           version: v3.8.1
 
       - name: Install Python
-        uses: actions/setup-python@v5
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065  # 
v5
         with:
           python-version: 3.13
 
@@ -53,10 +53,10 @@
           chmod +x /usr/local/bin/retry
 
       - name: Set up chart-testing
-        uses: helm/chart-testing-action@v2
+        uses: 
helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f  # v2
 
       - name: Create kind cluster
-        uses: helm/kind-action@v1
+        uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc  # v1
 
       - name: Download images
         run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/checklist.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/checklist.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/checklist.yml    
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/checklist.yml    
2026-07-02 14:38:52.000000000 +0200
@@ -10,9 +10,10 @@
     name: Checklist job
     steps:
       - name: Checkout
-        uses: actions/checkout@v6
+        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: Checklist
-        uses: wyozi/contextual-qa-checklist-action@master
+        uses: 
wyozi/contextual-qa-checklist-action@dd4b6b51d85a59f537b7ca9e2f162164627ec811  
# master
         with:
           gh-token: ${{ secrets.GITHUB_TOKEN }}
           input-file: .github/checklist.yml
+          include-hidden-files: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/commit-message-checker.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/commit-message-checker.yml
--- 
old/openQA-5.1782822561.fa3defef/.github/workflows/commit-message-checker.yml   
    2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/.github/workflows/commit-message-checker.yml   
    2026-07-02 14:38:52.000000000 +0200
@@ -11,4 +11,4 @@
   check-commit-message:
     permissions:
       contents: read
-    uses: 
os-autoinst/os-autoinst-common/.github/workflows/base-commit-message-checker.yml@master
+    uses: 
os-autoinst/os-autoinst-common/.github/workflows/base-commit-message-checker.yml@e9a35c74028cb8f1e64a4d787d5751dd7b0790c8
  # master
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/compose.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/compose.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/compose.yml      
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/compose.yml      
2026-07-02 14:38:52.000000000 +0200
@@ -9,6 +9,6 @@
     runs-on: ubuntu-latest
     timeout-minutes: 60
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: Verify that containers can be composed
         run: make test-containers-compose
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/javascript.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/javascript.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/javascript.yml   
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/javascript.yml   
2026-07-02 14:38:52.000000000 +0200
@@ -14,9 +14,9 @@
         node-version: [22]
         os: [ubuntu-latest]
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: Setup Node (version ${{ matrix.node-version }})
-        uses: actions/setup-node@v4
+        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020  # v4
         with:
           node-version: ${{ matrix.node-version }}
       - name: npm clean-install
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/obs-helper.yaml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/obs-helper.yaml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/obs-helper.yaml  
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/obs-helper.yaml  
2026-07-02 14:38:52.000000000 +0200
@@ -12,7 +12,7 @@
     name: Report OBS URL
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: debug
         run: |
           env | sort
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/.github/workflows/prove.yml 
new/openQA-5.1782995932.ffeb09be/.github/workflows/prove.yml
--- old/openQA-5.1782822561.fa3defef/.github/workflows/prove.yml        
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/.github/workflows/prove.yml        
2026-07-02 14:38:52.000000000 +0200
@@ -19,7 +19,7 @@
     container:
       image: 
registry.opensuse.org/devel/openqa/containers/opensuse/openqa_devel:latest
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - name: Build os-autoinst
         run: bash -x tools/ci/build_autoinst.sh
       - name: Make project folder user-writable
@@ -32,7 +32,7 @@
         run: cover -write cover_db cover_db*
       - name: Generate coverage report
         run: make coverage-report-html
-      - uses: actions/upload-artifact@v4
+      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 
 # v4
         with:
           name: Upload artifacts
           path: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/dependabot.yml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/dependabot.yml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/dependabot.yml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/dependabot.yml
 2026-07-02 14:38:52.000000000 +0200
@@ -0,0 +1,14 @@
+version: 2
+updates:
+  - package-ecosystem: 'github-actions'
+    directory: '/'
+    schedule:
+      interval: 'weekly'
+      day: 'monday'
+    cooldown:
+      default-days: 7
+    open-pull-requests-limit: 5
+    groups:
+      all-actions:
+        patterns:
+          - "*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/base-commit-message-checker.yml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/base-commit-message-checker.yml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/base-commit-message-checker.yml
      2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/base-commit-message-checker.yml
      2026-07-02 14:38:52.000000000 +0200
@@ -10,7 +10,7 @@
     permissions:
       contents: read
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
         with:
           fetch-depth: 0
       - name: Install gitlint
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/perl-author-tests.yml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/perl-author-tests.yml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/perl-author-tests.yml
        2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/perl-author-tests.yml
        2026-07-02 14:38:52.000000000 +0200
@@ -12,7 +12,7 @@
     container:
       image: registry.opensuse.org/devel/openqa/containers/os-autoinst_dev
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - run: |
           git config --system --add safe.directory "$GITHUB_WORKSPACE"
           make test-author
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/perl-lint-checks.yml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/perl-lint-checks.yml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/perl-lint-checks.yml
 2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/perl-lint-checks.yml
 2026-07-02 14:38:52.000000000 +0200
@@ -12,5 +12,5 @@
     container:
       image: registry.opensuse.org/devel/openqa/containers/os-autoinst_dev
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - run: GITHUB_ACTIONS=1 make test-tidy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/test.yaml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/test.yaml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/test.yaml
    2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/test.yaml
    2026-07-02 14:38:52.000000000 +0200
@@ -11,5 +11,5 @@
     container:
       image: registry.opensuse.org/devel/openqa/containers/os-autoinst_dev
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - run: make test-t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/yamllint.yml
 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/yamllint.yml
--- 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.github/workflows/yamllint.yml
 2026-06-30 14:29:21.000000000 +0200
+++ 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.github/workflows/yamllint.yml
 2026-07-02 14:38:52.000000000 +0200
@@ -10,7 +10,7 @@
       contents: read
     name: "YAML-lint"
     steps:
-      - uses: actions/checkout@v6
+      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10  # v6
       - uses: 
docker://registry.opensuse.org/home/okurz/container/containers/tumbleweed:yamllint
         with:
           entrypoint: make
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.gitlint 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.gitlint
--- old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.gitlint       
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.gitlint       
2026-07-02 14:38:52.000000000 +0200
@@ -10,5 +10,5 @@
 [ignore-by-title]
 # "git subrepo" creates automatic, non-conventional commits we need to accept
 # https://progress.opensuse.org/issues/198254
-regex=^git subrepo pull
+regex=^(git subrepo pull|(chore|build)\(deps(-dev)?\): bump)
 ignore=all
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.gitrepo 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.gitrepo
--- old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.gitrepo       
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.gitrepo       
2026-07-02 14:38:52.000000000 +0200
@@ -6,7 +6,7 @@
 [subrepo]
        remote = [email protected]:os-autoinst/os-autoinst-common.git
        branch = master
-       commit = e9a35c74028cb8f1e64a4d787d5751dd7b0790c8
+       commit = 5dec1da2bcbe4f40982d22f8cea2433604235431
        parent = 93fed5d3ab0eba22d8cea9f9685904ee8a612823
        method = merge
        cmdver = 0.4.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.mergify.yml 
new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.mergify.yml
--- old/openQA-5.1782822561.fa3defef/external/os-autoinst-common/.mergify.yml   
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/external/os-autoinst-common/.mergify.yml   
2026-07-02 14:38:52.000000000 +0200
@@ -1,3 +1,7 @@
+merge_queue:
+  status_comments: none
+  queue_controls_comment: false
+
 pull_request_rules:
   - name: automatic merge
     conditions:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/lib/OpenQA/Utils.pm 
new/openQA-5.1782995932.ffeb09be/lib/OpenQA/Utils.pm
--- old/openQA-5.1782822561.fa3defef/lib/OpenQA/Utils.pm        2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/lib/OpenQA/Utils.pm        2026-07-02 
14:38:52.000000000 +0200
@@ -137,8 +137,12 @@
   read_test_modules
   walker
   ensure_timestamp_appended
+  make_listen_url
+  make_access_url
   set_listen_address
+  to_plain_service_port
   service_port
+  raw_service_port
   change_sec_to_word
   find_video_files
   fix_top_level_help
@@ -794,24 +798,46 @@
     }
 }
 
-sub set_listen_address ($port) {
-    return if $ENV{MOJO_LISTEN};
-    # Show IPv6 compatible "localhost" instead of IPv4 loopback 127.0.0.1
-    # Also explicitly bind to 127.0.0.1 to ensure both IPv4 and IPv6 are 
supported
-    $ENV{MOJO_LISTEN} = 
"http://localhost:$port?reuse=1,http://127.0.0.1:$port?reuse=1";;
-}
+# Show IPv6 compatible "localhost" instead of IPv4 loopback 127.0.0.1
+# Also explicitly bind to 127.0.0.1 to ensure both IPv4 and IPv6 are supported
+sub make_listen_url ($raw_port) {
+    $raw_port =~ m/&fd=(.*)/
+      ? "http://*?fd=$1";
+      : 
"http://localhost:$raw_port?reuse=1,http://127.0.0.1:$raw_port?reuse=1";;
+}
+sub to_plain_service_port ($raw_port) { $raw_port =~ m/^(\d+)/ ? $1 : die 
"invalid port: $raw_port" }
+sub make_access_url ($raw_port) { 'http://localhost:' . 
to_plain_service_port($raw_port) }
+sub service_port ($service) { 
to_plain_service_port(raw_service_port($service)) }
+sub set_listen_address ($service) { $ENV{MOJO_LISTEN} //= 
make_listen_url(raw_service_port($service)) }
+
+my %SERVICE_OFFSETS = (webui => 0, websocket => 1, livehandler => 2, scheduler 
=> 3, cache_service => 4);
+my %RESERVED_SOCKETS;
 
-sub service_port ($service) {
+sub raw_service_port ($service) {
     my $base = $ENV{OPENQA_BASE_PORT} ||= DEFAULT_OPENQA_BASE_PORT;
-    my $offsets = {
-        webui => 0,
-        websocket => 1,
-        livehandler => 2,
-        scheduler => 3,
-        cache_service => 4
-    };
-    croak "Unknown service: $service" unless exists $offsets->{$service};
-    return $base + $offsets->{$service};
+    if (my $env_port = $ENV{"OPENQA_PORT_\U$service"}) {    # \U uppercases 
the interpolated variable
+        return $env_port;
+    }
+    croak "Unknown service: $service" unless exists $SERVICE_OFFSETS{$service};
+    return $base + $SERVICE_OFFSETS{$service};
+}
+
+sub reserve_ports ($services = [keys %SERVICE_OFFSETS], %options) {
+    for my $service (@$services) {
+        next if exists $RESERVED_SOCKETS{$service} && !$options{force};
+        my $socket = IO::Socket::IP->new(LocalAddr => '0.0.0.0', Listen => 
SOMAXCONN, ReuseAddr => 1, ReusePort => 1);
+        die "Failed to reserve port for $service: $!\n" unless $socket;
+        $RESERVED_SOCKETS{$service} = $socket;
+        my $port = $socket->sockport;
+        $ENV{"OPENQA_PORT_\U$service"} = "$port&fd=" . $socket->fileno;
+        log_info "Reserved port for $service: $port";
+    }
+    my $webui_socket = $RESERVED_SOCKETS{webui};
+    my $livehandler_socket = $RESERVED_SOCKETS{livehandler};
+    if ($webui_socket && $livehandler_socket) {
+        $ENV{OPENQA_SERVICE_PORT_DELTA} = $livehandler_socket->sockport - 
$webui_socket->sockport;
+    }
+    return @$services == 1 ? $RESERVED_SOCKETS{$services->[0]} : 
\%RESERVED_SOCKETS;
 }
 
 sub random_string ($length = RANDOM_STRING_DEFAULT_LENGTH, $chars = ['a' .. 
'z', 'A' .. 'Z', '0' .. '9', '_']) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Auth/OpenID.pm 
new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Auth/OpenID.pm
--- old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Auth/OpenID.pm   
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Auth/OpenID.pm   
2026-07-02 14:38:52.000000000 +0200
@@ -4,7 +4,7 @@
 package OpenQA::WebAPI::Auth::OpenID;
 use Mojo::Base -base, -signatures;
 
-use OpenQA::Log qw(log_error);
+use OpenQA::Log qw(log_info);
 use LWP::UserAgent;
 use Net::OpenID::Consumer;
 use MIME::Base64 qw(encode_base64url decode_base64url);
@@ -23,7 +23,7 @@
 
     my $claimed_id = $csr->claimed_identity($c->config->{openid}->{provider});
     if (!defined $claimed_id) {
-        log_error("Claiming OpenID identity for URL '$url' failed: " . 
$csr->err);
+        log_info("Claiming OpenID identity for URL '$url' failed: " . 
$csr->err);
         return undef;
     }
     $claimed_id->set_extension_args(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm
--- old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Controller/API/V1/Job.pm 
2026-07-02 14:38:52.000000000 +0200
@@ -228,6 +228,7 @@
 
 sub overview ($self) {
     my ($search_args, $groups) = $self->compose_job_overview_search_args;
+    return undef unless $search_args;
     my $failed_modules = $self->param_hash('failed_modules');
     my $jobs_rs = $self->schema->resultset('Jobs');
     my $latest_job_ids = $jobs_rs->complex_query_latest_ids(%$search_args);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Controller/Test.pm 
new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Controller/Test.pm
--- old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Controller/Test.pm       
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Controller/Test.pm       
2026-07-02 14:38:52.000000000 +0200
@@ -680,6 +680,7 @@
 
 sub _gather_overview_results ($self, %args) {
     my ($search_args, $groups) = $self->compose_job_overview_search_args;
+    return undef unless $search_args;
     my $jobs_rs = $self->schema->resultset('Jobs');
     my $latest_job_ids = $jobs_rs->complex_query_latest_ids(%$search_args);
     my $limit = $search_args->{limit};
@@ -701,6 +702,7 @@
 
 sub overview_badge ($self) {
     my $data = $self->_gather_overview_results(only_aggregated => 1);
+    return undef unless $data;
     my $aggregated = $data->{aggregated};
 
     my $status = (grep { $aggregated->{$_} } OVERVIEW_STATUS_PRIORITY)[0] // 
'none';
@@ -978,6 +980,7 @@
 # A generic query page showing test results in a configurable matrix
 sub overview ($self) {
     my $data = $self->_gather_overview_results;
+    return undef unless $data;
     my $search_args = $data->{search_args};
     my $groups = $data->{groups};
     my $latest_job_ids = $data->{latest_job_ids};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Plugin/Helpers.pm 
new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Plugin/Helpers.pm
--- old/openQA-5.1782822561.fa3defef/lib/OpenQA/WebAPI/Plugin/Helpers.pm        
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/lib/OpenQA/WebAPI/Plugin/Helpers.pm        
2026-07-02 14:38:52.000000000 +0200
@@ -408,6 +408,13 @@
         my @group_name_search = map { {name => $_} } 
@{$v->every_param('group')};
         my @search_terms = (@group_id_search, @group_name_search);
         @groups = $schema->resultset('JobGroups')->search(\@search_terms)->all;
+        if (!@groups) {
+            $c->stash(error_message => 'Group does not exist');
+            $c->respond_to(
+                json => {json => {error => 'Group does not exist'}, status => 
400},
+                any => sub { $c->render(template => 'main/specific_not_found', 
status => 400) });
+            return undef;
+        }
     }
 
     else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/script/openqa 
new/openQA-5.1782995932.ffeb09be/script/openqa
--- old/openQA-5.1782822561.fa3defef/script/openqa      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa      2026-07-02 
14:38:52.000000000 +0200
@@ -9,7 +9,7 @@
 use lib "$FindBin::RealBin/../lib";
 
 use OpenQA::WebAPI;
-use OpenQA::Utils qw(service_port set_listen_address fix_top_level_help);
+use OpenQA::Utils qw(set_listen_address fix_top_level_help);
 
 fix_top_level_help;
 
@@ -19,6 +19,6 @@
 # the default is EV, and this heavily screws with our children handling
 $ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll';
 
-set_listen_address(service_port('webui'));
+set_listen_address('webui');
 OpenQA::WebAPI::run;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/script/openqa-livehandler 
new/openQA-5.1782995932.ffeb09be/script/openqa-livehandler
--- old/openQA-5.1782822561.fa3defef/script/openqa-livehandler  2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa-livehandler  2026-07-02 
14:38:52.000000000 +0200
@@ -9,12 +9,12 @@
 use lib "$FindBin::RealBin/../lib";
 
 use OpenQA::LiveHandler;
-use OpenQA::Utils qw(service_port set_listen_address fix_top_level_help);
+use OpenQA::Utils qw(set_listen_address fix_top_level_help);
 
 fix_top_level_help;
 
 # ensure the web socket connection won't timeout
 $ENV{MOJO_INACTIVITY_TIMEOUT} ||= 15 * 60;
 
-set_listen_address(service_port('livehandler'));
+set_listen_address('livehandler');
 OpenQA::LiveHandler::run;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/script/openqa-load-templates 
new/openQA-5.1782995932.ffeb09be/script/openqa-load-templates
--- old/openQA-5.1782822561.fa3defef/script/openqa-load-templates       
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa-load-templates       
2026-07-02 14:38:52.000000000 +0200
@@ -59,7 +59,6 @@
 use Mojo::Util qw(decamelize);
 use Mojo::URL;
 use OpenQA::Client;
-#use OpenQA::Script::Client;
 use Mojo::JSON;    # booleans
 use Cpanel::JSON::XS ();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/script/openqa-scheduler 
new/openQA-5.1782995932.ffeb09be/script/openqa-scheduler
--- old/openQA-5.1782822561.fa3defef/script/openqa-scheduler    2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa-scheduler    2026-07-02 
14:38:52.000000000 +0200
@@ -9,9 +9,9 @@
 use lib "$FindBin::RealBin/../lib";
 
 use OpenQA::Scheduler;
-use OpenQA::Utils qw(service_port set_listen_address fix_top_level_help);
+use OpenQA::Utils qw(set_listen_address fix_top_level_help);
 
 fix_top_level_help;
 
-set_listen_address(service_port('scheduler'));
+set_listen_address('scheduler');
 OpenQA::Scheduler::run;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/script/openqa-websockets 
new/openQA-5.1782995932.ffeb09be/script/openqa-websockets
--- old/openQA-5.1782822561.fa3defef/script/openqa-websockets   2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa-websockets   2026-07-02 
14:38:52.000000000 +0200
@@ -9,9 +9,9 @@
 use lib "$FindBin::RealBin/../lib";
 
 use OpenQA::WebSockets;
-use OpenQA::Utils qw(service_port set_listen_address fix_top_level_help);
+use OpenQA::Utils qw(set_listen_address fix_top_level_help);
 
 fix_top_level_help;
 
-set_listen_address(service_port('websocket'));
+set_listen_address('websocket');
 OpenQA::WebSockets::run;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/script/openqa-workercache 
new/openQA-5.1782995932.ffeb09be/script/openqa-workercache
--- old/openQA-5.1782822561.fa3defef/script/openqa-workercache  2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/script/openqa-workercache  2026-07-02 
14:38:52.000000000 +0200
@@ -9,9 +9,9 @@
 use lib "$FindBin::RealBin/../lib";
 
 use OpenQA::CacheService;
-use OpenQA::Utils qw(service_port set_listen_address fix_top_level_help);
+use OpenQA::Utils qw(set_listen_address fix_top_level_help);
 
 fix_top_level_help;
 
-set_listen_address(service_port('cache_service'));
+set_listen_address('cache_service');
 exit OpenQA::CacheService::run(@ARGV);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/05-scheduler-full.t 
new/openQA-5.1782995932.ffeb09be/t/05-scheduler-full.t
--- old/openQA-5.1782822561.fa3defef/t/05-scheduler-full.t      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/05-scheduler-full.t      2026-07-02 
14:38:52.000000000 +0200
@@ -5,11 +5,18 @@
 
 use Test::Most;
 use Test::Warnings ':report_warnings';
+use OpenQA::Utils;
 
 BEGIN {
     # require the scheduler to be fixed in its actions since tests depends on 
timing
     $ENV{OPENQA_SCHEDULER_MAX_JOB_ALLOCATION} = 10;
     $ENV{OPENQA_SCHEDULER_SCHEDULE_TICK_MS} = 100;
+
+    # avoid delays due to long retry interval of worker
+    $ENV{OPENQA_WORKER_CONNECT_INTERVAL} = 0;
+    $ENV{MOJO_CONNECT_TIMEOUT} = 1;
+
+    OpenQA::Utils::reserve_ports;
 }
 
 use Test::MockModule;
@@ -27,7 +34,6 @@
 use OpenQA::Scheduler::Model::Jobs;
 use OpenQA::WebAPI;
 use OpenQA::Worker::WebUIConnection;
-use OpenQA::Utils;
 require OpenQA::Test::Database;
 use OpenQA::Test::Utils qw(
   setup_mojo_app_with_default_worker_timeout
@@ -277,7 +283,6 @@
 
     local $ENV{OPENQA_LOGFILE};
     local $ENV{MOJO_LOG_LEVEL};
-    local $ENV{OPENQA_WORKER_CONNECT_INTERVAL} = 0;
 
     my $log;
     # create unstable ws
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/09-job_clone.t 
new/openQA-5.1782995932.ffeb09be/t/09-job_clone.t
--- old/openQA-5.1782822561.fa3defef/t/09-job_clone.t   2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/09-job_clone.t   2026-07-02 
14:38:52.000000000 +0200
@@ -20,7 +20,7 @@
 
 OpenQA::Test::Database->new->create(fixtures_glob => '01-jobs.pl');
 my $t = client(Test::Mojo->new('OpenQA::WebAPI'));
-my $mojoport = Mojo::IOLoop::Server->generate_port;
+my $mojoport = OpenQA::Utils::reserve_ports(['webui'])->sockport;
 my $host = "localhost:$mojoport";
 my @common_options = (host => $host, from => $host, apikey => 'foo', apisecret 
=> 'bar');
 my $webapi = create_webapi($mojoport, sub { });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/10-tests_overview.t 
new/openQA-5.1782995932.ffeb09be/t/10-tests_overview.t
--- old/openQA-5.1782822561.fa3defef/t/10-tests_overview.t      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/10-tests_overview.t      2026-07-02 
14:38:52.000000000 +0200
@@ -72,9 +72,9 @@
 };
 
 subtest 'Job group selection' => sub {
-    my $form = {distri => 'opensuse', version => '13.1', build => '0091', 
group => 'opensuse 13.1'};
+    my $form = {distri => 'opensuse', version => '13.1', build => '0091', 
group => 'opensuse'};
     $t->get_ok('/tests/overview' => form => $form)->status_is(200);
-    like get_summary, qr/Overall Summary of opensuse 13\.1 build 0091/i, 
'specifying group parameter';
+    like get_summary, qr/Overall Summary of opensuse build 0091/i, 'specifying 
group parameter';
 
     $form = {distri => 'opensuse', version => '13.1', build => '0091', groupid 
=> 1001};
     $t->get_ok('/tests/overview' => form => $form)->status_is(200);
@@ -135,6 +135,11 @@
     like flash_msg, qr/Specified "groupid" is invalid/i, 'error message for 
invalid groupid';
 };
 
+subtest 'Nonexistent job group' => sub {
+    $t->get_ok('/tests/overview' => form => {groupid => 
12345})->status_is(400);
+    $t->get_ok('/tests/overview' => form => {group => 
'nonexistent_group'})->status_is(400);
+};
+
 subtest 'Default overview for Factory' => sub {
     $t->get_ok('/tests/overview' => form => {distri => 'opensuse', version => 
'Factory'})->status_is(200);
     my $summary = get_summary;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/14-grutasks-git.t 
new/openQA-5.1782995932.ffeb09be/t/14-grutasks-git.t
--- old/openQA-5.1782822561.fa3defef/t/14-grutasks-git.t        2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/14-grutasks-git.t        2026-07-02 
14:38:52.000000000 +0200
@@ -48,7 +48,7 @@
 my $t = Test::Mojo->new('OpenQA::WebAPI');
 
 # launch an additional app to serve some file for testing blocking downloads
-my $mojo_port = Mojo::IOLoop::Server->generate_port;
+my $mojo_port = OpenQA::Utils::reserve_ports(['webui'])->sockport;
 my $webapi = OpenQA::Test::Utils::create_webapi($mojo_port, sub { });
 
 # prevent writing to a log file to enable use of combined_like in the 
following tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/14-grutasks.t 
new/openQA-5.1782995932.ffeb09be/t/14-grutasks.t
--- old/openQA-5.1782822561.fa3defef/t/14-grutasks.t    2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/14-grutasks.t    2026-07-02 
14:38:52.000000000 +0200
@@ -110,7 +110,7 @@
 my $t = Test::Mojo->new('OpenQA::WebAPI');
 
 # launch an additional app to serve some file for testing blocking downloads
-my $mojo_port = Mojo::IOLoop::Server->generate_port;
+my $mojo_port = OpenQA::Utils::reserve_ports(['webui'])->sockport;
 my $webapi = OpenQA::Test::Utils::create_webapi($mojo_port, sub { });
 
 # define a fix asset_size_limit configuration for this test to be independent 
of the default value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/16-utils.t 
new/openQA-5.1782995932.ffeb09be/t/16-utils.t
--- old/openQA-5.1782822561.fa3defef/t/16-utils.t       2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/16-utils.t       2026-07-02 
14:38:52.000000000 +0200
@@ -50,9 +50,9 @@
 
 subtest 'set listen address' => sub {
     local $ENV{MOJO_LISTEN} = undef;
-    set_listen_address(9526);
+    set_listen_address('webui');
     like $ENV{MOJO_LISTEN}, qr/localhost:9526.*127\.0\.0\.1:9526/, 'address 
set';
-    set_listen_address(9527);
+    set_listen_address('websocket');
     unlike $ENV{MOJO_LISTEN}, qr/localhost:9527.*127\.0\.0\.1:9527/, 'not 
changed';
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/25-cache-client.t 
new/openQA-5.1782995932.ffeb09be/t/25-cache-client.t
--- old/openQA-5.1782822561.fa3defef/t/25-cache-client.t        2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/25-cache-client.t        2026-07-02 
14:38:52.000000000 +0200
@@ -41,7 +41,7 @@
 my $log = Mojo::Log->new(level => 'error');
 my $app = OpenQA::CacheService->new(log => $log);
 my $daemon = Mojo::Server::Daemon->new(
-    silent => 1,
+    silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1,
     listen => ['http://127.0.0.1'],
     ioloop => $client->ua->ioloop,
     app => $app
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/25-cache-service.t 
new/openQA-5.1782995932.ffeb09be/t/25-cache-service.t
--- old/openQA-5.1782822561.fa3defef/t/25-cache-service.t       2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/25-cache-service.t       2026-07-02 
14:38:52.000000000 +0200
@@ -18,7 +18,6 @@
     $ENV{OPENQA_RSYNC_RETRY_PERIOD} = 0;
     $ENV{OPENQA_RSYNC_RETRIES} = 1;
     $ENV{OPENQA_METRICS_DOWNLOAD_SIZE} = 1024;
-    $ENV{OPENQA_BASE_PORT} = 20000 + int rand 10000;
     $ENV{OPENQA_TEST_WAIT_INTERVAL} = 0.05;
 
     $tempdir = tempdir;
@@ -39,10 +38,9 @@
 use Test::Warnings ':report_warnings';
 use Test::Output qw(stderr_like);
 use Test::Mojo;
-use OpenQA::Utils;
+use OpenQA::Utils qw(make_access_url make_listen_url);
 use IO::Socket::INET;
 use Mojo::Server::Daemon;
-use Mojo::IOLoop::Server;
 use POSIX '_exit';
 use Mojo::IOLoop::ReadWriteProcess qw(queue process);
 use Mojo::IOLoop::ReadWriteProcess::Session 'session';
@@ -56,10 +54,7 @@
 use Time::Seconds;
 
 my $cachedir = $ENV{OPENQA_CACHE_DIR};
-my $port = Mojo::IOLoop::Server->generate_port;
-my $host = "http://localhost:$port";;
-
-my $cache_client = OpenQA::CacheService::Client->new();
+my ($sockets, $host, $cache_client);
 
 END { session->clean }
 
@@ -68,8 +63,9 @@
 
 my $server_instance = process sub {
     # Connect application with web server and start accepting connections
-    my $daemon = Mojo::Server::Daemon->new(app => fake_asset_server, listen => 
[$host])->silent(1);
-    $daemon->run;
+    my $listen = [make_listen_url($sockets->{webui}->sockport)];
+    Mojo::Server::Daemon->new(app => fake_asset_server, listen => $listen, 
silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1)
+      ->run;
     Devel::Cover::report() if Devel::Cover->can('report');
     _exit(0);    # uncoverable statement to ensure proper exit code of 
complete test at cleanup
   },
@@ -79,6 +75,9 @@
   kill_sleeptime => 0;
 
 sub start_servers () {
+    $sockets = OpenQA::Utils::reserve_ports([qw(webui cache_service)]);
+    $host = make_access_url($sockets->{webui}->sockport);
+    $cache_client = OpenQA::CacheService::Client->new;
     
$server_instance->set_pipes(0)->separate_err(0)->blocking_stop(1)->channels(0)->restart;
     
$cache_service->set_pipes(0)->separate_err(0)->blocking_stop(1)->channels(0)->restart;
     perform_minion_jobs($t->app->minion);
@@ -209,6 +208,8 @@
     is_deeply [OpenQA::CacheService::setup_workers(qw(run))], [qw(run -j 5)], 
'minion worker setup with parallel jobs';
 };
 
+start_servers;
+
 subtest 'Cache Requests' => sub {
     my $asset_request = $cache_client->asset_request(id => 922756, asset => 
'test', type => 'hdd', host => 'open.qa');
     my $rsync_request = $cache_client->rsync_request(from => 'foo', to => 
'bar');
@@ -226,8 +227,6 @@
       'to_array() not implemented in base request';
 };
 
-start_servers;
-
 subtest 'Invalid requests' => sub {
     my $url = $cache_client->url('/status/12345');
     my $invalid_request = $cache_client->ua->get($url);
@@ -302,7 +301,10 @@
 
 subtest 'Client can check if there are available workers' => sub {
     $cache_service->stop;
+    $cache_client->ua->connect_timeout(1)->inactivity_timeout(1);
     ok !$cache_client->info->available, 'Cache server is not available';
+    OpenQA::Utils::reserve_ports([qw(cache_service)], force => 1);
+    $cache_client = OpenQA::CacheService::Client->new;
     $cache_service->restart;
     perform_minion_jobs($t->app->minion);
     wait_for_or_bail_out { $cache_client->info->available } 'cache service';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/25-cache.t 
new/openQA-5.1782995932.ffeb09be/t/25-cache.t
--- old/openQA-5.1782822561.fa3defef/t/25-cache.t       2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/25-cache.t       2026-07-02 
14:38:52.000000000 +0200
@@ -36,9 +36,8 @@
 use Test::Warnings ':report_warnings';
 use Test::MockModule;
 use Test::Mojo;
-use OpenQA::Utils qw(:DEFAULT base_host);
+use OpenQA::Utils qw(:DEFAULT base_host make_listen_url to_plain_service_port);
 use OpenQA::CacheService;
-use IO::Socket::INET;
 use Mojo::Server::Daemon;
 use Mojo::IOLoop::Server;
 use Mojo::SQLite;
@@ -49,8 +48,8 @@
 use OpenQA::Test::Utils qw(fake_asset_server stop_service 
wait_for_or_bail_out);
 use OpenQA::Test::TimeLimit '30';
 
-my $port = Mojo::IOLoop::Server->generate_port;
-my $host = "localhost:$port";
+my $port = 0;
+my $host = 'localhost:0';
 
 # Capture logs
 my $log = Mojo::Log->new;
@@ -64,21 +63,26 @@
 
 END { session->clean }
 
+my $app = OpenQA::CacheService->new(log => $log);
+my $ua = $app->ua->connect_timeout(0.25)->inactivity_timeout(0.25);
+my $cache = $app->cache;
 my $server_instance;
 
 sub start_server {
     $server_instance = start sub {
-        Mojo::Server::Daemon->new(app => fake_asset_server, listen => 
["http://$host";], silent => 1)->run;
+        Mojo::Server::Daemon->new(
+            app => fake_asset_server,
+            listen => [make_listen_url(raw_service_port('test'))],
+            silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1
+        )->run;
         Devel::Cover::report() if Devel::Cover->can('report');
         _exit(0);    # uncoverable statement to ensure proper exit code of 
complete test at cleanup
     };
-    wait_for_or_bail_out { IO::Socket::INET->new(PeerAddr => '127.0.0.1', 
PeerPort => $port) } 'cache service';
+    wait_for_or_bail_out { $app->ua->get("http://$host/test";)->res->is_success 
} 'cache service';
 }
 
 END { stop_service($server_instance) }
 
-my $app = OpenQA::CacheService->new(log => $log);
-my $cache = $app->cache;
 is $cache->sqlite->migrations->latest, 5, 'Current version is the latest 
version';
 is $cache->sqlite->migrations->active, 5, 'Current version is the active 
version';
 like $cache_log, qr/Creating cache directory tree for "$cachedir"/, 'Cache 
directory tree created';
@@ -150,8 +154,8 @@
 like $cache_log, qr/failed: Connection refused/, 'Asset download fails with: 
Connection refused';
 $cache_log = '';
 
-$port = Mojo::IOLoop::Server->generate_port;
-$host = "127.0.0.1:$port";
+$port = OpenQA::Utils::reserve_ports(['test'])->sockport;
+$host = '127.0.0.1:' . to_plain_service_port($port);
 start_server;
 
 $cache->limit(1024);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/25-downloader.t 
new/openQA-5.1782995932.ffeb09be/t/25-downloader.t
--- old/openQA-5.1782822561.fa3defef/t/25-downloader.t  2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/25-downloader.t  2026-07-02 
14:38:52.000000000 +0200
@@ -11,21 +11,17 @@
 use lib "$FindBin::Bin/lib", 
"$FindBin::Bin/../external/os-autoinst-common/lib";
 
 use OpenQA::Downloader;
-use IO::Socket::INET;
 use Mojo::Server::Daemon;
-use Mojo::IOLoop::Server;
 use Mojo::Log;
 use POSIX '_exit';
 use Mojo::IOLoop::ReadWriteProcess 'process';
 use Mojo::IOLoop::ReadWriteProcess::Session 'session';
+use OpenQA::Utils qw(make_listen_url make_access_url to_plain_service_port);
 use OpenQA::Test::Utils qw(fake_asset_server wait_for_or_bail_out);
 use OpenQA::Test::TimeLimit '10';
 use Mojo::File qw(tempdir);
 use Test::MockModule;
 
-my $port = Mojo::IOLoop::Server->generate_port;
-my $host = "127.0.0.1:$port";
-
 # Capture logs
 my $log = Mojo::Log->new;
 $log->unsubscribe('message');
@@ -40,33 +36,11 @@
 
 END { session->clean }
 
-my $server_instance = process sub {
-    # uncoverable statement
-    Mojo::Server::Daemon->new(app => fake_asset_server, listen => 
["http://$host";], silent => 1)->run;
-    Devel::Cover::report() if Devel::Cover->can('report');
-    _exit(0);    # uncoverable statement to ensure proper exit code of 
complete test at cleanup
-  },
-  max_kill_attempts => 0,
-  blocking_stop => 1,
-  _default_blocking_signal => POSIX::SIGTERM,
-  kill_sleeptime => 0;
-
-sub start_server {
-    $server_instance->set_pipes(0)->start;
-    wait_for_or_bail_out { IO::Socket::INET->new(PeerAddr => '127.0.0.1', 
PeerPort => $port) } 'worker';
-}
-
-sub stop_server {
-    # now kill the worker
-    $server_instance->stop();
-}
-
 my $mojo_tmpdir = tempdir;
 my $downloader = OpenQA::Downloader->new(log => $log, sleep_time => 0.05, 
attempts => 3, tmpdir => $mojo_tmpdir);
 my $ua = $downloader->ua;
 my $tempdir = tempdir;
 my $to = $tempdir->child('test.qcow');
-
 $ua->connect_timeout(0.25)->inactivity_timeout(0.25);
 
 subtest 'Unable to create temporary directory' => sub {
@@ -76,7 +50,7 @@
 };
 
 subtest 'Connection refused' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"http://127.0.0.1:0/tests/922756/asset/hdd/[email protected]";;
     like $downloader->download($from, $to), qr/Download of "$to" failed: 
Connection refused/, 'Failed';
 
     ok !-e $to, 'File not downloaded';
@@ -89,12 +63,28 @@
     $cache_log = '';
 };
 
-$port = Mojo::IOLoop::Server->generate_port;
-$host = "127.0.0.1:$port";
-start_server;
+my $port = OpenQA::Utils::reserve_ports(['test'])->sockport;
+my $host = make_access_url($port);
+my $server_instance = process sub {
+    # uncoverable statement
+    Mojo::Server::Daemon->new(
+        app => fake_asset_server,
+        listen => [make_listen_url($port)],
+        silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1
+    )->run;
+    Devel::Cover::report() if Devel::Cover->can('report');
+    _exit(0);    # uncoverable statement to ensure proper exit code of 
complete test at cleanup
+  },
+  max_kill_attempts => 0,
+  blocking_stop => 1,
+  _default_blocking_signal => POSIX::SIGTERM,
+  kill_sleeptime => 0;
+$server_instance->set_pipes(0)->start;
+wait_for_or_bail_out { defined $ua->get($host)->res->code } 'worker';
+sub stop_server { $server_instance->stop() }
 
 subtest 'Not found' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"$host/tests/922756/asset/hdd/[email protected]";
     like $downloader->download($from, $to), qr/Download of "$to" failed: 404 
Not Found/, 'Failed';
 
     ok !-e $to, 'File not downloaded';
@@ -106,7 +96,7 @@
 };
 
 subtest 'Success' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"$host/tests/922756/asset/hdd/[email protected]";
     is $downloader->download($from, $to), undef, 'Success';
 
     ok -e $to, 'File downloaded';
@@ -119,7 +109,7 @@
 };
 
 subtest 'Connection closed early' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"$host/tests/922756/asset/hdd/[email protected]";
     like $downloader->download($from, $to), qr/Download of "$to" failed: 
Premature connection close/, 'Failed';
 
     ok !-e $to, 'File not downloaded';
@@ -132,7 +122,7 @@
 };
 
 subtest 'Server error' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"$host/tests/922756/asset/hdd/[email protected]";
     like $downloader->download($from, $to), qr/Download of "$to" failed: 500 
Internal Server Error/, 'Failed';
 
     ok !-e $to, 'File not downloaded';
@@ -145,7 +135,7 @@
 };
 
 subtest 'Size differs' => sub {
-    my $from = 
"http://$host/tests/922756/asset/hdd/[email protected]";;
+    my $from = 
"$host/tests/922756/asset/hdd/[email protected]";
     like $downloader->download($from, $to), qr/Size of .* differs, expected 
\d+ Byte but downloaded \d+ Byte/, 'Failed';
 
     ok !-e $to, 'File not downloaded';
@@ -159,7 +149,7 @@
 
 subtest 'Non-compressed files kept as-is - no complaint about unknown archive 
format' => sub {
     $to = $tempdir->child('test.txt');
-    my $from = "http://$host/test";;
+    my $from = "$host/test";
     # don't check the error message as it is not interesting
     # (it's a generic error message that the archive is invalid)
     is $downloader->download($from, $to, {extract => 1}), undef, 'Success';
@@ -172,7 +162,7 @@
 
 subtest 'Decompressing file' => sub {
     $to = $tempdir->child('test');
-    my $from = "http://$host/test.gz";;
+    my $from = "$host/test.gz";
     is $downloader->download($from, $to, {extract => 1}), undef, 'Success';
     ok -e $to, 'File downloaded and decompressed';
     is $to->slurp, 'This file was compressed!', 'File was decompressed';
@@ -184,7 +174,7 @@
 
 subtest 'Decompressing archive' => sub {
     $to = $tempdir->child('test');
-    my $from = "http://$host/test.tar.xz";;
+    my $from = "$host/test.tar.xz";
     is $downloader->download($from, $to, {extract => 1}), undef, 'Success';
     ok -d $to, 'File downloaded, uncompressed and extracted';
     is $to->child('test-file')->slurp, "Archived file!\n", 'File was 
extracted';
@@ -196,7 +186,7 @@
 
 subtest 'Error when decompressing archive' => sub {
     $to = $tempdir->child('fake-archive');
-    my $from = "http://$host/fake-archive.tar.xz";;
+    my $from = "$host/fake-archive.tar.xz";
     like $downloader->download($from, $to, {extract => 1}), qr/Unrecognized 
archive format/, 'Failed';
     ok !-e $to, 'Target not created';
     like $cache_log, qr/Downloading "fake-archive" from "$from"/, 'Download 
attempt';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/33-developer_mode.t 
new/openQA-5.1782995932.ffeb09be/t/33-developer_mode.t
--- old/openQA-5.1782822561.fa3defef/t/33-developer_mode.t      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/33-developer_mode.t      2026-07-02 
14:38:52.000000000 +0200
@@ -9,7 +9,7 @@
 
 use Test::Most;
 use Test::Warnings ':report_warnings';
-use Mojo::IOLoop::Server;
+use OpenQA::Utils;
 
 BEGIN {
     # require the scheduler to be fixed in its actions since tests depends on 
timing
@@ -19,13 +19,12 @@
     # ensure the web socket connection won't timeout
     $ENV{MOJO_INACTIVITY_TIMEOUT} = 10 * 60;
 
-    $ENV{OPENQA_BASE_PORT} ||= Mojo::IOLoop::Server->generate_port;
+    OpenQA::Utils::reserve_ports;
 }
 
 use FindBin;
 use lib "$FindBin::Bin/lib", 
"$FindBin::Bin/../external/os-autoinst-common/lib";
 use Mojo::Base -signatures;
-use Mojo::IOLoop::Server;
 use OpenQA::Test::TimeLimit '200';
 use Test::Mojo;
 use IO::Socket::INET;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/40-script_load_dump_templates.t 
new/openQA-5.1782995932.ffeb09be/t/40-script_load_dump_templates.t
--- old/openQA-5.1782822561.fa3defef/t/40-script_load_dump_templates.t  
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/40-script_load_dump_templates.t  
2026-07-02 14:38:52.000000000 +0200
@@ -9,6 +9,7 @@
 use Mojo::Base -signatures;
 use Mojo::File qw(path curfile);
 require OpenQA::Test::Database;
+use OpenQA::Utils qw(to_plain_service_port);
 use OpenQA::Test::Utils;
 use Test::Output;
 use Test::Warnings ':report_warnings';
@@ -19,7 +20,6 @@
 use Mojo::JSON;    # booleans
 use Cpanel::JSON::XS ();
 
-
 sub test_once (@args) {
     # Report failure at the callsite instead of the test function
     local $Test::Builder::Level = $Test::Builder::Level + 1;
@@ -42,15 +42,15 @@
 test_once '--help', qr/Usage:/, 'help text shown', 0, 'openqa-load-templates 
with no arguments shows usage';
 test_once '--host', qr/Option host requires an argument/, 'host argument error 
shown', 1, 'required arguments missing';
 
-my $host = 'testhost:1234';
+my $host = '123.456.789:0';
 my $filename = 't/data/40-templates.pl';
 my $morefilename = 't/data/40-templates-more.pl';
 my $args = "--host $host $filename";
 test_once $args, qr/unknown error code - host $host unreachable?/, 'invalid 
host error', 22, 'error on invalid host';
 
 $ENV{MOJO_LOG_LEVEL} = 'fatal';
-my $mojoport = Mojo::IOLoop::Server->generate_port;
-$host = "localhost:$mojoport";
+my $mojoport = OpenQA::Utils::reserve_ports(['webui'])->sockport;
+$host = 'localhost:' . to_plain_service_port($mojoport);
 my $schema = OpenQA::Test::Database->new->create(fixtures_glob => '01-jobs.pl 
03-users.pl 04-products.pl');
 my $webapi = OpenQA::Test::Utils::create_webapi($mojoport, sub { });
 END { stop_service $webapi; }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/43-scheduling-and-worker-scalability.t 
new/openQA-5.1782995932.ffeb09be/t/43-scheduling-and-worker-scalability.t
--- old/openQA-5.1782822561.fa3defef/t/43-scheduling-and-worker-scalability.t   
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/43-scheduling-and-worker-scalability.t   
2026-07-02 14:38:52.000000000 +0200
@@ -33,6 +33,7 @@
     # set defaults
     $ENV{SCALABILITY_TEST_WORKER_COUNT} //= 5;
     $ENV{SCALABILITY_TEST_WITH_OFFLINE_WEBUI_HOST} //= 1;
+    OpenQA::Utils::reserve_ports;
 }
 
 setup_mojo_app_with_default_worker_timeout;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/44-scripts-initdb.t 
new/openQA-5.1782995932.ffeb09be/t/44-scripts-initdb.t
--- old/openQA-5.1782822561.fa3defef/t/44-scripts-initdb.t      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/44-scripts-initdb.t      2026-07-02 
14:38:52.000000000 +0200
@@ -20,7 +20,7 @@
 $ENV{OPENQA_DATABASE_SEARCH_PATH} = $schema_name;
 $ENV{OPENQA_SCHEMA_VERSION_OVERRIDE} = $schema_version;
 
-my $schema = OpenQA::Schema::connect_db(deploy => 0, silent => 1, from_script 
=> 1);
+my $schema = OpenQA::Schema::connect_db(deploy => 0, silent => 
$ENV{HARNESS_IS_VERBOSE} ? 0 : 1, from_script => 1);
 $schema->storage->dbh->do("create schema \"$schema_name\"");
 
 my $tempdir = tempdir;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/api/04-jobs.t 
new/openQA-5.1782995932.ffeb09be/t/api/04-jobs.t
--- old/openQA-5.1782822561.fa3defef/t/api/04-jobs.t    2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/api/04-jobs.t    2026-07-02 
14:38:52.000000000 +0200
@@ -267,6 +267,11 @@
         $t->json_is('' => [\%job_99940], 'latest build present');
     };
 
+    subtest 'nonexistent job group in API overview' => sub {
+        $query->query(groupid => '12345');
+        $t->get_ok($query->path_query)->status_is(400)->json_is('/error', 
'Group does not exist');
+    };
+
     subtest 'specific build without additional parameters' => sub {
         $query->query(build => '0048');
         $t->get_ok($query->path_query)->status_is(200);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/full-stack.t 
new/openQA-5.1782995932.ffeb09be/t/full-stack.t
--- old/openQA-5.1782822561.fa3defef/t/full-stack.t     2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/full-stack.t     2026-07-02 
14:38:52.000000000 +0200
@@ -9,7 +9,7 @@
 #    execution)
 
 use Test::Most;
-use Mojo::IOLoop::Server;
+use OpenQA::Utils;
 
 BEGIN {
     # require the scheduler to be fixed in its actions since tests depends on 
timing
@@ -21,7 +21,7 @@
 
     $ENV{OS_AUTOINST_STORAGE_KEEP_FREE_RATIO} = 0;
 
-    $ENV{OPENQA_BASE_PORT} ||= Mojo::IOLoop::Server->generate_port;
+    OpenQA::Utils::reserve_ports;
 }
 
 use Test::Warnings ':report_warnings';
@@ -29,7 +29,6 @@
 use List::Util ();
 use Test::Mojo;
 use Test::MockModule;
-use Mojo::IOLoop::Server;
 use autodie ':all';
 use IO::Socket::INET;
 use POSIX '_exit';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/SeleniumTest.pm 
new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/SeleniumTest.pm
--- old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/SeleniumTest.pm       
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/SeleniumTest.pm       
2026-07-02 14:38:52.000000000 +0200
@@ -19,7 +19,6 @@
 use Data::Dump 'pp';
 use Feature::Compat::Try;
 use IPC::Run qw(start);
-use Mojo::IOLoop::Server;
 use Mojo::Server::Daemon;
 use Time::HiRes qw(time sleep);
 use OpenQA::WebAPI;
@@ -37,7 +36,8 @@
 use constant FIND_METHOD => 'css';
 
 sub _start_app ($args) {
-    $MOJOPORT = $ENV{OPENQA_BASE_PORT} = $args->{mojoport} // $ENV{MOJO_PORT} 
// Mojo::IOLoop::Server->generate_port;
+    $MOJOPORT = $ENV{OPENQA_BASE_PORT} = $args->{mojoport} // $ENV{MOJO_PORT}
+      // OpenQA::Utils::reserve_ports(['webui'])->sockport;
     $STARTINGPID = $$;
     $WEBAPI = OpenQA::Test::Utils::create_webapi($MOJOPORT);
     return $MOJOPORT;
@@ -63,9 +63,10 @@
         # pass options for Chromium via chromeOptions *and* goog:chromeOptions 
to support all versions of
         # Selenium::Remote::Driver which switched to use goog:chromeOptions in 
version 1.36
         my @chrome_option_keys = (qw(chromeOptions goog:chromeOptions));
-
+        my $base_url = make_access_url($mojoport);
+        note "Starting Selenium under port $mojoport: $base_url";
         my %opts = (
-            base_url => "http://localhost:$mojoport/";,
+            base_url => make_access_url($mojoport),
             default_finder => FIND_METHOD,
             webelement_class => 'Test::Selenium::Remote::WebElement',
             extra_capabilities => {
@@ -99,7 +100,7 @@
         # Scripts are considered stuck after this timeout
         $_DRIVER->set_timeout(script => 
$ENV{OPENQA_SELENIUM_SCRIPT_TIMEOUT_MS} // 2000);
         $_DRIVER->set_window_size(600, 800);
-        $_DRIVER->get("http://localhost:$mojoport/";);
+        $_DRIVER->get($base_url);
 
     }
     catch ($e) { die $e }    # uncoverable statement
@@ -378,7 +379,7 @@
     }
 }
 
-sub get_mojoport () { $MOJOPORT }
+sub get_mojo_url () { make_access_url($MOJOPORT) }
 
 # uncoverable subroutine
 # uncoverable statement
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/Test/FullstackUtils.pm 
new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/Test/FullstackUtils.pm
--- old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/Test/FullstackUtils.pm        
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/Test/FullstackUtils.pm        
2026-07-02 14:38:52.000000000 +0200
@@ -49,8 +49,7 @@
 }
 
 sub get_connect_args () {
-    my $mojoport = OpenQA::SeleniumTest::get_mojoport;
-    return ['--apikey=1234567890ABCDEF', '--apisecret=1234567890ABCDEF', 
"--host=http://localhost:$mojoport";];
+    ['--apikey=1234567890ABCDEF', '--apisecret=1234567890ABCDEF', '--host=' . 
OpenQA::SeleniumTest::get_mojo_url];
 }
 
 sub client_output ($args) { qx{perl ./script/openqa-cli api 
@{get_connect_args()} $args} }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/Test/Utils.pm 
new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/Test/Utils.pm
--- old/openQA-5.1782822561.fa3defef/t/lib/OpenQA/Test/Utils.pm 2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/lib/OpenQA/Test/Utils.pm 2026-07-02 
14:38:52.000000000 +0200
@@ -4,7 +4,6 @@
 
 use Exporter 'import';
 use FindBin;
-use IO::Socket::INET;
 use Storable qw(lock_store lock_retrieve);
 use Mojolicious;
 use POSIX qw(_exit WNOHANG);
@@ -15,7 +14,7 @@
 use OpenQA::Constants qw(DEFAULT_WORKER_TIMEOUT);
 use OpenQA::Log qw(log_error log_info log_debug);
 
-use OpenQA::Utils 'service_port';
+use OpenQA::Utils qw(raw_service_port to_plain_service_port make_listen_url 
make_access_url);
 use OpenQA::WebSockets;
 use OpenQA::WebSockets::Client;
 use OpenQA::Scheduler;
@@ -25,6 +24,7 @@
 use Mojo::Util 'dumper';
 use Mojo::URL;
 use Cwd qw(abs_path getcwd);
+use IO::Socket::IP;
 use IPC::Run qw(start);
 use Mojo::Util qw(b64_decode gzip);
 use Scalar::Util ();
@@ -33,6 +33,7 @@
 use Mojo::IOLoop::ReadWriteProcess 'process';
 use Mojo::Server::Daemon;
 use Mojo::IOLoop::Server;
+use Mojo::UserAgent;
 use Test::MockModule;
 use OpenQA::Test::TimeLimit ();
 use Feature::Compat::Try;
@@ -107,9 +108,9 @@
             # this service can be very noisy
             require OpenQA::CacheService;    # uncoverable statement
             local $ENV{MOJO_MODE} = 'test';    # uncoverable statement
-            my $port = service_port 'cache_service';    # uncoverable statement
+            my $port = raw_service_port 'cache_service';    # uncoverable 
statement
             note("Starting worker cache service on port $port");    # 
uncoverable statement
-            OpenQA::CacheService::run('daemon', '-l', "http://*:$port";);    # 
uncoverable statement
+            OpenQA::CacheService::run('daemon', '-l', make_listen_url($port)); 
   # uncoverable statement
             note("Worker cache service on port $port stopped");    # 
uncoverable statement
             Devel::Cover::report() if Devel::Cover->can('report');    # 
uncoverable statement
             _exit(0);    # uncoverable statement
@@ -268,39 +269,38 @@
 }
 
 sub create_webapi ($port = undef, $no_cover = undef) {
-    $port //= service_port 'webui';
+    $port //= raw_service_port 'webui';
     note("Starting WebUI service. Port: $port");
 
     my $h = _setup_sigchld_handler 'openqa-webapi', start sub {
         _setup_sub_process 'openqa-webapi';
         local $ENV{MOJO_MODE} = 'test';
 
-        my $daemon = Mojo::Server::Daemon->new(listen => 
["http://127.0.0.1:$port";], silent => 1);
+        my $daemon
+          = Mojo::Server::Daemon->new(listen => [make_listen_url($port)], 
silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1);
         $daemon->build_app('OpenQA::WebAPI');
         $daemon->run;
         Devel::Cover::report() if !$no_cover && Devel::Cover->can('report');
     };
     # as this might download assets on first test, we need to wait a while
     my $wait = time + 50;
+    my $ua = Mojo::UserAgent->new(connect_timeout => 1, inactivity_timeout => 
1);
+    my $address = make_access_url($port);
     while (time < $wait) {
         my $t = time;
-        my $socket = IO::Socket::INET->new(
-            PeerHost => '127.0.0.1',
-            PeerPort => $port,
-            Proto => 'tcp',
-        );
-        last if $socket;
+        note "Waiting for web UI on $address";
+        last if $ua->get($address)->res->is_success;
         sleep 1 if time - $t < 1;
     }
     return $h;
 }
 
 sub create_websocket_server ($port, $bogus, $with_embedded_scheduler = undef, 
$no_cover = undef) {
-    OpenQA::WebSockets::Client->singleton->port($port //= service_port 
'websocket');
+    OpenQA::WebSockets::Client->singleton->port(to_plain_service_port($port 
//= raw_service_port('websocket')));
     note "Starting WebSocket service (port: $port, bogus: $bogus)";
     my $h = _setup_sigchld_handler 'openqa-websocket', start sub {
         _setup_sub_process 'openqa-websocket';
-        local $ENV{MOJO_LISTEN} = "http://127.0.0.1:$port";;
+        local $ENV{MOJO_LISTEN} = make_listen_url($port);
         local $ENV{MOJO_INACTIVITY_TIMEOUT} = 9999;
 
         use OpenQA::WebSockets;
@@ -339,12 +339,12 @@
     return $h;
 }
 
-sub create_scheduler ($port = service_port 'scheduler') {
+sub create_scheduler ($port = raw_service_port('scheduler')) {
     note("Starting Scheduler service. Port: $port");
-    OpenQA::Scheduler::Client->singleton->port($port);
+    OpenQA::Scheduler::Client->singleton->port(to_plain_service_port($port));
     _setup_sigchld_handler 'openqa-scheduler', start sub {
         _setup_sub_process 'openqa-scheduler';
-        local $ENV{MOJO_LISTEN} = "http://127.0.0.1:$port";;
+        local $ENV{MOJO_LISTEN} = make_listen_url($port);
         local $ENV{MOJO_INACTIVITY_TIMEOUT} = 9999;
         local @ARGV = ('daemon');
         OpenQA::Scheduler::run;
@@ -352,12 +352,11 @@
     };
 }
 
-sub create_live_view_handler {
-    my ($port) = @_;
-    $port //= service_port 'livehandler';
+sub create_live_view_handler ($port = raw_service_port 'livehandler') {
     _setup_sigchld_handler 'openqa-livehandler', start sub {
         _setup_sub_process 'openqa-livehandler';
-        my $daemon = Mojo::Server::Daemon->new(listen => 
["http://127.0.0.1:$port";], silent => 1);
+        my $daemon
+          = Mojo::Server::Daemon->new(listen => [make_listen_url($port)], 
silent => $ENV{HARNESS_IS_VERBOSE} ? 0 : 1);
         $daemon->build_app('OpenQA::LiveHandler');
         $daemon->run;
         Devel::Cover::report() if Devel::Cover->can('report');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/15-comments.t 
new/openQA-5.1782995932.ffeb09be/t/ui/15-comments.t
--- old/openQA-5.1782822561.fa3defef/t/ui/15-comments.t 2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/15-comments.t 2026-07-02 
14:38:52.000000000 +0200
@@ -35,7 +35,7 @@
 
 driver_missing unless my $driver = call_driver;
 disable_timeout;
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 #
 # List with no parameters
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/15-search.t 
new/openQA-5.1782995932.ffeb09be/t/ui/15-search.t
--- old/openQA-5.1782822561.fa3defef/t/ui/15-search.t   2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/15-search.t   2026-07-02 
14:38:52.000000000 +0200
@@ -21,7 +21,7 @@
 
 my $t = Test::Mojo->new('OpenQA::WebAPI');
 # we need to talk to the phantom instance or else we're using wrong database
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 subtest 'Perl modules' => sub {
     my $search = $driver->find_element_by_id('global-search');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/16-activity-view.t 
new/openQA-5.1782995932.ffeb09be/t/ui/16-activity-view.t
--- old/openQA-5.1782822561.fa3defef/t/ui/16-activity-view.t    2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/16-activity-view.t    2026-07-02 
14:38:52.000000000 +0200
@@ -29,7 +29,7 @@
 
 my $t = Test::Mojo->new('OpenQA::WebAPI');
 # we need to talk to the phantom instance or else we're using the wrong 
database
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 subtest 'Access activity view via the menu' => sub {
     $driver->find_element_by_link_text('Login')->click();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/17-product-log.t 
new/openQA-5.1782995932.ffeb09be/t/ui/17-product-log.t
--- old/openQA-5.1782822561.fa3defef/t/ui/17-product-log.t      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/17-product-log.t      2026-07-02 
14:38:52.000000000 +0200
@@ -29,7 +29,7 @@
 my $t = client;
 
 # we need to talk to the phantom instance or else we're using wrong database
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 # schedule an ISO
 $t->post_ok(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/23-audit-log.t 
new/openQA-5.1782995932.ffeb09be/t/ui/23-audit-log.t
--- old/openQA-5.1782822561.fa3defef/t/ui/23-audit-log.t        2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/23-audit-log.t        2026-07-02 
14:38:52.000000000 +0200
@@ -37,7 +37,7 @@
 
 my $t = Test::Mojo->new('OpenQA::WebAPI');
 # we need to talk to the phantom instance or else we're using wrong database
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 # Scheduled isos are only available to operators and admins
 $t->get_ok($url . '/admin/auditlog')->status_is(302);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/ui/27-plugin_obs_rsync_obs_status.t 
new/openQA-5.1782995932.ffeb09be/t/ui/27-plugin_obs_rsync_obs_status.t
--- old/openQA-5.1782822561.fa3defef/t/ui/27-plugin_obs_rsync_obs_status.t      
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/27-plugin_obs_rsync_obs_status.t      
2026-07-02 14:38:52.000000000 +0200
@@ -5,13 +5,13 @@
 
 use FindBin;
 use lib "$FindBin::Bin/../lib", 
"$FindBin::Bin/../../external/os-autoinst-common/lib";
+use OpenQA::Utils qw(make_access_url make_listen_url to_plain_service_port);
 use OpenQA::Test::TimeLimit '30';
 use OpenQA::Test::Utils qw(perform_minion_jobs wait_for_or_bail_out);
 use OpenQA::Test::ObsRsync 'setup_obs_rsync_test';
 use Mojolicious;
 use IO::Socket::INET;
 use Mojo::Server::Daemon;
-use Mojo::IOLoop::Server;
 use Mojo::IOLoop::ReadWriteProcess 'process';
 use Mojo::IOLoop::ReadWriteProcess::Session 'session';
 use Mojo::File qw(path tempfile);
@@ -29,8 +29,8 @@
 
 END { session->clean }
 
-my $port = Mojo::IOLoop::Server->generate_port;
-my $host = "http://127.0.0.1:$port";;
+my $port = OpenQA::Utils::reserve_ports(['test'])->sockport;
+my $host = make_access_url($port);
 my $url = "$host/build/%%PROJECT/_result";
 my %fake_response_by_project = (
     Proj3 => '
@@ -122,7 +122,7 @@
                 return $c->render(status => 200, text => 
$fake_response_by_project{$project});
             });
     }
-    my $daemon = Mojo::Server::Daemon->new(app => $mock, listen => [$host]);
+    my $daemon = Mojo::Server::Daemon->new(app => $mock, listen => 
[make_listen_url($port)]);
     $daemon->run;
     note 'Fake API server stopped';
     Devel::Cover::report() if Devel::Cover->can('report');
@@ -138,7 +138,7 @@
 );
 
 $server_instance->set_pipes(0)->start;
-wait_for_or_bail_out { IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort 
=> $port) } 'API';
+wait_for_or_bail_out { IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort 
=> to_plain_service_port($port)) } 'API';
 
 my $ssh_keyfile = tempfile("$FindBin::Script-sshkey-XXXXX");
 # using the key from [0] to have a reproduceable output.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/openQA-5.1782822561.fa3defef/t/ui/28-keys_to_render_as_links.t 
new/openQA-5.1782995932.ffeb09be/t/ui/28-keys_to_render_as_links.t
--- old/openQA-5.1782822561.fa3defef/t/ui/28-keys_to_render_as_links.t  
2026-06-30 14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/28-keys_to_render_as_links.t  
2026-07-02 14:38:52.000000000 +0200
@@ -33,7 +33,7 @@
 $job->settings->create({key => 'SOME_URLS', value => 'https://foo http://bar 
http://baz'});
 
 driver_missing unless my $driver = call_driver;
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 $t->get_ok($uri_path_from_root_dir)->status_is(200)
   ->content_like(qr|root-test|i, 'setting file source found from the root of 
the test distribution');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/t/ui/29-create_tests.t 
new/openQA-5.1782995932.ffeb09be/t/ui/29-create_tests.t
--- old/openQA-5.1782822561.fa3defef/t/ui/29-create_tests.t     2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/t/ui/29-create_tests.t     2026-07-02 
14:38:52.000000000 +0200
@@ -14,7 +14,7 @@
 
 my $schema = OpenQA::Test::Case->new->init_data;
 driver_missing unless my $driver = call_driver;
-my $url = 'http://localhost:' . OpenQA::SeleniumTest::get_mojoport;
+my $url = OpenQA::SeleniumTest::get_mojo_url;
 
 subtest 'navigation to form' => sub {
     $driver->get("$url/tests/create");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openQA-5.1782822561.fa3defef/tools/ci/autoinst.sha 
new/openQA-5.1782995932.ffeb09be/tools/ci/autoinst.sha
--- old/openQA-5.1782822561.fa3defef/tools/ci/autoinst.sha      2026-06-30 
14:29:21.000000000 +0200
+++ new/openQA-5.1782995932.ffeb09be/tools/ci/autoinst.sha      2026-07-02 
14:38:52.000000000 +0200
@@ -1 +1 @@
-2148e4c593e6ded772e53cbc546052ff67a227b1
\ No newline at end of file
+dcc97e9540c42f722678e15002d38df1c18f658c
\ No newline at end of file

++++++ openQA.obsinfo ++++++
--- /var/tmp/diff_new_pack.aakR8v/_old  2026-07-02 20:13:53.850619245 +0200
+++ /var/tmp/diff_new_pack.aakR8v/_new  2026-07-02 20:13:53.858619521 +0200
@@ -1,5 +1,5 @@
 name: openQA
-version: 5.1782822561.fa3defef
-mtime: 1782822561
-commit: fa3defef214d244c54a4f01c8f5b9fe9fb673044
+version: 5.1782995932.ffeb09be
+mtime: 1782995932
+commit: ffeb09befc7935be9e2061df02043dee70f76d45
 

Reply via email to