3.6 KiB
PR#130: Repository Privacy Answer Kept and Renewed in Steps
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
RepositoryPrivacy.isPrivate is above the Mutation-CRAP target of 15 in the nightly mutation build of 2026-10-07 and 2026-10-09:
| Method | Mutation-CRAP | Complexity | Killed / eligible |
|---|---|---|---|
RepositoryPrivacy.isPrivate |
16.40 | 10 | 9 / 15 |
One method decided whether the cached answer still stands, asked the forge, warned about a silent forge and stored the new answer. The tests never touched the exact moment an answer expires, and nothing checked that a silent forge is reported once and not on every retry.
Non-Goals
- No change of the behaviour: the same answers, the same expiry times, the same warning.
The Scenarios
Feature: The privacy answer of a repository
Scenario#130.01: A cached answer expires at exactly its validity
So that a repository that changed its visibility is followed within the stated time, and not one poll later or earlier.
- Given the forge answered for a repository
- When one second less than the answer's validity has passed
- Then the cached answer is returned and the forge is not asked
- When the full validity has passed
- Then the forge is asked again
- The validity is
REFRESH_AFTER(15 minutes) for a confirmed answer andRETRY_UNKNOWN_AFTER(1 minute) for a guess.
Verified by
- RepositoryPrivacyUnitTest: a confirmed answer stands for exactly REFRESH_AFTER
- RepositoryPrivacyUnitTest: a guess stands for exactly RETRY_UNKNOWN_AFTER
Scenario#130.02: A forge that stops answering is reported once
So that the log names the outage without repeating it every minute while the forge stays silent.
- Given the forge answered for a repository
- When the forge stops answering and is asked three times in a row
- Then the warning "Cannot tell whether … is private" is logged once
Verified by
The Solution
Answer.standsAt(now)says whether a cached answer is still valid.isPrivatereturns the cached answer or callsask.askreads the visibility, warns when a known answer turns unknown, and stores the new answer.
Measured locally with PIT on RepositoryPrivacy:
| Method | Mutation-CRAP before | after |
|---|---|---|
RepositoryPrivacy.isPrivate |
16.40 | 6.04 |
RepositoryPrivacy.ask |
new | 6.11 |
Answer.standsAt |
new | 3.00 |
The gate stays at 15.
Prerequisite PRs
- PR#129 — this branch is stacked on it, for the version and the release notes.
Follow-up PRs
- PR#131 splits two more methods of
ConfigLoaderinto smaller steps, so that their scores drop below 15.ConfigLoader.renameLegacySandboxis at 15.93.ConfigLoader.checkRestartsInstanceis at exactly 15.00: one more surviving mutant would put it above the gate.