2023-04-21 15:00:01 +02:00
|
|
|
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
|
|
|
|
import { expect } from 'chai'
|
2023-05-04 15:29:34 +02:00
|
|
|
import {
|
|
|
|
checkPeerTubeRunnerCacheIsEmpty,
|
|
|
|
completeCheckHlsPlaylist,
|
|
|
|
completeWebVideoFilesCheck,
|
|
|
|
PeerTubeRunnerProcess
|
|
|
|
} from '@server/tests/shared'
|
2023-04-21 15:00:01 +02:00
|
|
|
import { areMockObjectStorageTestsDisabled, getAllFiles, wait } from '@shared/core-utils'
|
|
|
|
import { VideoPrivacy } from '@shared/models'
|
|
|
|
import {
|
|
|
|
cleanupTests,
|
|
|
|
createMultipleServers,
|
|
|
|
doubleFollow,
|
|
|
|
ObjectStorageCommand,
|
|
|
|
PeerTubeServer,
|
|
|
|
setAccessTokensToServers,
|
|
|
|
setDefaultVideoChannel,
|
|
|
|
waitJobs
|
|
|
|
} from '@shared/server-commands'
|
|
|
|
|
|
|
|
describe('Test VOD transcoding in peertube-runner program', function () {
|
|
|
|
let servers: PeerTubeServer[] = []
|
|
|
|
let peertubeRunner: PeerTubeRunnerProcess
|
|
|
|
|
|
|
|
function runSuite (options: {
|
|
|
|
webtorrentEnabled: boolean
|
|
|
|
hlsEnabled: boolean
|
2023-05-23 10:49:45 +02:00
|
|
|
objectStorage?: ObjectStorageCommand
|
2023-04-21 15:00:01 +02:00
|
|
|
}) {
|
|
|
|
const { webtorrentEnabled, hlsEnabled, objectStorage } = options
|
|
|
|
|
|
|
|
const objectStorageBaseUrlWebTorrent = objectStorage
|
2023-05-23 10:49:45 +02:00
|
|
|
? objectStorage.getMockWebVideosBaseUrl()
|
2023-04-21 15:00:01 +02:00
|
|
|
: undefined
|
|
|
|
|
|
|
|
const objectStorageBaseUrlHLS = objectStorage
|
2023-05-23 10:49:45 +02:00
|
|
|
? objectStorage.getMockPlaylistBaseUrl()
|
2023-04-21 15:00:01 +02:00
|
|
|
: undefined
|
|
|
|
|
|
|
|
it('Should upload a classic video mp4 and transcode it', async function () {
|
|
|
|
this.timeout(120000)
|
|
|
|
|
|
|
|
const { uuid } = await servers[0].videos.quickUpload({ name: 'mp4', fixture: 'video_short.mp4' })
|
|
|
|
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
if (webtorrentEnabled) {
|
|
|
|
await completeWebVideoFilesCheck({
|
|
|
|
server,
|
|
|
|
originServer: servers[0],
|
|
|
|
fixture: 'video_short.mp4',
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
|
|
|
|
files: [
|
|
|
|
{ resolution: 0 },
|
|
|
|
{ resolution: 144 },
|
|
|
|
{ resolution: 240 },
|
|
|
|
{ resolution: 360 },
|
|
|
|
{ resolution: 480 },
|
|
|
|
{ resolution: 720 }
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hlsEnabled) {
|
|
|
|
await completeCheckHlsPlaylist({
|
|
|
|
hlsOnly: !webtorrentEnabled,
|
|
|
|
servers,
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlHLS,
|
|
|
|
resolutions: [ 720, 480, 360, 240, 144, 0 ]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should upload a webm video and transcode it', async function () {
|
|
|
|
this.timeout(120000)
|
|
|
|
|
|
|
|
const { uuid } = await servers[0].videos.quickUpload({ name: 'mp4', fixture: 'video_short.webm' })
|
|
|
|
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
if (webtorrentEnabled) {
|
|
|
|
await completeWebVideoFilesCheck({
|
|
|
|
server,
|
|
|
|
originServer: servers[0],
|
|
|
|
fixture: 'video_short.webm',
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
|
|
|
|
files: [
|
|
|
|
{ resolution: 0 },
|
|
|
|
{ resolution: 144 },
|
|
|
|
{ resolution: 240 },
|
|
|
|
{ resolution: 360 },
|
|
|
|
{ resolution: 480 },
|
|
|
|
{ resolution: 720 }
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hlsEnabled) {
|
|
|
|
await completeCheckHlsPlaylist({
|
|
|
|
hlsOnly: !webtorrentEnabled,
|
|
|
|
servers,
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlHLS,
|
|
|
|
resolutions: [ 720, 480, 360, 240, 144, 0 ]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should upload an audio only video and transcode it', async function () {
|
|
|
|
this.timeout(120000)
|
|
|
|
|
|
|
|
const attributes = { name: 'audio_without_preview', fixture: 'sample.ogg' }
|
|
|
|
const { uuid } = await servers[0].videos.upload({ attributes, mode: 'resumable' })
|
|
|
|
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
for (const server of servers) {
|
|
|
|
if (webtorrentEnabled) {
|
|
|
|
await completeWebVideoFilesCheck({
|
|
|
|
server,
|
|
|
|
originServer: servers[0],
|
|
|
|
fixture: 'sample.ogg',
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
|
|
|
|
files: [
|
|
|
|
{ resolution: 0 },
|
|
|
|
{ resolution: 144 },
|
|
|
|
{ resolution: 240 },
|
|
|
|
{ resolution: 360 },
|
|
|
|
{ resolution: 480 }
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hlsEnabled) {
|
|
|
|
await completeCheckHlsPlaylist({
|
|
|
|
hlsOnly: !webtorrentEnabled,
|
|
|
|
servers,
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlHLS,
|
|
|
|
resolutions: [ 480, 360, 240, 144, 0 ]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should upload a private video and transcode it', async function () {
|
|
|
|
this.timeout(120000)
|
|
|
|
|
|
|
|
const { uuid } = await servers[0].videos.quickUpload({ name: 'mp4', fixture: 'video_short.mp4', privacy: VideoPrivacy.PRIVATE })
|
|
|
|
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
if (webtorrentEnabled) {
|
|
|
|
await completeWebVideoFilesCheck({
|
|
|
|
server: servers[0],
|
|
|
|
originServer: servers[0],
|
|
|
|
fixture: 'video_short.mp4',
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
|
|
|
|
files: [
|
|
|
|
{ resolution: 0 },
|
|
|
|
{ resolution: 144 },
|
|
|
|
{ resolution: 240 },
|
|
|
|
{ resolution: 360 },
|
|
|
|
{ resolution: 480 },
|
|
|
|
{ resolution: 720 }
|
|
|
|
]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hlsEnabled) {
|
|
|
|
await completeCheckHlsPlaylist({
|
|
|
|
hlsOnly: !webtorrentEnabled,
|
|
|
|
servers: [ servers[0] ],
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlHLS,
|
|
|
|
resolutions: [ 720, 480, 360, 240, 144, 0 ]
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
it('Should transcode videos on manual run', async function () {
|
2023-05-22 17:04:39 +02:00
|
|
|
this.timeout(120000)
|
2023-04-21 15:00:01 +02:00
|
|
|
|
|
|
|
await servers[0].config.disableTranscoding()
|
|
|
|
|
|
|
|
const { uuid } = await servers[0].videos.quickUpload({ name: 'manual transcoding', fixture: 'video_short.mp4' })
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
{
|
|
|
|
const video = await servers[0].videos.get({ id: uuid })
|
|
|
|
expect(getAllFiles(video)).to.have.lengthOf(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
await servers[0].config.enableTranscoding(true, true, true)
|
|
|
|
|
|
|
|
await servers[0].videos.runTranscoding({ transcodingType: 'webtorrent', videoId: uuid })
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
await completeWebVideoFilesCheck({
|
|
|
|
server: servers[0],
|
|
|
|
originServer: servers[0],
|
|
|
|
fixture: 'video_short.mp4',
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlWebTorrent,
|
|
|
|
files: [
|
|
|
|
{ resolution: 0 },
|
|
|
|
{ resolution: 144 },
|
|
|
|
{ resolution: 240 },
|
|
|
|
{ resolution: 360 },
|
|
|
|
{ resolution: 480 },
|
|
|
|
{ resolution: 720 }
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
|
|
|
await servers[0].videos.runTranscoding({ transcodingType: 'hls', videoId: uuid })
|
|
|
|
await waitJobs(servers, { runnerJobs: true })
|
|
|
|
|
|
|
|
await completeCheckHlsPlaylist({
|
|
|
|
hlsOnly: false,
|
|
|
|
servers: [ servers[0] ],
|
|
|
|
videoUUID: uuid,
|
|
|
|
objectStorageBaseUrl: objectStorageBaseUrlHLS,
|
|
|
|
resolutions: [ 720, 480, 360, 240, 144, 0 ]
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
this.timeout(120_000)
|
|
|
|
|
|
|
|
servers = await createMultipleServers(2)
|
|
|
|
|
|
|
|
await setAccessTokensToServers(servers)
|
|
|
|
await setDefaultVideoChannel(servers)
|
|
|
|
|
|
|
|
await doubleFollow(servers[0], servers[1])
|
|
|
|
|
|
|
|
await servers[0].config.enableRemoteTranscoding()
|
|
|
|
|
|
|
|
const registrationToken = await servers[0].runnerRegistrationTokens.getFirstRegistrationToken()
|
|
|
|
|
2023-05-19 13:33:27 +02:00
|
|
|
peertubeRunner = new PeerTubeRunnerProcess(servers[0])
|
2023-04-21 15:00:01 +02:00
|
|
|
await peertubeRunner.runServer()
|
2023-05-19 13:33:27 +02:00
|
|
|
await peertubeRunner.registerPeerTubeInstance({ registrationToken, runnerName: 'runner' })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('With videos on local filesystem storage', function () {
|
|
|
|
|
|
|
|
describe('Web video only enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(true, false, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: true, hlsEnabled: false })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('HLS videos only enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(false, true, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: false, hlsEnabled: true })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('Web video & HLS enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(true, true, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: true, hlsEnabled: true })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('With videos on object storage', function () {
|
|
|
|
if (areMockObjectStorageTestsDisabled()) return
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
const objectStorage = new ObjectStorageCommand()
|
|
|
|
|
2023-04-21 15:00:01 +02:00
|
|
|
before(async function () {
|
2023-05-23 10:49:45 +02:00
|
|
|
await objectStorage.prepareDefaultMockBuckets()
|
2023-04-21 15:00:01 +02:00
|
|
|
|
|
|
|
await servers[0].kill()
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
await servers[0].run(objectStorage.getDefaultMockConfig())
|
2023-04-21 15:00:01 +02:00
|
|
|
|
|
|
|
// Wait for peertube runner socket reconnection
|
|
|
|
await wait(1500)
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('Web video only enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(true, false, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: true, hlsEnabled: false, objectStorage })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('HLS videos only enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(false, true, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: false, hlsEnabled: true, objectStorage })
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
describe('Web video & HLS enabled', function () {
|
|
|
|
|
|
|
|
before(async function () {
|
|
|
|
await servers[0].config.enableTranscoding(true, true, true)
|
|
|
|
})
|
|
|
|
|
2023-05-23 10:49:45 +02:00
|
|
|
runSuite({ webtorrentEnabled: true, hlsEnabled: true, objectStorage })
|
|
|
|
})
|
|
|
|
|
|
|
|
after(async function () {
|
|
|
|
await objectStorage.cleanupMock()
|
2023-04-21 15:00:01 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2023-05-04 15:29:34 +02:00
|
|
|
describe('Check cleanup', function () {
|
|
|
|
|
|
|
|
it('Should have an empty cache directory', async function () {
|
2023-05-19 14:35:03 +02:00
|
|
|
await checkPeerTubeRunnerCacheIsEmpty(peertubeRunner)
|
2023-05-04 15:29:34 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2023-04-21 15:00:01 +02:00
|
|
|
after(async function () {
|
2023-05-05 13:41:48 +02:00
|
|
|
if (peertubeRunner) {
|
2023-05-26 09:03:50 +02:00
|
|
|
await peertubeRunner.unregisterPeerTubeInstance({ runnerName: 'runner' })
|
2023-05-05 13:41:48 +02:00
|
|
|
peertubeRunner.kill()
|
|
|
|
}
|
2023-04-21 15:00:01 +02:00
|
|
|
|
|
|
|
await cleanupTests(servers)
|
|
|
|
})
|
|
|
|
})
|