]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/live/live-constraints.ts
168241b797b87d20c586ec38a623eb0694c01ce4
[github/Chocobozzz/PeerTube.git] / server / tests / api / live / live-constraints.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import { expect } from 'chai'
4 import { wait } from '@shared/core-utils'
5 import { LiveVideoError, VideoPrivacy } from '@shared/models'
6 import {
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'
19 import { checkLiveCleanup } from '../../shared'
20
21 describe('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 const baseQuota = await servers[0].users.getMyQuotaUsed({ token: userAccessToken })
177
178 await wait(3000)
179
180 const quotaUser = await servers[0].users.getMyQuotaUsed({ token: userAccessToken })
181
182 const { data } = await servers[0].users.list()
183 const quotaAdmin = data.find(u => u.username === 'user1')
184
185 expect(quotaUser.videoQuotaUsed).to.be.above(baseQuota.videoQuotaUsed)
186 expect(quotaUser.videoQuotaUsedDaily).to.be.above(baseQuota.videoQuotaUsedDaily)
187
188 expect(quotaAdmin.videoQuotaUsed).to.be.above(baseQuota.videoQuotaUsed)
189 expect(quotaAdmin.videoQuotaUsedDaily).to.be.above(baseQuota.videoQuotaUsedDaily)
190
191 expect(quotaUser.videoQuotaUsed).to.be.above(10)
192 expect(quotaUser.videoQuotaUsedDaily).to.be.above(10)
193 expect(quotaAdmin.videoQuotaUsed).to.be.above(10)
194 expect(quotaAdmin.videoQuotaUsedDaily).to.be.above(10)
195
196 await stopFfmpeg(ffmpegCommand)
197 })
198
199 it('Should have max duration limit', async function () {
200 this.timeout(240000)
201
202 await servers[0].config.updateCustomSubConfig({
203 newConfig: {
204 live: {
205 enabled: true,
206 allowReplay: true,
207 maxDuration: 3,
208 transcoding: {
209 enabled: true,
210 resolutions: ConfigCommand.getCustomConfigResolutions(true)
211 }
212 }
213 }
214 })
215
216 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
217 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
218
219 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
220 await waitJobs(servers)
221
222 await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240, 144 ])
223
224 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
225 expect(session.error).to.equal(LiveVideoError.DURATION_EXCEEDED)
226 })
227
228 after(async function () {
229 await cleanupTests(servers)
230 })
231 })