mirror of
https://github.com/civitai/civitai.git
synced 2026-09-20 22:08:18 +08:00
test(images): cover the TTL slide the no-write-back guard was licensing
"Writes NOTHING to the cache" enumerated six command names and missed `expire`.
A TTL slide is the exact hazard the fallback's comment forbids - it is what
makes a cached value outlive the outage - so the case licensed the one write it
existed to prevent. Now eleven verbs including expire, hExpire, hIncrBy, del and
packed.setEx, and the comment says plainly that this is an allowlist of shapes
rather than a proof: it still cannot see a verb nobody thought of. The positive
form ("this arm issues hGetAll and nothing else") needs the hybrid mock to
export its node registry, which is shared test infrastructure and its own
change.
Both counter spies carry mockName, so a failure names the counter instead of
printing vi.fn().
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,8 +20,8 @@ const {
|
||||
logToAxiomMock,
|
||||
} = vi.hoisted(() => ({
|
||||
fetch: vi.fn(),
|
||||
counterIncMock: vi.fn(),
|
||||
staleCounterIncMock: vi.fn(),
|
||||
counterIncMock: vi.fn().mockName('image_metrics_clickhouse_timeout_total'),
|
||||
staleCounterIncMock: vi.fn().mockName('image_metrics_stale_cache_timeout_total'),
|
||||
logToAxiomMock: vi.fn(() => Promise.resolve()),
|
||||
}));
|
||||
|
||||
@@ -414,14 +414,24 @@ describe('getImageMetricsObject serves STALE cached counts when ClickHouse is un
|
||||
// never ran, because every other assertion here is an absence.
|
||||
expect(result[1]?.reactionLike).toBe(62);
|
||||
|
||||
// `packed.*` is how this codebase writes caches, so a write-back would most
|
||||
// likely be spelled there rather than on the bare client.
|
||||
expect(redisMock.redis.hSet).not.toHaveBeenCalled();
|
||||
expect(redisMock.redis.hSetEx).not.toHaveBeenCalled();
|
||||
expect(redisMock.redis.set).not.toHaveBeenCalled();
|
||||
expect(redisMock.redis.setEx).not.toHaveBeenCalled();
|
||||
expect(redisMock.redis.packed.set).not.toHaveBeenCalled();
|
||||
expect(redisMock.redis.packed.hSet).not.toHaveBeenCalled();
|
||||
// An ALLOWLIST of shapes, not a proof: it cannot see a verb nobody thought of.
|
||||
// `expire` is in it because a TTL slide is the specific thing the comment on the
|
||||
// fallback forbids - it is what makes a cached value outlive the outage - and
|
||||
// `packed.*` because that is how this codebase actually writes caches.
|
||||
for (const write of [
|
||||
redisMock.redis.hSet,
|
||||
redisMock.redis.hSetEx,
|
||||
redisMock.redis.set,
|
||||
redisMock.redis.setEx,
|
||||
redisMock.redis.expire,
|
||||
redisMock.redis.hExpire,
|
||||
redisMock.redis.hIncrBy,
|
||||
redisMock.redis.del,
|
||||
redisMock.redis.packed.set,
|
||||
redisMock.redis.packed.setEx,
|
||||
redisMock.redis.packed.hSet,
|
||||
])
|
||||
expect(write).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('returns no metrics rather than throwing when the cache read ALSO fails', async () => {
|
||||
|
||||
Reference in New Issue
Block a user