aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/live/live-save-replay.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/live/live-save-replay.ts')
-rw-r--r--server/tests/api/live/live-save-replay.ts307
1 files changed, 307 insertions, 0 deletions
diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts
new file mode 100644
index 000000000..3ffa0c093
--- /dev/null
+++ b/server/tests/api/live/live-save-replay.ts
@@ -0,0 +1,307 @@
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'
7import {
8 addVideoToBlacklist,
9 checkLiveCleanup,
10 cleanupTests,
11 createLive,
12 doubleFollow,
13 flushAndRunMultipleServers,
14 getVideo,
15 getVideosList,
16 removeVideo,
17 sendRTMPStreamInVideo,
18 ServerInfo,
19 setAccessTokensToServers,
20 setDefaultVideoChannel,
21 stopFfmpeg,
22 testFfmpegStreamError,
23 updateCustomSubConfig,
24 updateVideo,
25 waitJobs,
26 waitUntilLiveStarts
27} from '../../../../shared/extra-utils'
28
29const expect = chai.expect
30
31describe('Save replay setting', function () {
32 let servers: ServerInfo[] = []
33 let liveVideoUUID: string
34 let ffmpegCommand: FfmpegCommand
35
36 async function createLiveWrapper (saveReplay: boolean) {
37 if (liveVideoUUID) {
38 try {
39 await removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
40 await waitJobs(servers)
41 } catch {}
42 }
43
44 const attributes: LiveVideoCreate = {
45 channelId: servers[0].videoChannel.id,
46 privacy: VideoPrivacy.PUBLIC,
47 name: 'my super live',
48 saveReplay
49 }
50
51 const res = await createLive(servers[0].url, servers[0].accessToken, attributes)
52 return res.body.video.uuid
53 }
54
55 async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) {
56 for (const server of servers) {
57 const length = existsInList ? 1 : 0
58
59 const resVideos = await getVideosList(server.url)
60 expect(resVideos.body.data).to.have.lengthOf(length)
61 expect(resVideos.body.total).to.equal(length)
62
63 if (getStatus) {
64 await getVideo(server.url, videoId, getStatus)
65 }
66 }
67 }
68
69 async function checkVideoState (videoId: string, state: VideoState) {
70 for (const server of servers) {
71 const res = await getVideo(server.url, videoId)
72 expect((res.body as VideoDetails).state.id).to.equal(state)
73 }
74 }
75
76 before(async function () {
77 this.timeout(120000)
78
79 servers = await flushAndRunMultipleServers(2)
80
81 // Get the access tokens
82 await setAccessTokensToServers(servers)
83 await setDefaultVideoChannel(servers)
84
85 // Server 1 and server 2 follow each other
86 await doubleFollow(servers[0], servers[1])
87
88 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
89 live: {
90 enabled: true,
91 allowReplay: true,
92 maxDuration: null,
93 transcoding: {
94 enabled: false,
95 resolutions: {
96 '240p': true,
97 '360p': true,
98 '480p': true,
99 '720p': true,
100 '1080p': true,
101 '2160p': true
102 }
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
121 await checkVideosExist(liveVideoUUID, false, 200)
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 () {
126 this.timeout(20000)
127
128 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
129 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
130
131 await waitJobs(servers)
132
133 await checkVideosExist(liveVideoUUID, true, 200)
134 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
135 })
136
137 it('Should correctly delete the video files after the stream ended', async function () {
138 this.timeout(30000)
139
140 await stopFfmpeg(ffmpegCommand)
141
142 await waitJobs(servers)
143
144 // Live still exist, but cannot be played anymore
145 await checkVideosExist(liveVideoUUID, false, 200)
146 await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED)
147
148 // No resolutions saved since we did not save replay
149 await checkLiveCleanup(servers[0], liveVideoUUID, [])
150 })
151
152 it('Should correctly terminate the stream on blacklist and delete the live', async function () {
153 this.timeout(40000)
154
155 liveVideoUUID = await createLiveWrapper(false)
156
157 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
158 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
159
160 await waitJobs(servers)
161 await checkVideosExist(liveVideoUUID, true, 200)
162
163 await Promise.all([
164 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
165 testFfmpegStreamError(ffmpegCommand, true)
166 ])
167
168 await waitJobs(servers)
169
170 await checkVideosExist(liveVideoUUID, false)
171
172 await getVideo(servers[0].url, liveVideoUUID, 401)
173 await getVideo(servers[1].url, liveVideoUUID, 404)
174
175 await checkLiveCleanup(servers[0], liveVideoUUID, [])
176 })
177
178 it('Should correctly terminate the stream on delete and delete the video', async function () {
179 this.timeout(40000)
180
181 liveVideoUUID = await createLiveWrapper(false)
182
183 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
184 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
185
186 await waitJobs(servers)
187 await checkVideosExist(liveVideoUUID, true, 200)
188
189 await Promise.all([
190 testFfmpegStreamError(ffmpegCommand, true),
191 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
192 ])
193
194 await waitJobs(servers)
195
196 await checkVideosExist(liveVideoUUID, false, 404)
197 await checkLiveCleanup(servers[0], liveVideoUUID, [])
198 })
199 })
200
201 describe('With save replay enabled', function () {
202
203 it('Should correctly create and federate the "waiting for stream" live', async function () {
204 this.timeout(20000)
205
206 liveVideoUUID = await createLiveWrapper(true)
207
208 await waitJobs(servers)
209
210 await checkVideosExist(liveVideoUUID, false, 200)
211 await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE)
212 })
213
214 it('Should correctly have updated the live and federated it when streaming in the live', async function () {
215 this.timeout(20000)
216
217 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
218 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
219
220 await waitJobs(servers)
221
222 await checkVideosExist(liveVideoUUID, true, 200)
223 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
224 })
225
226 it('Should correctly have saved the live and federated it after the streaming', async function () {
227 this.timeout(30000)
228
229 await stopFfmpeg(ffmpegCommand)
230
231 await waitJobs(servers)
232
233 // Live has been transcoded
234 await checkVideosExist(liveVideoUUID, true, 200)
235 await checkVideoState(liveVideoUUID, VideoState.PUBLISHED)
236 })
237
238 it('Should update the saved live and correctly federate the updated attributes', async function () {
239 this.timeout(30000)
240
241 await updateVideo(servers[0].url, servers[0].accessToken, liveVideoUUID, { name: 'video updated' })
242 await waitJobs(servers)
243
244 for (const server of servers) {
245 const res = await getVideo(server.url, liveVideoUUID)
246 expect(res.body.name).to.equal('video updated')
247 expect(res.body.isLive).to.be.false
248 }
249 })
250
251 it('Should have cleaned up the live files', async function () {
252 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
253 })
254
255 it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
256 this.timeout(40000)
257
258 liveVideoUUID = await createLiveWrapper(true)
259
260 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
261 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
262
263 await waitJobs(servers)
264 await checkVideosExist(liveVideoUUID, true, 200)
265
266 await Promise.all([
267 addVideoToBlacklist(servers[0].url, servers[0].accessToken, liveVideoUUID, 'bad live', true),
268 testFfmpegStreamError(ffmpegCommand, true)
269 ])
270
271 await waitJobs(servers)
272
273 await checkVideosExist(liveVideoUUID, false)
274
275 await getVideo(servers[0].url, liveVideoUUID, 401)
276 await getVideo(servers[1].url, liveVideoUUID, 404)
277
278 await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ])
279 })
280
281 it('Should correctly terminate the stream on delete and delete the video', async function () {
282 this.timeout(40000)
283
284 liveVideoUUID = await createLiveWrapper(true)
285
286 ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID)
287 await waitUntilLiveStarts(servers[0].url, servers[0].accessToken, liveVideoUUID)
288
289 await waitJobs(servers)
290 await checkVideosExist(liveVideoUUID, true, 200)
291
292 await Promise.all([
293 removeVideo(servers[0].url, servers[0].accessToken, liveVideoUUID),
294 testFfmpegStreamError(ffmpegCommand, true)
295 ])
296
297 await waitJobs(servers)
298
299 await checkVideosExist(liveVideoUUID, false, 404)
300 await checkLiveCleanup(servers[0], liveVideoUUID, [])
301 })
302 })
303
304 after(async function () {
305 await cleanupTests(servers)
306 })
307})