Ctrl K
ComunidadGuías…

frontend/benchmarks/queue-sync.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Opt-in timing experiment, not a wall-clock assertion in CI.
import { execFileSync } from 'node:child_process'
import { performance } from 'node:perf_hooks'
import { env } from 'node:process'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { dirname, join, resolve } from 'node:path'
import { writeFileSync, unlinkSync } from 'node:fs'
import { describe, expect, it, vi } from 'vitest'

const fixture = vi.hoisted(() => ({ jobs: [] }))
vi.mock('/src/model/api', () => ({
  default: {
    getQueue: async () => ({ data: fixture.jobs }),
    onMessage: () => {},
    downloadFileURL: (file) => `/media/${file}`,
  },
}))
vi.mock('/src/model/settings', () => ({
  useSettingsManager: () => ({ settings: { value: {} } }),
}))

function generatedJobs(count) {
  return Array.from({ length: count }, (_, i) => ({
    song: {
      song_id: `generated:${i}`,
      name: `Track ${i}`,
      artists: ['Generated artist'],
    },
    status: i % 5 === 0 ? 'done' : i % 5 === 1 ? 'downloading' : 'queued',
    progress: i % 5 === 0 ? 100 : i % 5 === 1 ? 20 : 0,
    filename: i % 5 === 0 ? `generated/${i}.mp3` : null,
    provider: 'youtube-music',
    position: i + 1,
    message: '',
  }))
}

function snapshot(model) {
  return model.useProgressTracker().downloadQueue.value.map((item) => ({
    key: item.key,
    state: item.state,
    progress: item.progress,
    provider: item.provider,
    message: item.message,
    position: item.position,
    filename: item.filename,
    url: item.web_download_url,
  }))
}

function median(samples) {
  return [...samples].sort((a, b) => a - b)[Math.floor(samples.length / 2)]
}

async function measure(load, count) {
  vi.resetModules()
  fixture.jobs = []
  const model = await load()
  await model.syncQueueFromServer()
  fixture.jobs = generatedJobs(count)
  const started = performance.now()
  await model.syncQueueFromServer()
  const initial = performance.now() - started
  const tracker = model.useProgressTracker()
  const unchanged = []
  const changed = []
  const versionBefore = tracker.queueVersion.value
  for (let i = 0; i < 3; i++) {
    const start = performance.now()
    await model.syncQueueFromServer()
    unchanged.push(performance.now() - start)
  }
  const unchangedNotifications = tracker.queueVersion.value - versionBefore
  for (let i = 0; i < 3; i++) {
    fixture.jobs = fixture.jobs.map((row, index) =>
      index % 10 === 1 ? { ...row, progress: row.progress + 1 } : row
    )
    const start = performance.now()
    await model.syncQueueFromServer()
    changed.push(performance.now() - start)
  }
  vi.clearAllTimers()
  return {
    final: snapshot(model),
    timing: {
      initial_ms: initial,
      unchanged_median_ms: median(unchanged),
      changed_median_ms: median(changed),
      unchanged_notifications: unchangedNotifications,
    },
  }
}

describe.skipIf(env.DOWNTIFY_QUEUE_BENCHMARK !== '1')(
  'real queue synchronization benchmark',
  () => {
    it('compares generated snapshots with the public baseline', async () => {
      vi.useFakeTimers({ toFake: ['setInterval', 'clearInterval'] })
      const here = dirname(fileURLToPath(import.meta.url))
      const ref =
        env.DOWNTIFY_QUEUE_BASELINE_REF ||
        '6d7bebf00d7e41c011645b9ebe1de004c9e31e74'
      const baseline = execFileSync(
        'git',
        ['show', `${ref}:frontend/src/model/download.js`],
        {
          cwd: resolve(here, '../..'),
          encoding: 'utf8',
        }
      )
      const temporary = join(here, `.queue-baseline-${process.pid}.js`)
      writeFileSync(temporary, baseline)
      try {
        const results = []
        for (const count of [250, 2000, 10000]) {
          const old = await measure(
            () => import(/* @vite-ignore */ pathToFileURL(temporary).href),
            count
          )
          const current = await measure(
            () => import('../src/model/download.js'),
            count
          )
          expect(current.final).toEqual(old.final)
          expect(current.timing.unchanged_notifications).toBe(0)
          results.push({
            rows: count,
            baseline: old.timing,
            current: current.timing,
          })
        }
        const report = JSON.stringify({ ref, results }, null, 2)
        if (env.DOWNTIFY_QUEUE_BENCHMARK_OUTPUT) {
          writeFileSync(env.DOWNTIFY_QUEUE_BENCHMARK_OUTPUT, report + '\n')
        }
        console.log('QUEUE_SYNC_BENCHMARK ' + report)
      } finally {
        unlinkSync(temporary)
        vi.clearAllTimers()
        vi.useRealTimers()
      }
    }, 240000)
  }
)