Skip to content

test: add filesystem fallback tests for analytics provider (#1119)#1276

Merged
muddlebee merged 9 commits intoTracer-Cloud:mainfrom
vidhishah2209:main
May 5, 2026
Merged

test: add filesystem fallback tests for analytics provider (#1119)#1276
muddlebee merged 9 commits intoTracer-Cloud:mainfrom
vidhishah2209:main

Conversation

@vidhishah2209
Copy link
Copy Markdown
Contributor

Fixes #1119

Describe the changes you have made in this PR -

Adds unit tests to verify that analytics helper functions fail gracefully when filesystem operations raise OSError. Covers two error paths:

  • _get_or_create_anonymous_id() — returns a non-empty, UUID-like string even when the anonymous ID file write fails
  • capture_install_detected_if_needed() — returns False and emits no events when the marker file creation fails

Also adds a uuid import for UUID validation in tests, and updates a raise-helper annotation to typing.NoReturn per linter suggestion.

Files modified:

  • tests/analytics/test_provider.py — 2 new tests + minor annotation refactor

Code Understanding and AI Usage

Did you use AI assistance (ChatGPT, Claude, Copilot, etc.) to write any part of this code?

  • No, I wrote all the code myself
  • Yes, I used AI assistance (continue below)

If you used AI assistance:

  • I have reviewed every single line of the AI-generated code
  • I can explain the purpose and logic of each function/component I added
  • I have tested edge cases and understand how the code handles them
  • I have modified the AI output to follow this project's coding standards and conventions

Explain your implementation approach:

The goal was to ensure the analytics layer never crashes the CLI when filesystem operations fail in production (e.g. permission errors, read-only mounts, full disk).

I used unittest.mock.patch to simulate OSError during file writes and asserted that both helper functions return gracefully with expected fallback values — a valid UUID string for the anonymous ID helper, and False for the install marker helper — rather than propagating the exception. I also confirmed no analytics events are emitted on the failing path for the install marker test.

The typing.NoReturn annotation was added to the raise-helper to satisfy the linter and accurately document intent.

No alternative approaches were seriously considered — mocking is the standard, lightweight way to test error paths without touching the real filesystem.


Checklist before requesting a review

  • I have added proper PR title and linked to the issue
  • I have performed a self-review of my code
  • I can explain the purpose of every function, class, and logic block I added
  • I understand why my changes work and have tested them thoroughly
  • I have considered potential edge cases and how my code handles them
  • If it is a core feature, I have added thorough tests
  • My code follows the project's style guidelines and conventions

Note: Please check Allow edits from maintainers if you would like us to assist in the PR.

vidhishah2209 and others added 6 commits May 4, 2026 19:38
…-Cloud#1119)

- Add test for _get_or_create_anonymous_id() when file write fails (OSError)
- Add test for capture_install_detected_if_needed() when marker touch fails
- Both tests verify fail-safe behavior with monkeypatching (no real filesystem tricks)
…-Cloud#1119)\n\nRefactor: update helper annotations per linter suggestions
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Greptile Summary

Adds two unit tests verifying that _get_or_create_anonymous_id() and capture_install_detected_if_needed() degrade gracefully when Path.write_text / Path.touch raise OSError. The test logic is sound — mocking is correctly scoped via monkeypatch, assertions cover both the return value and the absence of side-effects, and UUID validation is thorough. The only finding is a minor import ordering issue.

Confidence Score: 4/5

Safe to merge; single P2 style finding only

All findings are P2 (import order). Test logic is correct, assertions are appropriate, and monkeypatch usage is idiomatic.

No files require special attention

Important Files Changed

Filename Overview
tests/analytics/test_provider.py Adds two new OSError fallback tests; logic is correct but from typing import NoReturn is misplaced below project imports (PEP 8 / isort violation)

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[test: write_text raises OSError] --> B["_get_or_create_anonymous_id()"]
    B --> C{mkdir succeeds?}
    C -- yes --> D{file exists?}
    D -- no --> E["write_text() → OSError"]
    E --> F["except OSError → return uuid4()"]
    F --> G[assert: valid UUID string]

    H[test: touch raises OSError] --> I["capture_install_detected_if_needed()"]
    I --> J["_touch_once(_FIRST_RUN_PATH)"]
    J --> K{mkdir succeeds?}
    K -- yes --> L{path exists?}
    L -- no --> M["path.touch() → OSError"]
    M --> N["except OSError → return False"]
    N --> O["capture_install_detected_if_needed → return False"]
    O --> P["assert: False, no events emitted"]
Loading

Reviews (1): Last reviewed commit: "Merge upstream/main into main" | Re-trigger Greptile

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Greptile Summary

Adds two unit tests verifying that _get_or_create_anonymous_id() and capture_install_detected_if_needed() degrade gracefully when Path.write_text / Path.touch raise OSError. The test logic is sound — mocking is correctly scoped via monkeypatch, assertions cover both the return value and the absence of side-effects, and UUID validation is thorough. The only finding is a minor import ordering issue.

Confidence Score: 4/5

Safe to merge; single P2 style finding only

All findings are P2 (import order). Test logic is correct, assertions are appropriate, and monkeypatch usage is idiomatic.

No files require special attention

Important Files Changed

Filename Overview
tests/analytics/test_provider.py Adds two new OSError fallback tests; logic is correct but from typing import NoReturn is misplaced below project imports (PEP 8 / isort violation)

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[test: write_text raises OSError] --> B["_get_or_create_anonymous_id()"]
    B --> C{mkdir succeeds?}
    C -- yes --> D{file exists?}
    D -- no --> E["write_text() → OSError"]
    E --> F["except OSError → return uuid4()"]
    F --> G[assert: valid UUID string]

    H[test: touch raises OSError] --> I["capture_install_detected_if_needed()"]
    I --> J["_touch_once(_FIRST_RUN_PATH)"]
    J --> K{mkdir succeeds?}
    K -- yes --> L{path exists?}
    L -- no --> M["path.touch() → OSError"]
    M --> N["except OSError → return False"]
    N --> O["capture_install_detected_if_needed → return False"]
    O --> P["assert: False, no events emitted"]
Loading

Comments Outside Diff (1)

  1. tests/analytics/test_provider.py, line 9 (link)

    P2 Stdlib import placed after third-party imports

    from typing import NoReturn is a stdlib import but is placed after the app.* project imports, violating PEP 8 / isort ordering (stdlib → third-party → local). Linters and CI isort checks will flag this.

    Move it alongside import uuid and from pathlib import Path in the stdlib block.

Reviews (1): Last reviewed commit: "Merge upstream/main into main" | Re-trigger Greptile

Comment thread tests/analytics/test_provider.py Outdated
from app.analytics import install, provider
from app.analytics.events import Event

from typing import NoReturn
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.

P2 Stdlib import placed after third-party imports

from typing import NoReturn is a stdlib import but is placed after the app.* project imports, violating PEP 8 / isort ordering (stdlib → third-party → local). Linters and CI isort checks will flag this.

Move it alongside import uuid and from pathlib import Path in the stdlib block.

Suggested change
from typing import NoReturn
from typing import NoReturn

@muddlebee
Copy link
Copy Markdown
Collaborator

@vidhishah2209 fix CI
image

@muddlebee muddlebee merged commit b666b97 into Tracer-Cloud:main May 5, 2026
6 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

💜 One more reason the project grows. Thanks @vidhishah2209 — your contribution just landed!


👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome.

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.

Add analytics filesystem fallback tests

2 participants