1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4 import * as chai from 'chai'
5 import { wait } from '@shared/core-utils'
6 import { LiveVideoError, VideoPrivacy } from '@shared/models'
10 createMultipleServers,
13 setAccessTokensToServers,
14 setDefaultVideoChannel,
17 waitUntilLiveReplacedByReplayOnAllServers,
18 waitUntilLiveWaitingOnAllServers
19 } from '@shared/server-commands'
20 import { checkLiveCleanup } from '../../shared'
22 const expect = chai.expect
24 describe('Test live constraints', function () {
25 let servers: PeerTubeServer[] = []
27 let userAccessToken: string
28 let userChannelId: number
30 async function createLiveWrapper (options: {
34 const { replay, permanent } = options
36 const liveAttributes = {
38 channelId: userChannelId,
39 privacy: VideoPrivacy.PUBLIC,
41 permanentLive: permanent
44 const { uuid } = await servers[0].live.create({ token: userAccessToken, fields: liveAttributes })
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)
55 await checkLiveCleanup(servers[0], videoId, resolutions)
58 function updateQuota (options: { total: number, daily: number }) {
59 return servers[0].users.update({
61 videoQuota: options.total,
62 videoQuotaDaily: options.daily
66 before(async function () {
69 servers = await createMultipleServers(2)
71 // Get the access tokens
72 await setAccessTokensToServers(servers)
73 await setDefaultVideoChannel(servers)
75 await servers[0].config.updateCustomSubConfig({
88 const res = await servers[0].users.generate('user1')
90 userChannelId = res.userChannelId
91 userAccessToken = res.token
93 await updateQuota({ total: 1, daily: -1 })
96 // Server 1 and server 2 follow each other
97 await doubleFollow(servers[0], servers[1])
100 it('Should not have size limit if save replay is disabled', async function () {
103 const userVideoLiveoId = await createLiveWrapper({ replay: false, permanent: false })
104 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false })
107 it('Should have size limit depending on user global quota if save replay is enabled on non permanent live', async function () {
110 // Wait for user quota memoize cache invalidation
113 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
114 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
116 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
117 await waitJobs(servers)
119 await checkSaveReplay(userVideoLiveoId)
121 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
122 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
125 it('Should have size limit depending on user global quota if save replay is enabled on a permanent live', async function () {
128 // Wait for user quota memoize cache invalidation
131 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: true })
132 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
134 await waitJobs(servers)
135 await waitUntilLiveWaitingOnAllServers(servers, userVideoLiveoId)
137 const session = await servers[0].live.findLatestSession({ videoId: userVideoLiveoId })
138 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
141 it('Should have size limit depending on user daily quota if save replay is enabled', async function () {
144 // Wait for user quota memoize cache invalidation
147 await updateQuota({ total: -1, daily: 1 })
149 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
150 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
152 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
153 await waitJobs(servers)
155 await checkSaveReplay(userVideoLiveoId)
157 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
158 expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED)
161 it('Should succeed without quota limit', async function () {
164 // Wait for user quota memoize cache invalidation
167 await updateQuota({ total: 10 * 1000 * 1000, daily: -1 })
169 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
170 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false })
173 it('Should have the same quota in admin and as a user', async function () {
176 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
177 const ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ token: userAccessToken, videoId: userVideoLiveoId })
179 await servers[0].live.waitUntilPublished({ videoId: userVideoLiveoId })
183 const quotaUser = await servers[0].users.getMyQuotaUsed({ token: userAccessToken })
185 const { data } = await servers[0].users.list()
186 const quotaAdmin = data.find(u => u.username === 'user1')
188 expect(quotaUser.videoQuotaUsed).to.equal(quotaAdmin.videoQuotaUsed)
189 expect(quotaUser.videoQuotaUsedDaily).to.equal(quotaAdmin.videoQuotaUsedDaily)
191 expect(quotaUser.videoQuotaUsed).to.be.above(10)
192 expect(quotaUser.videoQuotaUsedDaily).to.be.above(10)
194 await stopFfmpeg(ffmpegCommand)
197 it('Should have max duration limit', async function () {
200 await servers[0].config.updateCustomSubConfig({
208 resolutions: ConfigCommand.getCustomConfigResolutions(true)
214 const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false })
215 await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true })
217 await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId)
218 await waitJobs(servers)
220 await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240, 144 ])
222 const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId })
223 expect(session.error).to.equal(LiveVideoError.DURATION_EXCEEDED)
226 after(async function () {
227 await cleanupTests(servers)