aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/videos/video-source.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/api/videos/video-source.ts')
-rw-r--r--server/tests/api/videos/video-source.ts447
1 files changed, 429 insertions, 18 deletions
diff --git a/server/tests/api/videos/video-source.ts b/server/tests/api/videos/video-source.ts
index 5ecf8316f..8669f342e 100644
--- a/server/tests/api/videos/video-source.ts
+++ b/server/tests/api/videos/video-source.ts
@@ -1,36 +1,447 @@
1import { expect } from 'chai' 1import { expect } from 'chai'
2import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' 2import { expectStartWith } from '@server/tests/shared'
3/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
4import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils'
5import { HttpStatusCode } from '@shared/models'
6import {
7 cleanupTests,
8 createMultipleServers,
9 doubleFollow,
10 makeGetRequest,
11 makeRawRequest,
12 ObjectStorageCommand,
13 PeerTubeServer,
14 setAccessTokensToServers,
15 setDefaultAccountAvatar,
16 setDefaultVideoChannel,
17 waitJobs
18} from '@shared/server-commands'
3 19
4describe('Test video source', () => { 20describe('Test a video file replacement', function () {
5 let server: PeerTubeServer = null 21 let servers: PeerTubeServer[] = []
6 const fixture = 'video_short.webm' 22
23 let replaceDate: Date
24 let userToken: string
25 let uuid: string
7 26
8 before(async function () { 27 before(async function () {
9 this.timeout(30000) 28 this.timeout(50000)
29
30 servers = await createMultipleServers(2)
31
32 // Get the access tokens
33 await setAccessTokensToServers(servers)
34 await setDefaultVideoChannel(servers)
35 await setDefaultAccountAvatar(servers)
36
37 await servers[0].config.enableFileUpdate()
10 38
11 server = await createSingleServer(1) 39 userToken = await servers[0].users.generateUserAndToken('user1')
12 await setAccessTokensToServers([ server ]) 40
41 // Server 1 and server 2 follow each other
42 await doubleFollow(servers[0], servers[1])
13 }) 43 })
14 44
15 it('Should get the source filename with legacy upload', async function () { 45 describe('Getting latest video source', () => {
16 this.timeout(30000) 46 const fixture = 'video_short.webm'
47 const uuids: string[] = []
48
49 it('Should get the source filename with legacy upload', async function () {
50 this.timeout(30000)
51
52 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' })
53 uuids.push(uuid)
17 54
18 const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' }) 55 const source = await servers[0].videos.getSource({ id: uuid })
56 expect(source.filename).to.equal(fixture)
57 })
19 58
20 const source = await server.videos.getSource({ id: uuid }) 59 it('Should get the source filename with resumable upload', async function () {
21 expect(source.filename).to.equal(fixture) 60 this.timeout(30000)
61
62 const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' })
63 uuids.push(uuid)
64
65 const source = await servers[0].videos.getSource({ id: uuid })
66 expect(source.filename).to.equal(fixture)
67 })
68
69 after(async function () {
70 this.timeout(60000)
71
72 for (const uuid of uuids) {
73 await servers[0].videos.remove({ id: uuid })
74 }
75
76 await waitJobs(servers)
77 })
22 }) 78 })
23 79
24 it('Should get the source filename with resumable upload', async function () { 80 describe('Updating video source', function () {
25 this.timeout(30000) 81
82 describe('Filesystem', function () {
83
84 it('Should replace a video file with transcoding disabled', async function () {
85 this.timeout(120000)
86
87 await servers[0].config.disableTranscoding()
88
89 const { uuid } = await servers[0].videos.quickUpload({ name: 'fs without transcoding', fixture: 'video_short_720p.mp4' })
90 await waitJobs(servers)
91
92 for (const server of servers) {
93 const video = await server.videos.get({ id: uuid })
94
95 const files = getAllFiles(video)
96 expect(files).to.have.lengthOf(1)
97 expect(files[0].resolution.id).to.equal(720)
98 }
99
100 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
101 await waitJobs(servers)
102
103 for (const server of servers) {
104 const video = await server.videos.get({ id: uuid })
105
106 const files = getAllFiles(video)
107 expect(files).to.have.lengthOf(1)
108 expect(files[0].resolution.id).to.equal(360)
109 }
110 })
111
112 it('Should replace a video file with transcoding enabled', async function () {
113 this.timeout(120000)
114
115 const previousPaths: string[] = []
116
117 await servers[0].config.enableTranscoding(true, true, true)
118
119 const { uuid: videoUUID } = await servers[0].videos.quickUpload({ name: 'fs with transcoding', fixture: 'video_short_720p.mp4' })
120 uuid = videoUUID
121
122 await waitJobs(servers)
123
124 for (const server of servers) {
125 const video = await server.videos.get({ id: uuid })
126 expect(video.inputFileUpdatedAt).to.be.null
127
128 const files = getAllFiles(video)
129 expect(files).to.have.lengthOf(6 * 2)
130
131 // Grab old paths to ensure we'll regenerate
132
133 previousPaths.push(video.previewPath)
134 previousPaths.push(video.thumbnailPath)
135
136 for (const file of files) {
137 previousPaths.push(file.fileUrl)
138 previousPaths.push(file.torrentUrl)
139 previousPaths.push(file.metadataUrl)
140
141 const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl })
142 previousPaths.push(JSON.stringify(metadata))
143 }
144
145 const { storyboards } = await server.storyboard.list({ id: uuid })
146 for (const s of storyboards) {
147 previousPaths.push(s.storyboardPath)
148 }
149 }
150
151 replaceDate = new Date()
152
153 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
154 await waitJobs(servers)
155
156 for (const server of servers) {
157 const video = await server.videos.get({ id: uuid })
158
159 expect(video.inputFileUpdatedAt).to.not.be.null
160 expect(new Date(video.inputFileUpdatedAt)).to.be.above(replaceDate)
161
162 const files = getAllFiles(video)
163 expect(files).to.have.lengthOf(4 * 2)
164
165 expect(previousPaths).to.not.include(video.previewPath)
166 expect(previousPaths).to.not.include(video.thumbnailPath)
167
168 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
169 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
170
171 for (const file of files) {
172 expect(previousPaths).to.not.include(file.fileUrl)
173 expect(previousPaths).to.not.include(file.torrentUrl)
174 expect(previousPaths).to.not.include(file.metadataUrl)
175
176 await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 })
177 await makeRawRequest({ url: file.torrentUrl, expectedStatus: HttpStatusCode.OK_200 })
178
179 const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl })
180 expect(previousPaths).to.not.include(JSON.stringify(metadata))
181 }
182
183 const { storyboards } = await server.storyboard.list({ id: uuid })
184 for (const s of storyboards) {
185 expect(previousPaths).to.not.include(s.storyboardPath)
186
187 await makeGetRequest({ url: server.url, path: s.storyboardPath, expectedStatus: HttpStatusCode.OK_200 })
188 }
189 }
190
191 await servers[0].config.enableMinimumTranscoding()
192 })
193
194 it('Should have cleaned up old files', async function () {
195 {
196 const count = await servers[0].servers.countFiles('storyboards')
197 expect(count).to.equal(2)
198 }
199
200 {
201 const count = await servers[0].servers.countFiles('web-videos')
202 expect(count).to.equal(5 + 1) // +1 for private directory
203 }
204
205 {
206 const count = await servers[0].servers.countFiles('streaming-playlists/hls')
207 expect(count).to.equal(1 + 1) // +1 for private directory
208 }
209
210 {
211 const count = await servers[0].servers.countFiles('torrents')
212 expect(count).to.equal(9)
213 }
214 })
215
216 it('Should have the correct source input', async function () {
217 const source = await servers[0].videos.getSource({ id: uuid })
218
219 expect(source.filename).to.equal('video_short_360p.mp4')
220 expect(new Date(source.createdAt)).to.be.above(replaceDate)
221 })
222
223 it('Should not have regenerated miniatures that were previously uploaded', async function () {
224 this.timeout(120000)
225
226 const { uuid } = await servers[0].videos.upload({
227 attributes: {
228 name: 'custom miniatures',
229 thumbnailfile: 'custom-thumbnail.jpg',
230 previewfile: 'custom-preview.jpg'
231 }
232 })
233
234 await waitJobs(servers)
235
236 const previousPaths: string[] = []
237
238 for (const server of servers) {
239 const video = await server.videos.get({ id: uuid })
240
241 previousPaths.push(video.previewPath)
242 previousPaths.push(video.thumbnailPath)
243
244 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
245 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
246 }
247
248 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
249 await waitJobs(servers)
250
251 for (const server of servers) {
252 const video = await server.videos.get({ id: uuid })
253
254 expect(previousPaths).to.include(video.previewPath)
255 expect(previousPaths).to.include(video.thumbnailPath)
256
257 await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 })
258 await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 })
259 }
260 })
261 })
262
263 describe('Autoblacklist', function () {
264
265 function updateAutoBlacklist (enabled: boolean) {
266 return servers[0].config.updateExistingSubConfig({
267 newConfig: {
268 autoBlacklist: {
269 videos: {
270 ofUsers: {
271 enabled
272 }
273 }
274 }
275 }
276 })
277 }
278
279 async function expectBlacklist (uuid: string, value: boolean) {
280 const video = await servers[0].videos.getWithToken({ id: uuid })
281
282 expect(video.blacklisted).to.equal(value)
283 }
284
285 before(async function () {
286 await updateAutoBlacklist(true)
287 })
288
289 it('Should auto blacklist an unblacklisted video after file replacement', async function () {
290 this.timeout(120000)
291
292 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
293 await waitJobs(servers)
294 await expectBlacklist(uuid, true)
295
296 await servers[0].blacklist.remove({ videoId: uuid })
297 await expectBlacklist(uuid, false)
298
299 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' })
300 await waitJobs(servers)
301
302 await expectBlacklist(uuid, true)
303 })
304
305 it('Should auto blacklist an already blacklisted video after file replacement', async function () {
306 this.timeout(120000)
307
308 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
309 await waitJobs(servers)
310 await expectBlacklist(uuid, true)
311
312 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' })
313 await waitJobs(servers)
314
315 await expectBlacklist(uuid, true)
316 })
317
318 it('Should not auto blacklist if auto blacklist has been disabled between the upload and the replacement', async function () {
319 this.timeout(120000)
320
321 const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' })
322 await waitJobs(servers)
323 await expectBlacklist(uuid, true)
324
325 await servers[0].blacklist.remove({ videoId: uuid })
326 await expectBlacklist(uuid, false)
327
328 await updateAutoBlacklist(false)
329
330 await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short1.webm' })
331 await waitJobs(servers)
332
333 await expectBlacklist(uuid, false)
334 })
335 })
336
337 describe('With object storage enabled', function () {
338 if (areMockObjectStorageTestsDisabled()) return
339
340 const objectStorage = new ObjectStorageCommand()
341
342 before(async function () {
343 this.timeout(120000)
344
345 const configOverride = objectStorage.getDefaultMockConfig()
346 await objectStorage.prepareDefaultMockBuckets()
347
348 await servers[0].kill()
349 await servers[0].run(configOverride)
350 })
351
352 it('Should replace a video file with transcoding disabled', async function () {
353 this.timeout(120000)
354
355 await servers[0].config.disableTranscoding()
356
357 const { uuid } = await servers[0].videos.quickUpload({
358 name: 'object storage without transcoding',
359 fixture: 'video_short_720p.mp4'
360 })
361 await waitJobs(servers)
362
363 for (const server of servers) {
364 const video = await server.videos.get({ id: uuid })
365
366 const files = getAllFiles(video)
367 expect(files).to.have.lengthOf(1)
368 expect(files[0].resolution.id).to.equal(720)
369 expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl())
370 }
371
372 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' })
373 await waitJobs(servers)
374
375 for (const server of servers) {
376 const video = await server.videos.get({ id: uuid })
377
378 const files = getAllFiles(video)
379 expect(files).to.have.lengthOf(1)
380 expect(files[0].resolution.id).to.equal(360)
381 expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl())
382 }
383 })
384
385 it('Should replace a video file with transcoding enabled', async function () {
386 this.timeout(120000)
387
388 const previousPaths: string[] = []
389
390 await servers[0].config.enableTranscoding(true, true, true)
391
392 const { uuid: videoUUID } = await servers[0].videos.quickUpload({
393 name: 'object storage with transcoding',
394 fixture: 'video_short_360p.mp4'
395 })
396 uuid = videoUUID
397
398 await waitJobs(servers)
399
400 for (const server of servers) {
401 const video = await server.videos.get({ id: uuid })
402
403 const files = getAllFiles(video)
404 expect(files).to.have.lengthOf(4 * 2)
405
406 for (const file of files) {
407 previousPaths.push(file.fileUrl)
408 }
409
410 for (const file of video.files) {
411 expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl())
412 }
413
414 for (const file of video.streamingPlaylists[0].files) {
415 expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl())
416 }
417 }
418
419 await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_240p.mp4' })
420 await waitJobs(servers)
421
422 for (const server of servers) {
423 const video = await server.videos.get({ id: uuid })
424
425 const files = getAllFiles(video)
426 expect(files).to.have.lengthOf(3 * 2)
427
428 for (const file of files) {
429 expect(previousPaths).to.not.include(file.fileUrl)
430 }
26 431
27 const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' }) 432 for (const file of video.files) {
433 expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl())
434 }
28 435
29 const source = await server.videos.getSource({ id: uuid }) 436 for (const file of video.streamingPlaylists[0].files) {
30 expect(source.filename).to.equal(fixture) 437 expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl())
438 }
439 }
440 })
441 })
31 }) 442 })
32 443
33 after(async function () { 444 after(async function () {
34 await cleanupTests([ server ]) 445 await cleanupTests(servers)
35 }) 446 })
36}) 447})