aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/redundancy
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/redundancy')
-rw-r--r--server/tests/api/redundancy/manage-redundancy.ts193
-rw-r--r--server/tests/api/redundancy/redundancy-constraints.ts69
-rw-r--r--server/tests/api/redundancy/redundancy.ts298
3 files changed, 234 insertions, 326 deletions
diff --git a/server/tests/api/redundancy/manage-redundancy.ts b/server/tests/api/redundancy/manage-redundancy.ts
index 4253124c8..5fd464ded 100644
--- a/server/tests/api/redundancy/manage-redundancy.ts
+++ b/server/tests/api/redundancy/manage-redundancy.ts
@@ -1,32 +1,30 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import * as chai from 'chai'
4import 'mocha' 3import 'mocha'
4import * as chai from 'chai'
5import { 5import {
6 cleanupTests, 6 cleanupTests,
7 createMultipleServers,
7 doubleFollow, 8 doubleFollow,
8 flushAndRunMultipleServers, 9 PeerTubeServer,
9 getLocalIdByUUID, 10 RedundancyCommand,
10 ServerInfo,
11 setAccessTokensToServers, 11 setAccessTokensToServers,
12 uploadVideo, 12 waitJobs
13 uploadVideoAndGetId, 13} from '@shared/extra-utils'
14 waitUntilLog 14import { VideoPrivacy, VideoRedundanciesTarget } from '@shared/models'
15} from '../../../../shared/extra-utils'
16import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
17import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy, updateRedundancy } from '@shared/extra-utils/server/redundancy'
18import { VideoPrivacy, VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
19 15
20const expect = chai.expect 16const expect = chai.expect
21 17
22describe('Test manage videos redundancy', function () { 18describe('Test manage videos redundancy', function () {
23 const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ] 19 const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ]
24 20
25 let servers: ServerInfo[] 21 let servers: PeerTubeServer[]
26 let video1Server2UUID: string 22 let video1Server2UUID: string
27 let video2Server2UUID: string 23 let video2Server2UUID: string
28 let redundanciesToRemove: number[] = [] 24 let redundanciesToRemove: number[] = []
29 25
26 let commands: RedundancyCommand[]
27
30 before(async function () { 28 before(async function () {
31 this.timeout(120000) 29 this.timeout(120000)
32 30
@@ -50,40 +48,38 @@ describe('Test manage videos redundancy', function () {
50 } 48 }
51 } 49 }
52 } 50 }
53 servers = await flushAndRunMultipleServers(3, config) 51 servers = await createMultipleServers(3, config)
54 52
55 // Get the access tokens 53 // Get the access tokens
56 await setAccessTokensToServers(servers) 54 await setAccessTokensToServers(servers)
57 55
56 commands = servers.map(s => s.redundancy)
57
58 { 58 {
59 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' }) 59 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } })
60 video1Server2UUID = res.body.video.uuid 60 video1Server2UUID = uuid
61 } 61 }
62 62
63 { 63 {
64 const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2' }) 64 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2' } })
65 video2Server2UUID = res.body.video.uuid 65 video2Server2UUID = uuid
66 } 66 }
67 67
68 await waitJobs(servers) 68 await waitJobs(servers)
69 69
70 // Server 1 and server 2 follow each other 70 // Server 1 and server 2 follow each other
71 await doubleFollow(servers[0], servers[1]) 71 await doubleFollow(servers[0], servers[1])
72 await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true) 72 await commands[0].updateRedundancy({ host: servers[1].host, redundancyAllowed: true })
73 73
74 await waitJobs(servers) 74 await waitJobs(servers)
75 }) 75 })
76 76
77 it('Should not have redundancies on server 3', async function () { 77 it('Should not have redundancies on server 3', async function () {
78 for (const target of targets) { 78 for (const target of targets) {
79 const res = await listVideoRedundancies({ 79 const body = await commands[2].listVideos({ target })
80 url: servers[2].url,
81 accessToken: servers[2].accessToken,
82 target
83 })
84 80
85 expect(res.body.total).to.equal(0) 81 expect(body.total).to.equal(0)
86 expect(res.body.data).to.have.lengthOf(0) 82 expect(body.data).to.have.lengthOf(0)
87 } 83 }
88 }) 84 })
89 85
@@ -91,31 +87,22 @@ describe('Test manage videos redundancy', function () {
91 this.timeout(120000) 87 this.timeout(120000)
92 88
93 await waitJobs(servers) 89 await waitJobs(servers)
94 await waitUntilLog(servers[0], 'Duplicated ', 10) 90 await servers[0].servers.waitUntilLog('Duplicated ', 10)
95 await waitJobs(servers) 91 await waitJobs(servers)
96 92
97 const res = await listVideoRedundancies({ 93 const body = await commands[1].listVideos({ target: 'remote-videos' })
98 url: servers[1].url,
99 accessToken: servers[1].accessToken,
100 target: 'remote-videos'
101 })
102 94
103 expect(res.body.total).to.equal(0) 95 expect(body.total).to.equal(0)
104 expect(res.body.data).to.have.lengthOf(0) 96 expect(body.data).to.have.lengthOf(0)
105 }) 97 })
106 98
107 it('Should have "my-videos" redundancies on server 2', async function () { 99 it('Should have "my-videos" redundancies on server 2', async function () {
108 this.timeout(120000) 100 this.timeout(120000)
109 101
110 const res = await listVideoRedundancies({ 102 const body = await commands[1].listVideos({ target: 'my-videos' })
111 url: servers[1].url, 103 expect(body.total).to.equal(2)
112 accessToken: servers[1].accessToken,
113 target: 'my-videos'
114 })
115
116 expect(res.body.total).to.equal(2)
117 104
118 const videos = res.body.data as VideoRedundancy[] 105 const videos = body.data
119 expect(videos).to.have.lengthOf(2) 106 expect(videos).to.have.lengthOf(2)
120 107
121 const videos1 = videos.find(v => v.uuid === video1Server2UUID) 108 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
@@ -139,28 +126,19 @@ describe('Test manage videos redundancy', function () {
139 }) 126 })
140 127
141 it('Should not have "my-videos" redundancies on server 1', async function () { 128 it('Should not have "my-videos" redundancies on server 1', async function () {
142 const res = await listVideoRedundancies({ 129 const body = await commands[0].listVideos({ target: 'my-videos' })
143 url: servers[0].url,
144 accessToken: servers[0].accessToken,
145 target: 'my-videos'
146 })
147 130
148 expect(res.body.total).to.equal(0) 131 expect(body.total).to.equal(0)
149 expect(res.body.data).to.have.lengthOf(0) 132 expect(body.data).to.have.lengthOf(0)
150 }) 133 })
151 134
152 it('Should have "remote-videos" redundancies on server 1', async function () { 135 it('Should have "remote-videos" redundancies on server 1', async function () {
153 this.timeout(120000) 136 this.timeout(120000)
154 137
155 const res = await listVideoRedundancies({ 138 const body = await commands[0].listVideos({ target: 'remote-videos' })
156 url: servers[0].url, 139 expect(body.total).to.equal(2)
157 accessToken: servers[0].accessToken,
158 target: 'remote-videos'
159 })
160 140
161 expect(res.body.total).to.equal(2) 141 const videos = body.data
162
163 const videos = res.body.data as VideoRedundancy[]
164 expect(videos).to.have.lengthOf(2) 142 expect(videos).to.have.lengthOf(2)
165 143
166 const videos1 = videos.find(v => v.uuid === video1Server2UUID) 144 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
@@ -185,81 +163,67 @@ describe('Test manage videos redundancy', function () {
185 163
186 it('Should correctly paginate and sort results', async function () { 164 it('Should correctly paginate and sort results', async function () {
187 { 165 {
188 const res = await listVideoRedundancies({ 166 const body = await commands[0].listVideos({
189 url: servers[0].url,
190 accessToken: servers[0].accessToken,
191 target: 'remote-videos', 167 target: 'remote-videos',
192 sort: 'name', 168 sort: 'name',
193 start: 0, 169 start: 0,
194 count: 2 170 count: 2
195 }) 171 })
196 172
197 const videos = res.body.data 173 const videos = body.data
198 expect(videos[0].name).to.equal('video 1 server 2') 174 expect(videos[0].name).to.equal('video 1 server 2')
199 expect(videos[1].name).to.equal('video 2 server 2') 175 expect(videos[1].name).to.equal('video 2 server 2')
200 } 176 }
201 177
202 { 178 {
203 const res = await listVideoRedundancies({ 179 const body = await commands[0].listVideos({
204 url: servers[0].url,
205 accessToken: servers[0].accessToken,
206 target: 'remote-videos', 180 target: 'remote-videos',
207 sort: '-name', 181 sort: '-name',
208 start: 0, 182 start: 0,
209 count: 2 183 count: 2
210 }) 184 })
211 185
212 const videos = res.body.data 186 const videos = body.data
213 expect(videos[0].name).to.equal('video 2 server 2') 187 expect(videos[0].name).to.equal('video 2 server 2')
214 expect(videos[1].name).to.equal('video 1 server 2') 188 expect(videos[1].name).to.equal('video 1 server 2')
215 } 189 }
216 190
217 { 191 {
218 const res = await listVideoRedundancies({ 192 const body = await commands[0].listVideos({
219 url: servers[0].url,
220 accessToken: servers[0].accessToken,
221 target: 'remote-videos', 193 target: 'remote-videos',
222 sort: '-name', 194 sort: '-name',
223 start: 1, 195 start: 1,
224 count: 1 196 count: 1
225 }) 197 })
226 198
227 const videos = res.body.data 199 expect(body.data[0].name).to.equal('video 1 server 2')
228 expect(videos[0].name).to.equal('video 1 server 2')
229 } 200 }
230 }) 201 })
231 202
232 it('Should manually add a redundancy and list it', async function () { 203 it('Should manually add a redundancy and list it', async function () {
233 this.timeout(120000) 204 this.timeout(120000)
234 205
235 const uuid = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid 206 const uuid = (await servers[1].videos.quickUpload({ name: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid
236 await waitJobs(servers) 207 await waitJobs(servers)
237 const videoId = await getLocalIdByUUID(servers[0].url, uuid) 208 const videoId = await servers[0].videos.getId({ uuid })
238 209
239 await addVideoRedundancy({ 210 await commands[0].addVideo({ videoId })
240 url: servers[0].url,
241 accessToken: servers[0].accessToken,
242 videoId
243 })
244 211
245 await waitJobs(servers) 212 await waitJobs(servers)
246 await waitUntilLog(servers[0], 'Duplicated ', 15) 213 await servers[0].servers.waitUntilLog('Duplicated ', 15)
247 await waitJobs(servers) 214 await waitJobs(servers)
248 215
249 { 216 {
250 const res = await listVideoRedundancies({ 217 const body = await commands[0].listVideos({
251 url: servers[0].url,
252 accessToken: servers[0].accessToken,
253 target: 'remote-videos', 218 target: 'remote-videos',
254 sort: '-name', 219 sort: '-name',
255 start: 0, 220 start: 0,
256 count: 5 221 count: 5
257 }) 222 })
258 223
259 const videos = res.body.data 224 const video = body.data[0]
260 expect(videos[0].name).to.equal('video 3 server 2')
261 225
262 const video = videos[0] 226 expect(video.name).to.equal('video 3 server 2')
263 expect(video.redundancies.files).to.have.lengthOf(4) 227 expect(video.redundancies.files).to.have.lengthOf(4)
264 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) 228 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
265 229
@@ -276,19 +240,15 @@ describe('Test manage videos redundancy', function () {
276 } 240 }
277 } 241 }
278 242
279 const res = await listVideoRedundancies({ 243 const body = await commands[1].listVideos({
280 url: servers[1].url,
281 accessToken: servers[1].accessToken,
282 target: 'my-videos', 244 target: 'my-videos',
283 sort: '-name', 245 sort: '-name',
284 start: 0, 246 start: 0,
285 count: 5 247 count: 5
286 }) 248 })
287 249
288 const videos = res.body.data 250 const video = body.data[0]
289 expect(videos[0].name).to.equal('video 3 server 2') 251 expect(video.name).to.equal('video 3 server 2')
290
291 const video = videos[0]
292 expect(video.redundancies.files).to.have.lengthOf(4) 252 expect(video.redundancies.files).to.have.lengthOf(4)
293 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) 253 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
294 254
@@ -307,64 +267,47 @@ describe('Test manage videos redundancy', function () {
307 this.timeout(120000) 267 this.timeout(120000)
308 268
309 for (const redundancyId of redundanciesToRemove) { 269 for (const redundancyId of redundanciesToRemove) {
310 await removeVideoRedundancy({ 270 await commands[0].removeVideo({ redundancyId })
311 url: servers[0].url,
312 accessToken: servers[0].accessToken,
313 redundancyId
314 })
315 } 271 }
316 272
317 { 273 {
318 const res = await listVideoRedundancies({ 274 const body = await commands[0].listVideos({
319 url: servers[0].url,
320 accessToken: servers[0].accessToken,
321 target: 'remote-videos', 275 target: 'remote-videos',
322 sort: '-name', 276 sort: '-name',
323 start: 0, 277 start: 0,
324 count: 5 278 count: 5
325 }) 279 })
326 280
327 const videos = res.body.data 281 const videos = body.data
328 expect(videos).to.have.lengthOf(2)
329 282
330 expect(videos[0].name).to.equal('video 2 server 2') 283 expect(videos).to.have.lengthOf(2)
331 284
332 redundanciesToRemove = []
333 const video = videos[0] 285 const video = videos[0]
286 expect(video.name).to.equal('video 2 server 2')
334 expect(video.redundancies.files).to.have.lengthOf(4) 287 expect(video.redundancies.files).to.have.lengthOf(4)
335 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) 288 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
336 289
337 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists) 290 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
338 291
339 for (const r of redundancies) { 292 redundanciesToRemove = redundancies.map(r => r.id)
340 redundanciesToRemove.push(r.id)
341 }
342 } 293 }
343 }) 294 })
344 295
345 it('Should remove another (auto) redundancy', async function () { 296 it('Should remove another (auto) redundancy', async function () {
346 { 297 for (const redundancyId of redundanciesToRemove) {
347 for (const redundancyId of redundanciesToRemove) { 298 await commands[0].removeVideo({ redundancyId })
348 await removeVideoRedundancy({ 299 }
349 url: servers[0].url,
350 accessToken: servers[0].accessToken,
351 redundancyId
352 })
353 }
354 300
355 const res = await listVideoRedundancies({ 301 const body = await commands[0].listVideos({
356 url: servers[0].url, 302 target: 'remote-videos',
357 accessToken: servers[0].accessToken, 303 sort: '-name',
358 target: 'remote-videos', 304 start: 0,
359 sort: '-name', 305 count: 5
360 start: 0, 306 })
361 count: 5
362 })
363 307
364 const videos = res.body.data 308 const videos = body.data
365 expect(videos[0].name).to.equal('video 1 server 2') 309 expect(videos).to.have.lengthOf(1)
366 expect(videos).to.have.lengthOf(1) 310 expect(videos[0].name).to.equal('video 1 server 2')
367 }
368 }) 311 })
369 312
370 after(async function () { 313 after(async function () {
diff --git a/server/tests/api/redundancy/redundancy-constraints.ts b/server/tests/api/redundancy/redundancy-constraints.ts
index 1cb1603bc..933a2c776 100644
--- a/server/tests/api/redundancy/redundancy-constraints.ts
+++ b/server/tests/api/redundancy/redundancy-constraints.ts
@@ -1,29 +1,14 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2 2
3import 'mocha' 3import 'mocha'
4import * as chai from 'chai' 4import { expect } from 'chai'
5import { listVideoRedundancies, updateRedundancy } from '@shared/extra-utils/server/redundancy' 5import { cleanupTests, createSingleServer, killallServers, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/extra-utils'
6import { VideoPrivacy } from '@shared/models' 6import { VideoPrivacy } from '@shared/models'
7import {
8 cleanupTests,
9 flushAndRunServer,
10 follow,
11 killallServers,
12 reRunServer,
13 ServerInfo,
14 setAccessTokensToServers,
15 updateVideo,
16 uploadVideo,
17 waitUntilLog
18} from '../../../../shared/extra-utils'
19import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
20
21const expect = chai.expect
22 7
23describe('Test redundancy constraints', function () { 8describe('Test redundancy constraints', function () {
24 let remoteServer: ServerInfo 9 let remoteServer: PeerTubeServer
25 let localServer: ServerInfo 10 let localServer: PeerTubeServer
26 let servers: ServerInfo[] 11 let servers: PeerTubeServer[]
27 12
28 const remoteServerConfig = { 13 const remoteServerConfig = {
29 redundancy: { 14 redundancy: {
@@ -43,38 +28,30 @@ describe('Test redundancy constraints', function () {
43 28
44 async function uploadWrapper (videoName: string) { 29 async function uploadWrapper (videoName: string) {
45 // Wait for transcoding 30 // Wait for transcoding
46 const res = await uploadVideo(localServer.url, localServer.accessToken, { name: 'to transcode', privacy: VideoPrivacy.PRIVATE }) 31 const { id } = await localServer.videos.upload({ attributes: { name: 'to transcode', privacy: VideoPrivacy.PRIVATE } })
47 await waitJobs([ localServer ]) 32 await waitJobs([ localServer ])
48 33
49 // Update video to schedule a federation 34 // Update video to schedule a federation
50 await updateVideo(localServer.url, localServer.accessToken, res.body.video.id, { name: videoName, privacy: VideoPrivacy.PUBLIC }) 35 await localServer.videos.update({ id, attributes: { name: videoName, privacy: VideoPrivacy.PUBLIC } })
51 } 36 }
52 37
53 async function getTotalRedundanciesLocalServer () { 38 async function getTotalRedundanciesLocalServer () {
54 const res = await listVideoRedundancies({ 39 const body = await localServer.redundancy.listVideos({ target: 'my-videos' })
55 url: localServer.url,
56 accessToken: localServer.accessToken,
57 target: 'my-videos'
58 })
59 40
60 return res.body.total 41 return body.total
61 } 42 }
62 43
63 async function getTotalRedundanciesRemoteServer () { 44 async function getTotalRedundanciesRemoteServer () {
64 const res = await listVideoRedundancies({ 45 const body = await remoteServer.redundancy.listVideos({ target: 'remote-videos' })
65 url: remoteServer.url,
66 accessToken: remoteServer.accessToken,
67 target: 'remote-videos'
68 })
69 46
70 return res.body.total 47 return body.total
71 } 48 }
72 49
73 before(async function () { 50 before(async function () {
74 this.timeout(120000) 51 this.timeout(120000)
75 52
76 { 53 {
77 remoteServer = await flushAndRunServer(1, remoteServerConfig) 54 remoteServer = await createSingleServer(1, remoteServerConfig)
78 } 55 }
79 56
80 { 57 {
@@ -85,7 +62,7 @@ describe('Test redundancy constraints', function () {
85 } 62 }
86 } 63 }
87 } 64 }
88 localServer = await flushAndRunServer(2, config) 65 localServer = await createSingleServer(2, config)
89 } 66 }
90 67
91 servers = [ remoteServer, localServer ] 68 servers = [ remoteServer, localServer ]
@@ -93,14 +70,14 @@ describe('Test redundancy constraints', function () {
93 // Get the access tokens 70 // Get the access tokens
94 await setAccessTokensToServers(servers) 71 await setAccessTokensToServers(servers)
95 72
96 await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 1 server 2' }) 73 await localServer.videos.upload({ attributes: { name: 'video 1 server 2' } })
97 74
98 await waitJobs(servers) 75 await waitJobs(servers)
99 76
100 // Server 1 and server 2 follow each other 77 // Server 1 and server 2 follow each other
101 await follow(remoteServer.url, [ localServer.url ], remoteServer.accessToken) 78 await remoteServer.follows.follow({ hosts: [ localServer.url ] })
102 await waitJobs(servers) 79 await waitJobs(servers)
103 await updateRedundancy(remoteServer.url, remoteServer.accessToken, localServer.host, true) 80 await remoteServer.redundancy.updateRedundancy({ host: localServer.host, redundancyAllowed: true })
104 81
105 await waitJobs(servers) 82 await waitJobs(servers)
106 }) 83 })
@@ -109,7 +86,7 @@ describe('Test redundancy constraints', function () {
109 this.timeout(120000) 86 this.timeout(120000)
110 87
111 await waitJobs(servers) 88 await waitJobs(servers)
112 await waitUntilLog(remoteServer, 'Duplicated ', 5) 89 await remoteServer.servers.waitUntilLog('Duplicated ', 5)
113 await waitJobs(servers) 90 await waitJobs(servers)
114 91
115 { 92 {
@@ -134,11 +111,11 @@ describe('Test redundancy constraints', function () {
134 } 111 }
135 } 112 }
136 await killallServers([ localServer ]) 113 await killallServers([ localServer ])
137 await reRunServer(localServer, config) 114 await localServer.run(config)
138 115
139 await uploadWrapper('video 2 server 2') 116 await uploadWrapper('video 2 server 2')
140 117
141 await waitUntilLog(remoteServer, 'Duplicated ', 10) 118 await remoteServer.servers.waitUntilLog('Duplicated ', 10)
142 await waitJobs(servers) 119 await waitJobs(servers)
143 120
144 { 121 {
@@ -163,11 +140,11 @@ describe('Test redundancy constraints', function () {
163 } 140 }
164 } 141 }
165 await killallServers([ localServer ]) 142 await killallServers([ localServer ])
166 await reRunServer(localServer, config) 143 await localServer.run(config)
167 144
168 await uploadWrapper('video 3 server 2') 145 await uploadWrapper('video 3 server 2')
169 146
170 await waitUntilLog(remoteServer, 'Duplicated ', 15) 147 await remoteServer.servers.waitUntilLog('Duplicated ', 15)
171 await waitJobs(servers) 148 await waitJobs(servers)
172 149
173 { 150 {
@@ -184,11 +161,11 @@ describe('Test redundancy constraints', function () {
184 it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () { 161 it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () {
185 this.timeout(120000) 162 this.timeout(120000)
186 163
187 await follow(localServer.url, [ remoteServer.url ], localServer.accessToken) 164 await localServer.follows.follow({ hosts: [ remoteServer.url ] })
188 await waitJobs(servers) 165 await waitJobs(servers)
189 166
190 await uploadWrapper('video 4 server 2') 167 await uploadWrapper('video 4 server 2')
191 await waitUntilLog(remoteServer, 'Duplicated ', 20) 168 await remoteServer.servers.waitUntilLog('Duplicated ', 20)
192 await waitJobs(servers) 169 await waitJobs(servers)
193 170
194 { 171 {
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 () {