aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/redundancy/redundancy.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/redundancy/redundancy.ts')
-rw-r--r--server/tests/api/redundancy/redundancy.ts298
1 files changed, 143 insertions, 155 deletions
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index 0e0a73b9d..e1a12f5f8 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -4,72 +4,63 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { readdir } from 'fs-extra' 5import { readdir } from 'fs-extra'
6import * as magnetUtil from 'magnet-uri' 6import * as magnetUtil from 'magnet-uri'
7import { join } from 'path' 7import { basename, join } from 'path'
8import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
9import { 8import {
10 checkSegmentHash, 9 checkSegmentHash,
11 checkVideoFilesWereRemoved, 10 checkVideoFilesWereRemoved,
12 cleanupTests, 11 cleanupTests,
12 createMultipleServers,
13 doubleFollow, 13 doubleFollow,
14 flushAndRunMultipleServers,
15 getFollowingListPaginationAndSort,
16 getVideo,
17 getVideoWithToken,
18 immutableAssign,
19 killallServers, 14 killallServers,
20 makeGetRequest, 15 makeRawRequest,
21 removeVideo, 16 PeerTubeServer,
22 reRunServer,
23 root, 17 root,
24 ServerInfo, 18 saveVideoInServers,
25 setAccessTokensToServers, 19 setAccessTokensToServers,
26 unfollow,
27 updateVideo,
28 uploadVideo,
29 viewVideo,
30 wait, 20 wait,
31 waitUntilLog 21 waitJobs
32} from '../../../../shared/extra-utils' 22} from '@shared/extra-utils'
33import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
34import { 23import {
35 addVideoRedundancy, 24 HttpStatusCode,
36 listVideoRedundancies, 25 VideoDetails,
37 removeVideoRedundancy, 26 VideoFile,
38 updateRedundancy 27 VideoPrivacy,
39} from '../../../../shared/extra-utils/server/redundancy' 28 VideoRedundancyStrategy,
40import { getStats } from '../../../../shared/extra-utils/server/stats' 29 VideoRedundancyStrategyWithManual
41import { ActorFollow } from '../../../../shared/models/actors' 30} from '@shared/models'
42import { VideoRedundancy, VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../../shared/models/redundancy'
43import { ServerStats } from '../../../../shared/models/server/server-stats.model'
44import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos'
45 31
46const expect = chai.expect 32const expect = chai.expect
47 33
48let servers: ServerInfo[] = [] 34let servers: PeerTubeServer[] = []
49let video1Server2UUID: string 35let video1Server2: VideoDetails
50let video1Server2Id: number
51 36
52function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) { 37async function checkMagnetWebseeds (file: VideoFile, baseWebseeds: string[], server: PeerTubeServer) {
53 const parsed = magnetUtil.decode(file.magnetUri) 38 const parsed = magnetUtil.decode(file.magnetUri)
54 39
55 for (const ws of baseWebseeds) { 40 for (const ws of baseWebseeds) {
56 const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) 41 const found = parsed.urlList.find(url => url === `${ws}${basename(file.fileUrl)}`)
57 expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined 42 expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined
58 } 43 }
59 44
60 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length) 45 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length)
46
47 for (const url of parsed.urlList) {
48 await makeRawRequest(url, HttpStatusCode.OK_200)
49 }
61} 50}
62 51
63async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) { 52async function createSingleServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) {
64 const strategies: any[] = [] 53 const strategies: any[] = []
65 54
66 if (strategy !== null) { 55 if (strategy !== null) {
67 strategies.push( 56 strategies.push(
68 immutableAssign({ 57 {
69 min_lifetime: '1 hour', 58 min_lifetime: '1 hour',
70 strategy: strategy, 59 strategy: strategy,
71 size: '400KB' 60 size: '400KB',
72 }, additionalParams) 61
62 ...additionalParams
63 }
73 ) 64 )
74 } 65 }
75 66
@@ -90,17 +81,16 @@ async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, add
90 } 81 }
91 } 82 }
92 83
93 servers = await flushAndRunMultipleServers(3, config) 84 servers = await createMultipleServers(3, config)
94 85
95 // Get the access tokens 86 // Get the access tokens
96 await setAccessTokensToServers(servers) 87 await setAccessTokensToServers(servers)
97 88
98 { 89 {
99 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' }) 90 const { id } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } })
100 video1Server2UUID = res.body.video.uuid 91 video1Server2 = await servers[1].videos.get({ id })
101 video1Server2Id = res.body.video.id
102 92
103 await viewVideo(servers[1].url, video1Server2UUID) 93 await servers[1].videos.view({ id })
104 } 94 }
105 95
106 await waitJobs(servers) 96 await waitJobs(servers)
@@ -115,55 +105,65 @@ async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, add
115 await waitJobs(servers) 105 await waitJobs(servers)
116} 106}
117 107
108async function ensureSameFilenames (videoUUID: string) {
109 let webtorrentFilenames: string[]
110 let hlsFilenames: string[]
111
112 for (const server of servers) {
113 const video = await server.videos.getWithToken({ id: videoUUID })
114
115 // Ensure we use the same filenames that the origin
116
117 const localWebtorrentFilenames = video.files.map(f => basename(f.fileUrl)).sort()
118 const localHLSFilenames = video.streamingPlaylists[0].files.map(f => basename(f.fileUrl)).sort()
119
120 if (webtorrentFilenames) expect(webtorrentFilenames).to.deep.equal(localWebtorrentFilenames)
121 else webtorrentFilenames = localWebtorrentFilenames
122
123 if (hlsFilenames) expect(hlsFilenames).to.deep.equal(localHLSFilenames)
124 else hlsFilenames = localHLSFilenames
125 }
126
127 return { webtorrentFilenames, hlsFilenames }
128}
129
118async function check1WebSeed (videoUUID?: string) { 130async function check1WebSeed (videoUUID?: string) {
119 if (!videoUUID) videoUUID = video1Server2UUID 131 if (!videoUUID) videoUUID = video1Server2.uuid
120 132
121 const webseeds = [ 133 const webseeds = [
122 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}` 134 `http://localhost:${servers[1].port}/static/webseed/`
123 ] 135 ]
124 136
125 for (const server of servers) { 137 for (const server of servers) {
126 // With token to avoid issues with video follow constraints 138 // With token to avoid issues with video follow constraints
127 const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) 139 const video = await server.videos.getWithToken({ id: videoUUID })
128 140
129 const video: VideoDetails = res.body
130 for (const f of video.files) { 141 for (const f of video.files) {
131 checkMagnetWebseeds(f, webseeds, server) 142 await checkMagnetWebseeds(f, webseeds, server)
132 } 143 }
133 } 144 }
145
146 await ensureSameFilenames(videoUUID)
134} 147}
135 148
136async function check2Webseeds (videoUUID?: string) { 149async function check2Webseeds (videoUUID?: string) {
137 if (!videoUUID) videoUUID = video1Server2UUID 150 if (!videoUUID) videoUUID = video1Server2.uuid
138 151
139 const webseeds = [ 152 const webseeds = [
140 `http://localhost:${servers[0].port}/static/redundancy/${videoUUID}`, 153 `http://localhost:${servers[0].port}/static/redundancy/`,
141 `http://localhost:${servers[1].port}/static/webseed/${videoUUID}` 154 `http://localhost:${servers[1].port}/static/webseed/`
142 ] 155 ]
143 156
144 for (const server of servers) { 157 for (const server of servers) {
145 const res = await getVideo(server.url, videoUUID) 158 const video = await server.videos.get({ id: videoUUID })
146
147 const video: VideoDetails = res.body
148 159
149 for (const file of video.files) { 160 for (const file of video.files) {
150 checkMagnetWebseeds(file, webseeds, server) 161 await checkMagnetWebseeds(file, webseeds, server)
151
152 await makeGetRequest({
153 url: servers[0].url,
154 statusCodeExpected: HttpStatusCode.OK_200,
155 path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`,
156 contentType: null
157 })
158 await makeGetRequest({
159 url: servers[1].url,
160 statusCodeExpected: HttpStatusCode.OK_200,
161 path: `/static/webseed/${videoUUID}-${file.resolution.id}.mp4`,
162 contentType: null
163 })
164 } 162 }
165 } 163 }
166 164
165 const { webtorrentFilenames } = await ensureSameFilenames(videoUUID)
166
167 const directories = [ 167 const directories = [
168 'test' + servers[0].internalServerNumber + '/redundancy', 168 'test' + servers[0].internalServerNumber + '/redundancy',
169 'test' + servers[1].internalServerNumber + '/videos' 169 'test' + servers[1].internalServerNumber + '/videos'
@@ -173,32 +173,31 @@ async function check2Webseeds (videoUUID?: string) {
173 const files = await readdir(join(root(), directory)) 173 const files = await readdir(join(root(), directory))
174 expect(files).to.have.length.at.least(4) 174 expect(files).to.have.length.at.least(4)
175 175
176 for (const resolution of [ 240, 360, 480, 720 ]) { 176 // Ensure we files exist on disk
177 expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined 177 expect(files.find(f => webtorrentFilenames.includes(f))).to.exist
178 }
179 } 178 }
180} 179}
181 180
182async function check0PlaylistRedundancies (videoUUID?: string) { 181async function check0PlaylistRedundancies (videoUUID?: string) {
183 if (!videoUUID) videoUUID = video1Server2UUID 182 if (!videoUUID) videoUUID = video1Server2.uuid
184 183
185 for (const server of servers) { 184 for (const server of servers) {
186 // With token to avoid issues with video follow constraints 185 // With token to avoid issues with video follow constraints
187 const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) 186 const video = await server.videos.getWithToken({ id: videoUUID })
188 const video: VideoDetails = res.body
189 187
190 expect(video.streamingPlaylists).to.be.an('array') 188 expect(video.streamingPlaylists).to.be.an('array')
191 expect(video.streamingPlaylists).to.have.lengthOf(1) 189 expect(video.streamingPlaylists).to.have.lengthOf(1)
192 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0) 190 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0)
193 } 191 }
192
193 await ensureSameFilenames(videoUUID)
194} 194}
195 195
196async function check1PlaylistRedundancies (videoUUID?: string) { 196async function check1PlaylistRedundancies (videoUUID?: string) {
197 if (!videoUUID) videoUUID = video1Server2UUID 197 if (!videoUUID) videoUUID = video1Server2.uuid
198 198
199 for (const server of servers) { 199 for (const server of servers) {
200 const res = await getVideo(server.url, videoUUID) 200 const video = await server.videos.get({ id: videoUUID })
201 const video: VideoDetails = res.body
202 201
203 expect(video.streamingPlaylists).to.have.lengthOf(1) 202 expect(video.streamingPlaylists).to.have.lengthOf(1)
204 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1) 203 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1)
@@ -211,13 +210,15 @@ async function check1PlaylistRedundancies (videoUUID?: string) {
211 const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls' 210 const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls'
212 const baseUrlSegment = servers[0].url + '/static/redundancy/hls' 211 const baseUrlSegment = servers[0].url + '/static/redundancy/hls'
213 212
214 const res = await getVideo(servers[0].url, videoUUID) 213 const video = await servers[0].videos.get({ id: videoUUID })
215 const hlsPlaylist = (res.body as VideoDetails).streamingPlaylists[0] 214 const hlsPlaylist = video.streamingPlaylists[0]
216 215
217 for (const resolution of [ 240, 360, 480, 720 ]) { 216 for (const resolution of [ 240, 360, 480, 720 ]) {
218 await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist) 217 await checkSegmentHash({ server: servers[1], baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist })
219 } 218 }
220 219
220 const { hlsFilenames } = await ensureSameFilenames(videoUUID)
221
221 const directories = [ 222 const directories = [
222 'test' + servers[0].internalServerNumber + '/redundancy/hls', 223 'test' + servers[0].internalServerNumber + '/redundancy/hls',
223 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls' 224 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls'
@@ -227,11 +228,8 @@ async function check1PlaylistRedundancies (videoUUID?: string) {
227 const files = await readdir(join(root(), directory, videoUUID)) 228 const files = await readdir(join(root(), directory, videoUUID))
228 expect(files).to.have.length.at.least(4) 229 expect(files).to.have.length.at.least(4)
229 230
230 for (const resolution of [ 240, 360, 480, 720 ]) { 231 // Ensure we files exist on disk
231 const filename = `${videoUUID}-${resolution}-fragmented.mp4` 232 expect(files.find(f => hlsFilenames.includes(f))).to.exist
232
233 expect(files.find(f => f === filename)).to.not.be.undefined
234 }
235 } 233 }
236} 234}
237 235
@@ -244,9 +242,7 @@ async function checkStatsGlobal (strategy: VideoRedundancyStrategyWithManual) {
244 statsLength = 2 242 statsLength = 2
245 } 243 }
246 244
247 const res = await getStats(servers[0].url) 245 const data = await servers[0].stats.get()
248 const data: ServerStats = res.body
249
250 expect(data.videosRedundancy).to.have.lengthOf(statsLength) 246 expect(data.videosRedundancy).to.have.lengthOf(statsLength)
251 247
252 const stat = data.videosRedundancy[0] 248 const stat = data.videosRedundancy[0]
@@ -272,14 +268,20 @@ async function checkStatsWithoutRedundancy (strategy: VideoRedundancyStrategyWit
272 expect(stat.totalVideos).to.equal(0) 268 expect(stat.totalVideos).to.equal(0)
273} 269}
274 270
275async function enableRedundancyOnServer1 () { 271async function findServerFollows () {
276 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true) 272 const body = await servers[0].follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
277 273 const follows = body.data
278 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' })
279 const follows: ActorFollow[] = res.body.data
280 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`) 274 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
281 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`) 275 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
282 276
277 return { server2, server3 }
278}
279
280async function enableRedundancyOnServer1 () {
281 await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: true })
282
283 const { server2, server3 } = await findServerFollows()
284
283 expect(server3).to.not.be.undefined 285 expect(server3).to.not.be.undefined
284 expect(server3.following.hostRedundancyAllowed).to.be.false 286 expect(server3.following.hostRedundancyAllowed).to.be.false
285 287
@@ -288,12 +290,9 @@ async function enableRedundancyOnServer1 () {
288} 290}
289 291
290async function disableRedundancyOnServer1 () { 292async function disableRedundancyOnServer1 () {
291 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, false) 293 await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: false })
292 294
293 const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' }) 295 const { server2, server3 } = await findServerFollows()
294 const follows: ActorFollow[] = res.body.data
295 const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`)
296 const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`)
297 296
298 expect(server3).to.not.be.undefined 297 expect(server3).to.not.be.undefined
299 expect(server3.following.hostRedundancyAllowed).to.be.false 298 expect(server3.following.hostRedundancyAllowed).to.be.false
@@ -310,7 +309,7 @@ describe('Test videos redundancy', function () {
310 before(function () { 309 before(function () {
311 this.timeout(120000) 310 this.timeout(120000)
312 311
313 return flushAndRunServers(strategy) 312 return createSingleServers(strategy)
314 }) 313 })
315 314
316 it('Should have 1 webseed on the first video', async function () { 315 it('Should have 1 webseed on the first video', async function () {
@@ -327,7 +326,7 @@ describe('Test videos redundancy', function () {
327 this.timeout(80000) 326 this.timeout(80000)
328 327
329 await waitJobs(servers) 328 await waitJobs(servers)
330 await waitUntilLog(servers[0], 'Duplicated ', 5) 329 await servers[0].servers.waitUntilLog('Duplicated ', 5)
331 await waitJobs(servers) 330 await waitJobs(servers)
332 331
333 await check2Webseeds() 332 await check2Webseeds()
@@ -346,7 +345,7 @@ describe('Test videos redundancy', function () {
346 await check1WebSeed() 345 await check1WebSeed()
347 await check0PlaylistRedundancies() 346 await check0PlaylistRedundancies()
348 347
349 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos', join('playlists', 'hls') ]) 348 await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true })
350 }) 349 })
351 350
352 after(async function () { 351 after(async function () {
@@ -360,7 +359,7 @@ describe('Test videos redundancy', function () {
360 before(function () { 359 before(function () {
361 this.timeout(120000) 360 this.timeout(120000)
362 361
363 return flushAndRunServers(strategy) 362 return createSingleServers(strategy)
364 }) 363 })
365 364
366 it('Should have 1 webseed on the first video', async function () { 365 it('Should have 1 webseed on the first video', async function () {
@@ -377,7 +376,7 @@ describe('Test videos redundancy', function () {
377 this.timeout(80000) 376 this.timeout(80000)
378 377
379 await waitJobs(servers) 378 await waitJobs(servers)
380 await waitUntilLog(servers[0], 'Duplicated ', 5) 379 await servers[0].servers.waitUntilLog('Duplicated ', 5)
381 await waitJobs(servers) 380 await waitJobs(servers)
382 381
383 await check2Webseeds() 382 await check2Webseeds()
@@ -388,7 +387,7 @@ describe('Test videos redundancy', function () {
388 it('Should unfollow on server 1 and remove duplicated videos', async function () { 387 it('Should unfollow on server 1 and remove duplicated videos', async function () {
389 this.timeout(80000) 388 this.timeout(80000)
390 389
391 await unfollow(servers[0].url, servers[0].accessToken, servers[1]) 390 await servers[0].follows.unfollow({ target: servers[1] })
392 391
393 await waitJobs(servers) 392 await waitJobs(servers)
394 await wait(5000) 393 await wait(5000)
@@ -396,7 +395,7 @@ describe('Test videos redundancy', function () {
396 await check1WebSeed() 395 await check1WebSeed()
397 await check0PlaylistRedundancies() 396 await check0PlaylistRedundancies()
398 397
399 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos' ]) 398 await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true })
400 }) 399 })
401 400
402 after(async function () { 401 after(async function () {
@@ -410,7 +409,7 @@ describe('Test videos redundancy', function () {
410 before(function () { 409 before(function () {
411 this.timeout(120000) 410 this.timeout(120000)
412 411
413 return flushAndRunServers(strategy, { min_views: 3 }) 412 return createSingleServers(strategy, { min_views: 3 })
414 }) 413 })
415 414
416 it('Should have 1 webseed on the first video', async function () { 415 it('Should have 1 webseed on the first video', async function () {
@@ -438,8 +437,8 @@ describe('Test videos redundancy', function () {
438 it('Should view 2 times the first video to have > min_views config', async function () { 437 it('Should view 2 times the first video to have > min_views config', async function () {
439 this.timeout(80000) 438 this.timeout(80000)
440 439
441 await viewVideo(servers[0].url, video1Server2UUID) 440 await servers[0].videos.view({ id: video1Server2.uuid })
442 await viewVideo(servers[2].url, video1Server2UUID) 441 await servers[2].videos.view({ id: video1Server2.uuid })
443 442
444 await wait(10000) 443 await wait(10000)
445 await waitJobs(servers) 444 await waitJobs(servers)
@@ -449,7 +448,7 @@ describe('Test videos redundancy', function () {
449 this.timeout(80000) 448 this.timeout(80000)
450 449
451 await waitJobs(servers) 450 await waitJobs(servers)
452 await waitUntilLog(servers[0], 'Duplicated ', 5) 451 await servers[0].servers.waitUntilLog('Duplicated ', 5)
453 await waitJobs(servers) 452 await waitJobs(servers)
454 453
455 await check2Webseeds() 454 await check2Webseeds()
@@ -460,12 +459,13 @@ describe('Test videos redundancy', function () {
460 it('Should remove the video and the redundancy files', async function () { 459 it('Should remove the video and the redundancy files', async function () {
461 this.timeout(20000) 460 this.timeout(20000)
462 461
463 await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID) 462 await saveVideoInServers(servers, video1Server2.uuid)
463 await servers[1].videos.remove({ id: video1Server2.uuid })
464 464
465 await waitJobs(servers) 465 await waitJobs(servers)
466 466
467 for (const server of servers) { 467 for (const server of servers) {
468 await checkVideoFilesWereRemoved(video1Server2UUID, server.internalServerNumber) 468 await checkVideoFilesWereRemoved({ server, video: server.store.videoDetails })
469 } 469 }
470 }) 470 })
471 471
@@ -480,7 +480,7 @@ describe('Test videos redundancy', function () {
480 before(async function () { 480 before(async function () {
481 this.timeout(120000) 481 this.timeout(120000)
482 482
483 await flushAndRunServers(strategy, { min_views: 3 }, false) 483 await createSingleServers(strategy, { min_views: 3 }, false)
484 }) 484 })
485 485
486 it('Should have 0 playlist redundancy on the first video', async function () { 486 it('Should have 0 playlist redundancy on the first video', async function () {
@@ -506,14 +506,14 @@ describe('Test videos redundancy', function () {
506 it('Should have 1 redundancy on the first video', async function () { 506 it('Should have 1 redundancy on the first video', async function () {
507 this.timeout(160000) 507 this.timeout(160000)
508 508
509 await viewVideo(servers[0].url, video1Server2UUID) 509 await servers[0].videos.view({ id: video1Server2.uuid })
510 await viewVideo(servers[2].url, video1Server2UUID) 510 await servers[2].videos.view({ id: video1Server2.uuid })
511 511
512 await wait(10000) 512 await wait(10000)
513 await waitJobs(servers) 513 await waitJobs(servers)
514 514
515 await waitJobs(servers) 515 await waitJobs(servers)
516 await waitUntilLog(servers[0], 'Duplicated ', 1) 516 await servers[0].servers.waitUntilLog('Duplicated ', 1)
517 await waitJobs(servers) 517 await waitJobs(servers)
518 518
519 await check1PlaylistRedundancies() 519 await check1PlaylistRedundancies()
@@ -523,12 +523,13 @@ describe('Test videos redundancy', function () {
523 it('Should remove the video and the redundancy files', async function () { 523 it('Should remove the video and the redundancy files', async function () {
524 this.timeout(20000) 524 this.timeout(20000)
525 525
526 await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID) 526 await saveVideoInServers(servers, video1Server2.uuid)
527 await servers[1].videos.remove({ id: video1Server2.uuid })
527 528
528 await waitJobs(servers) 529 await waitJobs(servers)
529 530
530 for (const server of servers) { 531 for (const server of servers) {
531 await checkVideoFilesWereRemoved(video1Server2UUID, server.internalServerNumber) 532 await checkVideoFilesWereRemoved({ server, video: server.store.videoDetails })
532 } 533 }
533 }) 534 })
534 535
@@ -541,7 +542,7 @@ describe('Test videos redundancy', function () {
541 before(function () { 542 before(function () {
542 this.timeout(120000) 543 this.timeout(120000)
543 544
544 return flushAndRunServers(null) 545 return createSingleServers(null)
545 }) 546 })
546 547
547 it('Should have 1 webseed on the first video', async function () { 548 it('Should have 1 webseed on the first video', async function () {
@@ -551,18 +552,14 @@ describe('Test videos redundancy', function () {
551 }) 552 })
552 553
553 it('Should create a redundancy on first video', async function () { 554 it('Should create a redundancy on first video', async function () {
554 await addVideoRedundancy({ 555 await servers[0].redundancy.addVideo({ videoId: video1Server2.id })
555 url: servers[0].url,
556 accessToken: servers[0].accessToken,
557 videoId: video1Server2Id
558 })
559 }) 556 })
560 557
561 it('Should have 2 webseeds on the first video', async function () { 558 it('Should have 2 webseeds on the first video', async function () {
562 this.timeout(80000) 559 this.timeout(80000)
563 560
564 await waitJobs(servers) 561 await waitJobs(servers)
565 await waitUntilLog(servers[0], 'Duplicated ', 5) 562 await servers[0].servers.waitUntilLog('Duplicated ', 5)
566 await waitJobs(servers) 563 await waitJobs(servers)
567 564
568 await check2Webseeds() 565 await check2Webseeds()
@@ -573,22 +570,15 @@ describe('Test videos redundancy', function () {
573 it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () { 570 it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () {
574 this.timeout(80000) 571 this.timeout(80000)
575 572
576 const res = await listVideoRedundancies({ 573 const body = await servers[0].redundancy.listVideos({ target: 'remote-videos' })
577 url: servers[0].url,
578 accessToken: servers[0].accessToken,
579 target: 'remote-videos'
580 })
581 574
582 const videos = res.body.data as VideoRedundancy[] 575 const videos = body.data
583 expect(videos).to.have.lengthOf(1) 576 expect(videos).to.have.lengthOf(1)
584 577
585 const video = videos[0] 578 const video = videos[0]
579
586 for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) { 580 for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) {
587 await removeVideoRedundancy({ 581 await servers[0].redundancy.removeVideo({ redundancyId: r.id })
588 url: servers[0].url,
589 accessToken: servers[0].accessToken,
590 redundancyId: r.id
591 })
592 } 582 }
593 583
594 await waitJobs(servers) 584 await waitJobs(servers)
@@ -597,7 +587,7 @@ describe('Test videos redundancy', function () {
597 await check1WebSeed() 587 await check1WebSeed()
598 await check0PlaylistRedundancies() 588 await check0PlaylistRedundancies()
599 589
600 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) 590 await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true })
601 }) 591 })
602 592
603 after(async function () { 593 after(async function () {
@@ -608,10 +598,9 @@ describe('Test videos redundancy', function () {
608 describe('Test expiration', function () { 598 describe('Test expiration', function () {
609 const strategy = 'recently-added' 599 const strategy = 'recently-added'
610 600
611 async function checkContains (servers: ServerInfo[], str: string) { 601 async function checkContains (servers: PeerTubeServer[], str: string) {
612 for (const server of servers) { 602 for (const server of servers) {
613 const res = await getVideo(server.url, video1Server2UUID) 603 const video = await server.videos.get({ id: video1Server2.uuid })
614 const video: VideoDetails = res.body
615 604
616 for (const f of video.files) { 605 for (const f of video.files) {
617 expect(f.magnetUri).to.contain(str) 606 expect(f.magnetUri).to.contain(str)
@@ -619,10 +608,9 @@ describe('Test videos redundancy', function () {
619 } 608 }
620 } 609 }
621 610
622 async function checkNotContains (servers: ServerInfo[], str: string) { 611 async function checkNotContains (servers: PeerTubeServer[], str: string) {
623 for (const server of servers) { 612 for (const server of servers) {
624 const res = await getVideo(server.url, video1Server2UUID) 613 const video = await server.videos.get({ id: video1Server2.uuid })
625 const video: VideoDetails = res.body
626 614
627 for (const f of video.files) { 615 for (const f of video.files) {
628 expect(f.magnetUri).to.not.contain(str) 616 expect(f.magnetUri).to.not.contain(str)
@@ -633,7 +621,7 @@ describe('Test videos redundancy', function () {
633 before(async function () { 621 before(async function () {
634 this.timeout(120000) 622 this.timeout(120000)
635 623
636 await flushAndRunServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) 624 await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
637 625
638 await enableRedundancyOnServer1() 626 await enableRedundancyOnServer1()
639 }) 627 })
@@ -656,7 +644,7 @@ describe('Test videos redundancy', function () {
656 it('Should stop server 1 and expire video redundancy', async function () { 644 it('Should stop server 1 and expire video redundancy', async function () {
657 this.timeout(80000) 645 this.timeout(80000)
658 646
659 killallServers([ servers[0] ]) 647 await killallServers([ servers[0] ])
660 648
661 await wait(15000) 649 await wait(15000)
662 650
@@ -675,25 +663,25 @@ describe('Test videos redundancy', function () {
675 before(async function () { 663 before(async function () {
676 this.timeout(120000) 664 this.timeout(120000)
677 665
678 await flushAndRunServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) 666 await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
679 667
680 await enableRedundancyOnServer1() 668 await enableRedundancyOnServer1()
681 669
682 await waitJobs(servers) 670 await waitJobs(servers)
683 await waitUntilLog(servers[0], 'Duplicated ', 5) 671 await servers[0].servers.waitUntilLog('Duplicated ', 5)
684 await waitJobs(servers) 672 await waitJobs(servers)
685 673
686 await check2Webseeds(video1Server2UUID) 674 await check2Webseeds()
687 await check1PlaylistRedundancies(video1Server2UUID) 675 await check1PlaylistRedundancies()
688 await checkStatsWith1Redundancy(strategy) 676 await checkStatsWith1Redundancy(strategy)
689 677
690 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2', privacy: VideoPrivacy.PRIVATE }) 678 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2', privacy: VideoPrivacy.PRIVATE } })
691 video2Server2UUID = res.body.video.uuid 679 video2Server2UUID = uuid
692 680
693 // Wait transcoding before federation 681 // Wait transcoding before federation
694 await waitJobs(servers) 682 await waitJobs(servers)
695 683
696 await updateVideo(servers[1].url, servers[1].accessToken, video2Server2UUID, { privacy: VideoPrivacy.PUBLIC }) 684 await servers[1].videos.update({ id: video2Server2UUID, attributes: { privacy: VideoPrivacy.PUBLIC } })
697 }) 685 })
698 686
699 it('Should cache video 2 webseeds on the first video', async function () { 687 it('Should cache video 2 webseeds on the first video', async function () {
@@ -707,8 +695,8 @@ describe('Test videos redundancy', function () {
707 await wait(1000) 695 await wait(1000)
708 696
709 try { 697 try {
710 await check1WebSeed(video1Server2UUID) 698 await check1WebSeed()
711 await check0PlaylistRedundancies(video1Server2UUID) 699 await check0PlaylistRedundancies()
712 700
713 await check2Webseeds(video2Server2UUID) 701 await check2Webseeds(video2Server2UUID)
714 await check1PlaylistRedundancies(video2Server2UUID) 702 await check1PlaylistRedundancies(video2Server2UUID)
@@ -725,8 +713,8 @@ describe('Test videos redundancy', function () {
725 713
726 await waitJobs(servers) 714 await waitJobs(servers)
727 715
728 killallServers([ servers[0] ]) 716 await killallServers([ servers[0] ])
729 await reRunServer(servers[0], { 717 await servers[0].run({
730 redundancy: { 718 redundancy: {
731 videos: { 719 videos: {
732 check_interval: '1 second', 720 check_interval: '1 second',
@@ -737,7 +725,7 @@ describe('Test videos redundancy', function () {
737 725
738 await waitJobs(servers) 726 await waitJobs(servers)
739 727
740 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ join('redundancy', 'hls') ]) 728 await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true })
741 }) 729 })
742 730
743 after(async function () { 731 after(async function () {