mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
Add coverage for skill lock release and fix WebRTC test flakiness (#16846)
* test: add coverage for skill lock release and simplify WebRTC test - Add test for cleanupReleasedSkillInstallLock handling rmdir races - Improve error handling to cover all documented directory removal error codes - Simplify WebRTC egress test to use localhost addresses consistently * test: use network interface address for WebRTC egress probe - Discover the first non-internal IPv4 address instead of hardcoding localhost, allowing the test to work in CI and varied environments - Update proxy rules to use loopback designation for clarity - Bind UDP socket to all interfaces (0.0.0.0) to receive on the discovered address
This commit is contained in:
@@ -479,7 +479,6 @@ describe('OrcaRuntimeRpcServer', () => {
|
||||
deviceToken: mobile.token,
|
||||
params: { worktree: 'id:wt-1', page: 'page-1' }
|
||||
})
|
||||
|
||||
expect(replies).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: 'req_forbidden',
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { mkdtemp, mkdir, readdir, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { cleanupReleasedSkillInstallLock } from './skill-install-lock-release'
|
||||
|
||||
const roots: string[] = []
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })))
|
||||
})
|
||||
|
||||
describe('cleanupReleasedSkillInstallLock', () => {
|
||||
it('keeps a released lock recoverable when directory removal races', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'orca-skill-lock-release-test-'))
|
||||
roots.push(root)
|
||||
const releasePath = join(root, 'released')
|
||||
const token = '11111111-1111-4111-8111-111111111111'
|
||||
await mkdir(releasePath)
|
||||
await Promise.all([
|
||||
writeFile(join(releasePath, `${token}.owner`), 'owner'),
|
||||
writeFile(join(releasePath, `${token}.released`), '')
|
||||
])
|
||||
|
||||
const removeDirectory = async (): Promise<void> => {
|
||||
const error = new Error('injected-rmdir-race') as NodeJS.ErrnoException
|
||||
error.code = 'ENOTEMPTY'
|
||||
throw error
|
||||
}
|
||||
|
||||
await expect(
|
||||
cleanupReleasedSkillInstallLock(releasePath, token, removeDirectory)
|
||||
).resolves.toBeUndefined()
|
||||
await expect(readdir(releasePath)).resolves.toEqual([])
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,7 @@ import { readdir, rmdir, unlink } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
|
||||
const RELEASE_ENTRY_NAME = /^[a-f0-9-]{36}\.(?:owner|released)$/
|
||||
const RECOVERY_RMDIR_IGNORED_CODES = new Set(['ENOENT', 'ENOTEMPTY', 'EEXIST', 'EBUSY'])
|
||||
const LOCK_DIRECTORY_RMDIR_IGNORED_CODES = new Set(['ENOENT', 'ENOTEMPTY', 'EEXIST', 'EBUSY'])
|
||||
|
||||
async function unlinkIfPresent(path: string): Promise<void> {
|
||||
await unlink(path).catch((error) => {
|
||||
@@ -17,7 +17,7 @@ async function removeDirectoryIfPresent(
|
||||
removeDirectory: (path: string) => Promise<void>
|
||||
): Promise<void> {
|
||||
await removeDirectory(path).catch((error) => {
|
||||
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
||||
if (!LOCK_DIRECTORY_RMDIR_IGNORED_CODES.has((error as NodeJS.ErrnoException).code ?? '')) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
@@ -46,7 +46,7 @@ export async function reclaimReleasedSkillInstallLock(path: string): Promise<voi
|
||||
.map((entry) => unlinkIfPresent(join(path, entry.name)))
|
||||
)
|
||||
await rmdir(path).catch((error) => {
|
||||
if (!RECOVERY_RMDIR_IGNORED_CODES.has((error as NodeJS.ErrnoException).code ?? '')) {
|
||||
if (!LOCK_DIRECTORY_RMDIR_IGNORED_CODES.has((error as NodeJS.ErrnoException).code ?? '')) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user