From 12dc3a942a13c7f1489822dae052da197ef15905 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 19 Jul 2023 16:02:49 +0200 Subject: Implement replace file in server side --- server/tests/api/check-params/config.ts | 5 + server/tests/api/check-params/video-source.ts | 148 +++++++-- server/tests/api/server/config.ts | 9 + server/tests/api/videos/index.ts | 2 +- server/tests/api/videos/resumable-upload.ts | 8 +- server/tests/api/videos/video-source.ts | 447 ++++++++++++++++++++++++-- server/tests/cli/prune-storage.ts | 22 +- server/tests/shared/videos.ts | 2 +- 8 files changed, 587 insertions(+), 56 deletions(-) (limited to 'server/tests') diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index 80b616ccf..2f523d4ce 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts @@ -170,6 +170,11 @@ describe('Test config API validators', function () { enabled: true } }, + videoFile: { + update: { + enabled: true + } + }, import: { videos: { concurrency: 1, diff --git a/server/tests/api/check-params/video-source.ts b/server/tests/api/check-params/video-source.ts index ca324bb9d..3c641ccd3 100644 --- a/server/tests/api/check-params/video-source.ts +++ b/server/tests/api/check-params/video-source.ts @@ -1,5 +1,12 @@ import { HttpStatusCode } from '@shared/models' -import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' +import { + cleanupTests, + createSingleServer, + PeerTubeServer, + setAccessTokensToServers, + setDefaultVideoChannel, + waitJobs +} from '@shared/server-commands' describe('Test video sources API validator', function () { let server: PeerTubeServer = null @@ -7,35 +14,138 @@ describe('Test video sources API validator', function () { let userToken: string before(async function () { - this.timeout(30000) + this.timeout(120000) server = await createSingleServer(1) await setAccessTokensToServers([ server ]) + await setDefaultVideoChannel([ server ]) - const created = await server.videos.quickUpload({ name: 'video' }) - uuid = created.uuid - - userToken = await server.users.generateUserAndToken('user') + userToken = await server.users.generateUserAndToken('user1') }) - it('Should fail without a valid uuid', async function () { - await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df563d0b0', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) - }) + describe('When getting latest source', function () { - it('Should receive 404 when passing a non existing video id', async function () { - await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df5630b06', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) - }) + before(async function () { + const created = await server.videos.quickUpload({ name: 'video' }) + uuid = created.uuid + }) - it('Should not get the source as unauthenticated', async function () { - await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401, token: null }) - }) + it('Should fail without a valid uuid', async function () { + await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df563d0b0', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + }) + + it('Should receive 404 when passing a non existing video id', async function () { + await server.videos.getSource({ id: '4da6fde3-88f7-4d16-b119-108df5630b06', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + }) + + it('Should not get the source as unauthenticated', async function () { + await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.UNAUTHORIZED_401, token: null }) + }) + + it('Should not get the source with another user', async function () { + await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.FORBIDDEN_403, token: userToken }) + }) - it('Should not get the source with another user', async function () { - await server.videos.getSource({ id: uuid, expectedStatus: HttpStatusCode.FORBIDDEN_403, token: userToken }) + it('Should succeed with the correct parameters get the source as another user', async function () { + await server.videos.getSource({ id: uuid }) + }) }) - it('Should succeed with the correct parameters get the source as another user', async function () { - await server.videos.getSource({ id: uuid }) + describe('When updating source video file', function () { + let userAccessToken: string + let userId: number + + let videoId: string + let userVideoId: string + + before(async function () { + const res = await server.users.generate('user2') + userAccessToken = res.token + userId = res.userId + + const { uuid } = await server.videos.quickUpload({ name: 'video' }) + videoId = uuid + + await waitJobs([ server ]) + }) + + it('Should fail if not enabled on the instance', async function () { + await server.config.disableFileUpdate() + + await server.videos.replaceSourceFile({ videoId, fixture: 'video_short.mp4', expectedStatus: HttpStatusCode.FORBIDDEN_403 }) + }) + + it('Should fail on an unknown video', async function () { + await server.config.enableFileUpdate() + + await server.videos.replaceSourceFile({ videoId: 404, fixture: 'video_short.mp4', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + }) + + it('Should fail with an invalid video', async function () { + await server.config.enableLive({ allowReplay: false }) + + const { video } = await server.live.quickCreate({ saveReplay: false, permanentLive: true }) + await server.videos.replaceSourceFile({ + videoId: video.uuid, + fixture: 'video_short.mp4', + expectedStatus: HttpStatusCode.BAD_REQUEST_400 + }) + }) + + it('Should fail without token', async function () { + await server.videos.replaceSourceFile({ + token: null, + videoId, + fixture: 'video_short.mp4', + expectedStatus: HttpStatusCode.UNAUTHORIZED_401 + }) + }) + + it('Should fail with another user', async function () { + await server.videos.replaceSourceFile({ + token: userAccessToken, + videoId, + fixture: 'video_short.mp4', + expectedStatus: HttpStatusCode.FORBIDDEN_403 + }) + }) + + it('Should fail with an incorrect input file', async function () { + await server.videos.replaceSourceFile({ + fixture: 'video_short_fake.webm', + videoId, + expectedStatus: HttpStatusCode.UNPROCESSABLE_ENTITY_422 + }) + + await server.videos.replaceSourceFile({ + fixture: 'video_short.mkv', + videoId, + expectedStatus: HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415 + }) + }) + + it('Should fail if quota is exceeded', async function () { + this.timeout(60000) + + const { uuid } = await server.videos.quickUpload({ name: 'user video' }) + userVideoId = uuid + await waitJobs([ server ]) + + await server.users.update({ userId, videoQuota: 1 }) + await server.videos.replaceSourceFile({ + token: userAccessToken, + videoId: uuid, + fixture: 'video_short.mp4', + expectedStatus: HttpStatusCode.FORBIDDEN_403 + }) + }) + + it('Should succeed with the correct params', async function () { + this.timeout(60000) + + await server.users.update({ userId, videoQuota: 1000 * 1000 * 1000 }) + await server.videos.replaceSourceFile({ videoId: userVideoId, fixture: 'video_short.mp4' }) + }) }) after(async function () { diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index 0e700eddb..a614d92d2 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts @@ -105,6 +105,8 @@ function checkInitialConfig (server: PeerTubeServer, data: CustomConfig) { expect(data.videoStudio.enabled).to.be.false expect(data.videoStudio.remoteRunners.enabled).to.be.false + expect(data.videoFile.update.enabled).to.be.false + expect(data.import.videos.concurrency).to.equal(2) expect(data.import.videos.http.enabled).to.be.true expect(data.import.videos.torrent.enabled).to.be.true @@ -216,6 +218,8 @@ function checkUpdatedConfig (data: CustomConfig) { expect(data.videoStudio.enabled).to.be.true expect(data.videoStudio.remoteRunners.enabled).to.be.true + expect(data.videoFile.update.enabled).to.be.true + expect(data.import.videos.concurrency).to.equal(4) expect(data.import.videos.http.enabled).to.be.false expect(data.import.videos.torrent.enabled).to.be.false @@ -386,6 +390,11 @@ const newCustomConfig: CustomConfig = { enabled: true } }, + videoFile: { + update: { + enabled: true + } + }, import: { videos: { concurrency: 4, diff --git a/server/tests/api/videos/index.ts b/server/tests/api/videos/index.ts index 9c79b3aa6..01d0c5852 100644 --- a/server/tests/api/videos/index.ts +++ b/server/tests/api/videos/index.ts @@ -13,11 +13,11 @@ import './video-imports' import './video-nsfw' import './video-playlists' import './video-playlist-thumbnails' +import './video-source' import './video-privacy' import './video-schedule-update' import './videos-common-filters' import './videos-history' import './videos-overview' -import './video-source' import './video-static-file-privacy' import './video-storyboard' diff --git a/server/tests/api/videos/resumable-upload.ts b/server/tests/api/videos/resumable-upload.ts index 91eb61833..cac1201e9 100644 --- a/server/tests/api/videos/resumable-upload.ts +++ b/server/tests/api/videos/resumable-upload.ts @@ -11,6 +11,7 @@ import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServ // Most classic resumable upload tests are done in other test suites describe('Test resumable upload', function () { + const path = '/api/v1/videos/upload-resumable' const defaultFixture = 'video_short.mp4' let server: PeerTubeServer let rootId: number @@ -44,7 +45,7 @@ describe('Test resumable upload', function () { const mimetype = 'video/mp4' - const res = await server.videos.prepareResumableUpload({ token, attributes, size, mimetype, originalName, lastModified }) + const res = await server.videos.prepareResumableUpload({ path, token, attributes, size, mimetype, originalName, lastModified }) return res.header['location'].split('?')[1] } @@ -66,6 +67,7 @@ describe('Test resumable upload', function () { return server.videos.sendResumableChunks({ token, + path, pathUploadId, videoFilePath: absoluteFilePath, size, @@ -125,7 +127,7 @@ describe('Test resumable upload', function () { it('Should correctly delete files after an upload', async function () { const uploadId = await prepareUpload() await sendChunks({ pathUploadId: uploadId }) - await server.videos.endResumableUpload({ pathUploadId: uploadId }) + await server.videos.endResumableUpload({ path, pathUploadId: uploadId }) expect(await countResumableUploads()).to.equal(0) }) @@ -251,7 +253,7 @@ describe('Test resumable upload', function () { const uploadId1 = await prepareUpload({ originalName, lastModified, token: server.accessToken }) await sendChunks({ pathUploadId: uploadId1 }) - await server.videos.endResumableUpload({ pathUploadId: uploadId1 }) + await server.videos.endResumableUpload({ path, pathUploadId: uploadId1 }) const uploadId2 = await prepareUpload({ originalName, lastModified, token: server.accessToken }) expect(uploadId1).to.equal(uploadId2) 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 @@ import { expect } from 'chai' -import { cleanupTests, createSingleServer, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' +import { expectStartWith } from '@server/tests/shared' +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ +import { areMockObjectStorageTestsDisabled, getAllFiles } from '@shared/core-utils' +import { HttpStatusCode } from '@shared/models' +import { + cleanupTests, + createMultipleServers, + doubleFollow, + makeGetRequest, + makeRawRequest, + ObjectStorageCommand, + PeerTubeServer, + setAccessTokensToServers, + setDefaultAccountAvatar, + setDefaultVideoChannel, + waitJobs +} from '@shared/server-commands' -describe('Test video source', () => { - let server: PeerTubeServer = null - const fixture = 'video_short.webm' +describe('Test a video file replacement', function () { + let servers: PeerTubeServer[] = [] + + let replaceDate: Date + let userToken: string + let uuid: string before(async function () { - this.timeout(30000) + this.timeout(50000) + + servers = await createMultipleServers(2) + + // Get the access tokens + await setAccessTokensToServers(servers) + await setDefaultVideoChannel(servers) + await setDefaultAccountAvatar(servers) + + await servers[0].config.enableFileUpdate() - server = await createSingleServer(1) - await setAccessTokensToServers([ server ]) + userToken = await servers[0].users.generateUserAndToken('user1') + + // Server 1 and server 2 follow each other + await doubleFollow(servers[0], servers[1]) }) - it('Should get the source filename with legacy upload', async function () { - this.timeout(30000) + describe('Getting latest video source', () => { + const fixture = 'video_short.webm' + const uuids: string[] = [] + + it('Should get the source filename with legacy upload', async function () { + this.timeout(30000) + + const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' }) + uuids.push(uuid) - const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'legacy' }) + const source = await servers[0].videos.getSource({ id: uuid }) + expect(source.filename).to.equal(fixture) + }) - const source = await server.videos.getSource({ id: uuid }) - expect(source.filename).to.equal(fixture) + it('Should get the source filename with resumable upload', async function () { + this.timeout(30000) + + const { uuid } = await servers[0].videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' }) + uuids.push(uuid) + + const source = await servers[0].videos.getSource({ id: uuid }) + expect(source.filename).to.equal(fixture) + }) + + after(async function () { + this.timeout(60000) + + for (const uuid of uuids) { + await servers[0].videos.remove({ id: uuid }) + } + + await waitJobs(servers) + }) }) - it('Should get the source filename with resumable upload', async function () { - this.timeout(30000) + describe('Updating video source', function () { + + describe('Filesystem', function () { + + it('Should replace a video file with transcoding disabled', async function () { + this.timeout(120000) + + await servers[0].config.disableTranscoding() + + const { uuid } = await servers[0].videos.quickUpload({ name: 'fs without transcoding', fixture: 'video_short_720p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(1) + expect(files[0].resolution.id).to.equal(720) + } + + await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(1) + expect(files[0].resolution.id).to.equal(360) + } + }) + + it('Should replace a video file with transcoding enabled', async function () { + this.timeout(120000) + + const previousPaths: string[] = [] + + await servers[0].config.enableTranscoding(true, true, true) + + const { uuid: videoUUID } = await servers[0].videos.quickUpload({ name: 'fs with transcoding', fixture: 'video_short_720p.mp4' }) + uuid = videoUUID + + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + expect(video.inputFileUpdatedAt).to.be.null + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(6 * 2) + + // Grab old paths to ensure we'll regenerate + + previousPaths.push(video.previewPath) + previousPaths.push(video.thumbnailPath) + + for (const file of files) { + previousPaths.push(file.fileUrl) + previousPaths.push(file.torrentUrl) + previousPaths.push(file.metadataUrl) + + const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl }) + previousPaths.push(JSON.stringify(metadata)) + } + + const { storyboards } = await server.storyboard.list({ id: uuid }) + for (const s of storyboards) { + previousPaths.push(s.storyboardPath) + } + } + + replaceDate = new Date() + + await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + expect(video.inputFileUpdatedAt).to.not.be.null + expect(new Date(video.inputFileUpdatedAt)).to.be.above(replaceDate) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(4 * 2) + + expect(previousPaths).to.not.include(video.previewPath) + expect(previousPaths).to.not.include(video.thumbnailPath) + + await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 }) + await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 }) + + for (const file of files) { + expect(previousPaths).to.not.include(file.fileUrl) + expect(previousPaths).to.not.include(file.torrentUrl) + expect(previousPaths).to.not.include(file.metadataUrl) + + await makeRawRequest({ url: file.fileUrl, expectedStatus: HttpStatusCode.OK_200 }) + await makeRawRequest({ url: file.torrentUrl, expectedStatus: HttpStatusCode.OK_200 }) + + const metadata = await server.videos.getFileMetadata({ url: file.metadataUrl }) + expect(previousPaths).to.not.include(JSON.stringify(metadata)) + } + + const { storyboards } = await server.storyboard.list({ id: uuid }) + for (const s of storyboards) { + expect(previousPaths).to.not.include(s.storyboardPath) + + await makeGetRequest({ url: server.url, path: s.storyboardPath, expectedStatus: HttpStatusCode.OK_200 }) + } + } + + await servers[0].config.enableMinimumTranscoding() + }) + + it('Should have cleaned up old files', async function () { + { + const count = await servers[0].servers.countFiles('storyboards') + expect(count).to.equal(2) + } + + { + const count = await servers[0].servers.countFiles('web-videos') + expect(count).to.equal(5 + 1) // +1 for private directory + } + + { + const count = await servers[0].servers.countFiles('streaming-playlists/hls') + expect(count).to.equal(1 + 1) // +1 for private directory + } + + { + const count = await servers[0].servers.countFiles('torrents') + expect(count).to.equal(9) + } + }) + + it('Should have the correct source input', async function () { + const source = await servers[0].videos.getSource({ id: uuid }) + + expect(source.filename).to.equal('video_short_360p.mp4') + expect(new Date(source.createdAt)).to.be.above(replaceDate) + }) + + it('Should not have regenerated miniatures that were previously uploaded', async function () { + this.timeout(120000) + + const { uuid } = await servers[0].videos.upload({ + attributes: { + name: 'custom miniatures', + thumbnailfile: 'custom-thumbnail.jpg', + previewfile: 'custom-preview.jpg' + } + }) + + await waitJobs(servers) + + const previousPaths: string[] = [] + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + previousPaths.push(video.previewPath) + previousPaths.push(video.thumbnailPath) + + await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 }) + await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 }) + } + + await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + expect(previousPaths).to.include(video.previewPath) + expect(previousPaths).to.include(video.thumbnailPath) + + await makeGetRequest({ url: server.url, path: video.previewPath, expectedStatus: HttpStatusCode.OK_200 }) + await makeGetRequest({ url: server.url, path: video.thumbnailPath, expectedStatus: HttpStatusCode.OK_200 }) + } + }) + }) + + describe('Autoblacklist', function () { + + function updateAutoBlacklist (enabled: boolean) { + return servers[0].config.updateExistingSubConfig({ + newConfig: { + autoBlacklist: { + videos: { + ofUsers: { + enabled + } + } + } + } + }) + } + + async function expectBlacklist (uuid: string, value: boolean) { + const video = await servers[0].videos.getWithToken({ id: uuid }) + + expect(video.blacklisted).to.equal(value) + } + + before(async function () { + await updateAutoBlacklist(true) + }) + + it('Should auto blacklist an unblacklisted video after file replacement', async function () { + this.timeout(120000) + + const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' }) + await waitJobs(servers) + await expectBlacklist(uuid, true) + + await servers[0].blacklist.remove({ videoId: uuid }) + await expectBlacklist(uuid, false) + + await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + await expectBlacklist(uuid, true) + }) + + it('Should auto blacklist an already blacklisted video after file replacement', async function () { + this.timeout(120000) + + const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' }) + await waitJobs(servers) + await expectBlacklist(uuid, true) + + await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + await expectBlacklist(uuid, true) + }) + + it('Should not auto blacklist if auto blacklist has been disabled between the upload and the replacement', async function () { + this.timeout(120000) + + const { uuid } = await servers[0].videos.quickUpload({ token: userToken, name: 'user video' }) + await waitJobs(servers) + await expectBlacklist(uuid, true) + + await servers[0].blacklist.remove({ videoId: uuid }) + await expectBlacklist(uuid, false) + + await updateAutoBlacklist(false) + + await servers[0].videos.replaceSourceFile({ videoId: uuid, token: userToken, fixture: 'video_short1.webm' }) + await waitJobs(servers) + + await expectBlacklist(uuid, false) + }) + }) + + describe('With object storage enabled', function () { + if (areMockObjectStorageTestsDisabled()) return + + const objectStorage = new ObjectStorageCommand() + + before(async function () { + this.timeout(120000) + + const configOverride = objectStorage.getDefaultMockConfig() + await objectStorage.prepareDefaultMockBuckets() + + await servers[0].kill() + await servers[0].run(configOverride) + }) + + it('Should replace a video file with transcoding disabled', async function () { + this.timeout(120000) + + await servers[0].config.disableTranscoding() + + const { uuid } = await servers[0].videos.quickUpload({ + name: 'object storage without transcoding', + fixture: 'video_short_720p.mp4' + }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(1) + expect(files[0].resolution.id).to.equal(720) + expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl()) + } + + await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_360p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(1) + expect(files[0].resolution.id).to.equal(360) + expectStartWith(files[0].fileUrl, objectStorage.getMockWebVideosBaseUrl()) + } + }) + + it('Should replace a video file with transcoding enabled', async function () { + this.timeout(120000) + + const previousPaths: string[] = [] + + await servers[0].config.enableTranscoding(true, true, true) + + const { uuid: videoUUID } = await servers[0].videos.quickUpload({ + name: 'object storage with transcoding', + fixture: 'video_short_360p.mp4' + }) + uuid = videoUUID + + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(4 * 2) + + for (const file of files) { + previousPaths.push(file.fileUrl) + } + + for (const file of video.files) { + expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl()) + } + + for (const file of video.streamingPlaylists[0].files) { + expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl()) + } + } + + await servers[0].videos.replaceSourceFile({ videoId: uuid, fixture: 'video_short_240p.mp4' }) + await waitJobs(servers) + + for (const server of servers) { + const video = await server.videos.get({ id: uuid }) + + const files = getAllFiles(video) + expect(files).to.have.lengthOf(3 * 2) + + for (const file of files) { + expect(previousPaths).to.not.include(file.fileUrl) + } - const { uuid } = await server.videos.upload({ attributes: { name: 'my video', fixture }, mode: 'resumable' }) + for (const file of video.files) { + expectStartWith(file.fileUrl, objectStorage.getMockWebVideosBaseUrl()) + } - const source = await server.videos.getSource({ id: uuid }) - expect(source.filename).to.equal(fixture) + for (const file of video.streamingPlaylists[0].files) { + expectStartWith(file.fileUrl, objectStorage.getMockPlaylistBaseUrl()) + } + } + }) + }) }) after(async function () { - await cleanupTests([ server ]) + await cleanupTests(servers) }) }) diff --git a/server/tests/cli/prune-storage.ts b/server/tests/cli/prune-storage.ts index 00f63570f..72a4b1332 100644 --- a/server/tests/cli/prune-storage.ts +++ b/server/tests/cli/prune-storage.ts @@ -19,12 +19,6 @@ import { waitJobs } from '@shared/server-commands' -async function countFiles (server: PeerTubeServer, directory: string) { - const files = await readdir(server.servers.buildDirectory(directory)) - - return files.length -} - async function assertNotExists (server: PeerTubeServer, directory: string, substring: string) { const files = await readdir(server.servers.buildDirectory(directory)) @@ -35,28 +29,28 @@ async function assertNotExists (server: PeerTubeServer, directory: string, subst async function assertCountAreOkay (servers: PeerTubeServer[]) { for (const server of servers) { - const videosCount = await countFiles(server, 'web-videos') + const videosCount = await server.servers.countFiles('web-videos') expect(videosCount).to.equal(9) // 2 videos with 4 resolutions + private directory - const privateVideosCount = await countFiles(server, 'web-videos/private') + const privateVideosCount = await server.servers.countFiles('web-videos/private') expect(privateVideosCount).to.equal(4) - const torrentsCount = await countFiles(server, 'torrents') + const torrentsCount = await server.servers.countFiles('torrents') expect(torrentsCount).to.equal(24) - const previewsCount = await countFiles(server, 'previews') + const previewsCount = await server.servers.countFiles('previews') expect(previewsCount).to.equal(3) - const thumbnailsCount = await countFiles(server, 'thumbnails') + const thumbnailsCount = await server.servers.countFiles('thumbnails') expect(thumbnailsCount).to.equal(5) // 3 local videos, 1 local playlist, 2 remotes videos (lazy downloaded) and 1 remote playlist - const avatarsCount = await countFiles(server, 'avatars') + const avatarsCount = await server.servers.countFiles('avatars') expect(avatarsCount).to.equal(4) - const hlsRootCount = await countFiles(server, join('streaming-playlists', 'hls')) + const hlsRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls')) expect(hlsRootCount).to.equal(3) // 2 videos + private directory - const hlsPrivateRootCount = await countFiles(server, join('streaming-playlists', 'hls', 'private')) + const hlsPrivateRootCount = await server.servers.countFiles(join('streaming-playlists', 'hls', 'private')) expect(hlsPrivateRootCount).to.equal(1) } } diff --git a/server/tests/shared/videos.ts b/server/tests/shared/videos.ts index e09bd60b5..3f59c329f 100644 --- a/server/tests/shared/videos.ts +++ b/server/tests/shared/videos.ts @@ -277,7 +277,7 @@ function checkUploadVideoParam ( ) { return mode === 'legacy' ? server.videos.buildLegacyUpload({ token, attributes, expectedStatus }) - : server.videos.buildResumeUpload({ token, attributes, expectedStatus }) + : server.videos.buildResumeUpload({ token, attributes, expectedStatus, path: '/api/v1/videos/upload-resumable' }) } // serverNumber starts from 1 -- cgit v1.2.3