@@ -558,71 +558,13 @@ test.serial('should report usage metrics to mock API after queries through proxy
558558 }
559559} ) ;
560560
561- // ─── Budget exhaustion via rocketadmin API ──────────────────────────────────
562- //
563- // Drives the token bucket to negative balance under the TEST_TINY_PLAN (a
564- // deliberately tiny 2s/hour budget used only for tests). Uses supertest —
565- // each /connection/tables call fans out into several metadata queries, which
566- // is more than enough to exhaust 2 seconds of cumulative query time across a
567- // few calls. The next API call should surface the proxy's 53400 rejection.
568-
569- test . serial ( 'should reject queries once query-time budget is exhausted' , async ( t ) => {
570- if ( maybeSkip ( t ) ) return ;
571- t . timeout ( 60000 ) ;
572-
573- const probe = await getUsageReports ( ) ;
574- if ( ! Array . isArray ( probe ) ) {
575- t . pass ( 'skipped: proxy-mock-api does not expose test endpoints (rebuild required)' ) ;
576- return ;
577- }
578-
579- await setSubscriptionLevel ( 'TEST_TINY_PLAN' ) ;
580- try {
581- const firstUserToken = ( await registerUserAndReturnUserInfo ( app ) ) . token ;
582- const proxyConnectionDto = createProxyConnectionDto ( ) ;
583-
584- const createConnectionResponse = await request ( app . getHttpServer ( ) )
585- . post ( '/connection' )
586- . send ( proxyConnectionDto )
587- . set ( 'Cookie' , firstUserToken )
588- . set ( 'Content-Type' , 'application/json' )
589- . set ( 'Accept' , 'application/json' ) ;
590- t . is ( createConnectionResponse . status , 201 ) ;
591- const createConnectionRO = JSON . parse ( createConnectionResponse . text ) ;
592-
593- // Burn through the 2-second budget by repeatedly listing tables. Each
594- // call executes several introspection queries; within a handful of calls
595- // the post-consume balance goes negative and subsequent calls hit the
596- // pre-query CheckBudget rejection.
597- let rejected = false ;
598- let lastStatus = 0 ;
599- let lastBody = '' ;
600- for ( let i = 0 ; i < 30 ; i ++ ) {
601- const resp = await request ( app . getHttpServer ( ) )
602- . get ( `/connection/tables/${ createConnectionRO . id } ` )
603- . set ( 'Cookie' , firstUserToken )
604- . set ( 'Accept' , 'application/json' ) ;
605- lastStatus = resp . status ;
606- lastBody = resp . text || '' ;
607- if ( resp . status !== 200 ) {
608- rejected = true ;
609- break ;
610- }
611- }
612-
613- t . true (
614- rejected ,
615- `expected a 30-call burst under TEST_TINY_PLAN to hit a budget rejection; last status=${ lastStatus } ` ,
616- ) ;
617- t . regex (
618- lastBody ,
619- / b u d g e t | e x c e e d e d | p l a n | 5 3 4 0 0 / i,
620- `rejection response should mention budget/plan, got status=${ lastStatus } body=${ lastBody . slice ( 0 , 200 ) } ` ,
621- ) ;
622- } finally {
623- await setSubscriptionLevel ( 'TEAM_PLAN' ) ;
624- }
625- } ) ;
561+ // Budget-exhaustion behaviour is "queue, don't fail": queries past the
562+ // token-bucket budget park on `Limiter.WaitForBudget` until tokens refill,
563+ // rather than returning a 53400. End-to-end verification of that wait is
564+ // covered by `postgres-proxy/internal/ratelimit/bucket_test.go`
565+ // (TestLimiter_WaitForBudget_*), which can simulate refill in milliseconds.
566+ // An equivalent rocketadmin e2e check would need a custom plan with a refill
567+ // rate that completes inside the AVA timeout — not worth the moving pieces.
626568
627569// ─── Frozen plan / connection rejection test ────────────────────────────────
628570//
0 commit comments