Skip to content

Add foremanctl tests for sos report - #22099

Merged
amolpati30 merged 1 commit into
SatelliteQE:masterfrom
shubhamsg199:sos_report
Jul 29, 2026
Merged

Add foremanctl tests for sos report#22099
amolpati30 merged 1 commit into
SatelliteQE:masterfrom
shubhamsg199:sos_report

Conversation

@shubhamsg199

@shubhamsg199 shubhamsg199 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Adding foremanctl tests for sos report

ref: sosreport/sos#4376

Summary by Sourcery

Add end-to-end tests validating the foremanctl sosreport plugin behavior on containerized Satellite.

New Features:

  • Cover sosreport foremanctl plugin end-to-end to ensure expected files and command outputs are collected.
  • Verify sosreport foremanctl plugin scrubs sensitive credentials from parameters.yaml while preserving non-sensitive values.

Tests:

  • Introduce sosreport extraction fixture used by new foremanctl sosreport tests.

@shubhamsg199 shubhamsg199 self-assigned this Jul 8, 2026
@shubhamsg199 shubhamsg199 added the No-CherryPick PR doesnt need CherryPick to previous branches label Jul 8, 2026
@shubhamsg199
shubhamsg199 requested a review from a team as a code owner July 8, 2026 07:55
@shubhamsg199 shubhamsg199 added the Stream Introduced in or relating directly to Satellite Stream/Master label Jul 8, 2026
@sourcery-ai

sourcery-ai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds end-to-end tests for the foremanctl sos plugin to validate data collection and credential scrubbing in sos reports on containerized Satellite, using the existing logging test module as the host for new tests and a new constant import.

File-Level Changes

Change Details Files
Add end-to-end sosreport tests for the foremanctl plugin on containerized Satellite
  • Introduce TestSosreportForemanctl class with shared sosreport execution and extraction fixture
  • Define sosreport command and extraction directory constants for reuse in tests
  • Implement test validating that foremanctl sos plugin collects expected configuration files and command outputs from the extracted sos report
  • Implement test validating that sensitive password values in parameters.yaml are scrubbed in the collected sosreport while non-sensitive values remain intact
  • Use FOREMANCTL_PARAMETERS_FILE constant to locate the original parameters.yaml on the target Satellite
tests/foreman/cli/test_logging.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In sosreport_extract, relying on ls /var/tmp/sosreport-*.tar.xz | head -1 makes the test dependent on filesystem ordering and can pick an older tarball; consider capturing the exact tarball path from the sos report invocation or using a more deterministic selection (e.g., by timestamp or by cleaning old tarballs before running).
  • The tests mix FOREMANCTL_PARAMETERS_FILE with a hard-coded /var/lib/foremanctl/parameters.yaml path; it would be more robust to consistently use the constant (or a small helper) so that a path change only needs to be updated in one place.
  • In the password scrubbing test you define SENSITIVE_KEYWORD = ('password',) but use a hard-coded grep -i password; consider deriving the grep expression from the same keyword list so the detection of original sensitive values and the scrubbing assertions stay in sync.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `sosreport_extract`, relying on `ls /var/tmp/sosreport-*.tar.xz | head -1` makes the test dependent on filesystem ordering and can pick an older tarball; consider capturing the exact tarball path from the `sos report` invocation or using a more deterministic selection (e.g., by timestamp or by cleaning old tarballs before running).
- The tests mix `FOREMANCTL_PARAMETERS_FILE` with a hard-coded `/var/lib/foremanctl/parameters.yaml` path; it would be more robust to consistently use the constant (or a small helper) so that a path change only needs to be updated in one place.
- In the password scrubbing test you define `SENSITIVE_KEYWORD = ('password',)` but use a hard-coded `grep -i password`; consider deriving the grep expression from the same keyword list so the detection of original sensitive values and the scrubbing assertions stay in sync.

## Individual Comments

### Comment 1
<location path="tests/foreman/cli/test_logging.py" line_range="264-276" />
<code_context>
+        assert tarball, 'No sosreport tarball found'
+
+        module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
+        module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
+
+        report_dir = module_target_sat.execute(
+            f'ls -d {self.EXTRACT_DIR}/sosreport-*'
+        ).stdout.strip()
+        yield report_dir
+        module_target_sat.execute(f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}')
+
+    @pytest.mark.foremanctl
</code_context>
<issue_to_address>
**suggestion (testing):** Assert success of tar extraction and cleanup commands in the sosreport fixture

The fixture currently ignores the exit status of the `tar` extraction and cleanup commands, so failures (e.g., corrupt tar, permissions, disk full) would surface later as less clear test errors. Please capture the return values of these `execute` calls and assert `status == 0` so setup failures are detected and reported immediately.

```suggestion
        tarball = module_target_sat.execute(
            'ls /var/tmp/sosreport-*.tar.xz | head -1'
        ).stdout.strip()
        assert tarball, 'No sosreport tarball found'

        mkdir_result = module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
        assert mkdir_result.status == 0, (
            f'Failed to create sosreport extract directory {self.EXTRACT_DIR}:\n'
            f'{mkdir_result.stdout}\n{mkdir_result.stderr}'
        )

        tar_result = module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
        assert tar_result.status == 0, (
            f'Failed to extract sosreport tarball {tarball}:\n'
            f'{tar_result.stdout}\n{tar_result.stderr}'
        )

        report_dir = module_target_sat.execute(
            f'ls -d {self.EXTRACT_DIR}/sosreport-*'
        ).stdout.strip()
        yield report_dir

        cleanup_result = module_target_sat.execute(
            f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}'
        )
        assert cleanup_result.status == 0, (
            f'Failed to cleanup sosreport artifacts:\n'
            f'{cleanup_result.stdout}\n{cleanup_result.stderr}'
        )
```
</issue_to_address>

### Comment 2
<location path="tests/foreman/cli/test_logging.py" line_range="338-347" />
<code_context>
+        SENSITIVE_KEYWORD = ('password', )
</code_context>
<issue_to_address>
**suggestion:** Sensitive keyword coverage is limited to 'password' while the description mentions secrets/tokens

The docstring states we should scrub `password/secret/token`, but this constant (and the corresponding test) only covers `password`. If other keys like `secret`, `token`, or `client_secret` are meant to be scrubbed, please either extend `SENSITIVE_KEYWORD` to include them (or derive it from the implementation/requirements) and assert that each is masked as `********` in `parameters.yaml`. Otherwise, regressions for those fields may go unnoticed.

Suggested implementation:

```python
        SENSITIVE_KEYWORD = ('password', 'secret', 'token', 'client_secret')

```

```python
        original = module_target_sat.execute(
            f"grep -Ei '{'|'.join(SENSITIVE_KEYWORD)}' {FOREMANCTL_PARAMETERS_FILE}"
        )

```

To fully implement your comment, the rest of this test should:
1. Iterate over `SENSITIVE_KEYWORD` and assert that each matching entry in the extracted `parameters.yaml` is masked as `SCRUB_MARKER` (`********`), not just `password`.
2. Ensure any existing hard-coded references to "password" in subsequent assertions or scrubbing checks are updated to use `SENSITIVE_KEYWORD`, so regressions for `secret`, `token`, and `client_secret` cannot slip by untested.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +264 to +276
tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'

module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')

report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
module_target_sat.execute(f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Assert success of tar extraction and cleanup commands in the sosreport fixture

The fixture currently ignores the exit status of the tar extraction and cleanup commands, so failures (e.g., corrupt tar, permissions, disk full) would surface later as less clear test errors. Please capture the return values of these execute calls and assert status == 0 so setup failures are detected and reported immediately.

Suggested change
tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'
module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
module_target_sat.execute(f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}')
tarball = module_target_sat.execute(
'ls /var/tmp/sosreport-*.tar.xz | head -1'
).stdout.strip()
assert tarball, 'No sosreport tarball found'
mkdir_result = module_target_sat.execute(f'mkdir -p {self.EXTRACT_DIR}')
assert mkdir_result.status == 0, (
f'Failed to create sosreport extract directory {self.EXTRACT_DIR}:\n'
f'{mkdir_result.stdout}\n{mkdir_result.stderr}'
)
tar_result = module_target_sat.execute(f'tar xf {tarball} -C {self.EXTRACT_DIR}')
assert tar_result.status == 0, (
f'Failed to extract sosreport tarball {tarball}:\n'
f'{tar_result.stdout}\n{tar_result.stderr}'
)
report_dir = module_target_sat.execute(
f'ls -d {self.EXTRACT_DIR}/sosreport-*'
).stdout.strip()
yield report_dir
cleanup_result = module_target_sat.execute(
f'rm -rf /var/tmp/sosreport-* {self.EXTRACT_DIR}'
)
assert cleanup_result.status == 0, (
f'Failed to cleanup sosreport artifacts:\n'
f'{cleanup_result.stdout}\n{cleanup_result.stderr}'
)

Comment thread tests/foreman/cli/test_logging.py Outdated
Comment on lines +338 to +347
SENSITIVE_KEYWORD = ('password', )
SCRUB_MARKER = '********'

original = module_target_sat.execute(
f'grep -i password {FOREMANCTL_PARAMETERS_FILE}'
)
assert original.stdout.strip(), (
f'No password entries found in {FOREMANCTL_PARAMETERS_FILE}'
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Sensitive keyword coverage is limited to 'password' while the description mentions secrets/tokens

The docstring states we should scrub password/secret/token, but this constant (and the corresponding test) only covers password. If other keys like secret, token, or client_secret are meant to be scrubbed, please either extend SENSITIVE_KEYWORD to include them (or derive it from the implementation/requirements) and assert that each is masked as ******** in parameters.yaml. Otherwise, regressions for those fields may go unnoticed.

Suggested implementation:

        SENSITIVE_KEYWORD = ('password', 'secret', 'token', 'client_secret')
        original = module_target_sat.execute(
            f"grep -Ei '{'|'.join(SENSITIVE_KEYWORD)}' {FOREMANCTL_PARAMETERS_FILE}"
        )

To fully implement your comment, the rest of this test should:

  1. Iterate over SENSITIVE_KEYWORD and assert that each matching entry in the extracted parameters.yaml is masked as SCRUB_MARKER (********), not just password.
  2. Ensure any existing hard-coded references to "password" in subsequent assertions or scrubbing checks are updated to use SENSITIVE_KEYWORD, so regressions for secret, token, and client_secret cannot slip by untested.

@shubhamsg199

Copy link
Copy Markdown
Contributor Author

trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSosreportForemanctl
deployment_type: container

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16070
Build Status: UNSTABLE
PRT Comment: pytest tests/foreman/cli/test_logging.py::TestSosreportForemanctl --external-logging
Test Result : ================== 25 warnings, 2 errors in 841.97s (0:14:01) ==================

@Satellite-QE Satellite-QE added the PRT-Failed Indicates that latest PRT run is failed for the PR label Jul 8, 2026
@shubhamsg199

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSosreportForemanctl
deployment_type: container
sosreport:
    sos: 4376

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16072
Build Status: UNSTABLE
PRT Comment: pytest tests/foreman/cli/test_logging.py::TestSosreportForemanctl --external-logging
Test Result : ================== 25 warnings, 2 errors in 908.65s (0:15:08) ==================

Comment thread tests/foreman/cli/test_logging.py Outdated
Comment thread tests/foreman/cli/test_logging.py Outdated
@shubhamsg199
shubhamsg199 force-pushed the sos_report branch 3 times, most recently from b4d381b to ee69d88 Compare July 13, 2026 08:42
@shubhamsg199

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSOSReportForemanctl
sosreport:
    sos: 4376

@shubhamsg199

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSOSReportForemanctl
deployment_type: container
sosreport:
    sos: 4376

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16110
Build Status: UNSTABLE
PRT Comment: pytest tests/foreman/cli/test_logging.py::TestSOSReportForemanctl --external-logging
Test Result : ================== 27 warnings, 2 errors in 880.21s (0:14:40) ==================

@archanaserver

Copy link
Copy Markdown
Contributor

Looking at it the test failure is probably due to a version mismatch, test environment is running sos 4.11.0 which doesn't include the foremanctl plugin from PR sosreport/sos#4376.

@shubhamsg199

Copy link
Copy Markdown
Contributor Author

Looking at it the test failure is probably due to a version mismatch, test environment is running sos 4.11.0 which doesn't include the foremanctl plugin from PR sosreport/sos#4376.

Yes, seems the patch wasn't applied on the checked out satellite

@shubhamsg199

Copy link
Copy Markdown
Contributor Author

PRT doesn't support the sosreport org, so the PR couldn't be patched. I've attached the results from the manual tests.

$ pytest tests/foreman/cli/test_logging.py::TestSOSReportForemanctl -v
=========================================== test session starts =========================================================================
collected 2 items

tests/foreman/cli/test_logging.py::TestSOSReportForemanctl::test_positive_sosreport_foremanctl_collects_data PASSED                                            [ 50%]
tests/foreman/cli/test_logging.py::TestSOSReportForemanctl::test_positive_sosreport_foremanctl_scrub_sensitive_values PASSED                                   [100%]

=========================================== 2 passed in 56.58s =========================================================================

@evgeni

evgeni commented Jul 16, 2026

Copy link
Copy Markdown
Member

PRT doesn't support the sosreport org,

I always wondered about this. Why do we have it setup like this, where we need enablement of each org explicitly, instead of saying something like:

packit:
  theforeman:
     foreman: 123
  sosreport:
     sos: 333
  Dynflow:
     dynflow: 999

@archanaserver

Copy link
Copy Markdown
Contributor

Okay so the automated failure is due to the current PRT limitation rather than the tests themselves. Should we track support for the sosreport org separately and accept the manual test results for this PR?

PRT doesn't support the sosreport org,

I always wondered about this. Why do we have it setup like this, where we need enablement of each org explicitly, instead of saying something like:

packit:
  theforeman:
     foreman: 123
  sosreport:
     sos: 333
  Dynflow:
     dynflow: 999

@stejskalleos

Copy link
Copy Markdown
Contributor

Should we track support for the sosreport org separately and accept the manual test results for this PR?

@archanaserver IMO this is the way. Please create a GH issue and link it here.
@shubhamsg199 The code LGTM; if you don't have any objections, I'm going to merge today.

@archanaserver

Copy link
Copy Markdown
Contributor

Should we track support for the sosreport org separately and accept the manual test results for this PR?

@archanaserver IMO this is the way. Please create a GH issue and link it here. @shubhamsg199 The code LGTM; if you don't have any objections, I'm going to merge today.

Thanks @stejskalleos, I created issue #22274 to track PRT support for sosreport org.

@shubhamsg199

Copy link
Copy Markdown
Contributor Author

Should we track support for the sosreport org separately and accept the manual test results for this PR?

@archanaserver IMO this is the way. Please create a GH issue and link it here. @shubhamsg199 The code LGTM; if you don't have any objections, I'm going to merge today.

@stejskalleos Yes, I don't have any objections. @archanaserver Thanks for creating the issue. I'll work on adding the config for sosreport org later.

@archanaserver

Copy link
Copy Markdown
Contributor

@stejskalleos @evgeni any thoughts before we merge this?

@evgeni

evgeni commented Jul 28, 2026

Copy link
Copy Markdown
Member

no objections

Comment on lines +253 to +255
class TestSOSReportForemanctl:
"""Tests for the foremanctl sos plugin on containerized Satellite."""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this change in Foremanctl depends on the upstream SOS package, so while upstream PRT might pass, downstream tests will continue to fail until the package becomes available there.
To handle this in the interim, I think we should add a skip_if_open marker to skip these tests when running against downstream, we could try install from Packit COPR repos as a workaround until the downstream package catches up, wdyt?

@Gauravtalreja1 Gauravtalreja1 Jul 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a short-term workaround, we could add an autouse fixture to enable the COPR repo from the upstream SOS PR and get this merged sooner.
I think this gives us about a month before the Packit RPM expires. After that, we can switch to using a SOS upstream nightly RPM built from their main branch, that wasn't available today, so I've opened a PR upstream to add a nightly build similar to what we already do in @theforeman added by @evgeni

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added is_open to enable COPR repo from the upstream SOS PR as a short-term workaround

@shubhamsg199
shubhamsg199 force-pushed the sos_report branch 3 times, most recently from 790441b to 0d26954 Compare July 28, 2026 13:06
@shubhamsg199

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSOSReportForemanctl
deployment_type: container

Signed-off-by: Shubham Ganar <shubhamsg123m@gmail.com>
@shubhamsg199

Copy link
Copy Markdown
Contributor Author
trigger: test-robottelo
pytest: tests/foreman/cli/test_logging.py::TestSOSReportForemanctl
deployment_type: container

@Satellite-QE

Copy link
Copy Markdown
Collaborator

PRT Result

Build Number: 16280
Build Status: SUCCESS
PRT Comment: pytest tests/foreman/cli/test_logging.py::TestSOSReportForemanctl --external-logging
Test Result : ================== 2 passed, 28 warnings in 916.41s (0:15:16) ==================

@Satellite-QE Satellite-QE added PRT-Passed Indicates that latest PRT run is passed for the PR and removed PRT-Failed Indicates that latest PRT run is failed for the PR labels Jul 28, 2026
@amolpati30
amolpati30 merged commit 4cef23a into SatelliteQE:master Jul 29, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No-CherryPick PR doesnt need CherryPick to previous branches PRT-Passed Indicates that latest PRT run is passed for the PR Stream Introduced in or relating directly to Satellite Stream/Master

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants