-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
## Summary Fixes #2473 ### Time to review: __5 mins__ ## Changes proposed This adds a `processor.ts` file for running load tests runs get requests for opp pages, search pages, static pages, and 404 pages. To test locally, `artillery run -e local artillery-load-test.yml` . This only runs a few requests locally but you can see the log messages and check your local frontend server to see the results.
- Loading branch information
Showing
4 changed files
with
337 additions
and
16 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
{ | ||
"ids": { | ||
"local": [ | ||
1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, | ||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 | ||
], | ||
"dev": [], | ||
"prod": [] | ||
}, | ||
"queries": [ | ||
"test", | ||
"grants", | ||
"education", | ||
"transportation", | ||
"trauma", | ||
"veterans" | ||
], | ||
"status": ["posted", "forecasted", "closed", "archived", "none"], | ||
"agencies": [ | ||
"ARPAH", | ||
"USAID", | ||
"USAID-AFG", | ||
"USAID", | ||
"USAID-ARM", | ||
"USAID-AZE", | ||
"USAID-BAN", | ||
"USAID-BEN", | ||
"AC", | ||
"DC", | ||
"USDA", | ||
"USDA-AMS", | ||
"USDA-FNS1", | ||
"DOC", | ||
"DOC-DOCNOAAERA", | ||
"DOC-EDA", | ||
"DOC-NIST", | ||
"DOD", | ||
"DOD-AMC-ACCAPGN", | ||
"DOD-AMC-ACCAPGD", | ||
"DOD-AFRL-AFRLDET8", | ||
"DOD-AFRL", | ||
"DOD-USAFA", | ||
"DOD-AFOSR", | ||
"DOD-DARPA-BTO", | ||
"ED", | ||
"DOE", | ||
"DOE-ARPAE", | ||
"DOE-GFO", | ||
"DOE-01", | ||
"PAMS", | ||
"PAMS-SC", | ||
"HHS", | ||
"HHS-ACF-FYSB", | ||
"HHS-ACF", | ||
"HHS-ACF-CB", | ||
"DHS", | ||
"DHS-DHS", | ||
"DHS-OPO", | ||
"DHS-USCG", | ||
"HUD", | ||
"USDOJ", | ||
"USDOJ-OJP-BJA", | ||
"USDOJ-OJP-COPS", | ||
"DOL", | ||
"DOL-ETA-ILAB", | ||
"DOL-ETA-CEO", | ||
"DOS", | ||
"DOS-NEA-AC", | ||
"DOS-DRL", | ||
"DOS-ECA", | ||
"DOI", | ||
"DOI-BIA", | ||
"DOI-BLM", | ||
"DOI-BOR", | ||
"USDOT", | ||
"USDOT-ORP", | ||
"USDOT-DO-SIPPRA", | ||
"USDOT-GCR", | ||
"DOT", | ||
"DOT-DOT X-50", | ||
"DOT-RITA", | ||
"DOT-FAA-FAA ARG", | ||
"DOT-FRA", | ||
"DOT-FHWA", | ||
"DOT-FTA", | ||
"DOT-FAA-FAA COE-AJFE", | ||
"DOT-FAA-FAA COE-FAA JAMS", | ||
"DOT-FAA-FAA COE-TTHP", | ||
"DOT-MA", | ||
"DOT-NHTSA", | ||
"VA", | ||
"VA-CSHF", | ||
"VA-HPGPDP", | ||
"VA-LSV", | ||
"VA-NVSP", | ||
"VA-NCAC", | ||
"VA-OMHSP", | ||
"VA-SSVF", | ||
"VA-NCA", | ||
"VA-VLGP", | ||
"EPA", | ||
"IMLS", | ||
"MCC", | ||
"NASA", | ||
"NASA-HQ", | ||
"NASA-JSC", | ||
"NASA-SFC", | ||
"NASA", | ||
"NARA", | ||
"NEA", | ||
"NEH", | ||
"NSF", | ||
"SSA" | ||
], | ||
"eligibility": [ | ||
"state_governments", | ||
"county_governments", | ||
"city_or_township_governments", | ||
"special_district_governments", | ||
"independent_school_districts", | ||
"public_and_state_institutions_of_higher_education", | ||
"private_institutions_of_higher_education", | ||
"federally_recognized_native_american_tribal_governments", | ||
"other_native_american_tribal_organizations", | ||
"public_and_indian_housing_authorities", | ||
"nonprofits_non_higher_education_with_501c3", | ||
"nonprofits_non_higher_education_without_501c3", | ||
"for_profit_organizations_other_than_small_businesses", | ||
"small_businesses", | ||
"other", | ||
"unrestricted" | ||
], | ||
"funding": [ | ||
"cooperative_agreement", | ||
"grant", | ||
"procurement_contract", | ||
"other" | ||
], | ||
"category": [ | ||
"recovery_act", | ||
"agriculture", | ||
"arts", | ||
"business_and_commerce", | ||
"community_development", | ||
"consumer_protection", | ||
"disaster_prevention_and_relief", | ||
"education", | ||
"employment_labor_and_training", | ||
"energy", | ||
"environment", | ||
"food_and_nutrition", | ||
"health", | ||
"housing", | ||
"humanities", | ||
"information_and_statistics", | ||
"infrastructure_investment_and_jobs_act", | ||
"income_security_and_social_services", | ||
"law_justice_and_legal_services", | ||
"natural_resources", | ||
"opportunity_zone_benefits", | ||
"regional_development", | ||
"science_technology_and_other_research_and_development", | ||
"transportation", | ||
"affordable_care_act", | ||
"other" | ||
], | ||
"pages": ["", "process", "research", "subscribe", "subscribe/confirmation"] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import { readFile } from "fs/promises"; | ||
import { random } from "lodash"; | ||
|
||
type dataType = { | ||
ids: { | ||
[key: string]: Array<number>; | ||
}; | ||
queries: Array<string>; | ||
pages: Array<string>; | ||
status: Array<string>; | ||
agencies: Array<string>; | ||
funding: Array<string>; | ||
eligibility: Array<string>; | ||
category: Array<string>; | ||
}; | ||
type globalVars = { | ||
$environment?: string; | ||
}; | ||
|
||
type returnVars = { | ||
id: number; | ||
query: string; | ||
route: string; | ||
pages: string; | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/require-await | ||
async function getOppId(context: { vars: dataType & returnVars & globalVars }) { | ||
const env = context.vars.$environment as string; | ||
context.vars.id = | ||
context.vars.ids[env][random(context.vars.ids[env].length - 1)]; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/require-await | ||
async function get404(context: { vars: returnVars }) { | ||
const num = random(10); | ||
// ~50% of 404s are opp pages. | ||
if (num % 2 !== 0) { | ||
context.vars.route = `opportunity/${num}`; | ||
} else { | ||
context.vars.route = randomString(num); | ||
} | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/require-await | ||
async function getStatic(context: { vars: returnVars }) { | ||
context.vars.route = | ||
context.vars.pages[random(context.vars.pages.length - 1)]; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/require-await | ||
async function getSearchQuery(context: { vars: returnVars & dataType }) { | ||
const { queries, status, agencies, eligibility, category } = context.vars; | ||
const queryParam = `query=${queries[random(queries.length - 1)]}`; | ||
const statusParam = `status=${status[random(status.length - 1)]}`; | ||
const agencyParam = `agency=${agencies[random(agencies.length - 1)]}`; | ||
const categoryParam = `category=${category[random(category.length - 1)]}`; | ||
const eligibilityParam = `eligibility=${eligibility[random(eligibility.length - 1)]}`; | ||
const pagerParam = `page=${random(5)}`; | ||
// Most search params only include the queries, but smaller percent include | ||
// filters. This allows configuring that percent for composing the query | ||
const weights = [ | ||
{ | ||
percent: 50, | ||
params: [queryParam, statusParam, pagerParam], | ||
}, | ||
{ | ||
percent: 20, | ||
params: [queryParam, statusParam, agencyParam], | ||
}, | ||
{ | ||
percent: 20, | ||
params: [queryParam, statusParam, agencyParam, categoryParam], | ||
}, | ||
{ | ||
percent: 10, | ||
params: [ | ||
queryParam, | ||
statusParam, | ||
agencyParam, | ||
categoryParam, | ||
eligibilityParam, | ||
], | ||
}, | ||
]; | ||
// Weight of percents out of 100 | ||
const hundred = random(100); | ||
let total = 0; | ||
const selected = weights.find((item) => { | ||
total += item.percent; | ||
if (hundred <= total) { | ||
return true; | ||
} | ||
return false; | ||
}); | ||
context.vars.query = selected?.params.join("&") as string; | ||
} | ||
|
||
async function loadData(context: { vars: dataType & globalVars }) { | ||
// Dev and stage have the same data. | ||
const env = | ||
context.vars.$environment === "stage" ? "dev" : context.vars.$environment; | ||
const envs = new Set(["local", "dev", "stage", "prod"]); | ||
if (!env || !envs.has(env)) { | ||
throw new Error(`env ${env ?? ""} does not exist in env list`); | ||
} | ||
const path = "./tests/artillery/params.json"; | ||
const file = await readFile(path, "utf8"); | ||
context.vars = JSON.parse(file) as dataType; | ||
} | ||
|
||
function randomString(length: number) { | ||
const characters = | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | ||
let result = " "; | ||
const charactersLength = characters.length; | ||
for (let i = 0; i < length; i++) { | ||
result += characters.charAt(Math.floor(random(charactersLength))); | ||
} | ||
return result; | ||
} | ||
|
||
module.exports = { | ||
loadData, | ||
getOppId, | ||
get404, | ||
getStatic, | ||
getSearchQuery, | ||
}; |