Hi,
I have spent a combined time of a few days on this already, so any help will be appreciated.
Context: I have a reasonably restrictive scenario where I need to test at least 1 minute long trips during which 5 different type of queries run and with a hard requirement that the last query should hit the DB at a rate of 15/s. Unless I’m missing something obvious, in order to maintain 15ops/sec for 60 seconds long interactions I will need to start 900 VUs at a rate of 15/s. Unfortunately there’s something around our DB configuration/query types that makes it run out of RAM for anything over 750 connections.
Problem Description: When looking at the xk6-sql documentation is quite clear that this not just one isolated driver connection, but a connection manager that allows to specify the number of maximum connections. So instead of doing what I’m doing now and creating one db connection manager per VU as a global variable for the test
let db = sql.open(driver, dbUrl);
so practically establishing 900 DB connections at the start of the test, I would like to be able to create only one connection manager and provide that one instance to every VU and allow it to establish and de-establish connections as needed. I could simulate this by opening and closing myself the connection for each query, but that would definitely change the CPU usage profile and would not be a real testing scenario, cause that is not how it works in prod.
Attempted Solutions: In order to get this to work I have tried two things (excerpts from code are provided):
1. I have created the db in setup() and passed it down to the default(data)
import { group, sleep } from ‘k6’;
import exec from ‘k6/execution’;
import { Trend } from ‘k6/metrics’;
// @ts-ignore
import { openKv } from ‘k6/x/kv’;
// @ts-ignore
import sql, { Database } from ‘k6/x/sql’;
// @ts-ignore
import { expect } from ‘https://jslib.k6.io/k6-testing/0.5.0/index.js’;
// @ts-ignore
import driver from ‘k6/x/sql/driver/postgres’;export async function setup() {
const db: Database = sql.open(driver, dbUrl); return { database: db }; // tried returning the db object directly as well, same result}
export default async function(data: any) {
const kvdb : Database = data.database; group('IGNITION ON - 1/trip', () => { const result = TestSupport.runQueryWithTiming(kvdb, finalIgnitionOnQuery, \`\__VU${\__VU}-IT${\__ITER}-IGNON\`); });}
============================= TestSupport
public static runQueryWithTiming(
db: Database, query: string, runInformation: string = ''): { duration: number; result: any } {
const start = new Date().getTime(); var result = null; try { // result = query.startsWith('SELECT') ? db.query(query) : db.exec(query); result = db.query(query); // db.exec('COMMIT TRANSACTION'); } catch (e) { const end = new Date().getTime(); // @ts-ignore logger.error(\`${runInformation} SQLError - took ${end - start}ms caused by: ${e.message}\`); } const end = new Date().getTime(); return { duration: end - start, result: result };}
Running this fails with: e[31mERROe[0m[0004] e[32m16:00:32.693e[0m e[32m[PLM_psqlTest]e[0m __VU2-IT0-IGNON SQLError - took 0ms caused by: Object has no member ‘query’
2. I have used the xk6-kv ( GitHub - oleiade/xk6-kv: A key-value store extension for k6 ) to pass down the DB instance. The result was the same as above.
import { group, sleep } from ‘k6’;
import exec from ‘k6/execution’;
import { Trend } from ‘k6/metrics’;
// @ts-ignore
import { openKv } from ‘k6/x/kv’;
// @ts-ignore
import sql, { Database } from ‘k6/x/sql’;
// @ts-ignore
import { expect } from ‘https://jslib.k6.io/k6-testing/0.5.0/index.js’;
// @ts-ignore
import driver from ‘k6/x/sql/driver/postgres’;export async function setup() {
// deal with KV
await kv.clear();
const db: Database = sql.open(driver, dbUrl);
await kv.set(‘db’, db);
}
export default async function() {
const kvdb = await kv.get<Database>('db'); group('IGNITION ON - 1/trip', () => { const result = TestSupport.runQueryWithTiming(kvdb, finalIgnitionOnQuery, \`\__VU${\__VU}-IT${\__ITER}-IGNON\`); });}
Again the same type of error: e[31mERROe[0m[0002] e[32m15:24:00.453e[0m e[32m[PLM_psqlTest]e[0m __VU1-IT0-IGNON SQLError - took 0ms caused by: Object has no member ‘query’
So is there something that I’m doing wrong? Something I missed. Reading the documentation it does not look like the object type is relevant. Are there specific restrictions that I missed?
But in the end what I’m asking is if there is a way to share one sql connection manager instance across multiple VUs in k6? If yes, how can I achieve that?