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