0ef4c624c5
initial test from Ed's nuc:
metric pctl baseline current delta status
-----------------------------------------------------------------------------------------------
folder_cascade.list_depth1 p50 0.3ms 0.3ms -6.3% ok
folder_cascade.list_depth1 p95 2.3ms 0.5ms -75.7% ok
folder_cascade.list_depth1 p99 4.7ms 2.5ms -48.1% ok
folder_cascade.list_depth4 p50 0.4ms 0.3ms -10.0% ok
folder_cascade.list_depth4 p95 0.9ms 0.6ms -31.2% ok
folder_cascade.list_depth4 p99 2.4ms 1.0ms -56.7% ok
folder_cascade.list_depth8 p50 0.3ms 0.3ms -8.8% ok
folder_cascade.list_depth8 p95 0.6ms 0.5ms -22.2% ok
folder_cascade.list_depth8 p99 1.9ms 0.5ms -71.5% ok
folder_cascade.list_depth_deep p50 0.3ms 0.3ms -5.0% ok
folder_cascade.list_depth_deep p95 0.6ms 0.5ms -18.6% ok
folder_cascade.list_depth_deep p99 2.0ms 0.7ms -67.2% ok
share_cascade_rebac.list_grants p50 0.4ms 0.3ms -27.6% ok
share_cascade_rebac.list_grants p95 1.2ms 0.5ms -57.0% ok
share_cascade_rebac.list_grants p99 1.7ms 1.1ms -36.7% ok
share_cascade_rebac.fetch_as_grantee_depth1 p50 0.5ms 0.5ms -11.1% ok
share_cascade_rebac.fetch_as_grantee_depth1 p95 1.1ms 0.7ms -41.2% ok
share_cascade_rebac.fetch_as_grantee_depth1 p99 3.0ms 1.3ms -58.3% ok
share_cascade_rebac.fetch_as_grantee_depth4 p50 0.5ms 0.5ms -13.7% ok
share_cascade_rebac.fetch_as_grantee_depth4 p95 1.4ms 0.7ms -50.5% ok
share_cascade_rebac.fetch_as_grantee_depth4 p99 2.2ms 1.1ms -49.3% ok
share_cascade_rebac.fetch_as_grantee_depth8 p50 0.5ms 0.4ms -16.0% ok
share_cascade_rebac.fetch_as_grantee_depth8 p95 0.9ms 0.7ms -26.1% ok
share_cascade_rebac.fetch_as_grantee_depth8 p99 1.5ms 0.9ms -40.1% ok
share_cascade_rebac.fetch_as_grantee_depth_deep p50 0.5ms 0.4ms -17.3% ok
share_cascade_rebac.fetch_as_grantee_depth_deep p95 1.0ms 0.7ms -31.2% ok
share_cascade_rebac.fetch_as_grantee_depth_deep p99 1.6ms 0.8ms -49.4% ok
subject_group_nested.fetch_as_member_depth1 p50 0.5ms 0.4ms -8.4% ok
subject_group_nested.fetch_as_member_depth1 p95 0.6ms 0.6ms -10.2% ok
subject_group_nested.fetch_as_member_depth1 p99 1.4ms 0.6ms -55.2% ok
subject_group_nested.fetch_as_member_depth4 p50 0.5ms 0.5ms -7.9% ok
subject_group_nested.fetch_as_member_depth4 p95 0.6ms 0.6ms -4.0% ok
subject_group_nested.fetch_as_member_depth4 p99 0.7ms 0.6ms -2.2% ok
subject_group_nested.fetch_as_member_depth8 p50 0.5ms 0.4ms -8.9% ok
subject_group_nested.fetch_as_member_depth8 p95 0.5ms 0.6ms +7.1% ok
subject_group_nested.fetch_as_member_depth8 p99 0.6ms 0.7ms +10.3% ok
subject_group_nested.fetch_as_member_depth_deep p50 0.5ms 0.4ms -7.6% ok
subject_group_nested.fetch_as_member_depth_deep p95 0.6ms 0.5ms -11.9% ok
subject_group_nested.fetch_as_member_depth_deep p99 0.6ms 0.7ms +8.9% ok
61 lines
2.3 KiB
JavaScript
61 lines
2.3 KiB
JavaScript
// folder_cascade.js — measures the read-path of `GET /api/folders/{id}/resources?resource_types=folder`
|
|
// at four depths against a pre-seeded tree. Captures how listing cost scales
|
|
// with ltree depth (cf. `idx_folders_lpath` GiST index). Mid-depth samples
|
|
// (depth4, depth8) fall back to `deepest` when the seeded tree is shallower
|
|
// than that depth — see load-seed.rs::build_subtree.
|
|
|
|
import { check } from 'k6';
|
|
import http from 'k6/http';
|
|
import { BASE, authParams } from '../lib/http.js';
|
|
import { login } from '../lib/auth.js';
|
|
import { thresholdsFromBaseline, loadManifest } from '../lib/metrics.js';
|
|
|
|
const manifest = loadManifest();
|
|
|
|
export const options = {
|
|
vus: 1,
|
|
// 100 iterations gives p99 statistical meaning: at N=100, p99 = position 99,
|
|
// representing one bad sample out of a hundred — a real percentile rather
|
|
// than the worst-of-the-batch. At N=25 (the typical k6 example default),
|
|
// p99 ≈ max, dominated by single-sample kernel/scheduler noise.
|
|
iterations: 100,
|
|
thresholds: thresholdsFromBaseline('folder_cascade'),
|
|
};
|
|
|
|
// One per-VU login. K6 calls setup() once across the whole test, default()
|
|
// `iterations` times per VU. Logging in inside default() would dominate the
|
|
// per-iter cost; we hand the token down through the `data` arg.
|
|
export function setup() {
|
|
const token = login(manifest.admin.username, manifest.admin.password);
|
|
return { token };
|
|
}
|
|
|
|
export default function (data) {
|
|
const { token } = data;
|
|
const t = manifest.shared_subtree;
|
|
|
|
const r1 = http.get(
|
|
`${BASE}/api/folders/${t.root}/resources?resource_types=folder`,
|
|
authParams(token, 'folder_cascade.list_depth1'),
|
|
);
|
|
check(r1, { 'list depth1 200': (r) => r.status === 200 });
|
|
|
|
const r4 = http.get(
|
|
`${BASE}/api/folders/${t.depth4}/resources?resource_types=folder`,
|
|
authParams(token, 'folder_cascade.list_depth4'),
|
|
);
|
|
check(r4, { 'list depth4 200': (r) => r.status === 200 });
|
|
|
|
const r8 = http.get(
|
|
`${BASE}/api/folders/${t.depth8}/resources?resource_types=folder`,
|
|
authParams(token, 'folder_cascade.list_depth8'),
|
|
);
|
|
check(r8, { 'list depth8 200': (r) => r.status === 200 });
|
|
|
|
const rD = http.get(
|
|
`${BASE}/api/folders/${t.deepest}/resources?resource_types=folder`,
|
|
authParams(token, 'folder_cascade.list_depth_deep'),
|
|
);
|
|
check(rD, { 'list deepest 200': (r) => r.status === 200 });
|
|
}
|