aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-01-29 08:37:25 +0100
committerChocobozzz <chocobozzz@cpy.re>2019-02-11 09:13:02 +0100
commit092092969633bbcf6d4891a083ea497a7d5c3154 (patch)
tree69e82fe4f60c444cca216830e96afe143a9dac71 /server/tests/api
parent4348a27d252a3349bafa7ef4859c0e2cf060c255 (diff)
downloadPeerTube-092092969633bbcf6d4891a083ea497a7d5c3154.tar.gz
PeerTube-092092969633bbcf6d4891a083ea497a7d5c3154.tar.zst
PeerTube-092092969633bbcf6d4891a083ea497a7d5c3154.zip
Add hls support on server
Diffstat (limited to 'server/tests/api')
-rw-r--r--server/tests/api/check-params/config.ts3
-rw-r--r--server/tests/api/redundancy/redundancy.ts212
-rw-r--r--server/tests/api/server/config.ts6
-rw-r--r--server/tests/api/videos/index.ts1
-rw-r--r--server/tests/api/videos/video-hls.ts145
5 files changed, 302 insertions, 65 deletions
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts
index 4038ecbf0..07de2b5a5 100644
--- a/server/tests/api/check-params/config.ts
+++ b/server/tests/api/check-params/config.ts
@@ -65,6 +65,9 @@ describe('Test config API validators', function () {
65 '480p': true, 65 '480p': true,
66 '720p': false, 66 '720p': false,
67 '1080p': false 67 '1080p': false
68 },
69 hls: {
70 enabled: false
68 } 71 }
69 }, 72 },
70 import: { 73 import: {
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index 9d3ce8153..5b99309fb 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -17,7 +17,7 @@ import {
17 viewVideo, 17 viewVideo,
18 wait, 18 wait,
19 waitUntilLog, 19 waitUntilLog,
20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken 20 checkVideoFilesWereRemoved, removeVideo, getVideoWithToken, reRunServer
21} from '../../../../shared/utils' 21} from '../../../../shared/utils'
22import { waitJobs } from '../../../../shared/utils/server/jobs' 22import { waitJobs } from '../../../../shared/utils/server/jobs'
23 23
@@ -48,6 +48,11 @@ function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: numbe
48 48
49async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { 49async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) {
50 const config = { 50 const config = {
51 transcoding: {
52 hls: {
53 enabled: true
54 }
55 },
51 redundancy: { 56 redundancy: {
52 videos: { 57 videos: {
53 check_interval: '5 seconds', 58 check_interval: '5 seconds',
@@ -85,7 +90,7 @@ async function runServers (strategy: VideoRedundancyStrategy, additionalParams:
85 await waitJobs(servers) 90 await waitJobs(servers)
86} 91}
87 92
88async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: string) { 93async function check1WebSeed (videoUUID?: string) {
89 if (!videoUUID) videoUUID = video1Server2UUID 94 if (!videoUUID) videoUUID = video1Server2UUID
90 95
91 const webseeds = [ 96 const webseeds = [
@@ -93,47 +98,17 @@ async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: str
93 ] 98 ]
94 99
95 for (const server of servers) { 100 for (const server of servers) {
96 { 101 // With token to avoid issues with video follow constraints
97 // With token to avoid issues with video follow constraints 102 const res = await getVideoWithToken(server.url, server.accessToken, videoUUID)
98 const res = await getVideoWithToken(server.url, server.accessToken, videoUUID)
99 103
100 const video: VideoDetails = res.body 104 const video: VideoDetails = res.body
101 for (const f of video.files) { 105 for (const f of video.files) {
102 checkMagnetWebseeds(f, webseeds, server) 106 checkMagnetWebseeds(f, webseeds, server)
103 }
104 } 107 }
105 } 108 }
106} 109}
107 110
108async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) { 111async function check2Webseeds (videoUUID?: string) {
109 const res = await getStats(servers[0].url)
110 const data: ServerStats = res.body
111
112 expect(data.videosRedundancy).to.have.lengthOf(1)
113 const stat = data.videosRedundancy[0]
114
115 expect(stat.strategy).to.equal(strategy)
116 expect(stat.totalSize).to.equal(204800)
117 expect(stat.totalUsed).to.be.at.least(1).and.below(204801)
118 expect(stat.totalVideoFiles).to.equal(4)
119 expect(stat.totalVideos).to.equal(1)
120}
121
122async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) {
123 const res = await getStats(servers[0].url)
124 const data: ServerStats = res.body
125
126 expect(data.videosRedundancy).to.have.lengthOf(1)
127
128 const stat = data.videosRedundancy[0]
129 expect(stat.strategy).to.equal(strategy)
130 expect(stat.totalSize).to.equal(204800)
131 expect(stat.totalUsed).to.equal(0)
132 expect(stat.totalVideoFiles).to.equal(0)
133 expect(stat.totalVideos).to.equal(0)
134}
135
136async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: string) {
137 if (!videoUUID) videoUUID = video1Server2UUID 112 if (!videoUUID) videoUUID = video1Server2UUID
138 113
139 const webseeds = [ 114 const webseeds = [
@@ -158,7 +133,7 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
158 await makeGetRequest({ 133 await makeGetRequest({
159 url: servers[1].url, 134 url: servers[1].url,
160 statusCodeExpected: 200, 135 statusCodeExpected: 200,
161 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, 136 path: `/static/webseed/${videoUUID}-${file.resolution.id}.mp4`,
162 contentType: null 137 contentType: null
163 }) 138 })
164 } 139 }
@@ -174,6 +149,81 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
174 } 149 }
175} 150}
176 151
152async function check0PlaylistRedundancies (videoUUID?: string) {
153 if (!videoUUID) videoUUID = video1Server2UUID
154
155 for (const server of servers) {
156 // With token to avoid issues with video follow constraints
157 const res = await getVideoWithToken(server.url, server.accessToken, videoUUID)
158 const video: VideoDetails = res.body
159
160 expect(video.streamingPlaylists).to.be.an('array')
161 expect(video.streamingPlaylists).to.have.lengthOf(1)
162 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0)
163 }
164}
165
166async function check1PlaylistRedundancies (videoUUID?: string) {
167 if (!videoUUID) videoUUID = video1Server2UUID
168
169 for (const server of servers) {
170 const res = await getVideo(server.url, videoUUID)
171 const video: VideoDetails = res.body
172
173 expect(video.streamingPlaylists).to.have.lengthOf(1)
174 expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1)
175
176 const redundancy = video.streamingPlaylists[0].redundancies[0]
177
178 expect(redundancy.baseUrl).to.equal(servers[0].url + '/static/redundancy/hls/' + videoUUID)
179 }
180
181 await makeGetRequest({
182 url: servers[0].url,
183 statusCodeExpected: 200,
184 path: `/static/redundancy/hls/${videoUUID}/360_000.ts`,
185 contentType: null
186 })
187
188 for (const directory of [ 'test1/redundancy/hls', 'test2/playlists/hls' ]) {
189 const files = await readdir(join(root(), directory, videoUUID))
190 expect(files).to.have.length.at.least(4)
191
192 for (const resolution of [ 240, 360, 480, 720 ]) {
193 expect(files.find(f => f === `${resolution}_000.ts`)).to.not.be.undefined
194 expect(files.find(f => f === `${resolution}_001.ts`)).to.not.be.undefined
195 }
196 }
197}
198
199async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) {
200 const res = await getStats(servers[0].url)
201 const data: ServerStats = res.body
202
203 expect(data.videosRedundancy).to.have.lengthOf(1)
204 const stat = data.videosRedundancy[0]
205
206 expect(stat.strategy).to.equal(strategy)
207 expect(stat.totalSize).to.equal(204800)
208 expect(stat.totalUsed).to.be.at.least(1).and.below(204801)
209 expect(stat.totalVideoFiles).to.equal(4)
210 expect(stat.totalVideos).to.equal(1)
211}
212
213async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) {
214 const res = await getStats(servers[0].url)
215 const data: ServerStats = res.body
216
217 expect(data.videosRedundancy).to.have.lengthOf(1)
218
219 const stat = data.videosRedundancy[0]
220 expect(stat.strategy).to.equal(strategy)
221 expect(stat.totalSize).to.equal(204800)
222 expect(stat.totalUsed).to.equal(0)
223 expect(stat.totalVideoFiles).to.equal(0)
224 expect(stat.totalVideos).to.equal(0)
225}
226
177async function enableRedundancyOnServer1 () { 227async function enableRedundancyOnServer1 () {
178 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) 228 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true)
179 229
@@ -220,7 +270,8 @@ describe('Test videos redundancy', function () {
220 }) 270 })
221 271
222 it('Should have 1 webseed on the first video', async function () { 272 it('Should have 1 webseed on the first video', async function () {
223 await check1WebSeed(strategy) 273 await check1WebSeed()
274 await check0PlaylistRedundancies()
224 await checkStatsWith1Webseed(strategy) 275 await checkStatsWith1Webseed(strategy)
225 }) 276 })
226 277
@@ -229,27 +280,29 @@ describe('Test videos redundancy', function () {
229 }) 280 })
230 281
231 it('Should have 2 webseeds on the first video', async function () { 282 it('Should have 2 webseeds on the first video', async function () {
232 this.timeout(40000) 283 this.timeout(80000)
233 284
234 await waitJobs(servers) 285 await waitJobs(servers)
235 await waitUntilLog(servers[0], 'Duplicated ', 4) 286 await waitUntilLog(servers[0], 'Duplicated ', 5)
236 await waitJobs(servers) 287 await waitJobs(servers)
237 288
238 await check2Webseeds(strategy) 289 await check2Webseeds()
290 await check1PlaylistRedundancies()
239 await checkStatsWith2Webseed(strategy) 291 await checkStatsWith2Webseed(strategy)
240 }) 292 })
241 293
242 it('Should undo redundancy on server 1 and remove duplicated videos', async function () { 294 it('Should undo redundancy on server 1 and remove duplicated videos', async function () {
243 this.timeout(40000) 295 this.timeout(80000)
244 296
245 await disableRedundancyOnServer1() 297 await disableRedundancyOnServer1()
246 298
247 await waitJobs(servers) 299 await waitJobs(servers)
248 await wait(5000) 300 await wait(5000)
249 301
250 await check1WebSeed(strategy) 302 await check1WebSeed()
303 await check0PlaylistRedundancies()
251 304
252 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) 305 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos', join('playlists', 'hls') ])
253 }) 306 })
254 307
255 after(function () { 308 after(function () {
@@ -267,7 +320,8 @@ describe('Test videos redundancy', function () {
267 }) 320 })
268 321
269 it('Should have 1 webseed on the first video', async function () { 322 it('Should have 1 webseed on the first video', async function () {
270 await check1WebSeed(strategy) 323 await check1WebSeed()
324 await check0PlaylistRedundancies()
271 await checkStatsWith1Webseed(strategy) 325 await checkStatsWith1Webseed(strategy)
272 }) 326 })
273 327
@@ -276,25 +330,27 @@ describe('Test videos redundancy', function () {
276 }) 330 })
277 331
278 it('Should have 2 webseeds on the first video', async function () { 332 it('Should have 2 webseeds on the first video', async function () {
279 this.timeout(40000) 333 this.timeout(80000)
280 334
281 await waitJobs(servers) 335 await waitJobs(servers)
282 await waitUntilLog(servers[0], 'Duplicated ', 4) 336 await waitUntilLog(servers[0], 'Duplicated ', 5)
283 await waitJobs(servers) 337 await waitJobs(servers)
284 338
285 await check2Webseeds(strategy) 339 await check2Webseeds()
340 await check1PlaylistRedundancies()
286 await checkStatsWith2Webseed(strategy) 341 await checkStatsWith2Webseed(strategy)
287 }) 342 })
288 343
289 it('Should unfollow on server 1 and remove duplicated videos', async function () { 344 it('Should unfollow on server 1 and remove duplicated videos', async function () {
290 this.timeout(40000) 345 this.timeout(80000)
291 346
292 await unfollow(servers[0].url, servers[0].accessToken, servers[1]) 347 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
293 348
294 await waitJobs(servers) 349 await waitJobs(servers)
295 await wait(5000) 350 await wait(5000)
296 351
297 await check1WebSeed(strategy) 352 await check1WebSeed()
353 await check0PlaylistRedundancies()
298 354
299 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) 355 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ])
300 }) 356 })
@@ -314,7 +370,8 @@ describe('Test videos redundancy', function () {
314 }) 370 })
315 371
316 it('Should have 1 webseed on the first video', async function () { 372 it('Should have 1 webseed on the first video', async function () {
317 await check1WebSeed(strategy) 373 await check1WebSeed()
374 await check0PlaylistRedundancies()
318 await checkStatsWith1Webseed(strategy) 375 await checkStatsWith1Webseed(strategy)
319 }) 376 })
320 377
@@ -323,18 +380,19 @@ describe('Test videos redundancy', function () {
323 }) 380 })
324 381
325 it('Should still have 1 webseed on the first video', async function () { 382 it('Should still have 1 webseed on the first video', async function () {
326 this.timeout(40000) 383 this.timeout(80000)
327 384
328 await waitJobs(servers) 385 await waitJobs(servers)
329 await wait(15000) 386 await wait(15000)
330 await waitJobs(servers) 387 await waitJobs(servers)
331 388
332 await check1WebSeed(strategy) 389 await check1WebSeed()
390 await check0PlaylistRedundancies()
333 await checkStatsWith1Webseed(strategy) 391 await checkStatsWith1Webseed(strategy)
334 }) 392 })
335 393
336 it('Should view 2 times the first video to have > min_views config', async function () { 394 it('Should view 2 times the first video to have > min_views config', async function () {
337 this.timeout(40000) 395 this.timeout(80000)
338 396
339 await viewVideo(servers[ 0 ].url, video1Server2UUID) 397 await viewVideo(servers[ 0 ].url, video1Server2UUID)
340 await viewVideo(servers[ 2 ].url, video1Server2UUID) 398 await viewVideo(servers[ 2 ].url, video1Server2UUID)
@@ -344,13 +402,14 @@ describe('Test videos redundancy', function () {
344 }) 402 })
345 403
346 it('Should have 2 webseeds on the first video', async function () { 404 it('Should have 2 webseeds on the first video', async function () {
347 this.timeout(40000) 405 this.timeout(80000)
348 406
349 await waitJobs(servers) 407 await waitJobs(servers)
350 await waitUntilLog(servers[0], 'Duplicated ', 4) 408 await waitUntilLog(servers[0], 'Duplicated ', 5)
351 await waitJobs(servers) 409 await waitJobs(servers)
352 410
353 await check2Webseeds(strategy) 411 await check2Webseeds()
412 await check1PlaylistRedundancies()
354 await checkStatsWith2Webseed(strategy) 413 await checkStatsWith2Webseed(strategy)
355 }) 414 })
356 415
@@ -405,7 +464,7 @@ describe('Test videos redundancy', function () {
405 }) 464 })
406 465
407 it('Should still have 2 webseeds after 10 seconds', async function () { 466 it('Should still have 2 webseeds after 10 seconds', async function () {
408 this.timeout(40000) 467 this.timeout(80000)
409 468
410 await wait(10000) 469 await wait(10000)
411 470
@@ -420,7 +479,7 @@ describe('Test videos redundancy', function () {
420 }) 479 })
421 480
422 it('Should stop server 1 and expire video redundancy', async function () { 481 it('Should stop server 1 and expire video redundancy', async function () {
423 this.timeout(40000) 482 this.timeout(80000)
424 483
425 killallServers([ servers[0] ]) 484 killallServers([ servers[0] ])
426 485
@@ -446,10 +505,11 @@ describe('Test videos redundancy', function () {
446 await enableRedundancyOnServer1() 505 await enableRedundancyOnServer1()
447 506
448 await waitJobs(servers) 507 await waitJobs(servers)
449 await waitUntilLog(servers[0], 'Duplicated ', 4) 508 await waitUntilLog(servers[0], 'Duplicated ', 5)
450 await waitJobs(servers) 509 await waitJobs(servers)
451 510
452 await check2Webseeds(strategy) 511 await check2Webseeds()
512 await check1PlaylistRedundancies()
453 await checkStatsWith2Webseed(strategy) 513 await checkStatsWith2Webseed(strategy)
454 514
455 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) 515 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' })
@@ -467,8 +527,10 @@ describe('Test videos redundancy', function () {
467 await wait(1000) 527 await wait(1000)
468 528
469 try { 529 try {
470 await check1WebSeed(strategy, video1Server2UUID) 530 await check1WebSeed(video1Server2UUID)
471 await check2Webseeds(strategy, video2Server2UUID) 531 await check0PlaylistRedundancies(video1Server2UUID)
532 await check2Webseeds(video2Server2UUID)
533 await check1PlaylistRedundancies(video2Server2UUID)
472 534
473 checked = true 535 checked = true
474 } catch { 536 } catch {
@@ -477,6 +539,26 @@ describe('Test videos redundancy', function () {
477 } 539 }
478 }) 540 })
479 541
542 it('Should disable strategy and remove redundancies', async function () {
543 this.timeout(80000)
544
545 await waitJobs(servers)
546
547 killallServers([ servers[ 0 ] ])
548 await reRunServer(servers[ 0 ], {
549 redundancy: {
550 videos: {
551 check_interval: '1 second',
552 strategies: []
553 }
554 }
555 })
556
557 await waitJobs(servers)
558
559 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ join('redundancy', 'hls') ])
560 })
561
480 after(function () { 562 after(function () {
481 return cleanServers() 563 return cleanServers()
482 }) 564 })
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index bebfc7398..0dfe6e4fe 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -57,6 +57,8 @@ function checkInitialConfig (data: CustomConfig) {
57 expect(data.transcoding.resolutions['480p']).to.be.true 57 expect(data.transcoding.resolutions['480p']).to.be.true
58 expect(data.transcoding.resolutions['720p']).to.be.true 58 expect(data.transcoding.resolutions['720p']).to.be.true
59 expect(data.transcoding.resolutions['1080p']).to.be.true 59 expect(data.transcoding.resolutions['1080p']).to.be.true
60 expect(data.transcoding.hls.enabled).to.be.true
61
60 expect(data.import.videos.http.enabled).to.be.true 62 expect(data.import.videos.http.enabled).to.be.true
61 expect(data.import.videos.torrent.enabled).to.be.true 63 expect(data.import.videos.torrent.enabled).to.be.true
62} 64}
@@ -95,6 +97,7 @@ function checkUpdatedConfig (data: CustomConfig) {
95 expect(data.transcoding.resolutions['480p']).to.be.true 97 expect(data.transcoding.resolutions['480p']).to.be.true
96 expect(data.transcoding.resolutions['720p']).to.be.false 98 expect(data.transcoding.resolutions['720p']).to.be.false
97 expect(data.transcoding.resolutions['1080p']).to.be.false 99 expect(data.transcoding.resolutions['1080p']).to.be.false
100 expect(data.transcoding.hls.enabled).to.be.false
98 101
99 expect(data.import.videos.http.enabled).to.be.false 102 expect(data.import.videos.http.enabled).to.be.false
100 expect(data.import.videos.torrent.enabled).to.be.false 103 expect(data.import.videos.torrent.enabled).to.be.false
@@ -205,6 +208,9 @@ describe('Test config', function () {
205 '480p': true, 208 '480p': true,
206 '720p': false, 209 '720p': false,
207 '1080p': false 210 '1080p': false
211 },
212 hls: {
213 enabled: false
208 } 214 }
209 }, 215 },
210 import: { 216 import: {
diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts
index 97f467aae..a501a80b2 100644
--- a/server/tests/api/videos/index.ts
+++ b/server/tests/api/videos/index.ts
@@ -8,6 +8,7 @@ import './video-change-ownership'
8import './video-channels' 8import './video-channels'
9import './video-comments' 9import './video-comments'
10import './video-description' 10import './video-description'
11import './video-hls'
11import './video-imports' 12import './video-imports'
12import './video-nsfw' 13import './video-nsfw'
13import './video-privacy' 14import './video-privacy'
diff --git a/server/tests/api/videos/video-hls.ts b/server/tests/api/videos/video-hls.ts
new file mode 100644
index 000000000..71d863b12
--- /dev/null
+++ b/server/tests/api/videos/video-hls.ts
@@ -0,0 +1,145 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 checkDirectoryIsEmpty,
7 checkTmpIsEmpty,
8 doubleFollow,
9 flushAndRunMultipleServers,
10 flushTests,
11 getPlaylist,
12 getSegment,
13 getSegmentSha256,
14 getVideo,
15 killallServers,
16 removeVideo,
17 ServerInfo,
18 setAccessTokensToServers,
19 updateVideo,
20 uploadVideo,
21 waitJobs
22} from '../../../../shared/utils'
23import { VideoDetails } from '../../../../shared/models/videos'
24import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
25import { sha256 } from '../../../helpers/core-utils'
26import { join } from 'path'
27
28const expect = chai.expect
29
30async function checkHlsPlaylist (servers: ServerInfo[], videoUUID: string) {
31 const resolutions = [ 240, 360, 480, 720 ]
32
33 for (const server of servers) {
34 const res = await getVideo(server.url, videoUUID)
35 const videoDetails: VideoDetails = res.body
36
37 expect(videoDetails.streamingPlaylists).to.have.lengthOf(1)
38
39 const hlsPlaylist = videoDetails.streamingPlaylists.find(p => p.type === VideoStreamingPlaylistType.HLS)
40 expect(hlsPlaylist).to.not.be.undefined
41
42 {
43 const res2 = await getPlaylist(hlsPlaylist.playlistUrl)
44
45 const masterPlaylist = res2.text
46
47 expect(masterPlaylist).to.contain('#EXT-X-STREAM-INF:BANDWIDTH=55472,RESOLUTION=640x360,FRAME-RATE=25')
48
49 for (const resolution of resolutions) {
50 expect(masterPlaylist).to.contain(`${resolution}.m3u8`)
51 }
52 }
53
54 {
55 for (const resolution of resolutions) {
56 const res2 = await getPlaylist(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}.m3u8`)
57
58 const subPlaylist = res2.text
59 expect(subPlaylist).to.contain(resolution + '_000.ts')
60 }
61 }
62
63 {
64 for (const resolution of resolutions) {
65
66 const res2 = await getSegment(`http://localhost:9001/static/playlists/hls/${videoUUID}/${resolution}_000.ts`)
67
68 const resSha = await getSegmentSha256(hlsPlaylist.segmentsSha256Url)
69
70 const sha256Server = resSha.body[ resolution + '_000.ts' ]
71 expect(sha256(res2.body)).to.equal(sha256Server)
72 }
73 }
74 }
75}
76
77describe('Test HLS videos', function () {
78 let servers: ServerInfo[] = []
79 let videoUUID = ''
80
81 before(async function () {
82 this.timeout(120000)
83
84 servers = await flushAndRunMultipleServers(2, { transcoding: { enabled: true, hls: { enabled: true } } })
85
86 // Get the access tokens
87 await setAccessTokensToServers(servers)
88
89 // Server 1 and server 2 follow each other
90 await doubleFollow(servers[0], servers[1])
91 })
92
93 it('Should upload a video and transcode it to HLS', async function () {
94 this.timeout(120000)
95
96 {
97 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video 1', fixture: 'video_short.webm' })
98 videoUUID = res.body.video.uuid
99 }
100
101 await waitJobs(servers)
102
103 await checkHlsPlaylist(servers, videoUUID)
104 })
105
106 it('Should update the video', async function () {
107 await updateVideo(servers[0].url, servers[0].accessToken, videoUUID, { name: 'video 1 updated' })
108
109 await waitJobs(servers)
110
111 await checkHlsPlaylist(servers, videoUUID)
112 })
113
114 it('Should delete the video', async function () {
115 await removeVideo(servers[0].url, servers[0].accessToken, videoUUID)
116
117 await waitJobs(servers)
118
119 for (const server of servers) {
120 await getVideo(server.url, videoUUID, 404)
121 }
122 })
123
124 it('Should have the playlists/segment deleted from the disk', async function () {
125 for (const server of servers) {
126 await checkDirectoryIsEmpty(server, 'videos')
127 await checkDirectoryIsEmpty(server, join('playlists', 'hls'))
128 }
129 })
130
131 it('Should have an empty tmp directory', async function () {
132 for (const server of servers) {
133 await checkTmpIsEmpty(server)
134 }
135 })
136
137 after(async function () {
138 killallServers(servers)
139
140 // Keep the logs if the test failed
141 if (this['ok']) {
142 await flushTests()
143 }
144 })
145})