]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/redundancy/redundancy.ts
Merge branch 'release/3.3.0' into develop
[github/Chocobozzz/PeerTube.git] / server / tests / api / redundancy / redundancy.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
26370ce4 2
26370ce4 3import 'mocha'
6949a1a1
C
4import * as chai from 'chai'
5import { readdir } from 'fs-extra'
6import * as magnetUtil from 'magnet-uri'
7import { join } from 'path'
26370ce4 8import {
07b1a18a 9 checkSegmentHash,
b764380a
C
10 checkVideoFilesWereRemoved,
11 cleanupTests,
254d3579 12 createMultipleServers,
4c7e60bc 13 doubleFollow,
07b1a18a
C
14 killallServers,
15 makeGetRequest,
254d3579 16 PeerTubeServer,
4c7e60bc 17 root,
07b1a18a 18 setAccessTokensToServers,
26370ce4 19 wait,
6c5065a0 20 waitJobs
dab04709 21} from '@shared/extra-utils'
4c7e60bc 22import { HttpStatusCode, VideoPrivacy, VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '@shared/models'
26370ce4
C
23
24const expect = chai.expect
25
254d3579 26let servers: PeerTubeServer[] = []
26370ce4 27let video1Server2UUID: string
b764380a 28let video1Server2Id: number
26370ce4 29
254d3579 30function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: PeerTubeServer) {
26370ce4
C
31 const parsed = magnetUtil.decode(file.magnetUri)
32
33 for (const ws of baseWebseeds) {
34 const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`)
35 expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined
36 }
37
38 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length)
39}
40
254d3579 41async function createSingleServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) {
b764380a
C
42 const strategies: any[] = []
43
44 if (strategy !== null) {
45 strategies.push(
6c5065a0 46 {
b764380a
C
47 min_lifetime: '1 hour',
48 strategy: strategy,
6c5065a0
C
49 size: '400KB',
50
51 ...additionalParams
52 }
b764380a
C
53 )
54 }
55
26370ce4 56 const config = {
09209296 57 transcoding: {
7448551f
C
58 webtorrent: {
59 enabled: withWebtorrent
60 },
09209296
C
61 hls: {
62 enabled: true
63 }
64 },
26370ce4
C
65 redundancy: {
66 videos: {
67 check_interval: '5 seconds',
b764380a 68 strategies
26370ce4
C
69 }
70 }
71 }
b764380a 72
254d3579 73 servers = await createMultipleServers(3, config)
26370ce4
C
74
75 // Get the access tokens
76 await setAccessTokensToServers(servers)
77
78 {
89d241a7 79 const { uuid, id } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } })
d23dd9fb
C
80 video1Server2UUID = uuid
81 video1Server2Id = id
26370ce4 82
89d241a7 83 await servers[1].videos.view({ id: video1Server2UUID })
26370ce4
C
84 }
85
86 await waitJobs(servers)
87
88 // Server 1 and server 2 follow each other
a1587156 89 await doubleFollow(servers[0], servers[1])
26370ce4 90 // Server 1 and server 3 follow each other
a1587156 91 await doubleFollow(servers[0], servers[2])
26370ce4 92 // Server 2 and server 3 follow each other
a1587156 93 await doubleFollow(servers[1], servers[2])
26370ce4
C
94
95 await waitJobs(servers)
96}
97
09209296 98async function check1WebSeed (videoUUID?: string) {
26370ce4
C
99 if (!videoUUID) videoUUID = video1Server2UUID
100
101 const webseeds = [
a1587156 102 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}`
26370ce4
C
103 ]
104
105 for (const server of servers) {
09209296 106 // With token to avoid issues with video follow constraints
89d241a7 107 const video = await server.videos.getWithToken({ id: videoUUID })
26370ce4 108
09209296
C
109 for (const f of video.files) {
110 checkMagnetWebseeds(f, webseeds, server)
26370ce4
C
111 }
112 }
113}
114
09209296 115async function check2Webseeds (videoUUID?: string) {
26370ce4
C
116 if (!videoUUID) videoUUID = video1Server2UUID
117
118 const webseeds = [
a1587156
C
119 `http://localhost:${servers[0].port}/static/redundancy/${videoUUID}`,
120 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}`
26370ce4
C
121 ]
122
123 for (const server of servers) {
89d241a7 124 const video = await server.videos.get({ id: videoUUID })
26370ce4
C
125
126 for (const file of video.files) {
127 checkMagnetWebseeds(file, webseeds, server)
128
b9fffa29
C
129 await makeGetRequest({
130 url: servers[0].url,
c0e8b12e 131 expectedStatus: HttpStatusCode.OK_200,
b9fffa29
C
132 path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`,
133 contentType: null
134 })
135 await makeGetRequest({
136 url: servers[1].url,
c0e8b12e 137 expectedStatus: HttpStatusCode.OK_200,
09209296 138 path: `/static/webseed/${videoUUID}-${file.resolution.id}.mp4`,
b9fffa29
C
139 contentType: null
140 })
26370ce4
C
141 }
142 }
143
7243f84d
C
144 const directories = [
145 'test' + servers[0].internalServerNumber + '/redundancy',
146 'test' + servers[1].internalServerNumber + '/videos'
147 ]
148
149 for (const directory of directories) {
b9fffa29 150 const files = await readdir(join(root(), directory))
26370ce4
C
151 expect(files).to.have.length.at.least(4)
152
153 for (const resolution of [ 240, 360, 480, 720 ]) {
154 expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined
155 }
156 }
157}
158
09209296
C
159async function check0PlaylistRedundancies (videoUUID?: string) {
160 if (!videoUUID) videoUUID = video1Server2UUID
161
162 for (const server of servers) {
163 // With token to avoid issues with video follow constraints
89d241a7 164 const video = await server.videos.getWithToken({ id: videoUUID })
09209296
C
165
166 expect(video.streamingPlaylists).to.be.an('array')
167 expect(video.streamingPlaylists).to.have.lengthOf(1)
168 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0)
169 }
170}
171
172async function check1PlaylistRedundancies (videoUUID?: string) {
173 if (!videoUUID) videoUUID = video1Server2UUID
174
175 for (const server of servers) {
89d241a7 176 const video = await server.videos.get({ id: videoUUID })
09209296
C
177
178 expect(video.streamingPlaylists).to.have.lengthOf(1)
179 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1)
180
181 const redundancy = video.streamingPlaylists[0].redundancies[0]
182
183 expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID)
184 }
185
0b16f5f2 186 const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls'
4c280004
C
187 const baseUrlSegment = servers[0].url + '/static/redundancy/hls'
188
89d241a7 189 const video = await servers[0].videos.get({ id: videoUUID })
d23dd9fb 190 const hlsPlaylist = video.streamingPlaylists[0]
4c280004
C
191
192 for (const resolution of [ 240, 360, 480, 720 ]) {
57f879a5 193 await checkSegmentHash({ server: servers[1], baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist })
4c280004 194 }
09209296 195
7243f84d
C
196 const directories = [
197 'test' + servers[0].internalServerNumber + '/redundancy/hls',
198 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls'
199 ]
200
201 for (const directory of directories) {
09209296
C
202 const files = await readdir(join(root(), directory, videoUUID))
203 expect(files).to.have.length.at.least(4)
204
205 for (const resolution of [ 240, 360, 480, 720 ]) {
4c280004
C
206 const filename = `${videoUUID}-${resolution}-fragmented.mp4`
207
208 expect(files.find(f => f === filename)).to.not.be.undefined
09209296
C
209 }
210 }
211}
212
b764380a
C
213async function checkStatsGlobal (strategy: VideoRedundancyStrategyWithManual) {
214 let totalSize: number = null
215 let statsLength = 1
216
217 if (strategy !== 'manual') {
218 totalSize = 409600
219 statsLength = 2
220 }
221
89d241a7 222 const data = await servers[0].stats.get()
b764380a 223 expect(data.videosRedundancy).to.have.lengthOf(statsLength)
09209296 224
b764380a 225 const stat = data.videosRedundancy[0]
09209296 226 expect(stat.strategy).to.equal(strategy)
b764380a
C
227 expect(stat.totalSize).to.equal(totalSize)
228
229 return stat
230}
231
6949a1a1 232async function checkStatsWith1Redundancy (strategy: VideoRedundancyStrategyWithManual, onlyHls = false) {
b764380a
C
233 const stat = await checkStatsGlobal(strategy)
234
9e3e3617 235 expect(stat.totalUsed).to.be.at.least(1).and.below(409601)
6949a1a1 236 expect(stat.totalVideoFiles).to.equal(onlyHls ? 4 : 8)
09209296
C
237 expect(stat.totalVideos).to.equal(1)
238}
239
7448551f 240async function checkStatsWithoutRedundancy (strategy: VideoRedundancyStrategyWithManual) {
b764380a 241 const stat = await checkStatsGlobal(strategy)
09209296 242
09209296
C
243 expect(stat.totalUsed).to.equal(0)
244 expect(stat.totalVideoFiles).to.equal(0)
245 expect(stat.totalVideos).to.equal(0)
246}
247
c3d29f69 248async function findServerFollows () {
89d241a7 249 const body = await servers[0].follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
c3d29f69
C
250 const follows = body.data
251 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
252 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
253
254 return { server2, server3 }
255}
256
26370ce4 257async function enableRedundancyOnServer1 () {
89d241a7 258 await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: true })
26370ce4 259
c3d29f69 260 const { server2, server3 } = await findServerFollows()
26370ce4
C
261
262 expect(server3).to.not.be.undefined
263 expect(server3.following.hostRedundancyAllowed).to.be.false
264
265 expect(server2).to.not.be.undefined
266 expect(server2.following.hostRedundancyAllowed).to.be.true
267}
268
269async function disableRedundancyOnServer1 () {
89d241a7 270 await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: false })
26370ce4 271
c3d29f69 272 const { server2, server3 } = await findServerFollows()
26370ce4
C
273
274 expect(server3).to.not.be.undefined
275 expect(server3.following.hostRedundancyAllowed).to.be.false
276
277 expect(server2).to.not.be.undefined
278 expect(server2.following.hostRedundancyAllowed).to.be.false
279}
280
26370ce4
C
281describe('Test videos redundancy', function () {
282
283 describe('With most-views strategy', function () {
284 const strategy = 'most-views'
285
286 before(function () {
287 this.timeout(120000)
288
254d3579 289 return createSingleServers(strategy)
26370ce4
C
290 })
291
292 it('Should have 1 webseed on the first video', async function () {
09209296
C
293 await check1WebSeed()
294 await check0PlaylistRedundancies()
7448551f 295 await checkStatsWithoutRedundancy(strategy)
26370ce4
C
296 })
297
298 it('Should enable redundancy on server 1', function () {
299 return enableRedundancyOnServer1()
300 })
301
6cb3482c 302 it('Should have 2 webseeds on the first video', async function () {
09209296 303 this.timeout(80000)
26370ce4
C
304
305 await waitJobs(servers)
89d241a7 306 await servers[0].servers.waitUntilLog('Duplicated ', 5)
26370ce4
C
307 await waitJobs(servers)
308
09209296
C
309 await check2Webseeds()
310 await check1PlaylistRedundancies()
7448551f 311 await checkStatsWith1Redundancy(strategy)
26370ce4
C
312 })
313
314 it('Should undo redundancy on server 1 and remove duplicated videos', async function () {
09209296 315 this.timeout(80000)
26370ce4
C
316
317 await disableRedundancyOnServer1()
318
319 await waitJobs(servers)
320 await wait(5000)
321
09209296
C
322 await check1WebSeed()
323 await check0PlaylistRedundancies()
26370ce4 324
6c5065a0 325 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0], [ 'videos', join('playlists', 'hls') ])
26370ce4
C
326 })
327
7c3b7976
C
328 after(async function () {
329 return cleanupTests(servers)
26370ce4
C
330 })
331 })
332
333 describe('With trending strategy', function () {
334 const strategy = 'trending'
335
336 before(function () {
337 this.timeout(120000)
338
254d3579 339 return createSingleServers(strategy)
26370ce4
C
340 })
341
342 it('Should have 1 webseed on the first video', async function () {
09209296
C
343 await check1WebSeed()
344 await check0PlaylistRedundancies()
7448551f 345 await checkStatsWithoutRedundancy(strategy)
26370ce4
C
346 })
347
348 it('Should enable redundancy on server 1', function () {
349 return enableRedundancyOnServer1()
350 })
351
6cb3482c 352 it('Should have 2 webseeds on the first video', async function () {
09209296 353 this.timeout(80000)
26370ce4
C
354
355 await waitJobs(servers)
89d241a7 356 await servers[0].servers.waitUntilLog('Duplicated ', 5)
26370ce4
C
357 await waitJobs(servers)
358
09209296
C
359 await check2Webseeds()
360 await check1PlaylistRedundancies()
7448551f 361 await checkStatsWith1Redundancy(strategy)
26370ce4
C
362 })
363
364 it('Should unfollow on server 1 and remove duplicated videos', async function () {
09209296 365 this.timeout(80000)
26370ce4 366
89d241a7 367 await servers[0].follows.unfollow({ target: servers[1] })
26370ce4
C
368
369 await waitJobs(servers)
370 await wait(5000)
371
09209296
C
372 await check1WebSeed()
373 await check0PlaylistRedundancies()
26370ce4 374
6c5065a0 375 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0], [ 'videos' ])
26370ce4
C
376 })
377
7c3b7976
C
378 after(async function () {
379 await cleanupTests(servers)
26370ce4
C
380 })
381 })
382
383 describe('With recently added strategy', function () {
384 const strategy = 'recently-added'
385
386 before(function () {
387 this.timeout(120000)
388
254d3579 389 return createSingleServers(strategy, { min_views: 3 })
26370ce4
C
390 })
391
392 it('Should have 1 webseed on the first video', async function () {
09209296
C
393 await check1WebSeed()
394 await check0PlaylistRedundancies()
7448551f 395 await checkStatsWithoutRedundancy(strategy)
26370ce4
C
396 })
397
398 it('Should enable redundancy on server 1', function () {
399 return enableRedundancyOnServer1()
400 })
401
402 it('Should still have 1 webseed on the first video', async function () {
09209296 403 this.timeout(80000)
26370ce4
C
404
405 await waitJobs(servers)
406 await wait(15000)
407 await waitJobs(servers)
408
09209296
C
409 await check1WebSeed()
410 await check0PlaylistRedundancies()
7448551f 411 await checkStatsWithoutRedundancy(strategy)
26370ce4
C
412 })
413
414 it('Should view 2 times the first video to have > min_views config', async function () {
09209296 415 this.timeout(80000)
26370ce4 416
89d241a7
C
417 await servers[0].videos.view({ id: video1Server2UUID })
418 await servers[2].videos.view({ id: video1Server2UUID })
26370ce4
C
419
420 await wait(10000)
421 await waitJobs(servers)
422 })
423
6cb3482c 424 it('Should have 2 webseeds on the first video', async function () {
09209296 425 this.timeout(80000)
26370ce4
C
426
427 await waitJobs(servers)
89d241a7 428 await servers[0].servers.waitUntilLog('Duplicated ', 5)
26370ce4
C
429 await waitJobs(servers)
430
09209296
C
431 await check2Webseeds()
432 await check1PlaylistRedundancies()
7448551f 433 await checkStatsWith1Redundancy(strategy)
26370ce4
C
434 })
435
436 it('Should remove the video and the redundancy files', async function () {
437 this.timeout(20000)
438
89d241a7 439 await servers[1].videos.remove({ id: video1Server2UUID })
26370ce4
C
440
441 await waitJobs(servers)
442
443 for (const server of servers) {
6c5065a0 444 await checkVideoFilesWereRemoved(video1Server2UUID, server)
26370ce4
C
445 }
446 })
447
7c3b7976
C
448 after(async function () {
449 await cleanupTests(servers)
26370ce4
C
450 })
451 })
452
7448551f
C
453 describe('With only HLS files', function () {
454 const strategy = 'recently-added'
455
456 before(async function () {
457 this.timeout(120000)
458
254d3579 459 await createSingleServers(strategy, { min_views: 3 }, false)
7448551f
C
460 })
461
462 it('Should have 0 playlist redundancy on the first video', async function () {
463 await check1WebSeed()
464 await check0PlaylistRedundancies()
465 })
466
467 it('Should enable redundancy on server 1', function () {
468 return enableRedundancyOnServer1()
469 })
470
471 it('Should still have 0 redundancy on the first video', async function () {
472 this.timeout(80000)
473
474 await waitJobs(servers)
475 await wait(15000)
476 await waitJobs(servers)
477
478 await check0PlaylistRedundancies()
479 await checkStatsWithoutRedundancy(strategy)
480 })
481
482 it('Should have 1 redundancy on the first video', async function () {
483 this.timeout(160000)
484
89d241a7
C
485 await servers[0].videos.view({ id: video1Server2UUID })
486 await servers[2].videos.view({ id: video1Server2UUID })
7448551f
C
487
488 await wait(10000)
489 await waitJobs(servers)
490
491 await waitJobs(servers)
89d241a7 492 await servers[0].servers.waitUntilLog('Duplicated ', 1)
7448551f
C
493 await waitJobs(servers)
494
495 await check1PlaylistRedundancies()
6949a1a1 496 await checkStatsWith1Redundancy(strategy, true)
7448551f
C
497 })
498
499 it('Should remove the video and the redundancy files', async function () {
500 this.timeout(20000)
501
89d241a7 502 await servers[1].videos.remove({ id: video1Server2UUID })
7448551f
C
503
504 await waitJobs(servers)
505
506 for (const server of servers) {
6c5065a0 507 await checkVideoFilesWereRemoved(video1Server2UUID, server)
7448551f
C
508 }
509 })
6949a1a1
C
510
511 after(async function () {
512 await cleanupTests(servers)
513 })
7448551f
C
514 })
515
b764380a
C
516 describe('With manual strategy', function () {
517 before(function () {
518 this.timeout(120000)
519
254d3579 520 return createSingleServers(null)
b764380a
C
521 })
522
523 it('Should have 1 webseed on the first video', async function () {
524 await check1WebSeed()
525 await check0PlaylistRedundancies()
7448551f 526 await checkStatsWithoutRedundancy('manual')
b764380a
C
527 })
528
529 it('Should create a redundancy on first video', async function () {
89d241a7 530 await servers[0].redundancy.addVideo({ videoId: video1Server2Id })
b764380a
C
531 })
532
533 it('Should have 2 webseeds on the first video', async function () {
534 this.timeout(80000)
535
536 await waitJobs(servers)
89d241a7 537 await servers[0].servers.waitUntilLog('Duplicated ', 5)
b764380a
C
538 await waitJobs(servers)
539
540 await check2Webseeds()
541 await check1PlaylistRedundancies()
7448551f 542 await checkStatsWith1Redundancy('manual')
b764380a
C
543 })
544
545 it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () {
546 this.timeout(80000)
547
89d241a7 548 const body = await servers[0].redundancy.listVideos({ target: 'remote-videos' })
b764380a 549
dab04709 550 const videos = body.data
b764380a
C
551 expect(videos).to.have.lengthOf(1)
552
553 const video = videos[0]
dab04709 554
b764380a 555 for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) {
89d241a7 556 await servers[0].redundancy.removeVideo({ redundancyId: r.id })
b764380a
C
557 }
558
559 await waitJobs(servers)
560 await wait(5000)
561
562 await check1WebSeed()
563 await check0PlaylistRedundancies()
564
6c5065a0 565 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0], [ 'videos' ])
b764380a
C
566 })
567
568 after(async function () {
569 await cleanupTests(servers)
570 })
571 })
572
26370ce4
C
573 describe('Test expiration', function () {
574 const strategy = 'recently-added'
575
254d3579 576 async function checkContains (servers: PeerTubeServer[], str: string) {
26370ce4 577 for (const server of servers) {
89d241a7 578 const video = await server.videos.get({ id: video1Server2UUID })
26370ce4
C
579
580 for (const f of video.files) {
581 expect(f.magnetUri).to.contain(str)
582 }
583 }
584 }
585
254d3579 586 async function checkNotContains (servers: PeerTubeServer[], str: string) {
26370ce4 587 for (const server of servers) {
89d241a7 588 const video = await server.videos.get({ id: video1Server2UUID })
26370ce4
C
589
590 for (const f of video.files) {
591 expect(f.magnetUri).to.not.contain(str)
592 }
593 }
594 }
595
596 before(async function () {
597 this.timeout(120000)
598
254d3579 599 await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
26370ce4
C
600
601 await enableRedundancyOnServer1()
602 })
603
604 it('Should still have 2 webseeds after 10 seconds', async function () {
09209296 605 this.timeout(80000)
26370ce4
C
606
607 await wait(10000)
608
609 try {
7243f84d 610 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A' + servers[0].port)
26370ce4
C
611 } catch {
612 // Maybe a server deleted a redundancy in the scheduler
613 await wait(2000)
614
7243f84d 615 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A' + servers[0].port)
26370ce4
C
616 }
617 })
618
619 it('Should stop server 1 and expire video redundancy', async function () {
09209296 620 this.timeout(80000)
26370ce4 621
9293139f 622 await killallServers([ servers[0] ])
26370ce4 623
6cb3482c 624 await wait(15000)
26370ce4 625
7243f84d 626 await checkNotContains([ servers[1], servers[2] ], 'http%3A%2F%2Flocalhost%3A' + servers[0].port)
26370ce4
C
627 })
628
7c3b7976
C
629 after(async function () {
630 await cleanupTests(servers)
26370ce4
C
631 })
632 })
633
634 describe('Test file replacement', function () {
635 let video2Server2UUID: string
636 const strategy = 'recently-added'
637
638 before(async function () {
639 this.timeout(120000)
640
254d3579 641 await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
26370ce4
C
642
643 await enableRedundancyOnServer1()
644
645 await waitJobs(servers)
89d241a7 646 await servers[0].servers.waitUntilLog('Duplicated ', 5)
26370ce4
C
647 await waitJobs(servers)
648
5e8dd6e0
C
649 await check2Webseeds(video1Server2UUID)
650 await check1PlaylistRedundancies(video1Server2UUID)
7448551f 651 await checkStatsWith1Redundancy(strategy)
26370ce4 652
89d241a7 653 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2', privacy: VideoPrivacy.PRIVATE } })
d23dd9fb 654 video2Server2UUID = uuid
5e8dd6e0
C
655
656 // Wait transcoding before federation
657 await waitJobs(servers)
658
89d241a7 659 await servers[1].videos.update({ id: video2Server2UUID, attributes: { privacy: VideoPrivacy.PUBLIC } })
26370ce4
C
660 })
661
6cb3482c
C
662 it('Should cache video 2 webseeds on the first video', async function () {
663 this.timeout(120000)
26370ce4
C
664
665 await waitJobs(servers)
666
6cb3482c 667 let checked = false
26370ce4 668
6cb3482c
C
669 while (checked === false) {
670 await wait(1000)
26370ce4
C
671
672 try {
09209296
C
673 await check1WebSeed(video1Server2UUID)
674 await check0PlaylistRedundancies(video1Server2UUID)
5e8dd6e0 675
09209296
C
676 await check2Webseeds(video2Server2UUID)
677 await check1PlaylistRedundancies(video2Server2UUID)
26370ce4 678
6cb3482c
C
679 checked = true
680 } catch {
681 checked = false
26370ce4
C
682 }
683 }
684 })
685
09209296
C
686 it('Should disable strategy and remove redundancies', async function () {
687 this.timeout(80000)
688
689 await waitJobs(servers)
690
9293139f 691 await killallServers([ servers[0] ])
254d3579 692 await servers[0].run({
09209296
C
693 redundancy: {
694 videos: {
695 check_interval: '1 second',
696 strategies: []
697 }
698 }
699 })
700
701 await waitJobs(servers)
702
6c5065a0 703 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0], [ join('redundancy', 'hls') ])
09209296
C
704 })
705
7c3b7976
C
706 after(async function () {
707 await cleanupTests(servers)
26370ce4
C
708 })
709 })
710})