diff options
author | Chocobozzz <me@florianbigard.com> | 2023-05-04 15:29:34 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2023-05-09 08:57:34 +0200 |
commit | 5e47f6ab984a7d00782e4c7030afffa1ba480add (patch) | |
tree | 1ce586b591a8d71acbc301eba29b9a5e6490439e /server/tests/api/check-params | |
parent | 6a4905602636afd6650c9e6f4d0fcc2105d91100 (diff) | |
download | PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.gz PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.zst PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.zip |
Support studio transcoding in peertube runner
Diffstat (limited to 'server/tests/api/check-params')
-rw-r--r-- | server/tests/api/check-params/config.ts | 5 | ||||
-rw-r--r-- | server/tests/api/check-params/runners.ts | 211 |
2 files changed, 194 insertions, 22 deletions
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index c5cda203e..472cad182 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -162,7 +162,10 @@ describe('Test config API validators', function () { | |||
162 | } | 162 | } |
163 | }, | 163 | }, |
164 | videoStudio: { | 164 | videoStudio: { |
165 | enabled: true | 165 | enabled: true, |
166 | remoteRunners: { | ||
167 | enabled: true | ||
168 | } | ||
166 | }, | 169 | }, |
167 | import: { | 170 | import: { |
168 | videos: { | 171 | videos: { |
diff --git a/server/tests/api/check-params/runners.ts b/server/tests/api/check-params/runners.ts index 4da6fd91d..90a301392 100644 --- a/server/tests/api/check-params/runners.ts +++ b/server/tests/api/check-params/runners.ts | |||
@@ -1,6 +1,17 @@ | |||
1 | import { basename } from 'path' | ||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 2 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' | 3 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' |
3 | import { HttpStatusCode, RunnerJob, RunnerJobState, RunnerJobSuccessPayload, RunnerJobUpdatePayload, VideoPrivacy } from '@shared/models' | 4 | import { |
5 | HttpStatusCode, | ||
6 | isVideoStudioTaskIntro, | ||
7 | RunnerJob, | ||
8 | RunnerJobState, | ||
9 | RunnerJobSuccessPayload, | ||
10 | RunnerJobUpdatePayload, | ||
11 | RunnerJobVideoEditionTranscodingPayload, | ||
12 | VideoPrivacy, | ||
13 | VideoStudioTaskIntro | ||
14 | } from '@shared/models' | ||
4 | import { | 15 | import { |
5 | cleanupTests, | 16 | cleanupTests, |
6 | createSingleServer, | 17 | createSingleServer, |
@@ -10,6 +21,7 @@ import { | |||
10 | setAccessTokensToServers, | 21 | setAccessTokensToServers, |
11 | setDefaultVideoChannel, | 22 | setDefaultVideoChannel, |
12 | stopFfmpeg, | 23 | stopFfmpeg, |
24 | VideoStudioCommand, | ||
13 | waitJobs | 25 | waitJobs |
14 | } from '@shared/server-commands' | 26 | } from '@shared/server-commands' |
15 | 27 | ||
@@ -53,7 +65,10 @@ describe('Test managing runners', function () { | |||
53 | registrationTokenId = data[0].id | 65 | registrationTokenId = data[0].id |
54 | 66 | ||
55 | await server.config.enableTranscoding(true, true) | 67 | await server.config.enableTranscoding(true, true) |
68 | await server.config.enableStudio() | ||
56 | await server.config.enableRemoteTranscoding() | 69 | await server.config.enableRemoteTranscoding() |
70 | await server.config.enableRemoteStudio() | ||
71 | |||
57 | runnerToken = await server.runners.autoRegisterRunner() | 72 | runnerToken = await server.runners.autoRegisterRunner() |
58 | runnerToken2 = await server.runners.autoRegisterRunner() | 73 | runnerToken2 = await server.runners.autoRegisterRunner() |
59 | 74 | ||
@@ -249,6 +264,10 @@ describe('Test managing runners', function () { | |||
249 | await server.runnerJobs.cancelByAdmin({ jobUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 264 | await server.runnerJobs.cancelByAdmin({ jobUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) |
250 | }) | 265 | }) |
251 | 266 | ||
267 | it('Should fail with an already cancelled job', async function () { | ||
268 | await server.runnerJobs.cancelByAdmin({ jobUUID: cancelledJobUUID, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
269 | }) | ||
270 | |||
252 | it('Should succeed with the correct params', async function () { | 271 | it('Should succeed with the correct params', async function () { |
253 | await server.runnerJobs.cancelByAdmin({ jobUUID }) | 272 | await server.runnerJobs.cancelByAdmin({ jobUUID }) |
254 | }) | 273 | }) |
@@ -296,9 +315,13 @@ describe('Test managing runners', function () { | |||
296 | 315 | ||
297 | let pendingUUID: string | 316 | let pendingUUID: string |
298 | 317 | ||
318 | let videoStudioUUID: string | ||
319 | let studioFile: string | ||
320 | |||
299 | let liveAcceptedJob: RunnerJob & { jobToken: string } | 321 | let liveAcceptedJob: RunnerJob & { jobToken: string } |
322 | let studioAcceptedJob: RunnerJob & { jobToken: string } | ||
300 | 323 | ||
301 | async function fetchFiles (options: { | 324 | async function fetchVideoInputFiles (options: { |
302 | jobUUID: string | 325 | jobUUID: string |
303 | videoUUID: string | 326 | videoUUID: string |
304 | runnerToken: string | 327 | runnerToken: string |
@@ -315,6 +338,21 @@ describe('Test managing runners', function () { | |||
315 | } | 338 | } |
316 | } | 339 | } |
317 | 340 | ||
341 | async function fetchStudioFiles (options: { | ||
342 | jobUUID: string | ||
343 | videoUUID: string | ||
344 | runnerToken: string | ||
345 | jobToken: string | ||
346 | studioFile?: string | ||
347 | expectedStatus: HttpStatusCode | ||
348 | }) { | ||
349 | const { jobUUID, expectedStatus, videoUUID, runnerToken, jobToken, studioFile } = options | ||
350 | |||
351 | const path = `/api/v1/runners/jobs/${jobUUID}/files/videos/${videoUUID}/studio/task-files/${studioFile}` | ||
352 | |||
353 | await makePostBodyRequest({ url: server.url, path, fields: { runnerToken, jobToken }, expectedStatus }) | ||
354 | } | ||
355 | |||
318 | before(async function () { | 356 | before(async function () { |
319 | this.timeout(120000) | 357 | this.timeout(120000) |
320 | 358 | ||
@@ -353,6 +391,28 @@ describe('Test managing runners', function () { | |||
353 | } | 391 | } |
354 | 392 | ||
355 | { | 393 | { |
394 | await server.config.disableTranscoding() | ||
395 | |||
396 | const { uuid } = await server.videos.quickUpload({ name: 'video studio' }) | ||
397 | videoStudioUUID = uuid | ||
398 | |||
399 | await server.config.enableTranscoding(true, true) | ||
400 | await server.config.enableStudio() | ||
401 | |||
402 | await server.videoStudio.createEditionTasks({ | ||
403 | videoId: videoStudioUUID, | ||
404 | tasks: VideoStudioCommand.getComplexTask() | ||
405 | }) | ||
406 | |||
407 | const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'video-edition-transcoding' }) | ||
408 | studioAcceptedJob = job | ||
409 | |||
410 | const tasks = (job.payload as RunnerJobVideoEditionTranscodingPayload).tasks | ||
411 | const fileUrl = (tasks.find(t => isVideoStudioTaskIntro(t)) as VideoStudioTaskIntro).options.file as string | ||
412 | studioFile = basename(fileUrl) | ||
413 | } | ||
414 | |||
415 | { | ||
356 | await server.config.enableLive({ | 416 | await server.config.enableLive({ |
357 | allowReplay: false, | 417 | allowReplay: false, |
358 | resolutions: 'max', | 418 | resolutions: 'max', |
@@ -381,8 +441,6 @@ describe('Test managing runners', function () { | |||
381 | jobToken: string | 441 | jobToken: string |
382 | expectedStatus: HttpStatusCode | 442 | expectedStatus: HttpStatusCode |
383 | }) { | 443 | }) { |
384 | await fetchFiles({ ...options, videoUUID }) | ||
385 | |||
386 | await server.runnerJobs.abort({ ...options, reason: 'reason' }) | 444 | await server.runnerJobs.abort({ ...options, reason: 'reason' }) |
387 | await server.runnerJobs.update({ ...options }) | 445 | await server.runnerJobs.update({ ...options }) |
388 | await server.runnerJobs.error({ ...options, message: 'message' }) | 446 | await server.runnerJobs.error({ ...options, message: 'message' }) |
@@ -390,39 +448,95 @@ describe('Test managing runners', function () { | |||
390 | } | 448 | } |
391 | 449 | ||
392 | it('Should fail with an invalid job uuid', async function () { | 450 | it('Should fail with an invalid job uuid', async function () { |
393 | await testEndpoints({ jobUUID: 'a', runnerToken, jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 451 | const options = { jobUUID: 'a', runnerToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 } |
452 | |||
453 | await testEndpoints({ ...options, jobToken }) | ||
454 | await fetchVideoInputFiles({ ...options, videoUUID, jobToken }) | ||
455 | await fetchStudioFiles({ ...options, videoUUID, jobToken: studioAcceptedJob.jobToken, studioFile }) | ||
394 | }) | 456 | }) |
395 | 457 | ||
396 | it('Should fail with an unknown job uuid', async function () { | 458 | it('Should fail with an unknown job uuid', async function () { |
397 | const jobUUID = badUUID | 459 | const options = { jobUUID: badUUID, runnerToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 } |
398 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 460 | |
461 | await testEndpoints({ ...options, jobToken }) | ||
462 | await fetchVideoInputFiles({ ...options, videoUUID, jobToken }) | ||
463 | await fetchStudioFiles({ ...options, jobToken: studioAcceptedJob.jobToken, videoUUID, studioFile }) | ||
399 | }) | 464 | }) |
400 | 465 | ||
401 | it('Should fail with an invalid runner token', async function () { | 466 | it('Should fail with an invalid runner token', async function () { |
402 | await testEndpoints({ jobUUID, runnerToken: '', jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 467 | const options = { runnerToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 } |
468 | |||
469 | await testEndpoints({ ...options, jobUUID, jobToken }) | ||
470 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID, jobToken }) | ||
471 | await fetchStudioFiles({ | ||
472 | ...options, | ||
473 | jobToken: studioAcceptedJob.jobToken, | ||
474 | jobUUID: studioAcceptedJob.uuid, | ||
475 | videoUUID: videoStudioUUID, | ||
476 | studioFile | ||
477 | }) | ||
403 | }) | 478 | }) |
404 | 479 | ||
405 | it('Should fail with an unknown runner token', async function () { | 480 | it('Should fail with an unknown runner token', async function () { |
406 | const runnerToken = badUUID | 481 | const options = { runnerToken: badUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 } |
407 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 482 | |
483 | await testEndpoints({ ...options, jobUUID, jobToken }) | ||
484 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID, jobToken }) | ||
485 | await fetchStudioFiles({ | ||
486 | ...options, | ||
487 | jobToken: studioAcceptedJob.jobToken, | ||
488 | jobUUID: studioAcceptedJob.uuid, | ||
489 | videoUUID: videoStudioUUID, | ||
490 | studioFile | ||
491 | }) | ||
408 | }) | 492 | }) |
409 | 493 | ||
410 | it('Should fail with an invalid job token job uuid', async function () { | 494 | it('Should fail with an invalid job token job uuid', async function () { |
411 | await testEndpoints({ jobUUID, runnerToken, jobToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 495 | const options = { runnerToken, jobToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 } |
496 | |||
497 | await testEndpoints({ ...options, jobUUID }) | ||
498 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID }) | ||
499 | await fetchStudioFiles({ ...options, jobUUID: studioAcceptedJob.uuid, videoUUID: videoStudioUUID, studioFile }) | ||
412 | }) | 500 | }) |
413 | 501 | ||
414 | it('Should fail with an unknown job token job uuid', async function () { | 502 | it('Should fail with an unknown job token job uuid', async function () { |
415 | const jobToken = badUUID | 503 | const options = { runnerToken, jobToken: badUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 } |
416 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 504 | |
505 | await testEndpoints({ ...options, jobUUID }) | ||
506 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID }) | ||
507 | await fetchStudioFiles({ ...options, jobUUID: studioAcceptedJob.uuid, videoUUID: videoStudioUUID, studioFile }) | ||
417 | }) | 508 | }) |
418 | 509 | ||
419 | it('Should fail with a runner token not associated to this job', async function () { | 510 | it('Should fail with a runner token not associated to this job', async function () { |
420 | await testEndpoints({ jobUUID, runnerToken: runnerToken2, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 511 | const options = { runnerToken: runnerToken2, expectedStatus: HttpStatusCode.NOT_FOUND_404 } |
512 | |||
513 | await testEndpoints({ ...options, jobUUID, jobToken }) | ||
514 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID, jobToken }) | ||
515 | await fetchStudioFiles({ | ||
516 | ...options, | ||
517 | jobToken: studioAcceptedJob.jobToken, | ||
518 | jobUUID: studioAcceptedJob.uuid, | ||
519 | videoUUID: videoStudioUUID, | ||
520 | studioFile | ||
521 | }) | ||
421 | }) | 522 | }) |
422 | 523 | ||
423 | it('Should fail with a job uuid not associated to the job token', async function () { | 524 | it('Should fail with a job uuid not associated to the job token', async function () { |
424 | await testEndpoints({ jobUUID: jobUUID2, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 525 | { |
425 | await testEndpoints({ jobUUID, runnerToken, jobToken: jobToken2, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 526 | const options = { jobUUID: jobUUID2, runnerToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 } |
527 | |||
528 | await testEndpoints({ ...options, jobToken }) | ||
529 | await fetchVideoInputFiles({ ...options, jobToken, videoUUID }) | ||
530 | await fetchStudioFiles({ ...options, jobToken: studioAcceptedJob.jobToken, videoUUID: videoStudioUUID, studioFile }) | ||
531 | } | ||
532 | |||
533 | { | ||
534 | const options = { runnerToken, jobToken: jobToken2, expectedStatus: HttpStatusCode.NOT_FOUND_404 } | ||
535 | |||
536 | await testEndpoints({ ...options, jobUUID }) | ||
537 | await fetchVideoInputFiles({ ...options, jobUUID, videoUUID }) | ||
538 | await fetchStudioFiles({ ...options, jobUUID: studioAcceptedJob.uuid, videoUUID: videoStudioUUID, studioFile }) | ||
539 | } | ||
426 | }) | 540 | }) |
427 | }) | 541 | }) |
428 | 542 | ||
@@ -670,27 +784,82 @@ describe('Test managing runners', function () { | |||
670 | }) | 784 | }) |
671 | }) | 785 | }) |
672 | }) | 786 | }) |
787 | |||
788 | describe('Video studio', function () { | ||
789 | |||
790 | it('Should fail with an invalid video edition transcoding payload', async function () { | ||
791 | await server.runnerJobs.success({ | ||
792 | jobUUID: studioAcceptedJob.uuid, | ||
793 | jobToken: studioAcceptedJob.jobToken, | ||
794 | payload: { hello: 'video_short.mp4' } as any, | ||
795 | runnerToken, | ||
796 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
797 | }) | ||
798 | }) | ||
799 | }) | ||
673 | }) | 800 | }) |
674 | 801 | ||
675 | describe('Job files', function () { | 802 | describe('Job files', function () { |
676 | 803 | ||
677 | describe('Video files', function () { | 804 | describe('Check video param for common job file routes', function () { |
805 | |||
806 | async function fetchFiles (options: { | ||
807 | videoUUID?: string | ||
808 | expectedStatus: HttpStatusCode | ||
809 | }) { | ||
810 | await fetchVideoInputFiles({ videoUUID, ...options, jobToken, jobUUID, runnerToken }) | ||
811 | |||
812 | await fetchStudioFiles({ | ||
813 | videoUUID: videoStudioUUID, | ||
814 | |||
815 | ...options, | ||
816 | |||
817 | jobToken: studioAcceptedJob.jobToken, | ||
818 | jobUUID: studioAcceptedJob.uuid, | ||
819 | runnerToken, | ||
820 | studioFile | ||
821 | }) | ||
822 | } | ||
678 | 823 | ||
679 | it('Should fail with an invalid video id', async function () { | 824 | it('Should fail with an invalid video id', async function () { |
680 | await fetchFiles({ videoUUID: 'a', jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 825 | await fetchFiles({ |
826 | videoUUID: 'a', | ||
827 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
828 | }) | ||
681 | }) | 829 | }) |
682 | 830 | ||
683 | it('Should fail with an unknown video id', async function () { | 831 | it('Should fail with an unknown video id', async function () { |
684 | const videoUUID = '910ec12a-d9e6-458b-a274-0abb655f9464' | 832 | const videoUUID = '910ec12a-d9e6-458b-a274-0abb655f9464' |
685 | await fetchFiles({ videoUUID, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | 833 | |
834 | await fetchFiles({ | ||
835 | videoUUID, | ||
836 | expectedStatus: HttpStatusCode.NOT_FOUND_404 | ||
837 | }) | ||
686 | }) | 838 | }) |
687 | 839 | ||
688 | it('Should fail with a video id not associated to this job', async function () { | 840 | it('Should fail with a video id not associated to this job', async function () { |
689 | await fetchFiles({ videoUUID: videoUUID2, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | 841 | await fetchFiles({ |
842 | videoUUID: videoUUID2, | ||
843 | expectedStatus: HttpStatusCode.FORBIDDEN_403 | ||
844 | }) | ||
690 | }) | 845 | }) |
691 | 846 | ||
692 | it('Should succeed with the correct params', async function () { | 847 | it('Should succeed with the correct params', async function () { |
693 | await fetchFiles({ videoUUID, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.OK_200 }) | 848 | await fetchFiles({ expectedStatus: HttpStatusCode.OK_200 }) |
849 | }) | ||
850 | }) | ||
851 | |||
852 | describe('Video edition tasks file routes', function () { | ||
853 | |||
854 | it('Should fail with an invalid studio filename', async function () { | ||
855 | await fetchStudioFiles({ | ||
856 | videoUUID: videoStudioUUID, | ||
857 | jobUUID: studioAcceptedJob.uuid, | ||
858 | runnerToken, | ||
859 | jobToken: studioAcceptedJob.jobToken, | ||
860 | studioFile: 'toto', | ||
861 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
862 | }) | ||
694 | }) | 863 | }) |
695 | }) | 864 | }) |
696 | }) | 865 | }) |