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