-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
123 lines (101 loc) · 3.4 KB
/
script.js
File metadata and controls
123 lines (101 loc) · 3.4 KB
1
2
3
4
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Trend } from 'k6/metrics';
import { FormData } from 'https://jslib.k6.io/formdata/0.0.2/index.js';
import { open } from 'k6/experimental/fs';
const loginTrend = new Trend('login_duration');
const profileTrend = new Trend('profile_duration');
const uploadTrend = new Trend('upload_duration');
const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
const fileBytes = open('./Code Snippets.docx', 'b');
// Load test options with two scenarios
export const options = {
scenarios: {
authScenario: {
executor: 'constant-vus',
vus: 50,
duration: '3m',
exec: 'authScenario',
},
uploadScenario: {
executor: 'constant-vus',
vus: 50,
duration: '3m',
exec: 'uploadScenario',
startTime: '30s', // delay upload scenario for better realism
},
},
thresholds: {
login_duration: ['p(95)<1000'], // Login must be <1s for 95% of requests
upload_duration: ['p(95)<2000'], // Upload must be <2s for 95%
http_req_failed: ['rate<0.05'], // Less than 5% failures allowed
},
insecureSkipTLSVerify: true,
};
// Reusable login function
function loginAndGetToken() {
const loginForm = new FormData();
loginForm.append('Email', 'rosa.segers.2001@gmail.com');
loginForm.append('Password', 'PasswordPassword');
const res = http.post('http://131.189.232.222/gateway/auth/login', loginForm.body(), {
headers: { 'Content-Type': `multipart/form-data; boundary=${loginForm.boundary}` },
});
check(res, {
'login status 200': (r) => r.status === 200,
'token received': (r) => !!r.json('accessToken'),
});
loginTrend.add(res.timings.duration);
if (res.status !== 200) {
console.error('Login failed.');
return null;
}
return res.json('accessToken');
}
// Scenario 1: Login + Profile Fetch
export function authScenario() {
const token = loginAndGetToken();
if (!token) return;
sleep(Math.random() * 2 + 1); // simulate user think time
const profileRes = http.get('http://131.189.232.222/gateway/users/me', {
headers: { Authorization: `Bearer ${token}` },
});
check(profileRes, {
'profile status 200': (r) => r.status === 200,
});
profileTrend.add(profileRes.timings.duration);
sleep(Math.random() * 2 + 1);
}
// Scenario 2: Login + Upload
export function uploadScenario() {
const token = loginAndGetToken();
if (!token) return;
if (fileBytes.length === 0) {
console.error('File is empty. Skipping upload.');
return;
}
if (fileBytes.length > MAX_FILE_SIZE_BYTES) {
console.warn(`File too large: ${fileBytes.length} bytes.`);
return;
}
sleep(Math.random() * 2 + 1);
const uploadForm = new FormData();
uploadForm.append('Name', 'Architectural Decisions');
uploadForm.append('Description', 'Zero downtime soft test');
uploadForm.append('Version', '1');
uploadForm.append('File', {
data: fileBytes,
filename: 'LoadTest.docx',
content_type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
});
const res = http.post('http://131.189.232.222/gateway/documents', uploadForm.body(), {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': `multipart/form-data; boundary=${uploadForm.boundary}`,
},
});
check(res, {
'upload status 202': (r) => r.status === 202,
});
uploadTrend.add(res.timings.duration);
sleep(Math.random() * 3 + 2); // longer pause
}