aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api')
-rw-r--r--server/tests/api/server/redundancy.ts264
1 files changed, 191 insertions, 73 deletions
diff --git a/server/tests/api/server/redundancy.ts b/server/tests/api/server/redundancy.ts
index 6ce4b9dd1..a773e3de4 100644
--- a/server/tests/api/server/redundancy.ts
+++ b/server/tests/api/server/redundancy.ts
@@ -31,14 +31,13 @@ const expect = chai.expect
31 31
32let servers: ServerInfo[] = [] 32let servers: ServerInfo[] = []
33let video1Server2UUID: string 33let video1Server2UUID: string
34let video2Server2UUID: string
35 34
36function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[]) { 35function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) {
37 const parsed = magnetUtil.decode(file.magnetUri) 36 const parsed = magnetUtil.decode(file.magnetUri)
38 37
39 for (const ws of baseWebseeds) { 38 for (const ws of baseWebseeds) {
40 const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) 39 const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`)
41 expect(found, `Webseed ${ws} not found in ${file.magnetUri}`).to.not.be.undefined 40 expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined
42 } 41 }
43} 42}
44 43
@@ -49,6 +48,7 @@ async function runServers (strategy: VideoRedundancyStrategy, additionalParams:
49 check_interval: '5 seconds', 48 check_interval: '5 seconds',
50 strategies: [ 49 strategies: [
51 immutableAssign({ 50 immutableAssign({
51 min_lifetime: '1 hour',
52 strategy: strategy, 52 strategy: strategy,
53 size: '100KB' 53 size: '100KB'
54 }, additionalParams) 54 }, additionalParams)
@@ -68,11 +68,6 @@ async function runServers (strategy: VideoRedundancyStrategy, additionalParams:
68 await viewVideo(servers[ 1 ].url, video1Server2UUID) 68 await viewVideo(servers[ 1 ].url, video1Server2UUID)
69 } 69 }
70 70
71 {
72 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' })
73 video2Server2UUID = res.body.video.uuid
74 }
75
76 await waitJobs(servers) 71 await waitJobs(servers)
77 72
78 // Server 1 and server 2 follow each other 73 // Server 1 and server 2 follow each other
@@ -85,68 +80,69 @@ async function runServers (strategy: VideoRedundancyStrategy, additionalParams:
85 await waitJobs(servers) 80 await waitJobs(servers)
86} 81}
87 82
88async function check1WebSeed (strategy: VideoRedundancyStrategy) { 83async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: string) {
84 if (!videoUUID) videoUUID = video1Server2UUID
85
89 const webseeds = [ 86 const webseeds = [
90 'http://localhost:9002/static/webseed/' + video1Server2UUID 87 'http://localhost:9002/static/webseed/' + videoUUID
91 ] 88 ]
92 89
93 for (const server of servers) { 90 for (const server of servers) {
94 { 91 {
95 const res = await getVideo(server.url, video1Server2UUID) 92 const res = await getVideo(server.url, videoUUID)
96 93
97 const video: VideoDetails = res.body 94 const video: VideoDetails = res.body
98 video.files.forEach(f => checkMagnetWebseeds(f, webseeds)) 95 for (const f of video.files) {
96 checkMagnetWebseeds(f, webseeds, server)
97 }
99 } 98 }
99 }
100}
100 101
101 { 102async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) {
102 const res = await getStats(server.url) 103 const res = await getStats(servers[0].url)
103 const data: ServerStats = res.body 104 const data: ServerStats = res.body
104 105
105 expect(data.videosRedundancy).to.have.lengthOf(1) 106 expect(data.videosRedundancy).to.have.lengthOf(1)
107 const stat = data.videosRedundancy[0]
106 108
107 const stat = data.videosRedundancy[0] 109 expect(stat.strategy).to.equal(strategy)
108 expect(stat.strategy).to.equal(strategy) 110 expect(stat.totalSize).to.equal(102400)
109 expect(stat.totalSize).to.equal(102400) 111 expect(stat.totalUsed).to.be.at.least(1).and.below(102401)
110 expect(stat.totalUsed).to.equal(0) 112 expect(stat.totalVideoFiles).to.equal(4)
111 expect(stat.totalVideoFiles).to.equal(0) 113 expect(stat.totalVideos).to.equal(1)
112 expect(stat.totalVideos).to.equal(0)
113 }
114 }
115} 114}
116 115
117async function enableRedundancy () { 116async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) {
118 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) 117 const res = await getStats(servers[0].url)
118 const data: ServerStats = res.body
119 119
120 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') 120 expect(data.videosRedundancy).to.have.lengthOf(1)
121 const follows: ActorFollow[] = res.body.data
122 const server2 = follows.find(f => f.following.host === 'localhost:9002')
123 const server3 = follows.find(f => f.following.host === 'localhost:9003')
124
125 expect(server3).to.not.be.undefined
126 expect(server3.following.hostRedundancyAllowed).to.be.false
127 121
128 expect(server2).to.not.be.undefined 122 const stat = data.videosRedundancy[0]
129 expect(server2.following.hostRedundancyAllowed).to.be.true 123 expect(stat.strategy).to.equal(strategy)
124 expect(stat.totalSize).to.equal(102400)
125 expect(stat.totalUsed).to.equal(0)
126 expect(stat.totalVideoFiles).to.equal(0)
127 expect(stat.totalVideos).to.equal(0)
130} 128}
131 129
132async function check2Webseeds (strategy: VideoRedundancyStrategy) { 130async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: string) {
133 await waitJobs(servers) 131 if (!videoUUID) videoUUID = video1Server2UUID
134 await wait(15000)
135 await waitJobs(servers)
136 132
137 const webseeds = [ 133 const webseeds = [
138 'http://localhost:9001/static/webseed/' + video1Server2UUID, 134 'http://localhost:9001/static/webseed/' + videoUUID,
139 'http://localhost:9002/static/webseed/' + video1Server2UUID 135 'http://localhost:9002/static/webseed/' + videoUUID
140 ] 136 ]
141 137
142 for (const server of servers) { 138 for (const server of servers) {
143 { 139 {
144 const res = await getVideo(server.url, video1Server2UUID) 140 const res = await getVideo(server.url, videoUUID)
145 141
146 const video: VideoDetails = res.body 142 const video: VideoDetails = res.body
147 143
148 for (const file of video.files) { 144 for (const file of video.files) {
149 checkMagnetWebseeds(file, webseeds) 145 checkMagnetWebseeds(file, webseeds, server)
150 } 146 }
151 } 147 }
152 } 148 }
@@ -155,22 +151,23 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy) {
155 expect(files).to.have.lengthOf(4) 151 expect(files).to.have.lengthOf(4)
156 152
157 for (const resolution of [ 240, 360, 480, 720 ]) { 153 for (const resolution of [ 240, 360, 480, 720 ]) {
158 expect(files.find(f => f === `${video1Server2UUID}-${resolution}.mp4`)).to.not.be.undefined 154 expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined
159 } 155 }
156}
160 157
161 { 158async function enableRedundancyOnServer1 () {
162 const res = await getStats(servers[0].url) 159 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true)
163 const data: ServerStats = res.body
164 160
165 expect(data.videosRedundancy).to.have.lengthOf(1) 161 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt')
166 const stat = data.videosRedundancy[0] 162 const follows: ActorFollow[] = res.body.data
163 const server2 = follows.find(f => f.following.host === 'localhost:9002')
164 const server3 = follows.find(f => f.following.host === 'localhost:9003')
167 165
168 expect(stat.strategy).to.equal(strategy) 166 expect(server3).to.not.be.undefined
169 expect(stat.totalSize).to.equal(102400) 167 expect(server3.following.hostRedundancyAllowed).to.be.false
170 expect(stat.totalUsed).to.be.at.least(1).and.below(102401) 168
171 expect(stat.totalVideoFiles).to.equal(4) 169 expect(server2).to.not.be.undefined
172 expect(stat.totalVideos).to.equal(1) 170 expect(server2.following.hostRedundancyAllowed).to.be.true
173 }
174} 171}
175 172
176async function cleanServers () { 173async function cleanServers () {
@@ -188,18 +185,24 @@ describe('Test videos redundancy', function () {
188 return runServers(strategy) 185 return runServers(strategy)
189 }) 186 })
190 187
191 it('Should have 1 webseed on the first video', function () { 188 it('Should have 1 webseed on the first video', async function () {
192 return check1WebSeed(strategy) 189 await check1WebSeed(strategy)
190 await checkStatsWith1Webseed(strategy)
193 }) 191 })
194 192
195 it('Should enable redundancy on server 1', function () { 193 it('Should enable redundancy on server 1', function () {
196 return enableRedundancy() 194 return enableRedundancyOnServer1()
197 }) 195 })
198 196
199 it('Should have 2 webseed on the first video', function () { 197 it('Should have 2 webseed on the first video', async function () {
200 this.timeout(40000) 198 this.timeout(40000)
201 199
202 return check2Webseeds(strategy) 200 await waitJobs(servers)
201 await wait(15000)
202 await waitJobs(servers)
203
204 await check2Webseeds(strategy)
205 await checkStatsWith2Webseed(strategy)
203 }) 206 })
204 207
205 after(function () { 208 after(function () {
@@ -216,18 +219,24 @@ describe('Test videos redundancy', function () {
216 return runServers(strategy) 219 return runServers(strategy)
217 }) 220 })
218 221
219 it('Should have 1 webseed on the first video', function () { 222 it('Should have 1 webseed on the first video', async function () {
220 return check1WebSeed(strategy) 223 await check1WebSeed(strategy)
224 await checkStatsWith1Webseed(strategy)
221 }) 225 })
222 226
223 it('Should enable redundancy on server 1', function () { 227 it('Should enable redundancy on server 1', function () {
224 return enableRedundancy() 228 return enableRedundancyOnServer1()
225 }) 229 })
226 230
227 it('Should have 2 webseed on the first video', function () { 231 it('Should have 2 webseed on the first video', async function () {
228 this.timeout(40000) 232 this.timeout(40000)
229 233
230 return check2Webseeds(strategy) 234 await waitJobs(servers)
235 await wait(15000)
236 await waitJobs(servers)
237
238 await check2Webseeds(strategy)
239 await checkStatsWith2Webseed(strategy)
231 }) 240 })
232 241
233 after(function () { 242 after(function () {
@@ -241,15 +250,16 @@ describe('Test videos redundancy', function () {
241 before(function () { 250 before(function () {
242 this.timeout(120000) 251 this.timeout(120000)
243 252
244 return runServers(strategy, { minViews: 3 }) 253 return runServers(strategy, { min_views: 3 })
245 }) 254 })
246 255
247 it('Should have 1 webseed on the first video', function () { 256 it('Should have 1 webseed on the first video', async function () {
248 return check1WebSeed(strategy) 257 await check1WebSeed(strategy)
258 await checkStatsWith1Webseed(strategy)
249 }) 259 })
250 260
251 it('Should enable redundancy on server 1', function () { 261 it('Should enable redundancy on server 1', function () {
252 return enableRedundancy() 262 return enableRedundancyOnServer1()
253 }) 263 })
254 264
255 it('Should still have 1 webseed on the first video', async function () { 265 it('Should still have 1 webseed on the first video', async function () {
@@ -259,10 +269,11 @@ describe('Test videos redundancy', function () {
259 await wait(15000) 269 await wait(15000)
260 await waitJobs(servers) 270 await waitJobs(servers)
261 271
262 return check1WebSeed(strategy) 272 await check1WebSeed(strategy)
273 await checkStatsWith1Webseed(strategy)
263 }) 274 })
264 275
265 it('Should view 2 times the first video', async function () { 276 it('Should view 2 times the first video to have > min_views config', async function () {
266 this.timeout(40000) 277 this.timeout(40000)
267 278
268 await viewVideo(servers[ 0 ].url, video1Server2UUID) 279 await viewVideo(servers[ 0 ].url, video1Server2UUID)
@@ -272,10 +283,117 @@ describe('Test videos redundancy', function () {
272 await waitJobs(servers) 283 await waitJobs(servers)
273 }) 284 })
274 285
275 it('Should have 2 webseed on the first video', function () { 286 it('Should have 2 webseed on the first video', async function () {
276 this.timeout(40000) 287 this.timeout(40000)
277 288
278 return check2Webseeds(strategy) 289 await waitJobs(servers)
290 await wait(15000)
291 await waitJobs(servers)
292
293 await check2Webseeds(strategy)
294 await checkStatsWith2Webseed(strategy)
295 })
296
297 after(function () {
298 return cleanServers()
299 })
300 })
301
302 describe('Test expiration', function () {
303 const strategy = 'recently-added'
304
305 async function checkContains (servers: ServerInfo[], str: string) {
306 for (const server of servers) {
307 const res = await getVideo(server.url, video1Server2UUID)
308 const video: VideoDetails = res.body
309
310 for (const f of video.files) {
311 expect(f.magnetUri).to.contain(str)
312 }
313 }
314 }
315
316 async function checkNotContains (servers: ServerInfo[], str: string) {
317 for (const server of servers) {
318 const res = await getVideo(server.url, video1Server2UUID)
319 const video: VideoDetails = res.body
320
321 for (const f of video.files) {
322 expect(f.magnetUri).to.not.contain(str)
323 }
324 }
325 }
326
327 before(async function () {
328 this.timeout(120000)
329
330 await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
331
332 await enableRedundancyOnServer1()
333 })
334
335 it('Should still have 2 webseeds after 10 seconds', async function () {
336 this.timeout(40000)
337
338 await wait(10000)
339
340 try {
341 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001')
342 } catch {
343 // Maybe a server deleted a redundancy in the scheduler
344 await wait(2000)
345
346 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001')
347 }
348 })
349
350 it('Should stop server 1 and expire video redundancy', async function () {
351 this.timeout(40000)
352
353 killallServers([ servers[0] ])
354
355 await wait(10000)
356
357 await checkNotContains([ servers[1], servers[2] ], 'http%3A%2F%2Flocalhost%3A9001')
358 })
359
360 after(function () {
361 return killallServers([ servers[1], servers[2] ])
362 })
363 })
364
365 describe('Test file replacement', function () {
366 let video2Server2UUID: string
367 const strategy = 'recently-added'
368
369 before(async function () {
370 this.timeout(120000)
371
372 await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
373
374 await enableRedundancyOnServer1()
375
376 await waitJobs(servers)
377 await wait(5000)
378 await waitJobs(servers)
379
380 await check2Webseeds(strategy)
381 await checkStatsWith2Webseed(strategy)
382
383 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' })
384 video2Server2UUID = res.body.video.uuid
385 })
386
387 it('Should cache video 2 webseed on the first video', async function () {
388 this.timeout(40000)
389 this.retries(3)
390
391 await waitJobs(servers)
392
393 await wait(7000)
394
395 await check1WebSeed(strategy, video1Server2UUID)
396 await check2Webseeds(strategy, video2Server2UUID)
279 }) 397 })
280 398
281 after(function () { 399 after(function () {