Skip to content

attempts to fix integration test#2

Open
gamesguru wants to merge 12 commits into
masterfrom
dev
Open

attempts to fix integration test#2
gamesguru wants to merge 12 commits into
masterfrom
dev

Conversation

@gamesguru

@gamesguru gamesguru commented Mar 24, 2026

Copy link
Copy Markdown
Member

Summary by cubic

Ships a v2 rewrite that turns matrix-premid into a proper CLI/daemon with a systemd user service, keyring-backed multi-account config, and VCS versioning, now using direct REST via aiohttp (drops matrix-nio). CI installs the package and starts a configured Conduwuit container; the flaky integration test was removed.

  • New Features

    • Distributable package with matrix-premid entry point, tab completion via argcomplete, VCS versioning, and src layout.
    • Config-driven providers (regex, priorities, templates) with per-account control; ships config.template.json; improved parsing adds media time tracking and video vs. audio priority.
    • CLI adds daemon/shutdown, --debug/--version, installers for user or /opt, secure tokens via OS keyring, and a help epilog with keyring commands and config location.
  • Bug Fixes

    • Smoother idle/paused handling; fixed negative time deltas; graceful shutdown sets offline.
    • Safer lockfile handling and exponential backoff to avoid homeserver hammering.
    • CI runs with Docker + TOML config and activates the venv; help epilog hints now use the correct Python path.

Written for commit a749a53. Summary will update on new commits.

Review in cubic

Copilot AI review requested due to automatic review settings March 24, 2026 08:58

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 1 file

Copilot AI 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.

Pull request overview

Updates the GitHub Actions E2E workflow to start the Conduwuit homeserver via an explicit docker run with a generated TOML config, aiming to stabilize the integration test setup.

Changes:

  • Removes the GitHub Actions services: container definition for Conduwuit.
  • Adds a step that writes conduwuit.toml and starts Conduwuit via docker run.
  • Drops passing CONDUWUIT_CONTAINER_ID into the integration test step.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/integration.yml
Comment thread .github/workflows/integration.yml Outdated
Comment thread .github/workflows/integration.yml

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docker/test_integration.py">

<violation number="1" location="docker/test_integration.py:22">
P1: Fail fast when token discovery fails instead of silently falling back to a hardcoded token.</violation>

<violation number="2" location="docker/test_integration.py:44">
P2: Do not print the full registration token in logs; this leaks a credential used for registration.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread docker/test_integration.py Outdated
Comment thread docker/test_integration.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 10:21

Copilot AI 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.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread matrix_premid.py Outdated
Comment thread src/matrix_premid/__main__.py
Comment thread docker/test_integration.py Outdated
Comment thread docker/test_integration.py Outdated
Comment thread .github/workflows/integration.yml Outdated

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="matrix_premid.py">

<violation number="1" location="matrix_premid.py:206">
P2: Adding the new `Watching` prefix without updating `update()` quality parsing regresses metadata prioritization, so lower-quality statuses can overwrite richer ones for the same title.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread matrix_premid.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 11:06

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread matrix_premid.py Outdated
Comment thread docker/test_integration.py Outdated
Comment thread docker/test_integration.py Outdated
Comment thread .github/workflows/integration.yml Outdated
Comment thread matrix_premid.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 11:26

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="Makefile">

<violation number="1" location="Makefile:53">
P1: `test` no longer depends on `deps`, so `make test` can fail on fresh setups because pytest/dev dependencies are not installed.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread Makefile Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

tests/test_updater.py:172

  • test_main_execution_mocked_gather calls main(), but main() now exits early if playerctl is not found via shutil.which. This test (and the other main() test) should patch matrix_premid.shutil.which to return a fake path so the assertions exercise the intended code paths and don't become environment-dependent.
@pytest.mark.asyncio
@patch("matrix_premid.sys.exit")
@patch("matrix_premid.acquire_lock")
@patch("matrix_premid.HOMESERVER", "mock")
@patch("matrix_premid.USERNAME", "@user")
@patch("matrix_premid.ACCESS_TOKEN", "tok")
@patch("matrix_premid.DEVICE_ID", "dev")
async def test_main_execution_mocked_gather(_mock_lock, mock_exit):
    """Test main entrypoint setups everything cleanly resolving without errors."""
    with patch("matrix_premid.AsyncClient") as mock_client:
        mock_instance = AsyncMock()
        mock_client.return_value = mock_instance

        mock_event = MagicMock()
        mock_event.user_id = "@user"
        mock_event.presence = "dnd"

        mock_resp = MagicMock()
        mock_resp.presence.events = [mock_event]

        # Emit native valid presence payload once, then gracefully exit loop
        mock_instance.sync.side_effect = [mock_resp, asyncio.CancelledError()]

        with patch(
            "matrix_premid.MatrixStatusUpdater.update", new_callable=AsyncMock
        ) as mock_update:
            mock_update.side_effect = asyncio.CancelledError()

            with patch("matrix_premid.asyncio.create_subprocess_exec") as mock_exec:
                mock_proc = AsyncMock()
                mock_proc.communicate.side_effect = asyncio.CancelledError()
                mock_exec.return_value = mock_proc

                await main()

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/matrix_premid/__main__.py
Comment thread tests/test_updater.py Outdated
Comment thread docker/test_integration.py Outdated
Comment thread docker/test_integration.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 12:25

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread matrix_premid.py Outdated
Comment thread Makefile Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 12:29

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/test_updater.py">

<violation number="1" location="tests/test_updater.py:156">
P2: This test fixture now uses `online`, which makes it unable to catch regressions where native non-default presence is ignored and forced back to online.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread tests/test_updater.py Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_parser.py Outdated
Comment thread docker/test_integration.py Outdated
Comment thread matrix_premid.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 12:44

Copilot AI 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.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docker/test_integration.py Outdated
Comment thread matrix_premid.py Outdated
Copilot AI review requested due to automatic review settings March 24, 2026 12:57

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docker/test_integration.py">

<violation number="1" location="docker/test_integration.py:29">
P2: Using `docker logs --since 1s` can miss the one-time registration-token log line and make this integration test flaky.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread docker/test_integration.py Outdated

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/matrix_premid/__main__.py">

<violation number="1" location="src/matrix_premid/__main__.py:643">
P2: Time-quality bonus is granted based on raw non-empty fields, so zero/invalid durations can be misclassified as valid timestamps.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/matrix_premid/__main__.py Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 19 out of 22 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.rst
Comment on lines +57 to 60
1. **Install dependencies**: ``pip install .`` (or use installation methods above).
2. **Setup environment**: Place your ``.env`` file in the current directory or at ``~/.config/matrix-premid/.env``.
3. **Run the script**: ``matrix-premid``

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

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

The README now instructs users to place a .env file for configuration, but the new CLI no longer loads dotenv/env-based configuration; it requires ~/.config/matrix-premid/config.json and uses keyring for missing access tokens. Update the “Basic Usage” steps to describe creating/editing config.json (or using the provided template) and storing tokens in keyring (or placing access_token in config for non-interactive setups like CI).

Copilot uses AI. Check for mistakes.
Comment on lines +245 to +248
# If no activity detected, we don't force 'Idle' immediately.
# We preserve the last activity unless it's explicitly 'Idle'
# or we are exiting.
return

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

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

MatrixStatusUpdater.update() returns immediately when activity is empty (unless is_exit), but the idle debounce/idle_timeout logic only runs when activity is "Idle"/"Idle...". Combined with _get_best_mpris_activity() returning "" when nothing is playing, this means the updater may never transition to Idle when playback stops and idle_timeout becomes ineffective. Consider treating empty activity as an idle signal (possibly debounced via idle_strikes) or have _get_best_mpris_activity() return "Idle" when no active players are detected.

Suggested change
# If no activity detected, we don't force 'Idle' immediately.
# We preserve the last activity unless it's explicitly 'Idle'
# or we are exiting.
return
# Treat lack of activity as a potential idle state so that
# idle_timeout / idle_strikes logic can take effect.
activity = "Idle"
title = ""

Copilot uses AI. Check for mistakes.
Comment on lines +1037 to +1041
# Clean up lock file so next start works cleanly
try:
os.unlink(LOCK_FILE)
except OSError:
pass

Copilot AI Mar 29, 2026

Copy link

Choose a reason for hiding this comment

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

The lock file is unlinked during shutdown, but the lock file descriptor returned by acquire_lock() is never closed. Unlinking while still holding the lock releases the name while the process is still alive, allowing a second instance to create a new lock file and acquire a lock before this process exits. Keep a reference to the lock FD and close it before unlinking (or just leave the lock file in place and rely on lockf + truncation).

Suggested change
# Clean up lock file so next start works cleanly
try:
os.unlink(LOCK_FILE)
except OSError:
pass
# Do not unlink the lock file here. Locking is enforced via the file
# descriptor and POSIX locking (lockf), not by the mere presence of
# the file. Unlinking while still holding the lock can allow another
# process to recreate the file and acquire a separate lock before this
# process fully exits.

Copilot uses AI. Check for mistakes.
Comment thread Makefile Outdated

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/matrix_premid/__main__.py">

<violation number="1" location="src/matrix_premid/__main__.py:707">
P2: Validate `poll_interval`/`idle_timeout` from hot-reloaded config before assigning; invalid types can crash the monitor loop at runtime.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/matrix_premid/__main__.py
Copilot AI review requested due to automatic review settings March 30, 2026 05:15

Copilot AI 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.

Pull request overview

Copilot reviewed 19 out of 22 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1086 to +1090
# Clean up lock file so next start works cleanly
try:
os.unlink(LOCK_FILE)
except OSError:
pass

Copilot AI Mar 30, 2026

Copy link

Choose a reason for hiding this comment

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

The lock file is unlinked at shutdown, but the file descriptor returned from acquire_lock() is never closed before os.unlink(LOCK_FILE). On POSIX, unlinking while still holding the lock can allow a second process to create a new lock file and acquire a lock before the first process fully exits, defeating the single-instance guarantee. Fix by closing the lock fd before unlinking, or by leaving the lock file in place and relying on advisory locking + PID contents for cleanup.

Suggested change
# Clean up lock file so next start works cleanly
try:
os.unlink(LOCK_FILE)
except OSError:
pass
# Intentionally keep the lock file; rely on advisory locking and PID
# contents for cleanup to avoid unlink-while-locked races on POSIX.

Copilot uses AI. Check for mistakes.

if quality > best_quality:
best_activity, best_title, best_quality = activity, title, quality

Copilot AI Mar 30, 2026

Copy link

Choose a reason for hiding this comment

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

When no valid playerctl lines are found, _get_best_mpris_activity() returns empty strings. monitor_mpris() then passes an empty activity into MatrixStatusUpdater.update(), which returns early and never increments idle_strikes, so the last activity can be refreshed indefinitely (keep_alive sends last_activity). Consider returning an explicit idle sentinel (e.g., "Idle") in the no-activity case (or translating empty->Idle in monitor_mpris()), and update tests accordingly so debounced idle can work.

Suggested change
# If no suitable activity was found, explicitly return Idle so that
# downstream idle debouncing logic can trigger correctly.
if not best_activity:
return "Idle", ""

Copilot uses AI. Check for mistakes.
@cubic-dev-ai

cubic-dev-ai Bot commented Apr 4, 2026

Copy link
Copy Markdown

You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review.

- Removed matrix-nio dependency in favor of lightweight aiohttp requests
- Added multi-account support with secure keyring token storage
- Refactored into a distributable Python package with dynamic git versioning (hatch-vcs)
- Introduced daemon and shutdown CLI commands with robust lockfile management
- Improved provider parsing (media time tracking, watch vs. listen priority)
- Implemented exponential backoff for sync loop and fixed idle state transitions
- Expanded test coverage and fixed integration test instability
Copilot AI review requested due to automatic review settings April 5, 2026 06:45

Copilot AI 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.

Pull request overview

Copilot reviewed 19 out of 22 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.rst Outdated
Copilot AI review requested due to automatic review settings May 7, 2026 20:35

Copilot AI 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.

Pull request overview

Copilot reviewed 19 out of 22 changed files in this pull request and generated 2 comments.

Comment on lines +326 to +347
url_p = (
f"{self.homeserver}/_matrix/client/v3/presence/"
f"{self.username}/status"
)

if is_exit:
payload_p = {
"presence": "offline",
"status_msg": "",
}
else:
payload_p = {
"presence": self.current_presence,
}
if activity and activity != "Idle":
payload_p["status_msg"] = activity

# 2. Element Status Payload
url_s = (
f"{self.homeserver}/_matrix/client/v3/user/{self.username}/"
"account_data/im.vector.user_status"
)
Comment thread README.rst Outdated
Copilot AI review requested due to automatic review settings May 11, 2026 22:42

Copilot AI 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.

Pull request overview

Copilot reviewed 19 out of 22 changed files in this pull request and generated 4 comments.

Comment on lines +622 to +633
def _get_best_mpris_activity(lines: list[str]) -> tuple[str, str]:
"""Parse multiple player lines and extract the best metadata."""
# pylint: disable=too-many-branches,too-many-locals,too-many-statements
best_activity, best_title, best_quality = "", "", 0

# First pass: Parse each line and detect its own provider
parsed_lines = []
for raw in lines:
raw = raw.strip()
if not raw or SEP_STR not in raw:
continue
parts = raw.split(SEP_STR)
Comment thread README.rst Outdated
Comment thread README.rst Outdated
Comment thread tests/test_provider_config.py
gamesguru and others added 6 commits June 9, 2026 18:15
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

2 participants