live-constraints.ts 8.1 KB

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