Skip to content

Commit db77494

Browse files
arpandhakalrrojan
authored andcommitted
feat(OUT-2045): added a script to seed tasks in the load testing workspace
1 parent 3740ada commit db77494

2 files changed

Lines changed: 85 additions & 6 deletions

File tree

src/cmd/load-testing/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
- 2000 tasks
1111
*/
1212

13-
import config from '@cmd/load-testing/load-testing.config.json'
1413
import LoadTester from '@cmd/load-testing/load-testing-v2.service'
14+
import { AssigneeType } from '@prisma/client'
1515

1616
export const run = async () => {
1717
if (process.env.VERCEL_ENV === 'production') {
@@ -26,6 +26,8 @@ export const run = async () => {
2626
await loadTester.seedClients(200)
2727
// seed clients with a single company
2828
await loadTester.seedClients(200, true)
29+
// seed tasks
30+
await loadTester.seedTasks(100, AssigneeType.client)
2931
}
3032

3133
run()

src/cmd/load-testing/load-testing-v2.service.ts

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1+
import { MAX_FETCH_ASSIGNEE_COUNT } from '@/constants/users'
12
import DBClient from '@/lib/db'
23
import {
34
ClientRequest,
45
ClientRequestSchema,
6+
ClientResponseSchema,
57
CompanyCreateRequest,
68
CompanyCreateRequestSchema,
7-
InternalUsersResponse,
9+
Token,
10+
TokenSchema,
811
} from '@/types/common'
12+
import { CreateTaskRequest, CreateTaskRequestSchema } from '@/types/dto/tasks.dto'
13+
import { WorkflowStateResponse } from '@/types/dto/workflowStates.dto'
914
import { CopilotAPI } from '@/utils/CopilotAPI'
15+
import { faker } from '@faker-js/faker'
1016
import { AssigneeType, PrismaClient } from '@prisma/client'
1117
import Bottleneck from 'bottleneck'
12-
import { z } from 'zod'
13-
import { faker } from '@faker-js/faker'
1418
import fs from 'fs'
1519
import path from 'path'
16-
import { MAX_FETCH_ASSIGNEE_COUNT } from '@/constants/users'
20+
import { z } from 'zod'
1721

1822
class LoadTester {
1923
protected db: PrismaClient = DBClient.getInstance()
20-
24+
private apiUrl = 'https://tasks-app-git-feature-m16-load-testing-copilot-platforms.vercel.app'
2125
private token = z.string().parse(process.env.LOAD_TESTING_COPILOT_TOKEN)
2226
private apiKey = z.string().parse(process.env.COPILOT_API_KEY)
2327
private copilot: CopilotAPI = new CopilotAPI(this.token, this.apiKey)
@@ -75,6 +79,55 @@ class LoadTester {
7579
return responses
7680
}
7781

82+
async seedTasks(noOfTasks: number, userType: AssigneeType) {
83+
const [assigneeList, workflowStates, tokenPayload] = await Promise.all([
84+
userType == AssigneeType.client
85+
? (await this.copilot.getClients({ limit: MAX_FETCH_ASSIGNEE_COUNT })).data
86+
: (await this.copilot.getCompanies({ limit: MAX_FETCH_ASSIGNEE_COUNT })).data?.filter((data) => !data.isPlaceholder),
87+
this.getAllWorkflowStates(this.token),
88+
this.getTokenPayload(this.token),
89+
])
90+
91+
const seedPromises = []
92+
93+
for (let i = 0; i < noOfTasks; i++) {
94+
if (assigneeList) {
95+
const assignee = assigneeList[Math.floor(Math.random() * assigneeList.length)]
96+
let clientId,
97+
companyId,
98+
internalUserId = undefined
99+
if (userType == AssigneeType.client) {
100+
clientId = assignee.id
101+
companyId = ClientResponseSchema.parse(assignee).companyId
102+
} else if (userType == AssigneeType.company) {
103+
companyId = assignee.id
104+
} else {
105+
internalUserId = assignee.id
106+
}
107+
const workflowStateId = workflowStates[Math.floor(Math.random() * workflowStates.length)].id
108+
const createdById = tokenPayload.internalUserId
109+
const title = faker.music.songName()
110+
const body = faker.lorem.paragraph()
111+
const task = CreateTaskRequestSchema.parse({
112+
internalUserId,
113+
clientId,
114+
companyId,
115+
workflowStateId,
116+
createdById,
117+
title,
118+
body,
119+
})
120+
const seedPromiseWithBottleneck = this.bottlenecks.copilot.schedule(() => {
121+
console.info(`Seeding task ${task.title} `)
122+
return this.handleCreate(this.token, task)
123+
})
124+
seedPromises.push(seedPromiseWithBottleneck)
125+
}
126+
const responses = await Promise.all(seedPromises)
127+
return responses
128+
}
129+
}
130+
78131
private exportToCSV(data: Record<string, any>[], type: AssigneeType) {
79132
if (data.length === 0) return
80133

@@ -95,6 +148,30 @@ class LoadTester {
95148
fs.writeFileSync(outputPath, csvContent)
96149
console.log(`✅ CSV written to ${outputPath}`)
97150
}
151+
152+
private async getTokenPayload(token: string): Promise<Token> {
153+
const payload = TokenSchema.parse(await this.copilot.getTokenPayload())
154+
return payload as Token
155+
}
156+
157+
private async getAllWorkflowStates(token: string): Promise<WorkflowStateResponse[]> {
158+
const res = await fetch(`${this.apiUrl}/api/workflow-states?token=${token}`)
159+
160+
const data = await res.json()
161+
return data.workflowStates
162+
}
163+
164+
private async handleCreate(token: string, payload: CreateTaskRequest) {
165+
try {
166+
const response = await fetch(`${this.apiUrl}/api/tasks?token=${token}`, {
167+
method: 'POST',
168+
body: JSON.stringify(payload),
169+
})
170+
return await response.json()
171+
} catch (e: unknown) {
172+
console.error('Something went wrong while creating task!', e)
173+
}
174+
}
98175
}
99176

100177
export default LoadTester

0 commit comments

Comments
 (0)