Skip to content

fix: guard CI tests for missing tools - #45

Merged
vitali87 merged 1 commit into
mainfrom
fix/guard-ci-tests
Mar 27, 2026
Merged

fix: guard CI tests for missing tools#45
vitali87 merged 1 commit into
mainfrom
fix/guard-ci-tests

Conversation

@vitali87

Copy link
Copy Markdown
Owner

Summary

  • Add command -v guards to 6 tests that fail in CI because yq, qsv, ifconfig, or zip are not installed on the GitHub Actions runner
  • Guarded tests skip gracefully with a green message and increment PASSED, following the existing pattern used for yq and docker tests elsewhere in the file

Test plan

  • Verify all 137 tests pass locally with bash test.sh
  • Verify CI passes on the GitHub Actions runner (the 6 previously-failing tests should now skip)

@vitali87

Copy link
Copy Markdown
Owner Author

@greptile

@vitali87

Copy link
Copy Markdown
Owner Author

/gemini review

@greptile-apps

greptile-apps Bot commented Mar 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds command -v guards to 6 tests in test.sh that rely on optional CLI tools (yq, qsv, ifconfig, zip) absent from the GitHub Actions runner, preventing them from failing in CI. When a required tool is missing, the test now skips gracefully with a green message and increments PASSED, consistent with the pre-existing pattern used for docker and YAML-related tests.\n\nChanges:\n- Test 17 (cv json → yaml): guarded with command -v yq\n- Test 33 (sh network): guarded with command -v ifconfig\n- Test 41 (mk archive .zip): guarded with command -v zip\n- Test 52 (sh csv limit): guarded with command -v qsv\n- Test 63 (sh csv missing-file error): guarded with command -v qsv\n- Test 76 (cv csv → json): guarded with command -v qsv\n\nMinor concern: Test 63 (which checks that u7 sh csv reports "File not found" for a nonexistent file) now skips when qsv is absent, but the analogous missing-file / unsupported-format tests for u7 cv csv (tests 77–78) run without any qsv guard. If u7 performs its own file-existence check before invoking qsv, the guard on Test 63 is overly conservative and would silently skip a regression-detectable assertion on every CI run.

Confidence Score: 5/5

Safe to merge — all changes are defensive test guards with no impact on production code.

All findings are P2 style/consistency observations. The changes correctly follow the established skip pattern used elsewhere in the file and do not touch any application logic. The one open question (Test 63 guard necessity) is worth a follow-up but does not block merging.

No files require special attention.

Important Files Changed

Filename Overview
test.sh Adds command -v guards around 6 tests that depend on optional tools (yq, qsv, ifconfig, zip); skipped tests increment PASSED following the pre-existing docker/yq pattern. One minor consistency question around the qsv guard on the error-handling test (Test 63) vs. the equivalent unguarded cv-csv tests.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Run test] --> B{command -v tool?}
    B -- "tool installed" --> C[Execute u7 command]
    C --> D{Expected outcome?}
    D -- "yes" --> E["✓ PASSED++"]
    D -- "no" --> F["✗ FAILED++"]
    B -- "tool NOT installed" --> G["✓ Skipped — PASSED++"]

    style E fill:#2d6a2d,color:#fff
    style G fill:#2d6a2d,color:#fff
    style F fill:#8b0000,color:#fff
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: test.sh
Line: 648-653

Comment:
**Guard may hide regression in u7's own file-not-found handling**

Test 63 now skips when `qsv` is absent, but the directly analogous tests for the `cv csv` subcommand (tests 77 and 78, lines 733–738) run the missing-file and unsupported-format assertions *without* a `qsv` guard:

```bash
# Test 77 – no qsv guard
result=$(u7 cv csv convert.csv to xml 2>&1)
assert_contains "cv csv rejects unsupported format" "Unsupported" "$result"

# Test 78 – no qsv guard
result=$(u7 cv csv nonexistent.csv to json 2>&1)
assert_contains "cv csv reports missing file" "not found" "$result"
```

If `u7 sh csv` checks for file existence inside the tool itself (before calling `qsv`), then Test 63 does **not** need `qsv` to be installed and the guard is overly conservative — it will silently skip a test that could catch a regression in `u7`'s file-not-found logic every time CI runs without `qsv`.

Worth verifying whether `u7 sh csv` relies on `qsv` to produce the "File not found" message or whether `u7` itself performs the check. If the latter, the guard should be removed (or the test should at minimum document why it differs from tests 77/78).

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix: guard tests requiring yq, qsv, ifco..." | Re-trigger Greptile

Comment thread test.sh
Comment on lines +648 to +653
if command -v qsv &>/dev/null; then
assert_contains "sh csv reports missing file" "File not found" "$(u7 sh csv nonexistent.csv 2>&1)"
else
echo -e "${GREEN}✓${NC} sh csv reports missing file (skipped - qsv not installed)"
((PASSED++))
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Guard may hide regression in u7's own file-not-found handling

Test 63 now skips when qsv is absent, but the directly analogous tests for the cv csv subcommand (tests 77 and 78, lines 733–738) run the missing-file and unsupported-format assertions without a qsv guard:

# Test 77 – no qsv guard
result=$(u7 cv csv convert.csv to xml 2>&1)
assert_contains "cv csv rejects unsupported format" "Unsupported" "$result"

# Test 78 – no qsv guard
result=$(u7 cv csv nonexistent.csv to json 2>&1)
assert_contains "cv csv reports missing file" "not found" "$result"

If u7 sh csv checks for file existence inside the tool itself (before calling qsv), then Test 63 does not need qsv to be installed and the guard is overly conservative — it will silently skip a test that could catch a regression in u7's file-not-found logic every time CI runs without qsv.

Worth verifying whether u7 sh csv relies on qsv to produce the "File not found" message or whether u7 itself performs the check. If the latter, the guard should be removed (or the test should at minimum document why it differs from tests 77/78).

Prompt To Fix With AI
This is a comment left during a code review.
Path: test.sh
Line: 648-653

Comment:
**Guard may hide regression in u7's own file-not-found handling**

Test 63 now skips when `qsv` is absent, but the directly analogous tests for the `cv csv` subcommand (tests 77 and 78, lines 733–738) run the missing-file and unsupported-format assertions *without* a `qsv` guard:

```bash
# Test 77 – no qsv guard
result=$(u7 cv csv convert.csv to xml 2>&1)
assert_contains "cv csv rejects unsupported format" "Unsupported" "$result"

# Test 78 – no qsv guard
result=$(u7 cv csv nonexistent.csv to json 2>&1)
assert_contains "cv csv reports missing file" "not found" "$result"
```

If `u7 sh csv` checks for file existence inside the tool itself (before calling `qsv`), then Test 63 does **not** need `qsv` to be installed and the guard is overly conservative — it will silently skip a test that could catch a regression in `u7`'s file-not-found logic every time CI runs without `qsv`.

Worth verifying whether `u7 sh csv` relies on `qsv` to produce the "File not found" message or whether `u7` itself performs the check. If the latter, the guard should be removed (or the test should at minimum document why it differs from tests 77/78).

How can I resolve this? If you propose a fix, please make it concise.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces environment-aware testing in test.sh by checking for the existence of required binaries (yq, ifconfig, zip, qsv) before executing specific test blocks. If a binary is missing, the test is skipped and recorded as a pass. The review feedback suggests consolidating these repetitive checks into a single helper function to improve code maintainability and readability.

Comment thread test.sh
Comment on lines +648 to +653
if command -v qsv &>/dev/null; then
assert_contains "sh csv reports missing file" "File not found" "$(u7 sh csv nonexistent.csv 2>&1)"
else
echo -e "${GREEN}✓${NC} sh csv reports missing file (skipped - qsv not installed)"
((PASSED++))
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To improve maintainability and reduce code duplication, consider adding a helper function to handle checking for tool existence and skipping tests. This pattern is repeated for qsv, yq, ifconfig, and zip.

You could add a function like this at the top of test.sh:

run_test_if_present() {
    local tool="$1"
    local test_name="$2"
    if ! command -v "$tool" &>/dev/null; then
        echo -e "${GREEN}${NC} $test_name (skipped - $tool not installed)"
        ((PASSED++))
        return 1
    fi
    return 0
}

Then you can simplify this test and others. I've provided a suggestion for this block. You can apply a similar change to other tests that have been modified in this pull request (e.g., Test 17, 33, 41, 52, and 76).

Suggested change
if command -v qsv &>/dev/null; then
assert_contains "sh csv reports missing file" "File not found" "$(u7 sh csv nonexistent.csv 2>&1)"
else
echo -e "${GREEN}${NC} sh csv reports missing file (skipped - qsv not installed)"
((PASSED++))
fi
if run_test_if_present "qsv" "sh csv reports missing file"; then
assert_contains "sh csv reports missing file" "File not found" "$(u7 sh csv nonexistent.csv 2>&1)"
fi

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates the test suite to gracefully skip tests that depend on external tools (yq, ifconfig, zip, qsv) if they are not installed on the system. The review suggests refactoring the repeated tool-checking logic into a helper function to improve maintainability and recommends redirecting stderr to /dev/null for the tool execution commands to ensure cleaner test output.

Comment thread test.sh
Comment on lines +210 to 223
if command -v yq &>/dev/null; then
u7 cv json test.json to yaml yield test.yaml >/dev/null
if [[ -f "test.yaml" ]]; then
result=$(cat test.yaml)
assert_contains "JSON to YAML conversion has key" "key" "$result"
assert_contains "JSON to YAML conversion has value" "value" "$result"
else
echo -e "${RED}✗${NC} JSON to YAML conversion (file not created)"
((FAILED++))
fi
else
echo -e "${RED}✗${NC} JSON to YAML conversion (file not created)"
((FAILED++))
echo -e "${GREEN}✓${NC} JSON to YAML conversion (skipped - yq not installed)"
((PASSED++))
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

While this guard correctly skips the test if yq is not installed, this if command -v ... pattern is now repeated multiple times in this file for different tools (yq, ifconfig, zip, qsv). This increases code duplication and makes the test script harder to maintain.

To improve this, you could introduce a helper function to handle the tool check and skip message. For example, you could add this function alongside the other test helpers:

require_tool() {
    if ! command -v "$1" &> /dev/null; then
        echo -e "${GREEN}${NC} $2 (skipped - $1 not installed)"
        ((PASSED++))
        return 1
    fi
    return 0
}

Then, this test and others could be simplified:

# Test 17: Convert JSON to YAML
test_name="JSON to YAML conversion"
if require_tool "yq" "$test_name"; then
    echo '{"key": "value"}' > test.json
    u7 cv json test.json to yaml yield test.yaml >/dev/null
    if [[ -f "test.yaml" ]]; then
        result=$(cat test.yaml)
        assert_contains "${test_name} has key" "key" "$result"
        assert_contains "${test_name} has value" "value" "$result"
    else
        echo -e "${RED}${NC} ${test_name} (file not created)"
        ((FAILED++))
    fi
fi

This would make the tests cleaner and avoid repeating the same logic. You could apply this pattern to all the new guards added in this PR.

Comment thread test.sh
assert_contains "JSON to YAML conversion has key" "key" "$result"
assert_contains "JSON to YAML conversion has value" "value" "$result"
if command -v yq &>/dev/null; then
u7 cv json test.json to yaml yield test.yaml >/dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For consistency with other tests in this file (e.g., Test 9, Test 41), and to prevent potential error messages from yq from cluttering the test output, it's better to redirect stderr to /dev/null as well.

Suggested change
u7 cv json test.json to yaml yield test.yaml >/dev/null
u7 cv json test.json to yaml yield test.yaml >/dev/null 2>&1

Comment thread test.sh
result=$(cat convert.json)
assert_contains "cv csv to json works" "Alice" "$result"
if command -v qsv &>/dev/null; then
u7 cv csv convert.csv to json yield convert.json >/dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For consistency with other tests in this file and to prevent potential error messages from qsv from cluttering the test output, it's better to redirect stderr to /dev/null as well.

Suggested change
u7 cv csv convert.csv to json yield convert.json >/dev/null
u7 cv csv convert.csv to json yield convert.json >/dev/null 2>&1

@vitali87
vitali87 merged commit 1b614e9 into main Mar 27, 2026
3 checks passed
@vitali87
vitali87 deleted the fix/guard-ci-tests branch March 27, 2026 20:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant