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