diff --git a/.github/ISSUE_TEMPLATE/performance_test_report.md b/.github/ISSUE_TEMPLATE/performance_test_report.md index 0969d79e..4569f2ea 100644 --- a/.github/ISSUE_TEMPLATE/performance_test_report.md +++ b/.github/ISSUE_TEMPLATE/performance_test_report.md @@ -2,7 +2,7 @@ name: Performance Test Report about: Spike Test, Average Load Test... title: '' -labels: 'document, performanceTest' +labels: 'documentation, performanceTest' assignees: '' --- diff --git a/.gitignore b/.gitignore index e64c17d4..4cb1f6b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store +src/performanceTest/dummy-data/*.csv src/performanceTest/dummy-data/*.sql node_modules/ diff --git a/docs/open-api.yaml b/docs/open-api.yaml index 2337d3a3..185fed05 100644 --- a/docs/open-api.yaml +++ b/docs/open-api.yaml @@ -629,10 +629,10 @@ components: pageSize: type: integer format: int32 - unpaged: - type: boolean paged: type: boolean + unpaged: + type: boolean Reservation: required: - address diff --git a/src/performanceTest/dummy-data/src/config.js b/src/performanceTest/dummy-data/src/config.js index eb7d45df..e028af6a 100644 --- a/src/performanceTest/dummy-data/src/config.js +++ b/src/performanceTest/dummy-data/src/config.js @@ -8,8 +8,10 @@ if (GENERATE_COUNT == null) { process.exit(1) } +const FORLDER_NAME = path.join(__dirname, '../') module.exports = { - SQL_FILE_NAME: path.join(__dirname, '../../initdb/sqls/initdata.sql'), + FORLDER_NAME, + SQL_FILE_NAME: FORLDER_NAME + '/initdata.sql', GENERATE_COUNT, GENERATE_PER_LOOP, } \ No newline at end of file diff --git a/src/performanceTest/dummy-data/src/generate.js b/src/performanceTest/dummy-data/src/generate.js index 76cbb9ea..5e783499 100644 --- a/src/performanceTest/dummy-data/src/generate.js +++ b/src/performanceTest/dummy-data/src/generate.js @@ -25,20 +25,69 @@ const writeSqlFile = (table, data) => { fs.appendFileSync(config.SQL_FILE_NAME, sqlString); } +const sql = (tables) => { + try { + fs.unlinkSync(config.SQL_FILE_NAME) + } catch (e) { -module.exports = (table) => { - fs.appendFileSync(config.SQL_FILE_NAME, `\n\n-- ${table.name}`) - - console.log(`Generating ${table.name}...`) + } - let total = 0 + fs.appendFileSync(config.SQL_FILE_NAME, ` + USE ticketingdb; + SET unique_checks=0; + SET foreign_key_checks=0; + `) - while (total < config.GENERATE_COUNT) { - const count = Math.min(config.GENERATE_PER_LOOP, config.GENERATE_COUNT - total) - const raws = generateRaws(table, count, total) - writeSqlFile(table, raws) - total += raws.length + for (const table of tables) { + fs.appendFileSync(config.SQL_FILE_NAME, `\n\n-- ${table.name}`) + + console.log(`Generating ${table.name}...`) + + let total = 0 + + while (total < config.GENERATE_COUNT) { + const count = Math.min(config.GENERATE_PER_LOOP, config.GENERATE_COUNT - total) + const raws = generateRaws(table, count, total) + writeSqlFile(table, raws) + total += raws.length + } + + console.log(`Finish Generating ${table.name}: ${total}`) } + + fs.appendFileSync(config.SQL_FILE_NAME, ` + \n + SET unique_checks=1; + SET foreign_key_checks=1; + `) +} + +const csv = (tables) => { + for (const table of tables) { + const FILE_NAME = config.FORLDER_NAME + `/${table.name}.csv` + try { + fs.unlinkSync(FILE_NAME) + } catch (e) { + + } + fs.appendFileSync(FILE_NAME, `${table.fields.map(e => e.name).join(',')}\n`); + + console.log(`Generating ${table.name}...`) - console.log(`Finish Generating ${table.name}: ${total}`) + let total = 0 + + while (total < config.GENERATE_COUNT) { + const count = Math.min(config.GENERATE_PER_LOOP, config.GENERATE_COUNT - total) + const raws = generateRaws(table, count, total) + fs.appendFileSync(FILE_NAME, raws.map(r => Object.values(r).join(',')).join('\n')) + fs.appendFileSync(FILE_NAME, '\n') + total += raws.length + } + + console.log(`Finish Generating ${table.name}: ${total}`) + } +} +module.exports = { + sql, + csv, } \ No newline at end of file diff --git a/src/performanceTest/dummy-data/src/index.js b/src/performanceTest/dummy-data/src/index.js index 0e7a8691..bec5d6e0 100644 --- a/src/performanceTest/dummy-data/src/index.js +++ b/src/performanceTest/dummy-data/src/index.js @@ -3,25 +3,4 @@ const generate = require('./generate.js') const config = require('./config.js') const { tables } = require('./schema.js') - -try { - fs.unlinkSync(config.SQL_FILE_NAME) -} catch (e) { - -} - -fs.appendFileSync(config.SQL_FILE_NAME, ` -USE ticketingdb; -SET unique_checks=0; -SET foreign_key_checks=0; -`) - -for (const table of tables) { - generate(table) -} - -fs.appendFileSync(config.SQL_FILE_NAME, ` -\n -SET unique_checks=1; -SET foreign_key_checks=1; -`) \ No newline at end of file +generate.csv(tables) \ No newline at end of file diff --git a/src/performanceTest/dummy-data/src/schema.js b/src/performanceTest/dummy-data/src/schema.js index 472a8281..1332f2ab 100644 --- a/src/performanceTest/dummy-data/src/schema.js +++ b/src/performanceTest/dummy-data/src/schema.js @@ -1,6 +1,5 @@ const { faker } = require('@faker-js/faker') const userpassword = require('./userpassword.js') -const defaultValue = (value) => () => value class Field { constructor(name, generator) { @@ -17,18 +16,22 @@ class Table { } const event = new Table('event', [ + new Field('id', (i) => i + 1), new Field('title', (i) => faker.music.songName()), - new Field('date', (i) => faker.date.recent()), + new Field('start_date', (i) => faker.date.recent()), + new Field('end_date', (i) => faker.date.future()), new Field('reservation_start_time', (i) => faker.date.recent()), - new Field('reservation_end_time', (i) => faker.date.future()), - new Field('max_attendees', (i) => faker.number.int(1000)), - new Field('current_reservation_count', (i) => defaultValue(0)), + new Field('reservation_end_time', (i) => faker.date.future({ years: 1 })), + new Field('max_attendees', (i) => faker.number.int(10000)), + new Field('total_attendees', (i) => 0), new Field('created_at', (i) => faker.date.recent()), new Field('updated_at', (i) => faker.date.recent()), ]) const user = new Table('user', [ + new Field('id', (i) => `${i + 1}`), new Field('email', (i) => `K6-${i + 1}@email.com`), new Field('name', (i) => `${i + 1}`), + new Field('phone_number', (i) => "010-1234-1234"), new Field('pw', (i) => userpassword[i % 1000]), new Field('created_at', (i) => faker.date.recent()), new Field('updated_at', (i) => faker.date.recent()), diff --git a/src/performanceTest/scripts/lib/generator.js b/src/performanceTest/scripts/lib/generator.js index a86cb25a..cf944bad 100644 --- a/src/performanceTest/scripts/lib/generator.js +++ b/src/performanceTest/scripts/lib/generator.js @@ -12,10 +12,12 @@ const getPrefix = () => { const User = (ID) => { if (ID) { + let pw = Number(ID) % 1000 + if (pw == 0) pw = 1000 return { name: `${ID}`, email: `K6-${ID}@email.com`, - password: `K6-${Number(ID) % 1000}-password`, + password: `K6-${pw}-password`, } } else { return { diff --git a/src/performanceTest/scripts/lib/hooks.js b/src/performanceTest/scripts/lib/hooks.js index 51ee0bb6..212a4b94 100644 --- a/src/performanceTest/scripts/lib/hooks.js +++ b/src/performanceTest/scripts/lib/hooks.js @@ -32,7 +32,7 @@ export default { K6 (Native Histogram) : ${config.GRAFANA_HOST}/d/a3b2aaa8-bb66-4008-a1d8-16c49afedbf0/k6-prometheus-native-histograms?${query}&var-DS_PROMETHEUS=prometheus&var-testid=${__ENV.ENTRYPOINT}&var-quantile=0.95 [Cluster Resources] - CLUSTER : ${config.GRAFANA_HOST}/d/85a562078cdf77779eaa1add43ccec1e/kubernetes-compute-resources-namespace-pods?${query}&var-datasource=default&var-cluster=&var-namespace=default + CLUSTER : ${config.GRAFANA_HOST}/d/4b545447f/1-kubernetes-all-in-one-cluster-monitoring-kr??${query}&var-datasource=default&var-cluster=&var-namespace=default [Nginx] Official NGINX : ${config.GRAFANA_HOST}/d/nginx/nginx-ingress-controller?${query} diff --git a/src/performanceTest/scripts/lib/request.js b/src/performanceTest/scripts/lib/request.js index cb13279b..43d969df 100644 --- a/src/performanceTest/scripts/lib/request.js +++ b/src/performanceTest/scripts/lib/request.js @@ -19,7 +19,7 @@ export default class Request { } setToken(token) { - if (token.substring(0, 7) === 'Bearer ') { + if (token && token.substring(0, 7) === 'Bearer ') { // set this.token = token without 'Bearer ' this.Token = token.substring(7); } diff --git a/src/performanceTest/scripts/signinTest.js b/src/performanceTest/scripts/signinTest.js index b085864c..561bf2e0 100644 --- a/src/performanceTest/scripts/signinTest.js +++ b/src/performanceTest/scripts/signinTest.js @@ -2,12 +2,12 @@ import { check } from "k6"; import Request from "./lib/request.js"; import generator from "./lib/generator.js"; import hooks from "./lib/hooks.js"; -import { getUserIDFromExec, isSuccess } from "./lib/helpers.js"; +import { isSuccess, randomInt } from "./lib/helpers.js"; export const setup = hooks.setup export const handleSummary = hooks.handleSummary -const VU_COUNT = 20 +const VU_COUNT = 200 export const options = { tags: { testid: `${__ENV.ENTRYPOINT}` @@ -32,15 +32,18 @@ export const options = { thresholds: { http_req_failed: ['rate<0.01'], // http errors should be less than 1% - http_req_duration: ['p(95)<200'], // 95% of requests should be below 100ms + http_req_duration: ['p(95)<300'], // 95% of requests should be below 300ms }, }; export default function () { const req = new Request() - const ID = getUserIDFromExec(VU_COUNT) + const ID = randomInt(1, 1000000) const user = generator.User(ID) const res = req.signin(user) + if (!isSuccess(res)) { + console.log(user, res.body) + } check(res, {"Success SignIn": (r) => isSuccess(r) && r.json().Authorization}); } \ No newline at end of file diff --git a/src/performanceTest/scripts/spikeTest.js b/src/performanceTest/scripts/spikeTest.js index 4755edd2..e073d5fe 100644 --- a/src/performanceTest/scripts/spikeTest.js +++ b/src/performanceTest/scripts/spikeTest.js @@ -32,7 +32,7 @@ export const options = { thresholds: { http_req_failed: ['rate<0.01'], // http errors should be less than 1% - http_req_duration: ['p(95)<200'], // 95% of requests should be below 100ms + http_req_duration: ['p(95)<300'], // 95% of requests should be below 300ms }, };