Files
MikrotikManager/backend/src/db/operation-lock.test.ts
T

18 lines
2.0 KiB
TypeScript

import assert from "node:assert/strict"
import {withTrafficFlowPurgeLock} from "./operation-lock.js"
let held=false,runs=0,unlocks=0
const releases:boolean[]=[]
const connect=async()=>({query:async(sql:string,params:number[])=>{assert.deepEqual(params,[123]);if(sql.includes("pg_try_advisory_lock")){const acquired=!held;if(acquired)held=true;return {rows:[{acquired}]}}unlocks++;held=false;return {rows:[{released:true}]}},release:(destroy=false)=>{releases.push(destroy)}})
let release!:()=>void
const gate=new Promise<void>(resolve=>release=resolve)
const first=withTrafficFlowPurgeLock(connect,123,async()=>{runs++;await gate;return "confirmed"})
await new Promise<void>(resolve=>setImmediate(resolve))
await assert.rejects(withTrafficFlowPurgeLock(connect,123,async()=>{runs++;return "unexpected"}),/уже выполняется/)
assert.equal(runs,1);assert.equal(unlocks,0);assert.equal(held,true)
release();assert.equal(await first,"confirmed");assert.equal(unlocks,1);assert.deepEqual(releases,[false,false])
await assert.rejects(withTrafficFlowPurgeLock(connect,123,async()=>{throw Error("operation unknown")}),/operation unknown/);assert.equal(held,false);assert.equal(unlocks,2)
for(const unlock of [false,"throws"]){let destroyed=false;const result=await withTrafficFlowPurgeLock(async()=>({query:async(sql:string)=>{if(sql.includes("pg_try"))return {rows:[{acquired:true}]};if(unlock==="throws")throw Error("unlock unavailable");return {rows:[{released:false}]}},release:(value=false)=>{destroyed=value}}),123,async()=>"committed");assert.equal(result,"committed");assert.equal(destroyed,true)}
let released=false,discarded=false
await assert.rejects(withTrafficFlowPurgeLock(async()=>({query:async()=>({rows:[{}]}),release:(destroy=false)=>{released=true;discarded=destroy}}),123,async()=>{throw Error("must not run")}),/не подтверждена/);assert.equal(released,true);assert.equal(discarded,true)
console.log("NetFlow purge lock: concurrent request rejected before handler, unknown release destroys connection, operation receipt preserved")