]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame_incremental - server/tests/api/live/live-constraints.ts
Force stop remote live transcoding
[github/Chocobozzz/PeerTube.git] / server / tests / api / live / live-constraints.ts
... / ...
CommitLineData
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { wait } from '@shared/core-utils'
5import { LiveVideoError, VideoPrivacy } from '@shared/models'
6import {
7 cleanupTests,
8 ConfigCommand,
9 createMultipleServers,
10 doubleFollow,
11 PeerTubeServer,
12 setAccessTokensToServers,
13 setDefaultVideoChannel,
14 stopFfmpeg,
15 waitJobs,
16 waitUntilLiveReplacedByReplayOnAllServers,
17 waitUntilLiveWaitingOnAllServers
18} from '@shared/server-commands'
19import { checkLiveCleanup } from '../../shared'
20
21describe('Test live constraints', function () {
22 let servers: PeerTubeServer[] = []
23 let userId: number
24 let userAccessToken: string
25 let userChannelId: number
26
27 async function createLiveWrapper (options: { replay: boolean, permanent: boolean }) {
28 const { replay, permanent } = options
29
30 const liveAttributes = {
31 name: 'user live',
32 channelId: userChannelId,
33 privacy: VideoPrivacy.PUBLIC,
34 saveReplay: replay,
35 replaySettings: options.replay ? { privacy: VideoPrivacy.PUBLIC } : undefined,
36 permanentLive: permanent
37 }
38
39 const { uuid } = await servers[0].live.create({ token: userAccessToken, fields: liveAttributes })
40 return uuid
41 }
42
43 async function checkSaveReplay (videoId: string, resolutions = [ 720 ]) {
44 for (const server of servers) {
45 const video = await server.videos.get({ id: videoId })
46 expect(video.isLive).to.be.false
47 expect(video.duration).to.be.greaterThan(0)
48 }
49
50 await checkLiveCleanup({ server: servers[0], permanent: false, videoUUID: videoId, savedResolutions: resolutions })
51 }
52
53 function updateQuota (options: { total: number, daily: number }) {
54 return servers[0].users.update({
55 userId,
56 videoQuota: options.total,
57 videoQuotaDaily: options.daily
58 })
59 }
60
61 before(async function () {
62 this.timeout(120000)
63
64 servers = await createMultipleServers(2)
65
66 // Get the access tokens
67 await setAccessTokensToServers(servers)
68 await setDefaultVideoChannel(servers)
69
70 await servers[0].config.updateCustomSubConfig({
71 newConfig: {
72 live: {
73 enabled: true,
74 allowReplay: true,
75 transcoding: {
76 enabled: false
77 }
78 }
79 }
80 })
81
82 {
83 const res = await servers[0].users.generate('user1')
84 userId = res.userId
85 userChannelId = res.userChannelId
86 userAccessToken = res.token
87
88 await updateQuota({ total: 1, daily: -1 })
89 }
90
91 // Server 1 and server 2 follow each other
92 await doubleFollow(servers[0], servers[1])
93 })
94
95 it('Should not have size limit if save replay is disabled', async function () {
96 this.timeout(60000)
97
98 const userVideoLiveoId = await createLiveWrapper({ replay: false, permanent: false })
99 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false })
100 })
101
102 it('Should have size limit depending on user global quota if save replay is enabled on non permanent live', async function () {
103 this.timeout(60000)
104
105 // Wait for user quota memoize cache invalidation
106 await wait(5000)
107
108 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
109 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
110
111 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
112 await waitJobs(servers)
113
114 await checkSaveReplay(userVideoLiveoId)
115
116 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
117 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
118 })
119
120 it('Should have size limit depending on user global quota if save replay is enabled on a permanent live', async function () {
121 this.timeout(60000)
122
123 // Wait for user quota memoize cache invalidation
124 await wait(5000)
125
126 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: true })
127 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
128
129 await waitJobs(servers)
130 await waitUntilLiveWaitingOnAllServers(servers, userVideoLiveoId)
131
132 const session = await servers[0].live.findLatestSession({ videoId: userVideoLiveoId })
133 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
134 })
135
136 it('Should have size limit depending on user daily quota if save replay is enabled', async function () {
137 this.timeout(60000)
138
139 // Wait for user quota memoize cache invalidation
140 await wait(5000)
141
142 await updateQuota({ total: -1, daily: 1 })
143
144 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
145 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
146
147 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
148 await waitJobs(servers)
149
150 await checkSaveReplay(userVideoLiveoId)
151
152 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
153 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
154 })
155
156 it('Should succeed without quota limit', async function () {
157 this.timeout(60000)
158
159 // Wait for user quota memoize cache invalidation
160 await wait(5000)
161
162 await updateQuota({ total: 10 * 1000 * 1000, daily: -1 })
163
164 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
165 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false })
166 })
167
168 it('Should have the same quota in admin and as a user', async function () {
169 this.timeout(120000)
170
171 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
172 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ token: userAccessToken, videoId: userVideoLiveoId })
173
174 await servers[0].live.waitUntilPublished({ videoId: userVideoLiveoId })
175
176 await wait(3000)
177
178 const quotaUser = await servers[0].users.getMyQuotaUsed({ token: userAccessToken })
179
180 const { data } = await servers[0].users.list()
181 const quotaAdmin = data.find(u => u.username === 'user1')
182
183 expect(quotaUser.videoQuotaUsed).to.equal(quotaAdmin.videoQuotaUsed)
184 expect(quotaUser.videoQuotaUsedDaily).to.equal(quotaAdmin.videoQuotaUsedDaily)
185
186 expect(quotaUser.videoQuotaUsed).to.be.above(10)
187 expect(quotaUser.videoQuotaUsedDaily).to.be.above(10)
188
189 await stopFfmpeg(ffmpegCommand)
190 })
191
192 it('Should have max duration limit', async function () {
193 this.timeout(240000)
194
195 await servers[0].config.updateCustomSubConfig({
196 newConfig: {
197 live: {
198 enabled: true,
199 allowReplay: true,
200 maxDuration: 3,
201 transcoding: {
202 enabled: true,
203 resolutions: ConfigCommand.getCustomConfigResolutions(true)
204 }
205 }
206 }
207 })
208
209 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
210 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
211
212 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
213 await waitJobs(servers)
214
215 await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240, 144 ])
216
217 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
218 expect(session.error).to.equal(LiveVideoError.DURATION_EXCEEDED)
219 })
220
221 after(async function () {
222 await cleanupTests(servers)
223 })
224})