Files
pos-system/tests/load/k6/order-creation.js

120 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* EN: k6 load test — Order creation endpoint (POST /api/v1/orders).
* VI: k6 load test — endpoint tạo đơn hàng (POST /api/v1/orders).
*
* Usage:
* k6 run tests/load/k6/order-creation.js
* k6 run --env BASE_URL=http://api.staging.goodgo.vn tests/load/k6/order-creation.js
*
* Thresholds:
* - 95th-percentile response time < 500ms
* - Error rate < 1%
*/
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';
// ---------------------------------------------------------------------------
// Custom metrics
// ---------------------------------------------------------------------------
const orderCreationErrors = new Rate('order_creation_errors');
const orderCreationDuration = new Trend('order_creation_duration', true);
// ---------------------------------------------------------------------------
// Test options
// ---------------------------------------------------------------------------
export const options = {
stages: [
// EN: Ramp up to 20 VUs over 30s / VI: Tăng lên 20 VUs trong 30s
{ duration: '30s', target: 20 },
// EN: Hold at 20 VUs for 1 minute / VI: Duy trì 20 VUs trong 1 phút
{ duration: '1m', target: 20 },
// EN: Spike to 50 VUs for 30s / VI: Tăng đột biến lên 50 VUs trong 30s
{ duration: '30s', target: 50 },
// EN: Ramp down / VI: Giảm dần
{ duration: '30s', target: 0 },
],
thresholds: {
// EN: 95% of requests must complete below 500ms / VI: 95% requests phải hoàn thành dưới 500ms
http_req_duration: ['p(95)<500'],
// EN: Error rate must stay below 1% / VI: Tỷ lệ lỗi phải dưới 1%
order_creation_errors: ['rate<0.01'],
// EN: Custom trend threshold / VI: Ngưỡng trend tùy chỉnh
order_creation_duration: ['p(99)<1000'],
},
};
// ---------------------------------------------------------------------------
// Config
// ---------------------------------------------------------------------------
const BASE_URL = __ENV.BASE_URL || 'http://localhost:5010';
const JWT_TOKEN = __ENV.JWT_TOKEN || 'test-bearer-token';
const SHOP_ID = __ENV.SHOP_ID || '00000000-0000-0000-0000-000000000001';
const PRODUCT_ID = __ENV.PRODUCT_ID || '00000000-0000-0000-0000-000000000002';
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${JWT_TOKEN}`,
'X-Shop-Id': SHOP_ID,
};
// ---------------------------------------------------------------------------
// Helper — generate a random order payload
// ---------------------------------------------------------------------------
function buildOrderPayload() {
const tableNumber = Math.floor(Math.random() * 20) + 1;
const qty = Math.floor(Math.random() * 3) + 1;
return JSON.stringify({
shopId: SHOP_ID,
tableNumber: `T${tableNumber}`,
orderType: 'dine_in',
items: [
{
productId: PRODUCT_ID,
quantity: qty,
unitPrice: 35000,
note: '',
},
],
note: `k6-load-test-${Date.now()}`,
});
}
// ---------------------------------------------------------------------------
// Default function — executed per VU iteration
// ---------------------------------------------------------------------------
export default function () {
const payload = buildOrderPayload();
const startTime = Date.now();
const res = http.post(`${BASE_URL}/api/v1/orders`, payload, { headers });
const duration = Date.now() - startTime;
orderCreationDuration.add(duration);
const success = check(res, {
// EN: Status is 201 Created / VI: Status là 201 Created
'status is 201': (r) => r.status === 201,
// EN: Response body has success=true / VI: Body phản hồi có success=true
'body has success:true': (r) => {
try {
return JSON.parse(r.body).success === true;
} catch {
return false;
}
},
// EN: Response time below 500ms / VI: Thời gian phản hồi dưới 500ms
'response time < 500ms': (r) => r.timings.duration < 500,
});
if (!success) {
orderCreationErrors.add(1);
} else {
orderCreationErrors.add(0);
}
// EN: Think time between requests (0.51.5s) / VI: Thời gian nghỉ giữa các request
sleep(0.5 + Math.random());
}