]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/multiple-pods.js
Server: refractoring upload/update video test utils
[github/Chocobozzz/PeerTube.git] / server / tests / api / multiple-pods.js
1 /* eslint-disable no-unused-expressions */
2
3 'use strict'
4
5 const chai = require('chai')
6 const each = require('async/each')
7 const eachSeries = require('async/eachSeries')
8 const expect = chai.expect
9 const parallel = require('async/parallel')
10 const series = require('async/series')
11 const WebTorrent = require('webtorrent')
12 const webtorrent = new WebTorrent()
13
14 const loginUtils = require('../utils/login')
15 const miscsUtils = require('../utils/miscs')
16 const podsUtils = require('../utils/pods')
17 const serversUtils = require('../utils/servers')
18 const videosUtils = require('../utils/videos')
19
20 describe('Test multiple pods', function () {
21 let servers = []
22 const toRemove = []
23
24 before(function (done) {
25 this.timeout(30000)
26
27 series([
28 // Run servers
29 function (next) {
30 serversUtils.flushAndRunMultipleServers(3, function (serversRun) {
31 servers = serversRun
32 next()
33 })
34 },
35 // Get the access tokens
36 function (next) {
37 each(servers, function (server, callbackEach) {
38 loginUtils.loginAndGetAccessToken(server, function (err, accessToken) {
39 if (err) return callbackEach(err)
40
41 server.accessToken = accessToken
42 callbackEach()
43 })
44 }, next)
45 },
46 // The second pod make friend with the third
47 function (next) {
48 const server = servers[1]
49 podsUtils.makeFriends(server.url, server.accessToken, next)
50 },
51 // Wait for the request between pods
52 function (next) {
53 setTimeout(next, 10000)
54 },
55 // Pod 1 make friends too
56 function (next) {
57 const server = servers[0]
58 podsUtils.makeFriends(server.url, server.accessToken, next)
59 }
60 ], done)
61 })
62
63 it('Should not have videos for all pods', function (done) {
64 each(servers, function (server, callback) {
65 videosUtils.getVideosList(server.url, function (err, res) {
66 if (err) throw err
67
68 const videos = res.body.data
69 expect(videos).to.be.an('array')
70 expect(videos.length).to.equal(0)
71
72 callback()
73 })
74 }, done)
75 })
76
77 describe('Should upload the video and propagate on each pod', function () {
78 it('Should upload the video on pod 1 and propagate on each pod', function (done) {
79 this.timeout(15000)
80
81 series([
82 function (next) {
83 const videoAttributes = {
84 name: 'my super name for pod 1',
85 description: 'my super description for pod 1',
86 tags: [ 'tag1p1', 'tag2p1' ],
87 fixture: 'video_short1.webm'
88 }
89 videosUtils.uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes, next)
90 },
91 function (next) {
92 setTimeout(next, 11000)
93 }],
94 // All pods should have this video
95 function (err) {
96 if (err) throw err
97
98 each(servers, function (server, callback) {
99 let baseMagnet = null
100
101 videosUtils.getVideosList(server.url, function (err, res) {
102 if (err) throw err
103
104 const videos = res.body.data
105 expect(videos).to.be.an('array')
106 expect(videos.length).to.equal(1)
107 const video = videos[0]
108 expect(video.name).to.equal('my super name for pod 1')
109 expect(video.category).to.equal(5)
110 expect(video.categoryLabel).to.equal('Sports')
111 expect(video.description).to.equal('my super description for pod 1')
112 expect(video.podHost).to.equal('localhost:9001')
113 expect(video.magnetUri).to.exist
114 expect(video.duration).to.equal(10)
115 expect(video.tags).to.deep.equal([ 'tag1p1', 'tag2p1' ])
116 expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
117 expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
118 expect(video.author).to.equal('root')
119
120 if (server.url !== 'http://localhost:9001') {
121 expect(video.isLocal).to.be.false
122 } else {
123 expect(video.isLocal).to.be.true
124 }
125
126 // All pods should have the same magnet Uri
127 if (baseMagnet === null) {
128 baseMagnet = video.magnetUri
129 } else {
130 expect(video.magnetUri).to.equal.magnetUri
131 }
132
133 videosUtils.testVideoImage(server.url, 'video_short1.webm', video.thumbnailPath, function (err, test) {
134 if (err) throw err
135 expect(test).to.equal(true)
136
137 callback()
138 })
139 })
140 }, done)
141 }
142 )
143 })
144
145 it('Should upload the video on pod 2 and propagate on each pod', function (done) {
146 this.timeout(15000)
147
148 series([
149 function (next) {
150 const videoAttributes = {
151 name: 'my super name for pod 2',
152 category: 4,
153 description: 'my super description for pod 2',
154 tags: [ 'tag1p2', 'tag2p2', 'tag3p2' ],
155 fixture: 'video_short2.webm'
156 }
157 videosUtils.uploadVideo(servers[1].url, servers[1].accessToken, videoAttributes, next)
158 },
159 function (next) {
160 setTimeout(next, 11000)
161 }],
162 // All pods should have this video
163 function (err) {
164 if (err) throw err
165
166 each(servers, function (server, callback) {
167 let baseMagnet = null
168
169 videosUtils.getVideosList(server.url, function (err, res) {
170 if (err) throw err
171
172 const videos = res.body.data
173 expect(videos).to.be.an('array')
174 expect(videos.length).to.equal(2)
175 const video = videos[1]
176 expect(video.name).to.equal('my super name for pod 2')
177 expect(video.category).to.equal(4)
178 expect(video.categoryLabel).to.equal('Art')
179 expect(video.description).to.equal('my super description for pod 2')
180 expect(video.podHost).to.equal('localhost:9002')
181 expect(video.magnetUri).to.exist
182 expect(video.duration).to.equal(5)
183 expect(video.tags).to.deep.equal([ 'tag1p2', 'tag2p2', 'tag3p2' ])
184 expect(miscsUtils.dateIsValid(video.createdAt)).to.be.true
185 expect(miscsUtils.dateIsValid(video.updatedAt)).to.be.true
186 expect(video.author).to.equal('root')
187
188 if (server.url !== 'http://localhost:9002') {
189 expect(video.isLocal).to.be.false
190 } else {
191 expect(video.isLocal).to.be.true
192 }
193
194 // All pods should have the same magnet Uri
195 if (baseMagnet === null) {
196 baseMagnet = video.magnetUri
197 } else {
198 expect(video.magnetUri).to.equal.magnetUri
199 }
200
201 videosUtils.testVideoImage(server.url, 'video_short2.webm', video.thumbnailPath, function (err, test) {
202 if (err) throw err
203 expect(test).to.equal(true)
204
205 callback()
206 })
207 })
208 }, done)
209 }
210 )
211 })
212
213 it('Should upload two videos on pod 3 and propagate on each pod', function (done) {
214 this.timeout(30000)
215
216 series([
217 function (next) {
218 const videoAttributes = {
219 name: 'my super name for pod 3',
220 category: 6,
221 description: 'my super description for pod 3',
222 tags: [ 'tag1p3' ],
223 fixture: 'video_short3.webm'
224 }
225 videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes, next)
226 },
227 function (next) {
228 const videoAttributes = {
229 name: 'my super name for pod 3-2',
230 category: 7,
231 description: 'my super description for pod 3-2',
232 tags: [ 'tag2p3', 'tag3p3', 'tag4p3' ],
233 fixture: 'video_short.webm'
234 }
235 videosUtils.uploadVideo(servers[2].url, servers[2].accessToken, videoAttributes, next)
236 },
237 function (next) {
238 setTimeout(next, 22000)
239 }],
240 function (err) {
241 if (err) throw err
242
243 let baseMagnet = null
244 // All pods should have this video
245 each(servers, function (server, callback) {
246 videosUtils.getVideosList(server.url, function (err, res) {
247 if (err) throw err
248
249 const videos = res.body.data
250 expect(videos).to.be.an('array')
251 expect(videos.length).to.equal(4)
252
253 // We not sure about the order of the two last uploads
254 let video1 = null
255 let video2 = null
256 if (videos[2].name === 'my super name for pod 3') {
257 video1 = videos[2]
258 video2 = videos[3]
259 } else {
260 video1 = videos[3]
261 video2 = videos[2]
262 }
263
264 expect(video1.name).to.equal('my super name for pod 3')
265 expect(video1.category).to.equal(6)
266 expect(video1.categoryLabel).to.equal('Travels')
267 expect(video1.description).to.equal('my super description for pod 3')
268 expect(video1.podHost).to.equal('localhost:9003')
269 expect(video1.magnetUri).to.exist
270 expect(video1.duration).to.equal(5)
271 expect(video1.tags).to.deep.equal([ 'tag1p3' ])
272 expect(video1.author).to.equal('root')
273 expect(miscsUtils.dateIsValid(video1.createdAt)).to.be.true
274 expect(miscsUtils.dateIsValid(video1.updatedAt)).to.be.true
275
276 expect(video2.name).to.equal('my super name for pod 3-2')
277 expect(video2.category).to.equal(7)
278 expect(video2.categoryLabel).to.equal('Gaming')
279 expect(video2.description).to.equal('my super description for pod 3-2')
280 expect(video2.podHost).to.equal('localhost:9003')
281 expect(video2.magnetUri).to.exist
282 expect(video2.duration).to.equal(5)
283 expect(video2.tags).to.deep.equal([ 'tag2p3', 'tag3p3', 'tag4p3' ])
284 expect(video2.author).to.equal('root')
285 expect(miscsUtils.dateIsValid(video2.createdAt)).to.be.true
286 expect(miscsUtils.dateIsValid(video2.updatedAt)).to.be.true
287
288 if (server.url !== 'http://localhost:9003') {
289 expect(video1.isLocal).to.be.false
290 expect(video2.isLocal).to.be.false
291 } else {
292 expect(video1.isLocal).to.be.true
293 expect(video2.isLocal).to.be.true
294 }
295
296 // All pods should have the same magnet Uri
297 if (baseMagnet === null) {
298 baseMagnet = video2.magnetUri
299 } else {
300 expect(video2.magnetUri).to.equal.magnetUri
301 }
302
303 videosUtils.testVideoImage(server.url, 'video_short3.webm', video1.thumbnailPath, function (err, test) {
304 if (err) throw err
305 expect(test).to.equal(true)
306
307 videosUtils.testVideoImage(server.url, 'video_short.webm', video2.thumbnailPath, function (err, test) {
308 if (err) throw err
309 expect(test).to.equal(true)
310
311 callback()
312 })
313 })
314 })
315 }, done)
316 }
317 )
318 })
319 })
320
321 describe('Should seed the uploaded video', function () {
322 it('Should add the file 1 by asking pod 3', function (done) {
323 // Yes, this could be long
324 this.timeout(200000)
325
326 videosUtils.getVideosList(servers[2].url, function (err, res) {
327 if (err) throw err
328
329 const video = res.body.data[0]
330 toRemove.push(res.body.data[2])
331 toRemove.push(res.body.data[3])
332
333 webtorrent.add(video.magnetUri, function (torrent) {
334 expect(torrent.files).to.exist
335 expect(torrent.files.length).to.equal(1)
336 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
337
338 done()
339 })
340 })
341 })
342
343 it('Should add the file 2 by asking pod 1', function (done) {
344 // Yes, this could be long
345 this.timeout(200000)
346
347 videosUtils.getVideosList(servers[0].url, function (err, res) {
348 if (err) throw err
349
350 const video = res.body.data[1]
351
352 webtorrent.add(video.magnetUri, function (torrent) {
353 expect(torrent.files).to.exist
354 expect(torrent.files.length).to.equal(1)
355 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
356
357 done()
358 })
359 })
360 })
361
362 it('Should add the file 3 by asking pod 2', function (done) {
363 // Yes, this could be long
364 this.timeout(200000)
365
366 videosUtils.getVideosList(servers[1].url, function (err, res) {
367 if (err) throw err
368
369 const video = res.body.data[2]
370
371 webtorrent.add(video.magnetUri, function (torrent) {
372 expect(torrent.files).to.exist
373 expect(torrent.files.length).to.equal(1)
374 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
375
376 done()
377 })
378 })
379 })
380
381 it('Should add the file 3-2 by asking pod 1', function (done) {
382 // Yes, this could be long
383 this.timeout(200000)
384
385 videosUtils.getVideosList(servers[0].url, function (err, res) {
386 if (err) throw err
387
388 const video = res.body.data[3]
389
390 webtorrent.add(video.magnetUri, function (torrent) {
391 expect(torrent.files).to.exist
392 expect(torrent.files.length).to.equal(1)
393 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
394
395 done()
396 })
397 })
398 })
399 })
400
401 describe('Should update video views, likes and dislikes', function () {
402 let localVideosPod3 = []
403 let remoteVideosPod1 = []
404 let remoteVideosPod2 = []
405 let remoteVideosPod3 = []
406
407 before(function (done) {
408 parallel([
409 function (callback) {
410 videosUtils.getVideosList(servers[0].url, function (err, res) {
411 if (err) throw err
412
413 remoteVideosPod1 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
414
415 callback()
416 })
417 },
418
419 function (callback) {
420 videosUtils.getVideosList(servers[1].url, function (err, res) {
421 if (err) throw err
422
423 remoteVideosPod2 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
424
425 callback()
426 })
427 },
428
429 function (callback) {
430 videosUtils.getVideosList(servers[2].url, function (err, res) {
431 if (err) throw err
432
433 localVideosPod3 = res.body.data.filter(video => video.isLocal === true).map(video => video.id)
434 remoteVideosPod3 = res.body.data.filter(video => video.isLocal === false).map(video => video.id)
435
436 callback()
437 })
438 }
439 ], done)
440 })
441
442 it('Should view multiple videos on owned servers', function (done) {
443 this.timeout(30000)
444
445 parallel([
446 function (callback) {
447 videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
448 },
449
450 function (callback) {
451 videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
452 },
453
454 function (callback) {
455 videosUtils.getVideo(servers[2].url, localVideosPod3[0], callback)
456 },
457
458 function (callback) {
459 videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
460 },
461
462 function (callback) {
463 setTimeout(callback, 22000)
464 }
465 ], function (err) {
466 if (err) throw err
467
468 eachSeries(servers, function (server, callback) {
469 videosUtils.getVideosList(server.url, function (err, res) {
470 if (err) throw err
471
472 const videos = res.body.data
473 expect(videos.find(video => video.views === 3)).to.exist
474 expect(videos.find(video => video.views === 1)).to.exist
475
476 callback()
477 })
478 }, done)
479 })
480 })
481
482 it('Should view multiple videos on each servers', function (done) {
483 this.timeout(30000)
484
485 parallel([
486 function (callback) {
487 videosUtils.getVideo(servers[0].url, remoteVideosPod1[0], callback)
488 },
489
490 function (callback) {
491 videosUtils.getVideo(servers[1].url, remoteVideosPod2[0], callback)
492 },
493
494 function (callback) {
495 videosUtils.getVideo(servers[1].url, remoteVideosPod2[0], callback)
496 },
497
498 function (callback) {
499 videosUtils.getVideo(servers[2].url, remoteVideosPod3[0], callback)
500 },
501
502 function (callback) {
503 videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
504 },
505
506 function (callback) {
507 videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
508 },
509
510 function (callback) {
511 videosUtils.getVideo(servers[2].url, remoteVideosPod3[1], callback)
512 },
513
514 function (callback) {
515 videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
516 },
517
518 function (callback) {
519 videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
520 },
521
522 function (callback) {
523 videosUtils.getVideo(servers[2].url, localVideosPod3[1], callback)
524 },
525
526 function (callback) {
527 setTimeout(callback, 22000)
528 }
529 ], function (err) {
530 if (err) throw err
531
532 let baseVideos = null
533 eachSeries(servers, function (server, callback) {
534 videosUtils.getVideosList(server.url, function (err, res) {
535 if (err) throw err
536
537 const videos = res.body.data
538
539 // Initialize base videos for future comparisons
540 if (baseVideos === null) {
541 baseVideos = videos
542 return callback()
543 }
544
545 baseVideos.forEach(baseVideo => {
546 const sameVideo = videos.find(video => video.name === baseVideo.name)
547 expect(baseVideo.views).to.equal(sameVideo.views)
548 })
549
550 callback()
551 })
552 }, done)
553 })
554 })
555
556 it('Should like and dislikes videos on different services', function (done) {
557 this.timeout(30000)
558
559 parallel([
560 function (callback) {
561 videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like', callback)
562 },
563
564 function (callback) {
565 videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'dislike', callback)
566 },
567
568 function (callback) {
569 videosUtils.rateVideo(servers[0].url, servers[0].accessToken, remoteVideosPod1[0], 'like', callback)
570 },
571
572 function (callback) {
573 videosUtils.rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'like', callback)
574 },
575
576 function (callback) {
577 videosUtils.rateVideo(servers[2].url, servers[2].accessToken, localVideosPod3[1], 'dislike', callback)
578 },
579
580 function (callback) {
581 videosUtils.rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[1], 'dislike', callback)
582 },
583
584 function (callback) {
585 videosUtils.rateVideo(servers[2].url, servers[2].accessToken, remoteVideosPod3[0], 'like', callback)
586 },
587
588 function (callback) {
589 setTimeout(callback, 22000)
590 }
591 ], function (err) {
592 if (err) throw err
593
594 let baseVideos = null
595 eachSeries(servers, function (server, callback) {
596 videosUtils.getVideosList(server.url, function (err, res) {
597 if (err) throw err
598
599 const videos = res.body.data
600
601 // Initialize base videos for future comparisons
602 if (baseVideos === null) {
603 baseVideos = videos
604 return callback()
605 }
606
607 baseVideos.forEach(baseVideo => {
608 const sameVideo = videos.find(video => video.name === baseVideo.name)
609 expect(baseVideo.likes).to.equal(sameVideo.likes)
610 expect(baseVideo.dislikes).to.equal(sameVideo.dislikes)
611 })
612
613 callback()
614 })
615 }, done)
616 })
617 })
618 })
619
620 describe('Should manipulate these videos', function () {
621 it('Should update the video 3 by asking pod 3', function (done) {
622 this.timeout(15000)
623
624 const attributes = {
625 name: 'my super video updated',
626 category: 10,
627 description: 'my super description updated',
628 tags: [ 'tagup1', 'tagup2' ]
629 }
630 videosUtils.updateVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, attributes, function (err) {
631 if (err) throw err
632
633 setTimeout(done, 11000)
634 })
635 })
636
637 it('Should have the video 3 updated on each pod', function (done) {
638 this.timeout(200000)
639
640 each(servers, function (server, callback) {
641 // Avoid "duplicate torrent" errors
642 const webtorrent = new WebTorrent()
643
644 videosUtils.getVideosList(server.url, function (err, res) {
645 if (err) throw err
646
647 const videos = res.body.data
648 const videoUpdated = videos.find(function (video) {
649 return video.name === 'my super video updated'
650 })
651
652 expect(!!videoUpdated).to.be.true
653 expect(videoUpdated.category).to.equal(10)
654 expect(videoUpdated.categoryLabel).to.equal('Entertainment')
655 expect(videoUpdated.description).to.equal('my super description updated')
656 expect(videoUpdated.tags).to.deep.equal([ 'tagup1', 'tagup2' ])
657 expect(miscsUtils.dateIsValid(videoUpdated.updatedAt, 20000)).to.be.true
658
659 videosUtils.testVideoImage(server.url, 'video_short3.webm', videoUpdated.thumbnailPath, function (err, test) {
660 if (err) throw err
661 expect(test).to.equal(true)
662
663 webtorrent.add(videoUpdated.magnetUri, function (torrent) {
664 expect(torrent.files).to.exist
665 expect(torrent.files.length).to.equal(1)
666 expect(torrent.files[0].path).to.exist.and.to.not.equal('')
667
668 callback()
669 })
670 })
671 })
672 }, done)
673 })
674
675 it('Should remove the videos 3 and 3-2 by asking pod 3', function (done) {
676 this.timeout(15000)
677
678 series([
679 function (next) {
680 videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[0].id, next)
681 },
682 function (next) {
683 videosUtils.removeVideo(servers[2].url, servers[2].accessToken, toRemove[1].id, next)
684 }],
685 function (err) {
686 if (err) throw err
687 setTimeout(done, 11000)
688 }
689 )
690 })
691
692 it('Should have videos 1 and 3 on each pod', function (done) {
693 each(servers, function (server, callback) {
694 videosUtils.getVideosList(server.url, function (err, res) {
695 if (err) throw err
696
697 const videos = res.body.data
698 expect(videos).to.be.an('array')
699 expect(videos.length).to.equal(2)
700 expect(videos[0].name).not.to.equal(videos[1].name)
701 expect(videos[0].name).not.to.equal(toRemove[0].name)
702 expect(videos[1].name).not.to.equal(toRemove[0].name)
703 expect(videos[0].name).not.to.equal(toRemove[1].name)
704 expect(videos[1].name).not.to.equal(toRemove[1].name)
705
706 callback()
707 })
708 }, done)
709 })
710 })
711
712 after(function (done) {
713 servers.forEach(function (server) {
714 process.kill(-server.app.pid)
715 })
716
717 // Keep the logs if the test failed
718 if (this.ok) {
719 serversUtils.flushTests(done)
720 } else {
721 done()
722 }
723 })
724 })