Created
February 7, 2026 17:31
-
-
Save nickva/c6ed2bb9a883a6e4051ce7a2d94be244 to your computer and use it in GitHub Desktop.
couchdb k6 view query with constant arrival
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Examples: | |
| // BENCH_RATE=500 BENCH_DURATION=20s BENCH_VIEW_LIMIT=16 k6 run ./$script.js | |
| // | |
| // config:set("log", "level", "warning"). | |
| // | |
| import http from 'k6/http'; | |
| import encoding from 'k6/encoding'; | |
| import { sleep } from 'k6'; | |
| import { randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; | |
| // Parameters, defaults or from the environment | |
| // Note: environemnt variables are prefixed with "BENCH_" | |
| // | |
| const URL = env_str('URL', 'http://localhost:15984'); | |
| const USER = env_str('USER', 'adm'); | |
| const PASS = env_str('PASS', 'pass'); | |
| const DB = env_str('DB', 'db'); | |
| const DDOC = env_str('DDOC', 'ddoc') | |
| const VIEW = env_str('VIEW', 'view') | |
| const VIEW_LIMIT = env_num('VIEW_LIMIT', 1) | |
| const DURATION = env_str('DURATION', '5m'); | |
| const RATE = env_num('RATE', 500); | |
| const TAG = env_str('TAG', ''); | |
| const SCENARIOS = env_str('SCENARIOS', 'view_get'); | |
| const XHEADER = env_str('XHEADER', ''); | |
| // Derived params | |
| const DB_URL = `${URL}/${DB}`; | |
| const VIEW_URL = `${URL}/${DB}/_design/${DDOC}/_view/${VIEW}` | |
| const INFO_URL = `${URL}/${DB}/_design/${DDOC}/_info` | |
| const HEADERS = get_headers(XHEADER, USER, PASS); | |
| const SETUP_PAR = {'headers': HEADERS, tags: {name: 'setup'}}; | |
| const VIEW_PAR = {'headers': HEADERS, tags: {name: 'view_get'}}; | |
| const SCENARIO_DEFAULTS = { | |
| executor: 'constant-arrival-rate', | |
| duration: DURATION, | |
| timeUnit: '1s', | |
| preAllocatedVUs: 1000, | |
| maxVUs: 5000 | |
| }; | |
| // Callbacks & options. These are what k6 expects to call | |
| export const options = { | |
| scenarios: scenarios(), | |
| discardResponseBodies: true, | |
| setupTimeout: '60m', | |
| // These are bogus, always passing thresholds just so we can | |
| // see the individual tagged requests times in the summary | |
| // but in principle these could be turned into a pass/fail test | |
| thresholds: { | |
| 'http_req_duration{name:view_get}' : ['p(99)>=0'] | |
| } | |
| }; | |
| export function setup() { | |
| console.log(` | |
| * tag: ${TAG} | |
| * scanarios: ${SCENARIOS} | |
| * url: ${URL} | |
| * user: ${USER} | |
| * ddoc: ${DDOC} | |
| * view: ${VIEW} | |
| * duration: ${DURATION} | |
| \n`); | |
| let res; | |
| res = http.get(DB_URL, SETUP_PAR); | |
| if (res.status != 200) { | |
| throw new Error(`Could not find DB ${DB_URL} ${res.status}`); | |
| } | |
| res = http.get(INFO_URL, SETUP_PAR); | |
| if (res.status != 200) { | |
| throw new Error(`Could not find view at ${INFO_URL} ${res.status}`); | |
| } | |
| } | |
| export function view_get () { | |
| const skey = randomString(10, 'abcdef0123456789'); | |
| http.get(`${VIEW_URL}?start_key="${skey}"&limit=${VIEW_LIMIT}`, VIEW_PAR); | |
| } | |
| /// End of callback functions | |
| // Helpers | |
| function env_str(name, default_val) { | |
| name = 'BENCH_' + name; | |
| return __ENV[name] ? __ENV[name] : default_val; | |
| } | |
| function env_num(name, default_val) { | |
| name = 'BENCH_' + name; | |
| return __ENV[name] ? Number(__ENV[name]) : default_val; | |
| } | |
| function scenarios() { | |
| let scenario_keys = SCENARIOS.split(','); | |
| let scenarios_available = { | |
| view_get : {...SCENARIO_DEFAULTS, ...{exec: 'view_get'}, ...{rate: RATE}} | |
| }; | |
| return Object.fromEntries(scenario_keys.map(k => [k, scenarios_available[k]])); | |
| } | |
| function get_headers(xtra_header, user, pass) { | |
| let b64 = encoding.b64encode(`${user}:${pass}`); | |
| let xheader = parse_header(xtra_header); | |
| return { | |
| 'authorization': `Basic ${b64}`, | |
| 'content-type':'application/json', | |
| ...xheader | |
| } | |
| }; | |
| function parse_header(header_str) { | |
| let [name, ...rest] = header_str.split(":"); | |
| let val = rest.join(":"); | |
| return name ? {name : val} : {}; | |
| } | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run as:
Views can be created with view_cycle.py