Files
supabase/apps/studio/components/interfaces/Database/Replication/ReplicationPipelineStatus/ReplicationPipelineStatus.utils.test.ts
T
Danny White 8511f92314 feat(studio): show table WAL retention headroom (#50499)
## What kind of change does this PR introduce?

Feature

## What is the current behavior?

Replicated table rows show their temporary sync slot's pending bytes,
WAL risk, and last check-in, but omit the amount of WAL retention
remaining.

## What is the new behavior?

Replicated table rows include the temporary slot's WAL retention
headroom alongside the existing sync details. Finite values use a
compact byte value, an explicit unlimited value is labelled `Unlimited
WAL retention`, and absent values remain omitted.

| After |
| --- |
| <img width="1862" height="966" alt="CleanShot 2026-09-17 at 15 11
26@2x"
src="https://github.com/user-attachments/assets/8475bc8a-792c-46fc-b776-1ea20b7dfb89"
/> |

## To test

1. Open `/project/<ref>/database/replication/<pipeline-id>` for a
BigQuery pipeline while at least one table is completing its initial
sync (or was just restarted).
2. Find that table under **Replicated tables**.
3. Confirm its **Details** cell reads in this order when all values are
available: `720 MB waiting to sync · 1.3 GB WAL retention remaining ·
Last check-in 2 min`.
4. Confirm a temporary slot with unlimited retention shows `Unlimited
WAL retention`, and a missing retention value adds no placeholder.
5. Confirm WAL warnings such as `Some changes at risk` or `Some changes
lost` still appear alongside the retention value.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
  - Replication status now displays remaining WAL retention.
- Shows unlimited retention when applicable or presents finite capacity
in a readable format.
  - Reports when retention is exhausted and changes may be at risk.
- **Bug Fixes**
- Invalid retention values no longer produce misleading WAL retention
messages.
- Replication pipeline status more clearly identifies conditions where
changes may be at risk due to limited or exhausted retention.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-21 10:48:19 +10:00

78 lines
2.1 KiB
TypeScript

import { describe, expect, test } from 'vitest'
import { getTableSyncLagLabel } from './ReplicationPipelineStatus.utils'
describe('getTableSyncLagLabel', () => {
test('reports unlimited WAL retention for a healthy caught-up table slot', () => {
expect(
getTableSyncLagLabel({
active: true,
wal_status: 'reserved',
restart_lsn_bytes: 0,
confirmed_flush_lsn_bytes: 0,
safe_wal_size_bytes: null,
})
).toEqual(['Unlimited WAL retention'])
})
test('reports the backlog, finite WAL retention, and last check-in', () => {
expect(
getTableSyncLagLabel({
active: true,
wal_status: 'reserved',
restart_lsn_bytes: 4096,
confirmed_flush_lsn_bytes: 2048,
safe_wal_size_bytes: 1_363_148_800,
reply_time_lag: 4800,
})
).toEqual(['2 KB waiting to sync', '1.3 GB WAL retention remaining', 'Last check-in 4.80 s'])
})
test('reports slot risk without treating the expected inactive connection as a fault', () => {
expect(
getTableSyncLagLabel({
active: false,
wal_status: 'unreserved',
restart_lsn_bytes: 0,
confirmed_flush_lsn_bytes: 0,
safe_wal_size_bytes: 0,
})
).toEqual(['0 bytes WAL retention remaining', 'Some changes at risk'])
})
test('omits WAL retention when the API does not provide it', () => {
expect(
getTableSyncLagLabel({
active: true,
wal_status: 'reserved',
restart_lsn_bytes: 0,
confirmed_flush_lsn_bytes: 0,
})
).toEqual([])
})
test('omits an invalid WAL retention value', () => {
expect(
getTableSyncLagLabel({
active: true,
wal_status: 'reserved',
restart_lsn_bytes: 0,
confirmed_flush_lsn_bytes: 0,
safe_wal_size_bytes: Number.NaN,
})
).toEqual([])
})
test('omits a negative WAL retention value', () => {
expect(
getTableSyncLagLabel({
active: true,
wal_status: 'reserved',
restart_lsn_bytes: 0,
confirmed_flush_lsn_bytes: 0,
safe_wal_size_bytes: -1,
})
).toEqual([])
})
})