Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion infra/k6/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
"test:teams-me": "k6 run scenarios/teams-me.js",
"test:projects": "k6 run scenarios/projects.js",
"test:users": "k6 run scenarios/users.js",
"test:board": "k6 run scenarios/board-full.js",
"test:boards:all": "k6 run scenarios/boards.js && k6 run scenarios/boards-columns.js && k6 run scenarios/boards-views.js",
"test:boards": "k6 run scenarios/boards.js",
"test:boards:columns": "k6 run scenarios/boards-columns.js",
"test:boards:views": "k6 run scenarios/boards-views.js",
"test:tasks": "k6 run scenarios/tasks.js",
"smoke": "k6 run smoke.js"
},
Expand Down
134 changes: 134 additions & 0 deletions infra/k6/scenarios/boards-columns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { SharedArray } from 'k6/data';
import { sleep, check } from 'k6';
import { GET_OPTIONS } from '../common/config.js';
import getAuthUser from '../shared/get-auth-user.js';

const users = new SharedArray('test users', function () {
return JSON.parse(open('../data/users.json'));
});
const teams = new SharedArray('test teams', function () {
return JSON.parse(open('../data/teams.json'));
});
const randomStr = (len = 8) =>
Math.random()
.toString(36)
.substring(2, 2 + len);
const randomNum = (min = 1, max = 100) => Math.floor(Math.random() * (max - min + 1)) + min;

const baseOptions = GET_OPTIONS();
baseOptions.thresholds = Object.assign({}, baseOptions.thresholds, {
'http_req_duration{name:auth-sign-in}': ['p(95)<333'],
'http_req_duration{name:post-teams-projects}': ['p(95)<333'],
'http_req_duration{name:post-projects-boards}': ['p(95)<333'],
'http_req_duration{name:get-boards-columns}': ['p(95)<333'],
'http_req_duration{name:post-boards-columns}': ['p(95)<333'],
'http_req_duration{name:get-boards-columns-id}': ['p(95)<333'],
'http_req_duration{name:patch-boards-columns}': ['p(95)<333'],
'http_req_duration{name:delete-boards-columns}': ['p(95)<333'],
'http_req_duration{name:delete-teams-projects}': ['p(95)<333'],
});

export const options = baseOptions;

export default function () {
const user = users[(__VU - 1) % users.length];
const team = teams[(__VU - 1) % teams.length];
const { client } = getAuthUser(user);

sleep(1);

// --- create project ---
const project = {
name: `k6_columns_project_${randomStr(6)}`,
key: `K6${randomNum(1000, 9999)}`,
description: 'k6 columns scenario project',
visibility: 'public',
};
const createProjectRes = client.post(`/teams/${team.slug}/projects`, project, {
tags: { name: 'post-teams-projects' },
});
const projectId = createProjectRes.json().projectId;

check(createProjectRes, {
'POST /teams/:slug/projects: has projectId': (r) => r.json().projectId !== undefined,
});

sleep(1);

// --- create board ---
const boardPayload = {
name: `k6_columns_board_${randomStr(6)}`,
position: Date.now(),
};
const createBoardRes = client.post(`/projects/${projectId}/boards`, boardPayload, {
tags: { name: 'post-projects-boards' },
});
const boardId = createBoardRes.json().id;

check(createBoardRes, {
'POST /projects/:id/boards: has id': (r) => r.json().id !== undefined,
});

sleep(1);

// --- get all columns ---
const listRes = client.get(
`/boards/${boardId}/columns`,
{},
{ tags: { name: 'get-boards-columns' } },
);
check(listRes, { 'GET /boards/:id/columns: array': (r) => Array.isArray(r.json()) });

sleep(1);

// --- create column ---
const columnPayload = {
name: `k6_column_${randomStr(6)}`,
position: 4000,
color: '#22c55e',
};
const createColumnRes = client.post(`/boards/${boardId}/columns`, columnPayload, {
tags: { name: 'post-boards-columns' },
});
const columnId = createColumnRes.json().id;

check(createColumnRes, {
'POST /boards/:id/columns: has id': (r) => r.json().id !== undefined,
});

sleep(1);

// --- get column ---
client.get(
`/boards/${boardId}/columns/${columnId}`,
{},
{ tags: { name: 'get-boards-columns-id' } },
);

sleep(1);

// --- update column ---
const updatedColumn = {
name: `k6_column_${randomStr(7)}`,
color: '#3b82f6',
};
client.patch(`/boards/${boardId}/columns/${columnId}`, updatedColumn, {
tags: { name: 'patch-boards-columns' },
});

sleep(1);

// --- delete column ---
client.delete(`/boards/${boardId}/columns/${columnId}`, {
tags: { name: 'delete-boards-columns' },
});

sleep(1);

// --- delete project ---
client.delete(`/teams/${team.slug}/projects/${projectId}`, {
tags: { name: 'delete-teams-projects' },
});

sleep(1);
}
130 changes: 130 additions & 0 deletions infra/k6/scenarios/boards-views.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { SharedArray } from 'k6/data';
import { sleep, check } from 'k6';
import { GET_OPTIONS } from '../common/config.js';
import getAuthUser from '../shared/get-auth-user.js';

const users = new SharedArray('test users', function () {
return JSON.parse(open('../data/users.json'));
});
const teams = new SharedArray('test teams', function () {
return JSON.parse(open('../data/teams.json'));
});
const randomStr = (len = 8) =>
Math.random()
.toString(36)
.substring(2, 2 + len);
const randomNum = (min = 1, max = 100) => Math.floor(Math.random() * (max - min + 1)) + min;

const baseOptions = GET_OPTIONS();
baseOptions.thresholds = Object.assign({}, baseOptions.thresholds, {
'http_req_duration{name:auth-sign-in}': ['p(95)<333'],
'http_req_duration{name:post-teams-projects}': ['p(95)<333'],
'http_req_duration{name:post-projects-boards}': ['p(95)<333'],
'http_req_duration{name:get-boards-views}': ['p(95)<333'],
'http_req_duration{name:post-boards-views}': ['p(95)<333'],
'http_req_duration{name:get-boards-views-id}': ['p(95)<333'],
'http_req_duration{name:patch-boards-views}': ['p(95)<333'],
'http_req_duration{name:delete-boards-views}': ['p(95)<333'],
'http_req_duration{name:delete-teams-projects}': ['p(95)<333'],
});

export const options = baseOptions;

export default function () {
const user = users[(__VU - 1) % users.length];
const team = teams[(__VU - 1) % teams.length];
const { client } = getAuthUser(user);

sleep(1);

// --- create project ---
const project = {
name: `k6_views_project_${randomStr(6)}`,
key: `K6${randomNum(1000, 9999)}`,
description: 'k6 views scenario project',
visibility: 'public',
};
const createProjectRes = client.post(`/teams/${team.slug}/projects`, project, {
tags: { name: 'post-teams-projects' },
});
const projectId = createProjectRes.json().projectId;

check(createProjectRes, {
'POST /teams/:slug/projects: has projectId': (r) => r.json().projectId !== undefined,
});

sleep(1);

// --- create board ---
const boardPayload = {
name: `k6_views_board_${randomStr(6)}`,
position: Date.now(),
};
const createBoardRes = client.post(`/projects/${projectId}/boards`, boardPayload, {
tags: { name: 'post-projects-boards' },
});
const boardId = createBoardRes.json().id;

check(createBoardRes, {
'POST /projects/:id/boards: has id': (r) => r.json().id !== undefined,
});

sleep(1);

// --- get all views ---
const listRes = client.get(
`/boards/${boardId}/views`,
{},
{ tags: { name: 'get-boards-views' } },
);
check(listRes, { 'GET /boards/:id/views: array': (r) => Array.isArray(r.json()) });

sleep(1);

// --- create view ---
const viewPayload = {
type: 'kanban',
name: `k6_view_${randomStr(6)}`,
position: 4000,
settings: { mock: 'k6' },
};
const createViewRes = client.post(`/boards/${boardId}/views`, viewPayload, {
tags: { name: 'post-boards-views' },
});
const viewId = createViewRes.json().id;

check(createViewRes, {
'POST /boards/:id/views: has id': (r) => r.json().id !== undefined,
});

sleep(1);

// --- get view ---
client.get(`/boards/${boardId}/views/${viewId}`, {}, { tags: { name: 'get-boards-views-id' } });

sleep(1);

// --- update view ---
const updatedView = {
name: `k6_view_${randomStr(7)}`,
};
client.patch(`/boards/${boardId}/views/${viewId}`, updatedView, {
tags: { name: 'patch-boards-views' },
});

sleep(1);

// --- delete view ---
client.delete(`/boards/${boardId}/views/${viewId}`, {
tags: { name: 'delete-boards-views' },
});

sleep(1);

// --- delete project ---
client.delete(`/teams/${team.slug}/projects/${projectId}`, {
tags: { name: 'delete-teams-projects' },
});

sleep(1);
}
115 changes: 115 additions & 0 deletions infra/k6/scenarios/boards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { SharedArray } from 'k6/data';
import { sleep, check } from 'k6';
import { GET_OPTIONS } from '../common/config.js';
import getAuthUser from '../shared/get-auth-user.js';

const users = new SharedArray('test users', function () {
return JSON.parse(open('../data/users.json'));
});
const teams = new SharedArray('test teams', function () {
return JSON.parse(open('../data/teams.json'));
});
const randomStr = (len = 8) =>
Math.random()
.toString(36)
.substring(2, 2 + len);
const randomNum = (min = 1, max = 100) => Math.floor(Math.random() * (max - min + 1)) + min;

const baseOptions = GET_OPTIONS();
baseOptions.thresholds = Object.assign({}, baseOptions.thresholds, {
'http_req_duration{name:auth-sign-in}': ['p(95)<333'],
'http_req_duration{name:post-teams-projects}': ['p(95)<333'],
'http_req_duration{name:post-projects-boards}': ['p(95)<333'],
'http_req_duration{name:get-projects-boards}': ['p(95)<333'],
'http_req_duration{name:get-projects-boards-id}': ['p(95)<333'],
'http_req_duration{name:patch-projects-boards}': ['p(95)<333'],
'http_req_duration{name:delete-projects-boards}': ['p(95)<333'],
'http_req_duration{name:delete-teams-projects}': ['p(95)<333'],
});

export const options = baseOptions;

export default function () {
const user = users[(__VU - 1) % users.length];
const team = teams[(__VU - 1) % teams.length];
const { client } = getAuthUser(user);

sleep(1);

// --- create project ---
const project = {
name: `k6_board_project_${randomStr(6)}`,
key: `K6${randomNum(1000, 9999)}`,
description: 'k6 boards scenario project',
visibility: 'public',
};
const createProjectRes = client.post(`/teams/${team.slug}/projects`, project, {
tags: { name: 'post-teams-projects' },
});
const projectId = createProjectRes.json().projectId;

check(createProjectRes, {
'POST /teams/:slug/projects: has projectId': (r) => r.json().projectId !== undefined,
});

sleep(1);

// --- create board ---
const boardPayload = {
name: `k6_board_${randomStr(6)}`,
position: Date.now(),
};
const createBoardRes = client.post(`/projects/${projectId}/boards`, boardPayload, {
tags: { name: 'post-projects-boards' },
});
const boardId = createBoardRes.json().id;

check(createBoardRes, {
'POST /projects/:id/boards: has id': (r) => r.json().id !== undefined,
});

sleep(1);

// --- get all boards ---
const listRes = client.get(
`/projects/${projectId}/boards`,
{},
{ tags: { name: 'get-projects-boards' } },
);
check(listRes, { 'GET /projects/:id/boards: array': (r) => Array.isArray(r.json()) });

sleep(1);

// --- get board ---
client.get(
`/projects/${projectId}/boards/${boardId}`,
{},
{ tags: { name: 'get-projects-boards-id' } },
);

sleep(1);

// --- update board ---
const updatedBoard = {
name: `k6_board_${randomStr(7)}`,
};
client.patch(`/projects/${projectId}/boards/${boardId}`, updatedBoard, {
tags: { name: 'patch-projects-boards' },
});

sleep(1);

// --- delete board ---
client.delete(`/projects/${projectId}/boards/${boardId}`, {
tags: { name: 'delete-projects-boards' },
});

sleep(1);

// --- delete project ---
client.delete(`/teams/${team.slug}/projects/${projectId}`, {
tags: { name: 'delete-teams-projects' },
});

sleep(1);
}
Loading
Loading