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