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