]>
Commit | Line | Data |
---|---|---|
8f68c31a C |
1 | 'use strict' |
2 | ||
46132744 | 3 | const each = require('async/each') |
8f68c31a | 4 | const isEqual = require('lodash/isEqual') |
bb0b243c | 5 | const differenceWith = require('lodash/differenceWith') |
1a42c9e2 C |
6 | const program = require('commander') |
7 | const series = require('async/series') | |
8f68c31a C |
8 | |
9 | process.env.NODE_ENV = 'test' | |
10 | const constants = require('../../initializers/constants') | |
11 | ||
46132744 C |
12 | const loginUtils = require('../utils/login') |
13 | const podsUtils = require('../utils/pods') | |
14 | const serversUtils = require('../utils/servers') | |
15 | const videosUtils = require('../utils/videos') | |
f148e5ed | 16 | const requestStatsUtils = require('../utils/requests-stats') |
8f68c31a C |
17 | |
18 | program | |
19 | .option('-c, --create [weight]', 'Weight for creating videos') | |
20 | .option('-r, --remove [weight]', 'Weight for removing videos') | |
f2cdb866 | 21 | .option('-u, --update [weight]', 'Weight for updating videos') |
f148e5ed C |
22 | .option('-v, --view [weight]', 'Weight for viewing videos') |
23 | .option('-l, --like [weight]', 'Weight for liking videos') | |
3092476e | 24 | .option('-s, --dislike [weight]', 'Weight for disliking videos') |
8f68c31a C |
25 | .option('-p, --pods [n]', 'Number of pods to run (3 or 6)', /^3|6$/, 3) |
26 | .option('-a, --action [interval]', 'Interval in ms for an action') | |
27 | .option('-i, --integrity [interval]', 'Interval in ms for an integrity check') | |
28 | .option('-f, --flush', 'Flush datas on exit') | |
bb0b243c | 29 | .option('-d, --difference', 'Display difference if integrity is not okay') |
8f68c31a C |
30 | .parse(process.argv) |
31 | ||
bb0b243c C |
32 | const createWeight = program.create !== undefined ? parseInt(program.create) : 5 |
33 | const removeWeight = program.remove !== undefined ? parseInt(program.remove) : 4 | |
f2cdb866 | 34 | const updateWeight = program.update !== undefined ? parseInt(program.update) : 4 |
f148e5ed C |
35 | const viewWeight = program.view !== undefined ? parseInt(program.view) : 4 |
36 | const likeWeight = program.like !== undefined ? parseInt(program.like) : 4 | |
37 | const dislikeWeight = program.dislike !== undefined ? parseInt(program.dislike) : 4 | |
8f68c31a | 38 | const flushAtExit = program.flush || false |
bb0b243c | 39 | const actionInterval = program.action !== undefined ? parseInt(program.action) : 500 |
790e65fc | 40 | const integrityInterval = program.integrity !== undefined ? parseInt(program.integrity) : 60000 |
bb0b243c | 41 | const displayDiffOnFail = program.integrity || false |
8f68c31a C |
42 | |
43 | const numberOfPods = 6 | |
bb0b243c | 44 | |
f148e5ed | 45 | console.log('Create weight: %d, update weight: %d, remove weight: %d, view weight: %d, like weight: %d, dislike weight: %d.', createWeight, updateWeight, removeWeight, viewWeight, likeWeight, dislikeWeight) |
8f68c31a C |
46 | if (flushAtExit) { |
47 | console.log('Program will flush data on exit.') | |
48 | } else { | |
49 | console.log('Program will not flush data on exit.') | |
50 | } | |
bb0b243c C |
51 | if (displayDiffOnFail) { |
52 | console.log('Program will display diff on failure.') | |
53 | } else { | |
54 | console.log('Program will not display diff on failure') | |
55 | } | |
8f68c31a C |
56 | console.log('Interval in ms for each action: %d.', actionInterval) |
57 | console.log('Interval in ms for each integrity check: %d.', integrityInterval) | |
8f68c31a C |
58 | |
59 | console.log('Run servers...') | |
60 | runServers(numberOfPods, function (err, servers) { | |
61 | if (err) throw err | |
62 | ||
63 | process.on('exit', function () { | |
64 | exitServers(servers, flushAtExit) | |
65 | }) | |
66 | process.on('SIGINT', goodbye) | |
67 | process.on('SIGTERM', goodbye) | |
68 | ||
69 | console.log('Servers runned') | |
f148e5ed | 70 | initializeRequestsPerServer(servers) |
8f68c31a C |
71 | |
72 | let checking = false | |
73 | ||
74 | setInterval(function () { | |
75 | if (checking === true) return | |
76 | ||
f148e5ed C |
77 | const rand = getRandomInt(0, createWeight + updateWeight + removeWeight + viewWeight + likeWeight + dislikeWeight) |
78 | ||
79 | const numServer = getRandomNumServer(servers) | |
80 | servers[numServer].requestsNumber++ | |
8f68c31a C |
81 | |
82 | if (rand < createWeight) { | |
f148e5ed | 83 | upload(servers, numServer) |
f2cdb866 | 84 | } else if (rand < createWeight + updateWeight) { |
f148e5ed C |
85 | update(servers, numServer) |
86 | } else if (rand < createWeight + updateWeight + removeWeight) { | |
87 | remove(servers, numServer) | |
88 | } else if (rand < createWeight + updateWeight + removeWeight + viewWeight) { | |
89 | view(servers, numServer) | |
90 | } else if (rand < createWeight + updateWeight + removeWeight + viewWeight + likeWeight) { | |
91 | like(servers, numServer) | |
8f68c31a | 92 | } else { |
f148e5ed | 93 | dislike(servers, numServer) |
8f68c31a C |
94 | } |
95 | }, actionInterval) | |
96 | ||
f148e5ed | 97 | // The function will check the consistency between servers (should have the same videos with same attributes...) |
8f68c31a | 98 | setInterval(function () { |
bb0b243c C |
99 | if (checking === true) return |
100 | ||
8f68c31a C |
101 | console.log('Checking integrity...') |
102 | checking = true | |
103 | ||
f148e5ed | 104 | const waitingInterval = setInterval(function () { |
0dd079da C |
105 | isThereAwaitingRequests(servers, function (err, res) { |
106 | if (err) throw err | |
107 | ||
f148e5ed C |
108 | if (res === true) { |
109 | console.log('A server has awaiting requests, waiting...') | |
110 | return | |
111 | } | |
112 | ||
113 | checkIntegrity(servers, function () { | |
114 | initializeRequestsPerServer(servers) | |
115 | checking = false | |
116 | clearInterval(waitingInterval) | |
117 | }) | |
8f68c31a | 118 | }) |
f148e5ed | 119 | }, constants.REQUESTS_INTERVAL) |
8f68c31a C |
120 | }, integrityInterval) |
121 | }) | |
122 | ||
123 | // ---------------------------------------------------------------------------- | |
124 | ||
f148e5ed C |
125 | function initializeRequestsPerServer (servers) { |
126 | servers.forEach(function (server) { | |
127 | server.requestsNumber = 0 | |
128 | }) | |
129 | } | |
130 | ||
8f68c31a C |
131 | function getRandomInt (min, max) { |
132 | return Math.floor(Math.random() * (max - min)) + min | |
133 | } | |
134 | ||
135 | function getRandomNumServer (servers) { | |
136 | return getRandomInt(0, servers.length) | |
137 | } | |
138 | ||
139 | function runServers (numberOfPods, callback) { | |
140 | let servers = null | |
141 | ||
1a42c9e2 | 142 | series([ |
8f68c31a C |
143 | // Run servers |
144 | function (next) { | |
46132744 | 145 | serversUtils.flushAndRunMultipleServers(numberOfPods, function (serversRun) { |
8f68c31a C |
146 | servers = serversRun |
147 | next() | |
148 | }) | |
149 | }, | |
150 | // Get the access tokens | |
151 | function (next) { | |
1a42c9e2 | 152 | each(servers, function (server, callbackEach) { |
46132744 | 153 | loginUtils.loginAndGetAccessToken(server, function (err, accessToken) { |
8f68c31a C |
154 | if (err) return callbackEach(err) |
155 | ||
156 | server.accessToken = accessToken | |
157 | callbackEach() | |
158 | }) | |
159 | }, next) | |
160 | }, | |
161 | function (next) { | |
162 | const server = servers[1] | |
46132744 | 163 | podsUtils.makeFriends(server.url, server.accessToken, next) |
8f68c31a C |
164 | }, |
165 | function (next) { | |
166 | const server = servers[0] | |
46132744 | 167 | podsUtils.makeFriends(server.url, server.accessToken, next) |
8f68c31a C |
168 | }, |
169 | function (next) { | |
170 | setTimeout(next, 1000) | |
171 | }, | |
172 | function (next) { | |
173 | const server = servers[3] | |
46132744 | 174 | podsUtils.makeFriends(server.url, server.accessToken, next) |
8f68c31a C |
175 | }, |
176 | function (next) { | |
177 | const server = servers[5] | |
46132744 | 178 | podsUtils.makeFriends(server.url, server.accessToken, next) |
8f68c31a C |
179 | }, |
180 | function (next) { | |
181 | const server = servers[4] | |
46132744 | 182 | podsUtils.makeFriends(server.url, server.accessToken, next) |
8f68c31a C |
183 | }, |
184 | function (next) { | |
185 | setTimeout(next, 1000) | |
186 | } | |
187 | ], function (err) { | |
188 | return callback(err, servers) | |
189 | }) | |
190 | } | |
191 | ||
192 | function exitServers (servers, callback) { | |
193 | if (!callback) callback = function () {} | |
194 | ||
195 | servers.forEach(function (server) { | |
196 | if (server.app) process.kill(-server.app.pid) | |
197 | }) | |
198 | ||
46132744 | 199 | if (flushAtExit) serversUtils.flushTests(callback) |
8f68c31a C |
200 | } |
201 | ||
202 | function upload (servers, numServer, callback) { | |
203 | if (!callback) callback = function () {} | |
204 | ||
f148e5ed | 205 | console.log('Uploading video to server ' + numServer) |
8f68c31a | 206 | |
b4c5ac97 C |
207 | const videoAttributes = { |
208 | name: Date.now() + ' name', | |
209 | category: 4, | |
31b59b47 | 210 | nsfw: false, |
6f0c39e2 | 211 | licence: 2, |
3092476e | 212 | language: 1, |
b4c5ac97 C |
213 | description: Date.now() + ' description', |
214 | tags: [ Date.now().toString().substring(0, 5) + 't1', Date.now().toString().substring(0, 5) + 't2' ], | |
215 | fixture: 'video_short1.webm' | |
216 | } | |
217 | videosUtils.uploadVideo(servers[numServer].url, servers[numServer].accessToken, videoAttributes, callback) | |
8f68c31a C |
218 | } |
219 | ||
f2cdb866 C |
220 | function update (servers, numServer, callback) { |
221 | if (!callback) callback = function () {} | |
222 | ||
223 | videosUtils.getVideosList(servers[numServer].url, function (err, res) { | |
224 | if (err) throw err | |
225 | ||
226 | const videos = res.body.data.filter(function (video) { return video.isLocal }) | |
227 | if (videos.length === 0) return callback() | |
228 | ||
229 | const toUpdate = videos[getRandomInt(0, videos.length)].id | |
b4c5ac97 C |
230 | const attributes = { |
231 | name: Date.now() + ' name', | |
232 | description: Date.now() + ' description', | |
233 | tags: [ Date.now().toString().substring(0, 5) + 't1', Date.now().toString().substring(0, 5) + 't2' ] | |
234 | } | |
f2cdb866 C |
235 | |
236 | console.log('Updating video of server ' + numServer) | |
237 | ||
b4c5ac97 | 238 | videosUtils.updateVideo(servers[numServer].url, servers[numServer].accessToken, toUpdate, attributes, callback) |
f2cdb866 C |
239 | }) |
240 | } | |
241 | ||
8f68c31a C |
242 | function remove (servers, numServer, callback) { |
243 | if (!callback) callback = function () {} | |
244 | ||
46132744 | 245 | videosUtils.getVideosList(servers[numServer].url, function (err, res) { |
8f68c31a C |
246 | if (err) throw err |
247 | ||
248 | const videos = res.body.data | |
249 | if (videos.length === 0) return callback() | |
250 | ||
251 | const toRemove = videos[getRandomInt(0, videos.length)].id | |
252 | ||
253 | console.log('Removing video from server ' + numServer) | |
46132744 | 254 | videosUtils.removeVideo(servers[numServer].url, servers[numServer].accessToken, toRemove, callback) |
8f68c31a C |
255 | }) |
256 | } | |
257 | ||
f148e5ed C |
258 | function view (servers, numServer, callback) { |
259 | if (!callback) callback = function () {} | |
260 | ||
261 | videosUtils.getVideosList(servers[numServer].url, function (err, res) { | |
262 | if (err) throw err | |
263 | ||
264 | const videos = res.body.data | |
265 | if (videos.length === 0) return callback() | |
266 | ||
267 | const toView = videos[getRandomInt(0, videos.length)].id | |
268 | ||
269 | console.log('Viewing video from server ' + numServer) | |
270 | videosUtils.getVideo(servers[numServer].url, toView, callback) | |
271 | }) | |
272 | } | |
273 | ||
274 | function like (servers, numServer, callback) { | |
275 | rate(servers, numServer, 'like', callback) | |
276 | } | |
277 | ||
278 | function dislike (servers, numServer, callback) { | |
279 | rate(servers, numServer, 'dislike', callback) | |
280 | } | |
281 | ||
282 | function rate (servers, numServer, rating, callback) { | |
283 | if (!callback) callback = function () {} | |
284 | ||
285 | videosUtils.getVideosList(servers[numServer].url, function (err, res) { | |
286 | if (err) throw err | |
287 | ||
288 | const videos = res.body.data | |
289 | if (videos.length === 0) return callback() | |
290 | ||
291 | const toRate = videos[getRandomInt(0, videos.length)].id | |
292 | ||
293 | console.log('Rating (%s) video from server %d', rating, numServer) | |
294 | videosUtils.getVideo(servers[numServer].url, toRate, callback) | |
295 | }) | |
296 | } | |
297 | ||
8f68c31a C |
298 | function checkIntegrity (servers, callback) { |
299 | const videos = [] | |
1a42c9e2 | 300 | each(servers, function (server, callback) { |
46132744 | 301 | videosUtils.getAllVideosListBy(server.url, function (err, res) { |
8f68c31a C |
302 | if (err) throw err |
303 | const serverVideos = res.body.data | |
304 | for (const serverVideo of serverVideos) { | |
305 | delete serverVideo.id | |
306 | delete serverVideo.isLocal | |
307 | delete serverVideo.thumbnailPath | |
bb0b243c | 308 | delete serverVideo.updatedAt |
f148e5ed | 309 | delete serverVideo.views |
8f68c31a C |
310 | } |
311 | ||
312 | videos.push(serverVideos) | |
313 | callback() | |
314 | }) | |
315 | }, function () { | |
f148e5ed C |
316 | let i = 0 |
317 | ||
8f68c31a C |
318 | for (const video of videos) { |
319 | if (!isEqual(video, videos[0])) { | |
f148e5ed | 320 | console.error('Integrity not ok with server %d!', i + 1) |
56ac84d0 | 321 | |
bb0b243c C |
322 | if (displayDiffOnFail) { |
323 | console.log(differenceWith(videos[0], video, isEqual)) | |
f148e5ed | 324 | console.log(differenceWith(video, videos[0], isEqual)) |
bb0b243c C |
325 | } |
326 | ||
8f68c31a C |
327 | process.exit(-1) |
328 | } | |
f148e5ed C |
329 | |
330 | i++ | |
8f68c31a C |
331 | } |
332 | ||
333 | console.log('Integrity ok.') | |
334 | return callback() | |
335 | }) | |
336 | } | |
337 | ||
338 | function goodbye () { | |
339 | return process.exit(-1) | |
340 | } | |
f148e5ed C |
341 | |
342 | function isThereAwaitingRequests (servers, callback) { | |
343 | let noRequests = true | |
344 | ||
345 | // Check is each server has awaiting requestq | |
346 | each(servers, function (server, callbackEach) { | |
347 | requestStatsUtils.getRequestsStats(server, server.accessToken, function (err, res) { | |
348 | if (err) throw err | |
349 | ||
350 | const stats = res.body | |
351 | ||
352 | if ( | |
353 | stats.requestScheduler.totalRequests !== 0 || | |
354 | stats.requestVideoEventScheduler.totalRequests !== 0 || | |
355 | stats.requestVideoQaduScheduler.totalRequests !== 0 | |
356 | ) { | |
357 | noRequests = false | |
358 | } | |
359 | ||
360 | callbackEach() | |
361 | }) | |
362 | }, function (err) { | |
363 | if (err) throw err | |
364 | ||
0dd079da | 365 | return callback(null, noRequests === false) |
f148e5ed C |
366 | }) |
367 | } |