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