]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/shared/live.ts
Remove transcoding scripts
[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'
8059e050 6import { sha1 } from '@shared/extra-utils'
cfd57d2c
C
7import { LiveVideo, VideoStreamingPlaylistType } from '@shared/models'
8import { ObjectStorageCommand, PeerTubeServer } from '@shared/server-commands'
9import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist } from './streaming-playlists'
c55e3d72 10
aa887096
C
11async function checkLiveCleanup (options: {
12 server: PeerTubeServer
13 videoUUID: string
14 permanent: boolean
15 savedResolutions?: number[]
16}) {
17 const { server, videoUUID, permanent, savedResolutions = [] } = options
18
c55e3d72
C
19 const basePath = server.servers.buildDirectory('streaming-playlists')
20 const hlsPath = join(basePath, 'hls', videoUUID)
21
aa887096
C
22 if (permanent) {
23 if (!await pathExists(hlsPath)) return
24
25 const files = await readdir(hlsPath)
26 expect(files).to.have.lengthOf(0)
27 return
28 }
29
4ec52d04 30 if (savedResolutions.length === 0) {
cfd57d2c
C
31 return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
32 }
33
34 return checkSavedLiveCleanup(hlsPath, savedResolutions)
35}
36
37// ---------------------------------------------------------------------------
5333788c 38
cfd57d2c
C
39async function testVideoResolutions (options: {
40 originServer: PeerTubeServer
41 servers: PeerTubeServer[]
42 liveVideoId: string
43 resolutions: number[]
44 transcoded: boolean
8059e050 45
cfd57d2c 46 objectStorage: boolean
8059e050 47 objectStorageBaseUrl?: string
cfd57d2c 48}) {
8059e050
C
49 const {
50 originServer,
51 servers,
52 liveVideoId,
53 resolutions,
54 transcoded,
55 objectStorage,
56 objectStorageBaseUrl = ObjectStorageCommand.getMockPlaylistBaseUrl()
57 } = options
5333788c 58
cfd57d2c
C
59 for (const server of servers) {
60 const { data } = await server.videos.list()
61 expect(data.find(v => v.uuid === liveVideoId)).to.exist
5333788c 62
cfd57d2c
C
63 const video = await server.videos.get({ id: liveVideoId })
64 expect(video.streamingPlaylists).to.have.lengthOf(1)
5333788c 65
cfd57d2c
C
66 const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS)
67 expect(hlsPlaylist).to.exist
68 expect(hlsPlaylist.files).to.have.lengthOf(0) // Only fragmented mp4 files are displayed
69
8bd6aa04
C
70 await checkResolutionsInMasterPlaylist({
71 server,
72 playlistUrl: hlsPlaylist.playlistUrl,
73 resolutions,
74 transcoded,
75 withRetry: objectStorage
76 })
cfd57d2c
C
77
78 if (objectStorage) {
8059e050 79 expect(hlsPlaylist.playlistUrl).to.contain(objectStorageBaseUrl)
5333788c 80 }
c55e3d72 81
cfd57d2c
C
82 for (let i = 0; i < resolutions.length; i++) {
83 const segmentNum = 3
84 const segmentName = `${i}-00000${segmentNum}.ts`
bbae45c3
C
85 await originServer.live.waitUntilSegmentGeneration({
86 server: originServer,
87 videoUUID: video.uuid,
88 playlistNumber: i,
89 segment: segmentNum,
8059e050
C
90 objectStorage,
91 objectStorageBaseUrl
bbae45c3 92 })
cfd57d2c
C
93
94 const baseUrl = objectStorage
8059e050 95 ? join(objectStorageBaseUrl, 'hls')
cfd57d2c
C
96 : originServer.url + '/static/streaming-playlists/hls'
97
98 if (objectStorage) {
8059e050 99 expect(hlsPlaylist.segmentsSha256Url).to.contain(objectStorageBaseUrl)
cfd57d2c
C
100 }
101
34aa316f
C
102 const subPlaylist = await originServer.streamingPlaylists.get({
103 url: `${baseUrl}/${video.uuid}/${i}.m3u8`,
104 withRetry: objectStorage // With object storage, the request may fail because of inconsistent data in S3
105 })
cfd57d2c
C
106
107 expect(subPlaylist).to.contain(segmentName)
108
109 await checkLiveSegmentHash({
110 server,
111 baseUrlSegment: baseUrl,
112 videoUUID: video.uuid,
113 segmentName,
114 hlsPlaylist
115 })
54db8e3d
C
116
117 if (originServer.internalServerNumber === server.internalServerNumber) {
118 const infohash = sha1(`${2 + hlsPlaylist.playlistUrl}+V${i}`)
119 const dbInfohashes = await originServer.sql.getPlaylistInfohash(hlsPlaylist.id)
120
121 expect(dbInfohashes).to.include(infohash)
122 }
cfd57d2c 123 }
c55e3d72 124 }
cfd57d2c
C
125}
126
127// ---------------------------------------------------------------------------
128
129export {
130 checkLiveCleanup,
131 testVideoResolutions
132}
c55e3d72 133
cfd57d2c
C
134// ---------------------------------------------------------------------------
135
136async function checkSavedLiveCleanup (hlsPath: string, savedResolutions: number[] = []) {
c55e3d72
C
137 const files = await readdir(hlsPath)
138
139 // fragmented file and playlist per resolution + master playlist + segments sha256 json file
4ec52d04 140 expect(files).to.have.lengthOf(savedResolutions.length * 2 + 2)
c55e3d72 141
4ec52d04 142 for (const resolution of savedResolutions) {
c55e3d72
C
143 const fragmentedFile = files.find(f => f.endsWith(`-${resolution}-fragmented.mp4`))
144 expect(fragmentedFile).to.exist
145
146 const playlistFile = files.find(f => f.endsWith(`${resolution}.m3u8`))
147 expect(playlistFile).to.exist
148 }
149
150 const masterPlaylistFile = files.find(f => f.endsWith('-master.m3u8'))
151 expect(masterPlaylistFile).to.exist
152
153 const shaFile = files.find(f => f.endsWith('-segments-sha256.json'))
154 expect(shaFile).to.exist
155}
156
cfd57d2c
C
157async function checkUnsavedLiveCleanup (server: PeerTubeServer, videoUUID: string, hlsPath: string) {
158 let live: LiveVideo
159
160 try {
161 live = await server.live.get({ videoId: videoUUID })
162 } catch {}
163
164 if (live?.permanentLive) {
165 expect(await pathExists(hlsPath)).to.be.true
166
167 const hlsFiles = await readdir(hlsPath)
168 expect(hlsFiles).to.have.lengthOf(1) // Only replays directory
169
170 const replayDir = join(hlsPath, 'replay')
171 expect(await pathExists(replayDir)).to.be.true
172
173 const replayFiles = await readdir(join(hlsPath, 'replay'))
174 expect(replayFiles).to.have.lengthOf(0)
175
176 return
177 }
178
179 expect(await pathExists(hlsPath)).to.be.false
c55e3d72 180}