Skip to content

Test: Enhance expire_after_update_none_on_expired_entry test to ensure both expire_after_* paths #568

@tatsuya6502

Description

@tatsuya6502

Originally posted by @coderabbitai[bot] in #564 (review)

2907-2997: Ensure this test always exercises the expire_after_update path, not just expire_after_create.

The scenario and assertions look correct for the bug you’re targeting (clearing per-entry expiration when expire_after_update returns None), but there’s a subtle dependency on current eviction/timer behavior:

  • With Duration::ZERO and cache.run_pending_tasks() right after the first insert, the timer wheel may fully evict the entry before the second insert, causing that second call to go through the insert path (expire_after_create) instead of the update path (expire_after_update).
  • If that happens, the test would still pass even if the sync fix in expire_after_read_or_update regressed, because the problematic expire_after_update code path would not be covered.

It would be safer to make the “expired but still present” state explicit and independent of current timer-wheel internals, for example by:

  • Using Clock::mock() with a small non-zero per-entry duration, and:
    • Insert + run_pending_tasks() to admit the entry.
    • Advance the mock clock past the per-entry TTL without calling run_pending_tasks so the entry remains in the map but get() treats it as expired.
    • Flip should_expire to false and then call insert again, ensuring it’s an in-place update that triggers expire_after_update.
  • Or, more minimally, avoid the initial run_pending_tasks() so that the first entry is guaranteed to still be present in the CHT when the second insert happens, relying only on get()’s expiration checks for the first “expired” assertion.

This isn’t a blocker, but I’d recommend double-checking (or instrumenting once) that the second insert currently hits expire_after_update, and consider tightening the test so that it continues to do so even if eviction/timer internals change later.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions