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