mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
* [comment audit] Shorten daemon, hook, and emulator comments [skip ci] * [comment audit] Shorten VM, conversation, SQLite, and theme-import comments [skip ci] * [comment audit] Tighten Git execution and source-control comment contracts [skip ci] * [comment audit] Clarify repository probes and maintenance comments [skip ci] * [comment audit] Shorten status, diff-cache, and checkout comments [skip ci] * [comment audit] Clarify worktree lifecycle and WSL routing comments [skip ci] * [comment audit] Shorten forge identity and review-refresh comments [skip ci] * [comment audit] Tighten hosted-review client comment contracts [skip ci] * [comment audit] Clarify GitLab compatibility and review comments [skip ci] * [comment audit] Tighten hook ownership and watchdog rationale [skip ci] * [comment audit] Condense host and integration compatibility comments [skip ci] * [comment audit] Clarify IPC authority and remote-routing rationale [skip ci] * [comment audit] Finalize file-import and containment comment cleanup * [comment audit] Fix stale Jira type imports blocking full CI --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
150 lines
4.8 KiB
TypeScript
150 lines
4.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import type { GitDiffResult } from '../../shared/git-diff-compare-types'
|
|
import {
|
|
MAX_SETTLED_DIFF_CACHE_ENTRIES,
|
|
MAX_SETTLED_DIFF_CACHE_RESULT_CHARACTERS,
|
|
MAX_SETTLED_DIFF_CACHE_TOTAL_CHARACTERS,
|
|
SettledDiffCache
|
|
} from './source-control/settled-diff-cache'
|
|
import type { WorktreeDiffStamp } from './source-control/worktree-diff-stamp'
|
|
|
|
function settledStamp(value: string): WorktreeDiffStamp {
|
|
// Old enough that the racy-write margin is satisfied.
|
|
return { value, newestMtimeMs: Date.now() - 60_000, capturedAtMs: Date.now() }
|
|
}
|
|
|
|
function diffOfSize(characters: number): GitDiffResult {
|
|
return {
|
|
kind: 'text',
|
|
originalContent: '',
|
|
modifiedContent: 'x'.repeat(characters),
|
|
originalIsBinary: false,
|
|
modifiedIsBinary: false
|
|
}
|
|
}
|
|
|
|
describe('SettledDiffCache bounds', () => {
|
|
it('evicts the least recently used entry past the entry cap', () => {
|
|
const cache = new SettledDiffCache()
|
|
for (let index = 0; index <= MAX_SETTLED_DIFF_CACHE_ENTRIES; index += 1) {
|
|
cache.set(`key-${index}`, settledStamp(`stamp-${index}`), diffOfSize(1), cache.beginRead())
|
|
}
|
|
|
|
expect(cache.stats().entries).toBe(MAX_SETTLED_DIFF_CACHE_ENTRIES)
|
|
expect(cache.get('key-0', settledStamp('stamp-0'))).toBeUndefined()
|
|
expect(
|
|
cache.get(
|
|
`key-${MAX_SETTLED_DIFF_CACHE_ENTRIES}`,
|
|
settledStamp(`stamp-${MAX_SETTLED_DIFF_CACHE_ENTRIES}`)
|
|
)
|
|
).toBeDefined()
|
|
})
|
|
|
|
it('keeps a re-read entry alive by refreshing its LRU position', () => {
|
|
const cache = new SettledDiffCache()
|
|
cache.set('hot', settledStamp('hot-stamp'), diffOfSize(1), cache.beginRead())
|
|
for (let index = 0; index < MAX_SETTLED_DIFF_CACHE_ENTRIES; index += 1) {
|
|
cache.get('hot', settledStamp('hot-stamp'))
|
|
cache.set(`cold-${index}`, settledStamp(`cold-${index}`), diffOfSize(1), cache.beginRead())
|
|
}
|
|
|
|
expect(cache.get('hot', settledStamp('hot-stamp'))).toBeDefined()
|
|
})
|
|
|
|
it('holds total retained content under the character budget', () => {
|
|
const cache = new SettledDiffCache()
|
|
const chunk = MAX_SETTLED_DIFF_CACHE_RESULT_CHARACTERS
|
|
const needed = Math.ceil(MAX_SETTLED_DIFF_CACHE_TOTAL_CHARACTERS / chunk) + 2
|
|
|
|
for (let index = 0; index < needed; index += 1) {
|
|
cache.set(
|
|
`key-${index}`,
|
|
settledStamp(`stamp-${index}`),
|
|
diffOfSize(chunk),
|
|
cache.beginRead()
|
|
)
|
|
}
|
|
|
|
expect(cache.stats().retainedCharacters).toBeLessThanOrEqual(
|
|
MAX_SETTLED_DIFF_CACHE_TOTAL_CHARACTERS
|
|
)
|
|
})
|
|
|
|
it('declines a single result larger than the per-entry cap', () => {
|
|
const cache = new SettledDiffCache()
|
|
|
|
cache.set(
|
|
'huge',
|
|
settledStamp('huge-stamp'),
|
|
diffOfSize(MAX_SETTLED_DIFF_CACHE_RESULT_CHARACTERS + 1),
|
|
cache.beginRead()
|
|
)
|
|
|
|
expect(cache.stats().entries).toBe(0)
|
|
expect(cache.stats().retainedCharacters).toBe(0)
|
|
})
|
|
|
|
it('releases retained characters when a key is overwritten', () => {
|
|
const cache = new SettledDiffCache()
|
|
cache.set('key', settledStamp('first'), diffOfSize(1_000), cache.beginRead())
|
|
cache.set('key', settledStamp('second'), diffOfSize(10), cache.beginRead())
|
|
|
|
expect(cache.stats().entries).toBe(1)
|
|
expect(cache.stats().retainedCharacters).toBe(10)
|
|
expect(cache.get('key', settledStamp('first'))).toBeUndefined()
|
|
expect(cache.get('key', settledStamp('second'))).toBeDefined()
|
|
})
|
|
|
|
it('drops everything and refuses in-flight stores after a clear', () => {
|
|
const cache = new SettledDiffCache()
|
|
const readGeneration = cache.beginRead()
|
|
cache.clear()
|
|
cache.set('key', settledStamp('stamp'), diffOfSize(1), readGeneration)
|
|
|
|
expect(cache.stats().entries).toBe(0)
|
|
expect(cache.stats().invalidatedDuringRead).toBe(1)
|
|
})
|
|
})
|
|
|
|
// Count WSL guest-clock skew separately from ordinary racy writes so repeated store refusals are observable.
|
|
describe('settled diff cache clock skew', () => {
|
|
const result: GitDiffResult = diffOfSize(10)
|
|
|
|
it('counts a future-dated mtime separately from an ordinary racy write', () => {
|
|
const cache = new SettledDiffCache()
|
|
const now = Date.now()
|
|
|
|
cache.set(
|
|
'fresh',
|
|
{ value: 'a', newestMtimeMs: now, capturedAtMs: now },
|
|
result,
|
|
cache.beginRead()
|
|
)
|
|
cache.set(
|
|
'skewed',
|
|
{ value: 'b', newestMtimeMs: now + 60_000, capturedAtMs: now },
|
|
result,
|
|
cache.beginRead()
|
|
)
|
|
|
|
const stats = cache.stats()
|
|
expect(stats.racyWrites).toBe(2)
|
|
expect(stats.clockSkewedWrites).toBe(1)
|
|
expect(stats.stores).toBe(0)
|
|
})
|
|
|
|
it('does not flag a stamp whose components were all absent', () => {
|
|
const cache = new SettledDiffCache()
|
|
const now = Date.now()
|
|
|
|
cache.set(
|
|
'absent',
|
|
{ value: 'c', newestMtimeMs: Number.NEGATIVE_INFINITY, capturedAtMs: now },
|
|
result,
|
|
cache.beginRead()
|
|
)
|
|
|
|
expect(cache.stats().clockSkewedWrites).toBe(0)
|
|
})
|
|
})
|