Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions load-testing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
"load": "yarn build && k6 run dist/loadTest.bundle.js",
"spike": "yarn build && k6 run dist/spikeTest.bundle.js",
"soak": "yarn build && k6 run dist/soakTest.bundle.js",
"queue": "yarn build && k6 run dist/queueTest.bundle.js",
"smoke-cloud": "yarn build && k6 cloud dist/smokeTest.bundle.js",
"load-cloud": "yarn build && k6 cloud dist/loadTest.bundle.js",
"queue-cloud": "yarn build && k6 cloud dist/queueTest.bundle.js",
"go:docker": "yarn build && yarn test"
},
"dependencies": {
"@types/k6": "^0.25.1",
"@types/node": "^13.13.27"
"@types/node": "^20.12.7"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand All @@ -40,8 +42,9 @@
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-prettier": "^3.1.2",
"prettier": "^1.19.1",
"typescript": "^3.7.5",
"webpack": "^4.41.6",
"random-word-slugs": "^0.1.7",
"typescript": "4.5.5",
"webpack": "5.78",
"webpack-cli": "^3.3.11"
}
}
252 changes: 252 additions & 0 deletions load-testing/src/actions/namex-api.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
import { group, check, fail } from "k6"
import http from "k6/http"

import { setSleep } from "../helpers/sleep"
import { generateCompanyName, generateNameAnalysisParams } from "../helpers/namerequest"
import { NAMEX_API_URL, USER_EMAIL, USER_PHONE } from "../utils/config.util"
import { User } from "../types/user.type"
import { Contact } from "../types/contact.type"
import * as tokenAction from "./token.action"

const BASE_URL = NAMEX_API_URL

const user: User = {
firstname: 'Leonardo',
lastname: 'DaVinci',
}

const contact: Contact = {
email: USER_EMAIL,
phone: USER_PHONE,
postalCode: 'V5M 4X6',
phoneExtension: '',
city: 'Vancouver',
country: 'CA',
street: '1234 Madeup Way',
streetAdditional: '',
region: 'BC'
}


export function healthCheck (_httpParams: any) {

let url = `${BASE_URL}/api/v1/nr-ops/healthz`

group('Namex API', () => {

let res = http.get(url, _httpParams({ name: 'Healthcheck' }))

// check the user is query
if (!check(res, { 'Health Check': (r) => r.status === 200 })) {
fail(`Unable to connect api ${res.status} ${res.body}`)
}

setSleep(0.5, 1)
})
}

function nameAnalysis(name: string, analysis_type: string, _httpParams: any) {
let params = generateNameAnalysisParams(name)

let url = `${BASE_URL}/api/v1/name-analysis${params}${analysis_type}`
console.log(url)

group('Namex API', () => {
let res = http.get(url)
if (!check(res, { 'Namerequest analysis performed correctly': (r) => r.status === 200 })) {
fail(`Unable to perform name analysis ${res.status} ${res.body}`)
}

setSleep(0.5, 1)

})
}


function exactNameMatch(name: string, _httpParams: any) {

let url = `${BASE_URL}/api/v1/exact-match?query=${encodeURI(name.toUpperCase())}`
console.log(url)

group('Namex API', () => {

let res = http.get(url, _httpParams({ name: 'exactNameMatch' }))
if (!check(res, { 'Namerequest name exact match performed correctly': (r) => r.status === 200 })) {
fail(`Unable to perform name exact match ${res.status} ${res.body}`)
}

setSleep(0.5, 1)

})
}


function createNamerequest(name: string, _httpParams: any) {

let url = `${BASE_URL}/api/v1/namerequests`
console.log(url)

let data = {
"applicants": [{ "addrLine1":contact.street,
"city":contact.city,
"countryTypeCd":contact.country,
"declineNotificationInd":"",
"emailAddress":contact.email,
"firstName":user.firstname,
"lastName":user.lastname,
"phoneNumber":contact.phone,
"postalCd":contact.postalCode,
"stateProvinceCd":contact.region
}],
"names":[{
"name": name,
"designation":"LIMITED",
"choice":1,
"name_type_cd":"CO",
"consent_words":"",
"conflict1":"",
"conflict1_num":"",
}],
"natureBusinessInfo":"TESTING",
"priorityCd":"N",
"entity_type_cd":"CR",
"request_action_cd":"NEW",
"conversion_type_cd":null,
"stateCd":"DRAFT",
"english":true,
"nameFlag":false,
"submit_count":0,
"additionalInfo":"*** New Request ***"}

let resp: any = null
let json: string = JSON.stringify(data)


group('Namex API', () => {
let res = http.post(url, json, { headers: { 'Content-Type': 'application/json' }})
resp = JSON.parse(res.body as string)
// check the user is created
if (!check(res, { 'Namerequest created correctly': (r) => r.status === 201 })) {
fail(`Unable to create namerequest ${res.status} ${res.body}`)
}

setSleep(10, 30)

})

return resp
}


function getNamerequestFees(nr: string) {

let url = `${BASE_URL}/api/v1/payments/fees`
console.log(url)

let data = {
"filing_type_code":"NM620",
"jurisdiction":"BC",
"date":"2024-05-16T18:45:06.000Z",
"priority":false
}

let json: string = JSON.stringify(data)

group('Namex API', () => {

let res = http.post(url, json, { headers: { 'Content-Type': 'application/json', 'BCREG-NR': nr, 'BCREG-User-Email': contact.email, 'BCREG-User-Phone': contact.phone}})
if (!check(res, { 'Namerequest retrieved fees correctly': (r) => r.status === 200 })) {
fail(`Unable to retrieve fees ${res.status} ${res.body}`)
}

setSleep(5, 10)

})
}

function createPayment(nd_id: string, _httpParams: any) {

let url = `${BASE_URL}/api/v1/payments/${nd_id}/CREATE`
console.log(url)
let token = tokenAction.get_token()
let token_str = `Bearer ${token}`

let data = { "filingInfo": {
"filingTypes": [
{
"filingTypeCode": "NM620",
"priority": false
}
]},
"headers": {
'Content-Type': 'application/json', 'waiveFees': true, 'Authorization': token_str
}
}

let resp: any = null
let json: string = JSON.stringify(data)


group('Namex API', () => {
let res = http.post(url, json, _httpParams({ name: 'PaymentCheck' }))

resp = JSON.parse(res.body as string)
// check the user is created
if (!check(res, { 'Payment processed correctly': (r) => r.status === 201 })) {
fail(`Unable to process payment ${res.status} ${res.body}`)
}
setSleep(10, 30)

})


return resp
}

function getPayments(nr: string, nrNUm: string) {

let url = `${BASE_URL}/api/v1/payments/${nr}`

group('Namex API', () => {

let res = http.get(url, { headers: { 'Content-Type': 'application/json', 'BCREG-NR': nrNUm, 'BCREG-User-Email': contact.email, 'BCREG-User-Phone': contact.phone}})
if (!check(res, { 'Namerequest payment retrieved correctly': (r) => r.status === 200 })) {
fail(`Unable to retrieve payment ${res.status} ${res.body}`)
}

setSleep(0.5, 1)

})
}


function processPaymentRefund(nr: string, nrNUm: string) {

let url = `${BASE_URL}/api/v1/namerequests/${nr}/REQUEST_REFUND`
console.log(url)

group('Namex API', () => {

let res = http.patch(url, JSON.stringify({}), { headers: { 'Content-Type': 'application/json', 'BCREG-NR': nrNUm, 'BCREG-User-Email': contact.email, 'BCREG-User-Phone': contact.phone}})

if (!check(res, { 'Namerequest payment refunded correctly': (r) => r.status === 200 })) {
fail(`Unable to process refund ${res.status} ${res.body}`)
}

setSleep(10, 30)

})
}


export function processNamerequest (_httpParams: any): any {
let company_name = generateCompanyName()
nameAnalysis(company_name, 'structure', _httpParams)
nameAnalysis(company_name, 'designation', _httpParams)
exactNameMatch(company_name, _httpParams)
let nr = createNamerequest(company_name, _httpParams)
getNamerequestFees(nr.nrNum)
let pay = createPayment(nr.id, _httpParams)
getPayments(pay.nrId, pay.nrNum)
processPaymentRefund(pay.nrId, pay.nrNum)
}
10 changes: 10 additions & 0 deletions load-testing/src/helpers/namerequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { generateSlug } from "random-word-slugs"

export function generateCompanyName() {
return generateSlug(4, { format: "title" });
}

export function generateNameAnalysisParams(name: string) {
const params: string = '?name=' + encodeURI(name.toUpperCase()) + '&location=BC&entity_type_cd=CR&request_action_cd=NEW&jurisdiction=BC&analysis_type='
return params
}
53 changes: 53 additions & 0 deletions load-testing/src/tests/queue.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { group } from 'k6'
import { Options } from 'k6/options'

import { createRequestConfigWithTag } from '../helpers/request'
import { setSleep } from '../helpers/sleep'


import * as tokenAction from '../actions/token.action'
import * as namexApiAction from '../actions/namex-api.action'

import { Trend } from 'k6/metrics'
let groupDuration = new Trend('groupDuration');

export let options: Partial<Options> = {
stages: [
{ duration: '1m', target: 50 }, // simulate ramp-up of traffic from 1 to 50 users over 3 minutes.
{ duration: '1m', target: 50 }, // stay at 50 users for 6 minutes
{ duration: '1m', target: 0 }, // ramp-down to 0 users
],
thresholds: {
http_req_duration: ['avg<15000', 'p(95)<10000'], // 95% of requests must complete below 800ms
'groupDuration{groupName:Queue Testing}': ['avg < 15000'],
},
}

function groupWithDurationMetric (name, group_function) {
let start: any = new Date()
group(name, group_function)
let end: any = new Date()
groupDuration.add(end - start, { groupName: name })
}

// The Setup Function is run once before the Load Test https://docs.k6.io/docs/test-life-cycle
export function setup () {
let token: string = tokenAction.get_token()
return token
}

export default (_token: any) => {

let httpParams = createRequestConfigWithTag(_token)
groupWithDurationMetric('Queue Testing', () => {
namexApiAction.processNamerequest(httpParams)
})

setSleep()
}

// The Teardown Function is run once after the Load Test https://docs.k6.io/docs/test-life-cycle
export function teardown () {


}
2 changes: 2 additions & 0 deletions load-testing/src/tests/smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { setSleep } from '../helpers/sleep'
import * as authApiAction from '../actions/auth-api.action'
import * as payApiAction from '../actions/pay-api.action'
import * as legalApiAction from '../actions/legal-api.action'
import * as namexApiAction from '../actions/namex-api.action'


export let options: Partial<Options> = {
Expand All @@ -30,6 +31,7 @@ export default () => {
authApiAction.healthCheck(httpParams)
payApiAction.healthCheck(httpParams)
legalApiAction.healthCheck(httpParams)
namexApiAction.healthCheck(httpParams)
})

setSleep()
Expand Down
4 changes: 4 additions & 0 deletions load-testing/src/utils/config.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ export const SERVICE_CLIENT_SECRET = process.env.SERVICE_CLIENT_SECRET
export const AUTH_API_URL = process.env.AUTH_API_URL
export const PAY_API_URL = process.env.PAY_API_URL
export const LEGAL_API_URL = process.env.LEGAL_API_URL
export const NAMEX_API_URL = process.env.NAMEX_API_URL

export const USER_EMAIL = process.env.USER_EMAIL
export const USER_PHONE = process.env.USER_PHONE
1 change: 1 addition & 0 deletions load-testing/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
loadTest: './src/tests/load.test.ts',
spikeTest: './src/tests/spike.test.ts',
soakTest: './src/tests/soak.test.ts',
queueTest: './src/tests/queue.test.ts',
},
output: {
path: path.resolve(__dirname, 'dist'),
Expand Down
Loading