Files
asepharyana 1cdb82a76f Sync config from arch
- hypr/apps.lua
- hypr/autostart.lua
- hypr/envs.lua
- hypr/hyprland.lua
- hypr/hyprsunset.conf
- hypr/input.lua
- hypr/looknfeel.lua
- hypr/omasettings.lua
- hypr/xdph.conf
- omarchy/branding/about.txt
- omarchy/branding/screensaver.txt
- omarchy/extensions/omarchy-menu.jsonc
- omarchy/hooks/battery-low.d/play-warning-sound.sample
- omarchy/hooks/font-set.d/show-font-notification.sample
- omarchy/hooks/post-boot.d/weather.sample
- omarchy/hooks/post-update.d/install-voxtype.hook
- omarchy/hooks/post-update.d/setup-agent.hook
- omarchy/hooks/post-update.d/setup-fingerprint.hook
- omarchy/hooks/post-update.d/show-update-notification.sample
- omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample
- omarchy/hooks/theme-set.d/show-theme-notification.sample
- omarchy/shell.json
- omarchy/shell.toml
- omarchy/theme.name
- omarchy/themes/azure-glow/README.md
- omarchy/themes/azure-glow/alacritty.toml
- omarchy/themes/azure-glow/btop.theme
- omarchy/themes/azure-glow/hyprland.conf
- omarchy/themes/azure-glow/hyprlock.conf
- omarchy/themes/azure-glow/icons.theme
- … 269 more
2026-09-23 15:19:12 +07:00

165 lines
6.1 KiB
JavaScript

#!/usr/bin/env node
// Deterministic synthetic-vault performance guardrails. These measure the
// work the plugin owns after `bw list items` returns; they never read a real
// vault or make a network request.
//
// node tests/performance.test.js
const fs = require("fs")
const path = require("path")
const Model = {}
new Function("exports", fs.readFileSync(path.join(__dirname, "..", "BitwardenModel.js"), "utf8")
.replace(/^\.pragma library\s*$/m, "") + `
exports.parseItems = parseItems
exports.filterItems = filterItems
exports.findContextualMatches = findContextualMatches
`)(Model)
const MIB = 1024 * 1024
const tiers = [
{ name: "small", items: 100, bytes: Math.round(0.25 * MIB), folders: 10, orgs: 1,
parseP95Ms: 75, filterP95Ms: 50, contextP95Ms: 75 },
{ name: "typical", items: 500, bytes: 1 * MIB, folders: 50, orgs: 3,
parseP95Ms: 100, filterP95Ms: 75, contextP95Ms: 100 },
{ name: "large", items: 2000, bytes: 5 * MIB, folders: 200, orgs: 10,
parseP95Ms: 175, filterP95Ms: 100, contextP95Ms: 150 },
{ name: "stress", items: 5000, bytes: 14 * MIB, folders: 500, orgs: 25,
parseP95Ms: 300, filterP95Ms: 150, contextP95Ms: 250 }
]
let pass = 0
const failures = []
const check = (label, ok, detail) => ok ? pass++ : failures.push(`${label}\n ${detail}`)
function fakeItem(index, tier) {
const ordinal = String(index).padStart(5, "0")
const kind = index % 10
const item = {
object: "item",
id: `00000000-0000-4000-8000-${String(index).padStart(12, "0")}`,
organizationId: index % 4 === 0 ? null : `org-${index % tier.orgs}`,
folderId: `folder-${index % tier.folders}`,
type: kind < 7 ? 1 : kind === 7 ? 2 : kind === 8 ? 3 : 4,
name: `Service ${ordinal}`,
notes: `Synthetic fixture note ${ordinal}`,
favorite: index % 17 === 0,
fields: [{ name: "fixture-field", value: `value-${ordinal}`, type: index % 2 }],
attachments: index % 23 === 0
? [{ id: `attachment-${index}`, fileName: `fixture-${ordinal}.txt`, size: "1024" }]
: []
}
if (item.type === 1) {
item.login = {
username: `user-${ordinal}@example.test`,
password: `not-a-real-password-${ordinal}`,
totp: index % 11 === 0 ? "JBSWY3DPEHPK3PXP" : null,
uris: [{ match: null, uri: `https://service-${index % 80}.example.test/login/${ordinal}` }]
}
} else if (item.type === 3) {
item.card = {
cardholderName: "Fixture Person", brand: "Visa", number: "4111111111111111",
expMonth: "04", expYear: "2030", code: "123"
}
} else if (item.type === 4) {
item.identity = {
firstName: "Fixture", lastName: ordinal, email: `identity-${ordinal}@example.test`,
phone: "5550100", address1: "1 Fixture Road", city: "Testville",
state: "TS", postalCode: "00000", country: "US"
}
}
return item
}
function buildFixture(tier) {
const items = []
for (let i = 0; i < tier.items; i++) items.push(fakeItem(i, tier))
// Spread deterministic padding across the entries so parseItems still does
// realistic per-item work instead of parsing one giant outlier note.
let raw = JSON.stringify(items)
const remaining = tier.bytes - Buffer.byteLength(raw)
if (remaining > 0) {
const paddingPerItem = Math.floor(remaining / tier.items)
const tail = remaining % tier.items
for (let i = 0; i < items.length; i++) {
items[i].notes += "x".repeat(paddingPerItem + (i < tail ? 1 : 0))
}
raw = JSON.stringify(items)
}
return raw
}
function timed(fn) {
const start = process.hrtime.bigint()
const value = fn()
return { value, ms: Number(process.hrtime.bigint() - start) / 1e6 }
}
function p95(values) {
const sorted = values.slice().sort((a, b) => a - b)
return sorted[Math.ceil(sorted.length * 0.95) - 1]
}
const results = []
for (const tier of tiers) {
const raw = buildFixture(tier)
const actualBytes = Buffer.byteLength(raw)
check(`${tier.name}: fixture item count`, JSON.parse(raw).length === tier.items,
`expected ${tier.items}`)
check(`${tier.name}: fixture payload size`,
actualBytes >= tier.bytes && actualBytes <= tier.bytes + tier.items * 2,
`expected approximately ${tier.bytes} bytes, got ${actualBytes}`)
// Warm V8 before collecting the samples so the guard measures steady-state
// panel work rather than Node's compilation of the test itself.
let parsed = Model.parseItems(raw)
Model.filterItems(parsed, "service 0004", "all", "all", "all")
Model.findContextualMatches(parsed,
{ class: "firefox", title: "Service 42 - Mozilla Firefox" }, {})
const parseSamples = []
const filterSamples = []
const contextSamples = []
for (let sample = 0; sample < 20; sample++) {
const parseRun = timed(() => Model.parseItems(raw))
parsed = parseRun.value
parseSamples.push(parseRun.ms)
filterSamples.push(timed(() => Model.filterItems(parsed,
sample % 2 ? "service 0042" : "user-0004", "all", "all", "all")).ms)
contextSamples.push(timed(() => Model.findContextualMatches(parsed,
{ class: "firefox", title: "Service 42 login - Mozilla Firefox" }, {})).ms)
}
const row = {
tier: tier.name,
items: tier.items,
mib: actualBytes / MIB,
parse: p95(parseSamples),
filter: p95(filterSamples),
context: p95(contextSamples)
}
results.push(row)
check(`${tier.name}: parse p95`, row.parse <= tier.parseP95Ms,
`${row.parse.toFixed(2)}ms > ${tier.parseP95Ms}ms`)
check(`${tier.name}: filter p95`, row.filter <= tier.filterP95Ms,
`${row.filter.toFixed(2)}ms > ${tier.filterP95Ms}ms`)
check(`${tier.name}: contextual match p95`, row.context <= tier.contextP95Ms,
`${row.context.toFixed(2)}ms > ${tier.contextP95Ms}ms`)
}
console.log("tier items MiB parse p95 filter p95 context p95")
for (const row of results) {
console.log(`${row.tier.padEnd(8)} ${String(row.items).padStart(5)} ${row.mib.toFixed(2).padStart(5)}`
+ ` ${(row.parse.toFixed(2) + "ms").padStart(9)}`
+ ` ${(row.filter.toFixed(2) + "ms").padStart(10)}`
+ ` ${(row.context.toFixed(2) + "ms").padStart(11)}`)
}
console.log(`\n${pass} passed, ${failures.length} failed`)
if (failures.length) {
console.error("\nFAILURES:\n " + failures.join("\n "))
process.exit(1)
}