]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/live/live-save-replay.ts
Reorganize imports
[github/Chocobozzz/PeerTube.git] / server / tests / api / live / live-save-replay.ts
CommitLineData
68e70a74
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import * as chai from 'chai'
5import { FfmpegCommand } from 'fluent-ffmpeg'
68e70a74 6import {
68e70a74
C
7 checkLiveCleanup,
8 cleanupTests,
65e6e260 9 ConfigCommand,
254d3579 10 createMultipleServers,
4c7e60bc 11 doubleFollow,
254d3579 12 PeerTubeServer,
68e70a74
C
13 setAccessTokensToServers,
14 setDefaultVideoChannel,
15 stopFfmpeg,
16 testFfmpegStreamError,
94d721ef 17 wait,
4f219914 18 waitJobs
d23dd9fb 19} from '@shared/extra-utils'
4c7e60bc 20import { HttpStatusCode, LiveVideoCreate, VideoPrivacy, VideoState } from '@shared/models'
68e70a74
C
21
22const expect = chai.expect
23
24describe('Save replay setting', function () {
254d3579 25 let servers: PeerTubeServer[] = []
68e70a74
C
26 let liveVideoUUID: string
27 let ffmpegCommand: FfmpegCommand
28
29 async function createLiveWrapper (saveReplay: boolean) {
30 if (liveVideoUUID) {
31 try {
89d241a7 32 await servers[0].videos.remove({ id: liveVideoUUID })
68e70a74
C
33 await waitJobs(servers)
34 } catch {}
35 }
36
37 const attributes: LiveVideoCreate = {
89d241a7 38 channelId: servers[0].store.channel.id,
68e70a74
C
39 privacy: VideoPrivacy.PUBLIC,
40 name: 'my super live',
41 saveReplay
42 }
43
89d241a7 44 const { uuid } = await servers[0].live.create({ fields: attributes })
4f219914 45 return uuid
68e70a74
C
46 }
47
d23dd9fb 48 async function checkVideosExist (videoId: string, existsInList: boolean, expectedStatus?: number) {
68e70a74
C
49 for (const server of servers) {
50 const length = existsInList ? 1 : 0
51
89d241a7 52 const { data, total } = await server.videos.list()
d23dd9fb
C
53 expect(data).to.have.lengthOf(length)
54 expect(total).to.equal(length)
68e70a74 55
d23dd9fb 56 if (expectedStatus) {
89d241a7 57 await server.videos.get({ id: videoId, expectedStatus })
68e70a74
C
58 }
59 }
60 }
61
62 async function checkVideoState (videoId: string, state: VideoState) {
63 for (const server of servers) {
89d241a7 64 const video = await server.videos.get({ id: videoId })
d23dd9fb 65 expect(video.state.id).to.equal(state)
68e70a74
C
66 }
67 }
68
fae6e4da
C
69 async function waitUntilLivePublishedOnAllServers (videoId: string) {
70 for (const server of servers) {
89d241a7 71 await server.live.waitUntilPublished({ videoId })
fae6e4da
C
72 }
73 }
74
94d721ef
C
75 async function waitUntilLiveSavedOnAllServers (videoId: string) {
76 for (const server of servers) {
89d241a7 77 await server.live.waitUntilSaved({ videoId })
94d721ef
C
78 }
79 }
80
68e70a74
C
81 before(async function () {
82 this.timeout(120000)
83
254d3579 84 servers = await createMultipleServers(2)
68e70a74
C
85
86 // Get the access tokens
87 await setAccessTokensToServers(servers)
88 await setDefaultVideoChannel(servers)
89
90 // Server 1 and server 2 follow each other
91 await doubleFollow(servers[0], servers[1])
92
89d241a7 93 await servers[0].config.updateCustomSubConfig({
65e6e260
C
94 newConfig: {
95 live: {
96 enabled: true,
97 allowReplay: true,
98 maxDuration: -1,
99 transcoding: {
100 enabled: false,
101 resolutions: ConfigCommand.getCustomConfigResolutions(true)
102 }
68e70a74
C
103 }
104 }
105 })
106 })
107
108 describe('With save replay disabled', function () {
109
110 before(async function () {
111 this.timeout(10000)
112 })
113
114 it('Should correctly create and federate the "waiting for stream" live', async function () {
115 this.timeout(20000)
116
117 liveVideoUUID = await createLiveWrapper(false)
118
119 await waitJobs(servers)
120
f2eb23cd 121 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
68e70a74
C
122 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
123 })
124
125 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
fae6e4da 126 this.timeout(30000)
68e70a74 127
89d241a7 128 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da
C
129
130 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
131
132 await waitJobs(servers)
133
f2eb23cd 134 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
135 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
136 })
137
138 it('Should correctly delete the video files after the stream ended', async function () {
59fd824c 139 this.timeout(40000)
68e70a74
C
140
141 await stopFfmpeg(ffmpegCommand)
142
fae6e4da 143 for (const server of servers) {
89d241a7 144 await server.live.waitUntilEnded({ videoId: liveVideoUUID })
fae6e4da 145 }
68e70a74
C
146 await waitJobs(servers)
147
148 // Live still exist, but cannot be played anymore
f2eb23cd 149 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
68e70a74
C
150 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
151
152 // No resolutions saved since we did not save replay
153 await checkLiveCleanup(servers[0], liveVideoUUID, [])
154 })
155
156 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
157 this.timeout(40000)
158
159 liveVideoUUID = await createLiveWrapper(false)
160
89d241a7 161 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da
C
162
163 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
164
165 await waitJobs(servers)
f2eb23cd 166 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
167
168 await Promise.all([
89d241a7 169 servers[0].blacklist.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }),
68e70a74
C
170 testFfmpegStreamError(ffmpegCommand, true)
171 ])
172
173 await waitJobs(servers)
174
175 await checkVideosExist(liveVideoUUID, false)
176
89d241a7
C
177 await servers[0].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
178 await servers[1].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
68e70a74 179
94d721ef
C
180 await wait(5000)
181 await waitJobs(servers)
68e70a74
C
182 await checkLiveCleanup(servers[0], liveVideoUUID, [])
183 })
184
185 it('Should correctly terminate the stream on delete and delete the video', async function () {
186 this.timeout(40000)
187
188 liveVideoUUID = await createLiveWrapper(false)
189
89d241a7 190 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da
C
191
192 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
193
194 await waitJobs(servers)
f2eb23cd 195 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
196
197 await Promise.all([
198 testFfmpegStreamError(ffmpegCommand, true),
89d241a7 199 servers[0].videos.remove({ id: liveVideoUUID })
68e70a74
C
200 ])
201
94d721ef 202 await wait(5000)
68e70a74
C
203 await waitJobs(servers)
204
f2eb23cd 205 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
68e70a74
C
206 await checkLiveCleanup(servers[0], liveVideoUUID, [])
207 })
208 })
209
210 describe('With save replay enabled', function () {
211
212 it('Should correctly create and federate the "waiting for stream" live', async function () {
213 this.timeout(20000)
214
215 liveVideoUUID = await createLiveWrapper(true)
216
217 await waitJobs(servers)
218
f2eb23cd 219 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200)
68e70a74
C
220 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
221 })
222
223 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
224 this.timeout(20000)
225
89d241a7 226 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da 227 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
228
229 await waitJobs(servers)
230
f2eb23cd 231 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
232 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
233 })
234
235 it('Should correctly have saved the live and federated it after the streaming', async function () {
236 this.timeout(30000)
237
238 await stopFfmpeg(ffmpegCommand)
239
94d721ef 240 await waitUntilLiveSavedOnAllServers(liveVideoUUID)
68e70a74
C
241 await waitJobs(servers)
242
243 // Live has been transcoded
f2eb23cd 244 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
245 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
246 })
247
248 it('Should update the saved live and correctly federate the updated attributes', async function () {
249 this.timeout(30000)
250
89d241a7 251 await servers[0].videos.update({ id: liveVideoUUID, attributes: { name: 'video updated' } })
68e70a74
C
252 await waitJobs(servers)
253
254 for (const server of servers) {
89d241a7 255 const video = await server.videos.get({ id: liveVideoUUID })
d23dd9fb
C
256 expect(video.name).to.equal('video updated')
257 expect(video.isLive).to.be.false
68e70a74
C
258 }
259 })
260
261 it('Should have cleaned up the live files', async function () {
262 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
263 })
264
265 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
266 this.timeout(40000)
267
268 liveVideoUUID = await createLiveWrapper(true)
269
89d241a7 270 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da 271 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
272
273 await waitJobs(servers)
f2eb23cd 274 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
275
276 await Promise.all([
89d241a7 277 servers[0].blacklist.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }),
68e70a74
C
278 testFfmpegStreamError(ffmpegCommand, true)
279 ])
280
281 await waitJobs(servers)
282
283 await checkVideosExist(liveVideoUUID, false)
284
89d241a7
C
285 await servers[0].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 })
286 await servers[1].videos.get({ id: liveVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
68e70a74 287
94d721ef
C
288 await wait(5000)
289 await waitJobs(servers)
68e70a74
C
290 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
291 })
292
293 it('Should correctly terminate the stream on delete and delete the video', async function () {
294 this.timeout(40000)
295
296 liveVideoUUID = await createLiveWrapper(true)
297
89d241a7 298 ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
fae6e4da 299 await waitUntilLivePublishedOnAllServers(liveVideoUUID)
68e70a74
C
300
301 await waitJobs(servers)
f2eb23cd 302 await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200)
68e70a74
C
303
304 await Promise.all([
89d241a7 305 servers[0].videos.remove({ id: liveVideoUUID }),
68e70a74
C
306 testFfmpegStreamError(ffmpegCommand, true)
307 ])
308
94d721ef 309 await wait(5000)
68e70a74
C
310 await waitJobs(servers)
311
f2eb23cd 312 await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404)
68e70a74
C
313 await checkLiveCleanup(servers[0], liveVideoUUID, [])
314 })
315 })
316
317 after(async function () {
318 await cleanupTests(servers)
319 })
320})