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