OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer / test / dual-blob-store.test.js

37 lines · javascript ref:
// DualBlobStore — write NEW blobs to the content-addressed OverlayBlobStore; READ from it first and fall
// back to the legacy Hyperbee BlobStore for pre-migration blobs (so existing avatars don't 404 during the
// overlay swap). No bulk rewrite of live data. Run: bare test/dual-blob-store.test.js
import '../lib/bare-globals.js'
import test from 'brittle'
import fs from 'bare-fs'
import b4a from 'b4a'
import { openCorestore } from 'atproto-store/lib/corestore.js'
import { BlobStore } from 'atproto-store/lib/blob-store.js'
import { OverlayBlobStore } from 'atproto-store/lib/overlay-blob-store.js'
import { DualBlobStore } from '../lib/dual-blob-store.js'

test('DualBlobStore: write-new(overlay) + read-both, legacy fallback', async (t) => {
  const dir = 'data/dualblob-test-' + Date.now()
  const store = openCorestore(dir + '/store')
  const legacy = await new BlobStore(store, { name: 'legacy' }).ready()
  const overlay = await new OverlayBlobStore(dir + '/blobs', { indexStore: store, name: 'overlay' }).ready()

  // A pre-migration blob lives ONLY in the legacy store.
  const oldBytes = b4a.from('OLD avatar bytes')
  const { cid: oldCid } = await legacy.put(oldBytes, 'image/png')

  const dual = new DualBlobStore(overlay, legacy)
  const newBytes = b4a.from('NEW image bytes here')
  const { cid: newCid } = await dual.put(newBytes, 'image/jpeg')

  t.ok(b4a.equals((await dual.get(newCid.toString())).bytes, newBytes), 'new blob served from the OVERLAY store')
  t.ok(b4a.equals((await dual.get(oldCid.toString())).bytes, oldBytes), 'pre-migration blob served via LEGACY fallback (no 404)')
  t.absent(await legacy.has(newCid.toString()), 'new blob written ONLY to the overlay, never the legacy balloon')
  t.absent(await overlay.has(oldCid.toString()), 'old blob is NOT in the overlay — dual-read is what serves it')
  t.ok((await dual.has(newCid.toString())) && (await dual.has(oldCid.toString())), 'has() sees both stores')
  t.is(await dual.get('bafkreiabsent0000000000000000000000000000000000000000000'), null, 'a truly absent cid -> null')

  await dual.close()
  try { fs.rmSync(dir, { recursive: true, force: true }) } catch {}
})