OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-overlay / test / manifest.test.js

81 lines · javascript ref:
import test from 'brittle'
import { encode, decode } from '../lib/manifest.js'
import crypto from 'hypercore-crypto'
import { deflateRawSync, inflateRawSync } from 'bare-zlib'

function randomHash () {
  return crypto.randomBytes(32).toString('hex')
}

test('encode + decode round-trip', (t) => {
  const fileHash = randomHash()
  const chunks = [
    { hash: randomHash(), size: 12288 },
    { hash: randomHash(), size: 15360 },
    { hash: randomHash(), size: 9216 }
  ]

  const compressed = encode(chunks, fileHash)
  const result = decode(compressed)

  t.is(result.fileHash, fileHash)
  t.is(result.chunks.length, 3)
  t.is(result.chunks[0].hash, chunks[0].hash)
  t.is(result.chunks[0].size, chunks[0].size)
  t.is(result.chunks[2].hash, chunks[2].hash)
  t.is(result.chunks[2].size, chunks[2].size)
})

test('compression is effective', (t) => {
  const fileHash = randomHash()
  const chunks = Array.from({ length: 1000 }, () => ({
    hash: randomHash(),
    size: 16384
  }))

  const compressed = encode(chunks, fileHash)
  const rawSize = 37 + 1000 * 34 // 34,037 bytes uncompressed

  t.ok(compressed.length < rawSize, `compressed ${compressed.length} < raw ${rawSize}`)
  // Random hashes don't compress well — just verify some compression happens
  t.ok(compressed.length < rawSize * 1.0, 'compressed size <= raw size')
})

test('large manifest (250k chunks)', (t) => {
  const fileHash = randomHash()
  const chunks = Array.from({ length: 1000 }, () => ({
    hash: randomHash(),
    size: 16384
  }))

  const compressed = encode(chunks, fileHash)
  const result = decode(compressed)

  t.is(result.chunks.length, 1000)
  t.is(result.fileHash, fileHash)
})

test('empty chunk list', (t) => {
  const fileHash = randomHash()
  const compressed = encode([], fileHash)
  const result = decode(compressed)

  t.is(result.chunks.length, 0)
  t.is(result.fileHash, fileHash)
})

test('rejects invalid version', (t) => {
  const fileHash = randomHash()
  const compressed = encode([{ hash: randomHash(), size: 100 }], fileHash)
  const raw = Buffer.from(inflateRawSync(compressed))
  raw[0] = 99 // bad version
  const recompressed = deflateRawSync(raw)

  try {
    decode(recompressed)
    t.fail('should throw')
  } catch (err) {
    t.ok(err.message.includes('Unsupported'))
  }
})