]>
Commit | Line | Data |
---|---|---|
68e70a74 C |
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | ||
86347717 | 3 | import { expect } from 'chai' |
c55e3d72 | 4 | import { wait } from '@shared/core-utils' |
3f0ceab0 | 5 | import { LiveVideoError, UserVideoQuota, VideoPrivacy } from '@shared/models' |
68e70a74 | 6 | import { |
68e70a74 | 7 | cleanupTests, |
65e6e260 | 8 | ConfigCommand, |
254d3579 | 9 | createMultipleServers, |
4c7e60bc | 10 | doubleFollow, |
254d3579 | 11 | PeerTubeServer, |
68e70a74 C |
12 | setAccessTokensToServers, |
13 | setDefaultVideoChannel, | |
9a82ce24 | 14 | stopFfmpeg, |
26e3e98f | 15 | waitJobs, |
9295c68b | 16 | waitUntilLiveReplacedByReplayOnAllServers, |
26e3e98f | 17 | waitUntilLiveWaitingOnAllServers |
c55e3d72 | 18 | } from '@shared/server-commands' |
4ec52d04 | 19 | import { checkLiveCleanup } from '../../shared' |
68e70a74 | 20 | |
68e70a74 | 21 | describe('Test live constraints', function () { |
254d3579 | 22 | let servers: PeerTubeServer[] = [] |
68e70a74 C |
23 | let userId: number |
24 | let userAccessToken: string | |
25 | let userChannelId: number | |
26 | ||
05a60d85 | 27 | async function createLiveWrapper (options: { replay: boolean, permanent: boolean }) { |
26e3e98f C |
28 | const { replay, permanent } = options |
29 | ||
68e70a74 C |
30 | const liveAttributes = { |
31 | name: 'user live', | |
32 | channelId: userChannelId, | |
33 | privacy: VideoPrivacy.PUBLIC, | |
26e3e98f | 34 | saveReplay: replay, |
05a60d85 | 35 | replaySettings: options.replay ? { privacy: VideoPrivacy.PUBLIC } : undefined, |
26e3e98f | 36 | permanentLive: permanent |
68e70a74 C |
37 | } |
38 | ||
89d241a7 | 39 | const { uuid } = await servers[0].live.create({ token: userAccessToken, fields: liveAttributes }) |
4f219914 | 40 | return uuid |
68e70a74 C |
41 | } |
42 | ||
43 | async function checkSaveReplay (videoId: string, resolutions = [ 720 ]) { | |
44 | for (const server of servers) { | |
89d241a7 | 45 | const video = await server.videos.get({ id: videoId }) |
68e70a74 C |
46 | expect(video.isLive).to.be.false |
47 | expect(video.duration).to.be.greaterThan(0) | |
48 | } | |
49 | ||
aa887096 | 50 | await checkLiveCleanup({ server: servers[0], permanent: false, videoUUID: videoId, savedResolutions: resolutions }) |
68e70a74 C |
51 | } |
52 | ||
a1bb73f9 | 53 | function updateQuota (options: { total: number, daily: number }) { |
89d241a7 | 54 | return servers[0].users.update({ |
a1bb73f9 C |
55 | userId, |
56 | videoQuota: options.total, | |
57 | videoQuotaDaily: options.daily | |
58 | }) | |
59 | } | |
60 | ||
68e70a74 C |
61 | before(async function () { |
62 | this.timeout(120000) | |
63 | ||
254d3579 | 64 | servers = await createMultipleServers(2) |
68e70a74 C |
65 | |
66 | // Get the access tokens | |
67 | await setAccessTokensToServers(servers) | |
68 | await setDefaultVideoChannel(servers) | |
69 | ||
89d241a7 | 70 | await servers[0].config.updateCustomSubConfig({ |
65e6e260 C |
71 | newConfig: { |
72 | live: { | |
73 | enabled: true, | |
74 | allowReplay: true, | |
75 | transcoding: { | |
76 | enabled: false | |
77 | } | |
68e70a74 C |
78 | } |
79 | } | |
80 | }) | |
81 | ||
82 | { | |
89d241a7 | 83 | const res = await servers[0].users.generate('user1') |
a1bb73f9 C |
84 | userId = res.userId |
85 | userChannelId = res.userChannelId | |
86 | userAccessToken = res.token | |
87 | ||
88 | await updateQuota({ total: 1, daily: -1 }) | |
68e70a74 C |
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 | ||
26e3e98f | 98 | const userVideoLiveoId = await createLiveWrapper({ replay: false, permanent: false }) |
89d241a7 | 99 | await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false }) |
68e70a74 C |
100 | }) |
101 | ||
26e3e98f | 102 | it('Should have size limit depending on user global quota if save replay is enabled on non permanent live', async function () { |
68e70a74 C |
103 | this.timeout(60000) |
104 | ||
105 | // Wait for user quota memoize cache invalidation | |
106 | await wait(5000) | |
107 | ||
26e3e98f | 108 | const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false }) |
89d241a7 | 109 | await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) |
68e70a74 | 110 | |
9295c68b | 111 | await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId) |
68e70a74 C |
112 | await waitJobs(servers) |
113 | ||
114 | await checkSaveReplay(userVideoLiveoId) | |
26e3e98f C |
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) | |
68e70a74 C |
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 | ||
a1bb73f9 | 142 | await updateQuota({ total: -1, daily: 1 }) |
68e70a74 | 143 | |
26e3e98f | 144 | const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false }) |
89d241a7 | 145 | await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) |
68e70a74 | 146 | |
9295c68b | 147 | await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId) |
68e70a74 C |
148 | await waitJobs(servers) |
149 | ||
150 | await checkSaveReplay(userVideoLiveoId) | |
26e3e98f C |
151 | |
152 | const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId }) | |
153 | expect(session.error).to.equal(LiveVideoError.QUOTA_EXCEEDED) | |
68e70a74 C |
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 | ||
a1bb73f9 | 162 | await updateQuota({ total: 10 * 1000 * 1000, daily: -1 }) |
68e70a74 | 163 | |
26e3e98f | 164 | const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false }) |
89d241a7 | 165 | await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false }) |
68e70a74 C |
166 | }) |
167 | ||
9a82ce24 C |
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 }) | |
3f0ceab0 C |
175 | // Wait previous live cleanups |
176 | await wait(3000) | |
9a82ce24 | 177 | |
6a9b3151 C |
178 | const baseQuota = await servers[0].users.getMyQuotaUsed({ token: userAccessToken }) |
179 | ||
3f0ceab0 C |
180 | let quotaUser: UserVideoQuota |
181 | ||
182 | do { | |
183 | await wait(500) | |
9a82ce24 | 184 | |
3f0ceab0 | 185 | quotaUser = await servers[0].users.getMyQuotaUsed({ token: userAccessToken }) |
57c31865 | 186 | } while (quotaUser.videoQuotaUsed <= baseQuota.videoQuotaUsed) |
9a82ce24 C |
187 | |
188 | const { data } = await servers[0].users.list() | |
189 | const quotaAdmin = data.find(u => u.username === 'user1') | |
190 | ||
6a9b3151 C |
191 | expect(quotaUser.videoQuotaUsed).to.be.above(baseQuota.videoQuotaUsed) |
192 | expect(quotaUser.videoQuotaUsedDaily).to.be.above(baseQuota.videoQuotaUsedDaily) | |
193 | ||
194 | expect(quotaAdmin.videoQuotaUsed).to.be.above(baseQuota.videoQuotaUsed) | |
195 | expect(quotaAdmin.videoQuotaUsedDaily).to.be.above(baseQuota.videoQuotaUsedDaily) | |
9a82ce24 C |
196 | |
197 | expect(quotaUser.videoQuotaUsed).to.be.above(10) | |
198 | expect(quotaUser.videoQuotaUsedDaily).to.be.above(10) | |
6a9b3151 C |
199 | expect(quotaAdmin.videoQuotaUsed).to.be.above(10) |
200 | expect(quotaAdmin.videoQuotaUsedDaily).to.be.above(10) | |
9a82ce24 C |
201 | |
202 | await stopFfmpeg(ffmpegCommand) | |
203 | }) | |
204 | ||
68e70a74 | 205 | it('Should have max duration limit', async function () { |
21609258 | 206 | this.timeout(240000) |
68e70a74 | 207 | |
89d241a7 | 208 | await servers[0].config.updateCustomSubConfig({ |
65e6e260 C |
209 | newConfig: { |
210 | live: { | |
68e70a74 | 211 | enabled: true, |
65e6e260 | 212 | allowReplay: true, |
d8fe90dd | 213 | maxDuration: 10, |
65e6e260 C |
214 | transcoding: { |
215 | enabled: true, | |
216 | resolutions: ConfigCommand.getCustomConfigResolutions(true) | |
217 | } | |
68e70a74 C |
218 | } |
219 | } | |
220 | }) | |
221 | ||
26e3e98f | 222 | const userVideoLiveoId = await createLiveWrapper({ replay: true, permanent: false }) |
89d241a7 | 223 | await servers[0].live.runAndTestStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) |
68e70a74 | 224 | |
9295c68b | 225 | await waitUntilLiveReplacedByReplayOnAllServers(servers, userVideoLiveoId) |
68e70a74 C |
226 | await waitJobs(servers) |
227 | ||
8dd754c7 | 228 | await checkSaveReplay(userVideoLiveoId, [ 720, 480, 360, 240, 144 ]) |
26e3e98f C |
229 | |
230 | const session = await servers[0].live.getReplaySession({ videoId: userVideoLiveoId }) | |
231 | expect(session.error).to.equal(LiveVideoError.DURATION_EXCEEDED) | |
68e70a74 C |
232 | }) |
233 | ||
234 | after(async function () { | |
235 | await cleanupTests(servers) | |
236 | }) | |
237 | }) |