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
