]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/shared/live.ts
Update upluad artifacts
[github/Chocobozzz/PeerTube.git] / server / tests / shared / live.ts
CommitLineData
c55e3d72
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { pathExists, readdir } from 'fs-extra'
5import { join } from 'path'
cfd57d2c
C
6import { LiveVideo, VideoStreamingPlaylistType } from '@shared/models'
7import { ObjectStorageCommand, PeerTubeServer } from '@shared/server-commands'
8import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist } from './streaming-playlists'
c55e3d72 9
4ec52d04 10async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, savedResolutions: number[] = []) {
c55e3d72
C
11 const basePath = server.servers.buildDirectory('streaming-playlists')
12 const hlsPath = join(basePath, 'hls', videoUUID)
13
4ec52d04 14 if (savedResolutions.length === 0) {
cfd57d2c
C
15 return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
16 }
17
18 return checkSavedLiveCleanup(hlsPath, savedResolutions)
19}
20
21// ---------------------------------------------------------------------------
5333788c 22
cfd57d2c
C
23async function testVideoResolutions (options: {
24 originServer: PeerTubeServer
25 servers: PeerTubeServer[]
26 liveVideoId: string
27 resolutions: number[]
28 transcoded: boolean
29 objectStorage: boolean
30}) {
31 const { originServer, servers, liveVideoId, resolutions, transcoded, objectStorage } = options
5333788c 32
cfd57d2c
C
33 for (const server of servers) {
34 const { data } = await server.videos.list()
35 expect(data.find(v => v.uuid === liveVideoId)).to.exist
5333788c 36
cfd57d2c
C
37 const video = await server.videos.get({ id: liveVideoId })
38 expect(video.streamingPlaylists).to.have.lengthOf(1)
5333788c 39
cfd57d2c
C
40 const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS)
41 expect(hlsPlaylist).to.exist
42 expect(hlsPlaylist.files).to.have.lengthOf(0) // Only fragmented mp4 files are displayed
43
8bd6aa04
C
44 await checkResolutionsInMasterPlaylist({
45 server,
46 playlistUrl: hlsPlaylist.playlistUrl,
47 resolutions,
48 transcoded,
49 withRetry: objectStorage
50 })
cfd57d2c
C
51
52 if (objectStorage) {
53 expect(hlsPlaylist.playlistUrl).to.contain(ObjectStorageCommand.getPlaylistBaseUrl())
5333788c 54 }
c55e3d72 55
cfd57d2c
C
56 for (let i = 0; i < resolutions.length; i++) {
57 const segmentNum = 3
58 const segmentName = `${i}-00000${segmentNum}.ts`
59 await originServer.live.waitUntilSegmentGeneration({ videoUUID: video.uuid, playlistNumber: i, segment: segmentNum })
60
61 const baseUrl = objectStorage
62 ? ObjectStorageCommand.getPlaylistBaseUrl() + 'hls'
63 : originServer.url + '/static/streaming-playlists/hls'
64
65 if (objectStorage) {
34aa316f 66 await originServer.live.waitUntilSegmentUpload({ playlistNumber: i, segment: segmentNum })
cfd57d2c
C
67
68 expect(hlsPlaylist.segmentsSha256Url).to.contain(ObjectStorageCommand.getPlaylistBaseUrl())
69 }
70
34aa316f
C
71 const subPlaylist = await originServer.streamingPlaylists.get({
72 url: `${baseUrl}/${video.uuid}/${i}.m3u8`,
73 withRetry: objectStorage // With object storage, the request may fail because of inconsistent data in S3
74 })
cfd57d2c
C
75
76 expect(subPlaylist).to.contain(segmentName)
77
78 await checkLiveSegmentHash({
79 server,
80 baseUrlSegment: baseUrl,
81 videoUUID: video.uuid,
82 segmentName,
83 hlsPlaylist
84 })
85 }
c55e3d72 86 }
cfd57d2c
C
87}
88
89// ---------------------------------------------------------------------------
90
91export {
92 checkLiveCleanup,
93 testVideoResolutions
94}
c55e3d72 95
cfd57d2c
C
96// ---------------------------------------------------------------------------
97
98async function checkSavedLiveCleanup (hlsPath: string, savedResolutions: number[] = []) {
c55e3d72
C
99 const files = await readdir(hlsPath)
100
101 // fragmented file and playlist per resolution + master playlist + segments sha256 json file
4ec52d04 102 expect(files).to.have.lengthOf(savedResolutions.length * 2 + 2)
c55e3d72 103
4ec52d04 104 for (const resolution of savedResolutions) {
c55e3d72
C
105 const fragmentedFile = files.find(f => f.endsWith(`-${resolution}-fragmented.mp4`))
106 expect(fragmentedFile).to.exist
107
108 const playlistFile = files.find(f => f.endsWith(`${resolution}.m3u8`))
109 expect(playlistFile).to.exist
110 }
111
112 const masterPlaylistFile = files.find(f => f.endsWith('-master.m3u8'))
113 expect(masterPlaylistFile).to.exist
114
115 const shaFile = files.find(f => f.endsWith('-segments-sha256.json'))
116 expect(shaFile).to.exist
117}
118
cfd57d2c
C
119async function checkUnsavedLiveCleanup (server: PeerTubeServer, videoUUID: string, hlsPath: string) {
120 let live: LiveVideo
121
122 try {
123 live = await server.live.get({ videoId: videoUUID })
124 } catch {}
125
126 if (live?.permanentLive) {
127 expect(await pathExists(hlsPath)).to.be.true
128
129 const hlsFiles = await readdir(hlsPath)
130 expect(hlsFiles).to.have.lengthOf(1) // Only replays directory
131
132 const replayDir = join(hlsPath, 'replay')
133 expect(await pathExists(replayDir)).to.be.true
134
135 const replayFiles = await readdir(join(hlsPath, 'replay'))
136 expect(replayFiles).to.have.lengthOf(0)
137
138 return
139 }
140
141 expect(await pathExists(hlsPath)).to.be.false
c55e3d72 142}