aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/runners
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-05-04 15:29:34 +0200
committerChocobozzz <chocobozzz@cpy.re>2023-05-09 08:57:34 +0200
commit5e47f6ab984a7d00782e4c7030afffa1ba480add (patch)
tree1ce586b591a8d71acbc301eba29b9a5e6490439e /server/tests/api/runners
parent6a4905602636afd6650c9e6f4d0fcc2105d91100 (diff)
downloadPeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.gz
PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.zst
PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.zip
Support studio transcoding in peertube runner
Diffstat (limited to 'server/tests/api/runners')
-rw-r--r--server/tests/api/runners/index.ts1
-rw-r--r--server/tests/api/runners/runner-common.ts12
-rw-r--r--server/tests/api/runners/runner-studio-transcoding.ts168
-rw-r--r--server/tests/api/runners/runner-vod-transcoding.ts16
4 files changed, 187 insertions, 10 deletions
diff --git a/server/tests/api/runners/index.ts b/server/tests/api/runners/index.ts
index 7f33ec8dd..642a3a96d 100644
--- a/server/tests/api/runners/index.ts
+++ b/server/tests/api/runners/index.ts
@@ -1,4 +1,5 @@
1export * from './runner-common' 1export * from './runner-common'
2export * from './runner-live-transcoding' 2export * from './runner-live-transcoding'
3export * from './runner-socket' 3export * from './runner-socket'
4export * from './runner-studio-transcoding'
4export * from './runner-vod-transcoding' 5export * from './runner-vod-transcoding'
diff --git a/server/tests/api/runners/runner-common.ts b/server/tests/api/runners/runner-common.ts
index a2204753b..554024190 100644
--- a/server/tests/api/runners/runner-common.ts
+++ b/server/tests/api/runners/runner-common.ts
@@ -2,7 +2,15 @@
2 2
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { wait } from '@shared/core-utils' 4import { wait } from '@shared/core-utils'
5import { HttpStatusCode, Runner, RunnerJob, RunnerJobAdmin, RunnerJobState, RunnerRegistrationToken } from '@shared/models' 5import {
6 HttpStatusCode,
7 Runner,
8 RunnerJob,
9 RunnerJobAdmin,
10 RunnerJobState,
11 RunnerJobVODWebVideoTranscodingPayload,
12 RunnerRegistrationToken
13} from '@shared/models'
6import { 14import {
7 cleanupTests, 15 cleanupTests,
8 createSingleServer, 16 createSingleServer,
@@ -349,7 +357,7 @@ describe('Test runner common actions', function () {
349 for (const job of availableJobs) { 357 for (const job of availableJobs) {
350 expect(job.uuid).to.exist 358 expect(job.uuid).to.exist
351 expect(job.payload.input).to.exist 359 expect(job.payload.input).to.exist
352 expect(job.payload.output).to.exist 360 expect((job.payload as RunnerJobVODWebVideoTranscodingPayload).output).to.exist
353 361
354 expect((job as RunnerJobAdmin).privatePayload).to.not.exist 362 expect((job as RunnerJobAdmin).privatePayload).to.not.exist
355 } 363 }
diff --git a/server/tests/api/runners/runner-studio-transcoding.ts b/server/tests/api/runners/runner-studio-transcoding.ts
new file mode 100644
index 000000000..9ae629be6
--- /dev/null
+++ b/server/tests/api/runners/runner-studio-transcoding.ts
@@ -0,0 +1,168 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { readFile } from 'fs-extra'
5import { checkPersistentTmpIsEmpty, checkVideoDuration } from '@server/tests/shared'
6import { buildAbsoluteFixturePath } from '@shared/core-utils'
7import {
8 RunnerJobVideoEditionTranscodingPayload,
9 VideoEditionTranscodingSuccess,
10 VideoState,
11 VideoStudioTask,
12 VideoStudioTaskIntro
13} from '@shared/models'
14import {
15 cleanupTests,
16 createMultipleServers,
17 doubleFollow,
18 PeerTubeServer,
19 setAccessTokensToServers,
20 setDefaultVideoChannel,
21 VideoStudioCommand,
22 waitJobs
23} from '@shared/server-commands'
24
25describe('Test runner video studio transcoding', function () {
26 let servers: PeerTubeServer[] = []
27 let runnerToken: string
28 let videoUUID: string
29 let jobUUID: string
30
31 async function renewStudio (tasks: VideoStudioTask[] = VideoStudioCommand.getComplexTask()) {
32 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
33 videoUUID = uuid
34
35 await waitJobs(servers)
36
37 await servers[0].videoStudio.createEditionTasks({ videoId: uuid, tasks })
38 await waitJobs(servers)
39
40 const { availableJobs } = await servers[0].runnerJobs.request({ runnerToken })
41 expect(availableJobs).to.have.lengthOf(1)
42
43 jobUUID = availableJobs[0].uuid
44 }
45
46 before(async function () {
47 this.timeout(120_000)
48
49 servers = await createMultipleServers(2)
50
51 await setAccessTokensToServers(servers)
52 await setDefaultVideoChannel(servers)
53
54 await doubleFollow(servers[0], servers[1])
55
56 await servers[0].config.enableTranscoding(true, true)
57 await servers[0].config.enableStudio()
58 await servers[0].config.enableRemoteStudio()
59
60 runnerToken = await servers[0].runners.autoRegisterRunner()
61 })
62
63 it('Should error a studio transcoding job', async function () {
64 this.timeout(60000)
65
66 await renewStudio()
67
68 for (let i = 0; i < 5; i++) {
69 const { job } = await servers[0].runnerJobs.accept({ runnerToken, jobUUID })
70 const jobToken = job.jobToken
71
72 await servers[0].runnerJobs.error({ runnerToken, jobUUID, jobToken, message: 'Error' })
73 }
74
75 const video = await servers[0].videos.get({ id: videoUUID })
76 expect(video.state.id).to.equal(VideoState.PUBLISHED)
77
78 await checkPersistentTmpIsEmpty(servers[0])
79 })
80
81 it('Should cancel a transcoding job', async function () {
82 this.timeout(60000)
83
84 await renewStudio()
85
86 await servers[0].runnerJobs.cancelByAdmin({ jobUUID })
87
88 const video = await servers[0].videos.get({ id: videoUUID })
89 expect(video.state.id).to.equal(VideoState.PUBLISHED)
90
91 await checkPersistentTmpIsEmpty(servers[0])
92 })
93
94 it('Should execute a remote studio job', async function () {
95 this.timeout(240_000)
96
97 const tasks = [
98 {
99 name: 'add-outro' as 'add-outro',
100 options: {
101 file: 'video_short.webm'
102 }
103 },
104 {
105 name: 'add-watermark' as 'add-watermark',
106 options: {
107 file: 'thumbnail.png'
108 }
109 },
110 {
111 name: 'add-intro' as 'add-intro',
112 options: {
113 file: 'video_very_short_240p.mp4'
114 }
115 }
116 ]
117
118 await renewStudio(tasks)
119
120 for (const server of servers) {
121 await checkVideoDuration(server, videoUUID, 5)
122 }
123
124 const { job } = await servers[0].runnerJobs.accept<RunnerJobVideoEditionTranscodingPayload>({ runnerToken, jobUUID })
125 const jobToken = job.jobToken
126
127 expect(job.type === 'video-edition-transcoding')
128 expect(job.payload.input.videoFileUrl).to.exist
129
130 // Check video input file
131 {
132 await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
133 }
134
135 // Check task files
136 for (let i = 0; i < tasks.length; i++) {
137 const task = tasks[i]
138 const payloadTask = job.payload.tasks[i]
139
140 expect(payloadTask.name).to.equal(task.name)
141
142 const inputFile = await readFile(buildAbsoluteFixturePath(task.options.file))
143
144 const { body } = await servers[0].runnerJobs.getJobFile({
145 url: (payloadTask as VideoStudioTaskIntro).options.file as string,
146 jobToken,
147 runnerToken
148 })
149
150 expect(body).to.deep.equal(inputFile)
151 }
152
153 const payload: VideoEditionTranscodingSuccess = { videoFile: 'video_very_short_240p.mp4' }
154 await servers[0].runnerJobs.success({ runnerToken, jobUUID, jobToken, payload })
155
156 await waitJobs(servers)
157
158 for (const server of servers) {
159 await checkVideoDuration(server, videoUUID, 2)
160 }
161
162 await checkPersistentTmpIsEmpty(servers[0])
163 })
164
165 after(async function () {
166 await cleanupTests(servers)
167 })
168})
diff --git a/server/tests/api/runners/runner-vod-transcoding.ts b/server/tests/api/runners/runner-vod-transcoding.ts
index 92a47ac3b..b08ee312c 100644
--- a/server/tests/api/runners/runner-vod-transcoding.ts
+++ b/server/tests/api/runners/runner-vod-transcoding.ts
@@ -155,7 +155,7 @@ describe('Test runner VOD transcoding', function () {
155 expect(job.payload.output.resolution).to.equal(720) 155 expect(job.payload.output.resolution).to.equal(720)
156 expect(job.payload.output.fps).to.equal(25) 156 expect(job.payload.output.fps).to.equal(25)
157 157
158 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 158 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
159 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.webm')) 159 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.webm'))
160 160
161 expect(body).to.deep.equal(inputFile) 161 expect(body).to.deep.equal(inputFile)
@@ -200,7 +200,7 @@ describe('Test runner VOD transcoding', function () {
200 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODWebVideoTranscodingPayload>({ runnerToken, jobUUID }) 200 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODWebVideoTranscodingPayload>({ runnerToken, jobUUID })
201 jobToken = job.jobToken 201 jobToken = job.jobToken
202 202
203 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 203 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
204 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4')) 204 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4'))
205 205
206 expect(body).to.deep.equal(inputFile) 206 expect(body).to.deep.equal(inputFile)
@@ -221,7 +221,7 @@ describe('Test runner VOD transcoding', function () {
221 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODWebVideoTranscodingPayload>({ runnerToken, jobUUID }) 221 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODWebVideoTranscodingPayload>({ runnerToken, jobUUID })
222 jobToken = job.jobToken 222 jobToken = job.jobToken
223 223
224 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 224 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
225 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4')) 225 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4'))
226 expect(body).to.deep.equal(inputFile) 226 expect(body).to.deep.equal(inputFile)
227 227
@@ -293,7 +293,7 @@ describe('Test runner VOD transcoding', function () {
293 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID }) 293 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID })
294 jobToken = job.jobToken 294 jobToken = job.jobToken
295 295
296 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 296 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
297 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4')) 297 const inputFile = await readFile(buildAbsoluteFixturePath('video_short.mp4'))
298 298
299 expect(body).to.deep.equal(inputFile) 299 expect(body).to.deep.equal(inputFile)
@@ -337,7 +337,7 @@ describe('Test runner VOD transcoding', function () {
337 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID }) 337 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID })
338 jobToken = job.jobToken 338 jobToken = job.jobToken
339 339
340 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 340 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
341 const inputFile = await readFile(buildAbsoluteFixturePath(maxQualityFile)) 341 const inputFile = await readFile(buildAbsoluteFixturePath(maxQualityFile))
342 expect(body).to.deep.equal(inputFile) 342 expect(body).to.deep.equal(inputFile)
343 343
@@ -446,13 +446,13 @@ describe('Test runner VOD transcoding', function () {
446 expect(job.payload.output.resolution).to.equal(480) 446 expect(job.payload.output.resolution).to.equal(480)
447 447
448 { 448 {
449 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.audioFileUrl, jobToken, runnerToken }) 449 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.audioFileUrl, jobToken, runnerToken })
450 const inputFile = await readFile(buildAbsoluteFixturePath('sample.ogg')) 450 const inputFile = await readFile(buildAbsoluteFixturePath('sample.ogg'))
451 expect(body).to.deep.equal(inputFile) 451 expect(body).to.deep.equal(inputFile)
452 } 452 }
453 453
454 { 454 {
455 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.previewFileUrl, jobToken, runnerToken }) 455 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.previewFileUrl, jobToken, runnerToken })
456 456
457 const video = await servers[0].videos.get({ id: videoUUID }) 457 const video = await servers[0].videos.get({ id: videoUUID })
458 const { body: inputFile } = await makeGetRequest({ 458 const { body: inputFile } = await makeGetRequest({
@@ -503,7 +503,7 @@ describe('Test runner VOD transcoding', function () {
503 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID }) 503 const { job } = await servers[0].runnerJobs.accept<RunnerJobVODHLSTranscodingPayload>({ runnerToken, jobUUID })
504 jobToken = job.jobToken 504 jobToken = job.jobToken
505 505
506 const { body } = await servers[0].runnerJobs.getInputFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken }) 506 const { body } = await servers[0].runnerJobs.getJobFile({ url: job.payload.input.videoFileUrl, jobToken, runnerToken })
507 const inputFile = await readFile(buildAbsoluteFixturePath('video_short_480p.mp4')) 507 const inputFile = await readFile(buildAbsoluteFixturePath('video_short_480p.mp4'))
508 expect(body).to.deep.equal(inputFile) 508 expect(body).to.deep.equal(inputFile)
509 509