From 4f2199144e428c16460750305f737b890c1ac322 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Jul 2021 10:18:40 +0200 Subject: [PATCH] Introduce live command --- server/tests/api/check-params/live.ts | 72 ++++---- server/tests/api/live/live-constraints.ts | 21 +-- server/tests/api/live/live-permanent.ts | 43 ++--- server/tests/api/live/live-save-replay.ts | 29 ++-- server/tests/api/live/live-socket-messages.ts | 19 +-- server/tests/api/live/live-views.ts | 8 +- server/tests/api/live/live.ts | 90 +++++----- server/tests/api/search/search-videos.ts | 22 ++- .../api/videos/video-change-ownership.ts | 5 +- server/tests/plugins/action-hooks.ts | 3 +- server/tests/plugins/filter-hooks.ts | 3 +- server/tests/plugins/plugin-transcoding.ts | 28 ++-- shared/extra-utils/index.ts | 16 +- shared/extra-utils/requests/index.ts | 3 + shared/extra-utils/server/servers.ts | 3 + shared/extra-utils/shared/abstract-command.ts | 32 +++- shared/extra-utils/users/index.ts | 1 - shared/extra-utils/videos/index.ts | 13 ++ shared/extra-utils/videos/live-command.ts | 156 ++++++++++++++++++ shared/extra-utils/videos/live.ts | 139 +--------------- 20 files changed, 369 insertions(+), 337 deletions(-) create mode 100644 shared/extra-utils/requests/index.ts create mode 100644 shared/extra-utils/videos/index.ts create mode 100644 shared/extra-utils/videos/live-command.ts diff --git a/server/tests/api/check-params/live.ts b/server/tests/api/check-params/live.ts index 7a623c169..56116848f 100644 --- a/server/tests/api/check-params/live.ts +++ b/server/tests/api/check-params/live.ts @@ -2,27 +2,24 @@ import 'mocha' import { omit } from 'lodash' -import { LiveVideo, VideoCreateResult, VideoPrivacy } from '@shared/models' +import { VideoCreateResult, VideoPrivacy } from '@shared/models' import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { buildAbsoluteFixturePath, cleanupTests, createUser, flushAndRunServer, - getLive, getMyUserInformation, immutableAssign, + LiveCommand, makePostBodyRequest, makeUploadRequest, - runAndTestFfmpegStreamError, sendRTMPStream, ServerInfo, setAccessTokensToServers, stopFfmpeg, - updateLive, uploadVideoAndGetId, - userLogin, - waitUntilLivePublished + userLogin } from '../../../../shared/extra-utils' describe('Test video lives API validator', function () { @@ -32,6 +29,7 @@ describe('Test video lives API validator', function () { let channelId: number let video: VideoCreateResult let videoIdNotLive: number + let command: LiveCommand // --------------------------------------------------------------- @@ -66,6 +64,8 @@ describe('Test video lives API validator', function () { { videoIdNotLive = (await uploadVideoAndGetId({ server, videoName: 'not live' })).id } + + command = server.liveCommand }) describe('When creating a live', function () { @@ -337,70 +337,72 @@ describe('Test video lives API validator', function () { describe('When getting live information', function () { it('Should fail without access token', async function () { - await getLive(server.url, '', video.id, HttpStatusCode.UNAUTHORIZED_401) + await command.getLive({ token: '', videoId: video.id, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) }) it('Should fail with a bad access token', async function () { - await getLive(server.url, 'toto', video.id, HttpStatusCode.UNAUTHORIZED_401) + await command.getLive({ token: 'toto', videoId: video.id, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) }) it('Should fail with access token of another user', async function () { - await getLive(server.url, userAccessToken, video.id, HttpStatusCode.FORBIDDEN_403) + await command.getLive({ token: userAccessToken, videoId: video.id, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) }) it('Should fail with a bad video id', async function () { - await getLive(server.url, server.accessToken, 'toto', HttpStatusCode.BAD_REQUEST_400) + await command.getLive({ videoId: 'toto', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) }) it('Should fail with an unknown video id', async function () { - await getLive(server.url, server.accessToken, 454555, HttpStatusCode.NOT_FOUND_404) + await command.getLive({ videoId: 454555, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) }) it('Should fail with a non live video', async function () { - await getLive(server.url, server.accessToken, videoIdNotLive, HttpStatusCode.NOT_FOUND_404) + await command.getLive({ videoId: videoIdNotLive, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) }) it('Should succeed with the correct params', async function () { - await getLive(server.url, server.accessToken, video.id) - await getLive(server.url, server.accessToken, video.shortUUID) + await command.getLive({ videoId: video.id }) + await command.getLive({ videoId: video.uuid }) + await command.getLive({ videoId: video.shortUUID }) }) }) describe('When updating live information', async function () { it('Should fail without access token', async function () { - await updateLive(server.url, '', video.id, {}, HttpStatusCode.UNAUTHORIZED_401) + await command.updateLive({ token: '', videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) }) it('Should fail with a bad access token', async function () { - await updateLive(server.url, 'toto', video.id, {}, HttpStatusCode.UNAUTHORIZED_401) + await command.updateLive({ token: 'toto', videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) }) it('Should fail with access token of another user', async function () { - await updateLive(server.url, userAccessToken, video.id, {}, HttpStatusCode.FORBIDDEN_403) + await command.updateLive({ token: userAccessToken, videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) }) it('Should fail with a bad video id', async function () { - await updateLive(server.url, server.accessToken, 'toto', {}, HttpStatusCode.BAD_REQUEST_400) + await command.updateLive({ videoId: 'toto', fields: {}, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) }) it('Should fail with an unknown video id', async function () { - await updateLive(server.url, server.accessToken, 454555, {}, HttpStatusCode.NOT_FOUND_404) + await command.updateLive({ videoId: 454555, fields: {}, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) }) it('Should fail with a non live video', async function () { - await updateLive(server.url, server.accessToken, videoIdNotLive, {}, HttpStatusCode.NOT_FOUND_404) + await command.updateLive({ videoId: videoIdNotLive, fields: {}, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) }) it('Should fail with save replay and permanent live set to true', async function () { const fields = { saveReplay: true, permanentLive: true } - await updateLive(server.url, server.accessToken, video.id, fields, HttpStatusCode.BAD_REQUEST_400) + await command.updateLive({ videoId: video.id, fields, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) }) it('Should succeed with the correct params', async function () { - await updateLive(server.url, server.accessToken, video.id, { saveReplay: false }) - await updateLive(server.url, server.accessToken, video.shortUUID, { saveReplay: false }) + await command.updateLive({ videoId: video.id, fields: { saveReplay: false } }) + await command.updateLive({ videoId: video.uuid, fields: { saveReplay: false } }) + await command.updateLive({ videoId: video.shortUUID, fields: { saveReplay: false } }) }) it('Should fail to update replay status if replay is not allowed on the instance', async function () { @@ -413,36 +415,34 @@ describe('Test video lives API validator', function () { } }) - await updateLive(server.url, server.accessToken, video.id, { saveReplay: true }, HttpStatusCode.FORBIDDEN_403) + await command.updateLive({ videoId: video.id, fields: { saveReplay: true }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) }) it('Should fail to update a live if it has already started', async function () { this.timeout(40000) - const resLive = await getLive(server.url, server.accessToken, video.id) - const live: LiveVideo = resLive.body + const live = await command.getLive({ videoId: video.id }) - const command = sendRTMPStream(live.rtmpUrl, live.streamKey) + const ffmpegCommand = sendRTMPStream(live.rtmpUrl, live.streamKey) - await waitUntilLivePublished(server.url, server.accessToken, video.id) - await updateLive(server.url, server.accessToken, video.id, {}, HttpStatusCode.BAD_REQUEST_400) + await command.waitUntilLivePublished({ videoId: video.id }) + await command.updateLive({ videoId: video.id, fields: {}, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) it('Should fail to stream twice in the save live', async function () { this.timeout(40000) - const resLive = await getLive(server.url, server.accessToken, video.id) - const live: LiveVideo = resLive.body + const live = await command.getLive({ videoId: video.id }) - const command = sendRTMPStream(live.rtmpUrl, live.streamKey) + const ffmpegCommand = sendRTMPStream(live.rtmpUrl, live.streamKey) - await waitUntilLivePublished(server.url, server.accessToken, video.id) + await command.waitUntilLivePublished({ videoId: video.id }) - await runAndTestFfmpegStreamError(server.url, server.accessToken, video.id, true) + await command.runAndTestFfmpegStreamError({ videoId: video.id, shouldHaveError: true }) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) }) diff --git a/server/tests/api/live/live-constraints.ts b/server/tests/api/live/live-constraints.ts index c64d10dcd..5c4817b40 100644 --- a/server/tests/api/live/live-constraints.ts +++ b/server/tests/api/live/live-constraints.ts @@ -7,19 +7,16 @@ import { checkLiveCleanup, cleanupTests, ConfigCommand, - createLive, doubleFollow, flushAndRunMultipleServers, generateUser, getVideo, - runAndTestFfmpegStreamError, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, updateUser, wait, - waitJobs, - waitUntilLivePublished + waitJobs } from '../../../../shared/extra-utils' const expect = chai.expect @@ -38,8 +35,8 @@ describe('Test live constraints', function () { saveReplay } - const res = await createLive(servers[0].url, userAccessToken, liveAttributes) - return res.body.video.uuid as string + const { uuid } = await servers[0].liveCommand.createLive({ token: userAccessToken, fields: liveAttributes }) + return uuid } async function checkSaveReplay (videoId: string, resolutions = [ 720 ]) { @@ -56,7 +53,7 @@ describe('Test live constraints', function () { async function waitUntilLivePublishedOnAllServers (videoId: string) { for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoId) + await server.liveCommand.waitUntilLivePublished({ videoId }) } } @@ -108,7 +105,7 @@ describe('Test live constraints', function () { this.timeout(60000) const userVideoLiveoId = await createLiveWrapper(false) - await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, false) + await servers[0].liveCommand.runAndTestFfmpegStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false }) }) it('Should have size limit depending on user global quota if save replay is enabled', async function () { @@ -118,7 +115,7 @@ describe('Test live constraints', function () { await wait(5000) const userVideoLiveoId = await createLiveWrapper(true) - await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, true) + await servers[0].liveCommand.runAndTestFfmpegStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) await waitUntilLivePublishedOnAllServers(userVideoLiveoId) await waitJobs(servers) @@ -135,7 +132,7 @@ describe('Test live constraints', function () { await updateQuota({ total: -1, daily: 1 }) const userVideoLiveoId = await createLiveWrapper(true) - await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, true) + await servers[0].liveCommand.runAndTestFfmpegStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) await waitUntilLivePublishedOnAllServers(userVideoLiveoId) await waitJobs(servers) @@ -152,7 +149,7 @@ describe('Test live constraints', function () { await updateQuota({ total: 10 * 1000 * 1000, daily: -1 }) const userVideoLiveoId = await createLiveWrapper(true) - await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, false) + await servers[0].liveCommand.runAndTestFfmpegStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: false }) }) it('Should have max duration limit', async function () { @@ -173,7 +170,7 @@ describe('Test live constraints', function () { }) const userVideoLiveoId = await createLiveWrapper(true) - await runAndTestFfmpegStreamError(servers[0].url, userAccessToken, userVideoLiveoId, true) + await servers[0].liveCommand.runAndTestFfmpegStreamError({ token: userAccessToken, videoId: userVideoLiveoId, shouldHaveError: true }) await waitUntilLivePublishedOnAllServers(userVideoLiveoId) await waitJobs(servers) diff --git a/server/tests/api/live/live-permanent.ts b/server/tests/api/live/live-permanent.ts index b9e37c834..a0f70dfdb 100644 --- a/server/tests/api/live/live-permanent.ts +++ b/server/tests/api/live/live-permanent.ts @@ -6,22 +6,15 @@ import { LiveVideoCreate, VideoDetails, VideoPrivacy, VideoState } from '@shared import { cleanupTests, ConfigCommand, - createLive, doubleFollow, flushAndRunMultipleServers, - getLive, - getPlaylistsCount, getVideo, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, stopFfmpeg, - updateLive, wait, - waitJobs, - waitUntilLivePublished, - waitUntilLiveWaiting + waitJobs } from '../../../../shared/extra-utils' const expect = chai.expect @@ -39,8 +32,8 @@ describe('Permanent live', function () { permanentLive } - const res = await createLive(servers[0].url, servers[0].accessToken, attributes) - return res.body.video.uuid + const { uuid } = await servers[0].liveCommand.createLive({ fields: attributes }) + return uuid } async function checkVideoState (videoId: string, state: VideoState) { @@ -83,15 +76,15 @@ describe('Permanent live', function () { const videoUUID = await createLiveWrapper(false) { - const res = await getLive(servers[0].url, servers[0].accessToken, videoUUID) - expect(res.body.permanentLive).to.be.false + const live = await servers[0].liveCommand.getLive({ videoId: videoUUID }) + expect(live.permanentLive).to.be.false } - await updateLive(servers[0].url, servers[0].accessToken, videoUUID, { permanentLive: true }) + await servers[0].liveCommand.updateLive({ videoId: videoUUID, fields: { permanentLive: true } }) { - const res = await getLive(servers[0].url, servers[0].accessToken, videoUUID) - expect(res.body.permanentLive).to.be.true + const live = await servers[0].liveCommand.getLive({ videoId: videoUUID }) + expect(live.permanentLive).to.be.true } }) @@ -100,8 +93,8 @@ describe('Permanent live', function () { videoUUID = await createLiveWrapper(true) - const res = await getLive(servers[0].url, servers[0].accessToken, videoUUID) - expect(res.body.permanentLive).to.be.true + const live = await servers[0].liveCommand.getLive({ videoId: videoUUID }) + expect(live.permanentLive).to.be.true await waitJobs(servers) }) @@ -109,16 +102,16 @@ describe('Permanent live', function () { it('Should stream into this permanent live', async function () { this.timeout(120000) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, videoUUID) + const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: videoUUID }) for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoUUID) + await server.liveCommand.waitUntilLivePublished({ videoId: videoUUID }) } await checkVideoState(videoUUID, VideoState.PUBLISHED) - await stopFfmpeg(command) - await waitUntilLiveWaiting(servers[0].url, servers[0].accessToken, videoUUID) + await stopFfmpeg(ffmpegCommand) + await servers[0].liveCommand.waitUntilLiveWaiting({ videoId: videoUUID }) await waitJobs(servers) }) @@ -160,19 +153,19 @@ describe('Permanent live', function () { } }) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, videoUUID) + const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: videoUUID }) for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoUUID) + await server.liveCommand.waitUntilLivePublished({ videoId: videoUUID }) } await checkVideoState(videoUUID, VideoState.PUBLISHED) - const count = await getPlaylistsCount(servers[0], videoUUID) + const count = await servers[0].liveCommand.getPlaylistsCount({ videoUUID }) // master playlist and 720p playlist expect(count).to.equal(2) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) after(async function () { diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts index e74bc3e8d..d3c252ffd 100644 --- a/server/tests/api/live/live-save-replay.ts +++ b/server/tests/api/live/live-save-replay.ts @@ -10,13 +10,11 @@ import { checkLiveCleanup, cleanupTests, ConfigCommand, - createLive, doubleFollow, flushAndRunMultipleServers, getVideo, getVideosList, removeVideo, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, @@ -24,10 +22,7 @@ import { testFfmpegStreamError, updateVideo, wait, - waitJobs, - waitUntilLiveEnded, - waitUntilLivePublished, - waitUntilLiveSaved + waitJobs } from '../../../../shared/extra-utils' const expect = chai.expect @@ -52,8 +47,8 @@ describe('Save replay setting', function () { saveReplay } - const res = await createLive(servers[0].url, servers[0].accessToken, attributes) - return res.body.video.uuid + const { uuid } = await servers[0].liveCommand.createLive({ fields: attributes }) + return uuid } async function checkVideosExist (videoId: string, existsInList: boolean, getStatus?: number) { @@ -79,13 +74,13 @@ describe('Save replay setting', function () { async function waitUntilLivePublishedOnAllServers (videoId: string) { for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoId) + await server.liveCommand.waitUntilLivePublished({ videoId }) } } async function waitUntilLiveSavedOnAllServers (videoId: string) { for (const server of servers) { - await waitUntilLiveSaved(server.url, server.accessToken, videoId) + await server.liveCommand.waitUntilLiveSaved({ videoId }) } } @@ -136,7 +131,7 @@ describe('Save replay setting', function () { it('Should correctly have updated the live and federated it when streaming in the live', async function () { this.timeout(30000) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) @@ -152,7 +147,7 @@ describe('Save replay setting', function () { await stopFfmpeg(ffmpegCommand) for (const server of servers) { - await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID) + await server.liveCommand.waitUntilLiveEnded({ videoId: liveVideoUUID }) } await waitJobs(servers) @@ -169,7 +164,7 @@ describe('Save replay setting', function () { liveVideoUUID = await createLiveWrapper(false) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) @@ -198,7 +193,7 @@ describe('Save replay setting', function () { liveVideoUUID = await createLiveWrapper(false) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) @@ -234,7 +229,7 @@ describe('Save replay setting', function () { it('Should correctly have updated the live and federated it when streaming in the live', async function () { this.timeout(20000) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) await waitJobs(servers) @@ -278,7 +273,7 @@ describe('Save replay setting', function () { liveVideoUUID = await createLiveWrapper(true) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) await waitJobs(servers) @@ -306,7 +301,7 @@ describe('Save replay setting', function () { liveVideoUUID = await createLiveWrapper(true) - ffmpegCommand = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(liveVideoUUID) await waitJobs(servers) diff --git a/server/tests/api/live/live-socket-messages.ts b/server/tests/api/live/live-socket-messages.ts index 20fec16a9..73a300384 100644 --- a/server/tests/api/live/live-socket-messages.ts +++ b/server/tests/api/live/live-socket-messages.ts @@ -5,11 +5,9 @@ import * as chai from 'chai' import { VideoPrivacy, VideoState } from '@shared/models' import { cleanupTests, - createLive, doubleFollow, flushAndRunMultipleServers, getVideoIdFromUUID, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, @@ -17,7 +15,6 @@ import { viewVideo, wait, waitJobs, - waitUntilLiveEnded, waitUntilLivePublishedOnAllServers } from '../../../../shared/extra-utils' @@ -60,8 +57,8 @@ describe('Test live', function () { privacy: VideoPrivacy.PUBLIC } - const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes) - return res.body.video.uuid + const { uuid } = await servers[0].liveCommand.createLive({ fields: liveAttributes }) + return uuid } it('Should correctly send a message when the live starts and ends', async function () { @@ -89,7 +86,7 @@ describe('Test live', function () { remoteSocket.emit('subscribe', { videoId }) } - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) await waitJobs(servers) @@ -99,10 +96,10 @@ describe('Test live', function () { expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.PUBLISHED) } - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) for (const server of servers) { - await waitUntilLiveEnded(server.url, server.accessToken, liveVideoUUID) + await server.liveCommand.waitUntilLiveEnded({ videoId: liveVideoUUID }) } await waitJobs(servers) @@ -137,7 +134,7 @@ describe('Test live', function () { remoteSocket.emit('subscribe', { videoId }) } - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) await waitJobs(servers) @@ -155,7 +152,7 @@ describe('Test live', function () { expect(localLastVideoViews).to.equal(2) expect(remoteLastVideoViews).to.equal(2) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) it('Should not receive a notification after unsubscribe', async function () { @@ -172,7 +169,7 @@ describe('Test live', function () { socket.on('state-change', data => stateChanges.push(data.state)) socket.emit('subscribe', { videoId }) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoUUID) + const command = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) await waitJobs(servers) diff --git a/server/tests/api/live/live-views.ts b/server/tests/api/live/live-views.ts index ca571c962..ae6af7cfd 100644 --- a/server/tests/api/live/live-views.ts +++ b/server/tests/api/live/live-views.ts @@ -6,11 +6,9 @@ import { FfmpegCommand } from 'fluent-ffmpeg' import { VideoDetails, VideoPrivacy } from '@shared/models' import { cleanupTests, - createLive, doubleFollow, flushAndRunMultipleServers, getVideo, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, @@ -73,10 +71,10 @@ describe('Test live', function () { privacy: VideoPrivacy.PUBLIC } - const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes) - liveVideoId = res.body.video.uuid + const live = await servers[0].liveCommand.createLive({ fields: liveAttributes }) + liveVideoId = live.uuid - command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId) + command = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId }) await waitUntilLivePublishedOnAllServers(servers, liveVideoId) await waitJobs(servers) }) diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts index 2c3102994..5b4e479b6 100644 --- a/server/tests/api/live/live.ts +++ b/server/tests/api/live/live.ts @@ -13,41 +13,36 @@ import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist, cleanupTests, - createLive, doubleFollow, flushAndRunMultipleServers, - getLive, getMyVideosWithFilter, getPlaylist, getVideo, getVideosList, getVideosWithFilters, killallServers, + LiveCommand, makeRawRequest, removeVideo, reRunServer, sendRTMPStream, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, stopFfmpeg, testFfmpegStreamError, testImage, - updateLive, uploadVideoAndGetId, wait, waitJobs, - waitUntilLiveEnded, - waitUntilLivePublished, - waitUntilLivePublishedOnAllServers, - waitUntilLiveSegmentGeneration + waitUntilLivePublishedOnAllServers } from '../../../../shared/extra-utils' const expect = chai.expect describe('Test live', function () { let servers: ServerInfo[] = [] + let commands: LiveCommand[] before(async function () { this.timeout(120000) @@ -72,6 +67,8 @@ describe('Test live', function () { // Server 1 and server 2 follow each other await doubleFollow(servers[0], servers[1]) + + commands = servers.map(s => s.liveCommand) }) describe('Live creation, update and delete', function () { @@ -99,8 +96,8 @@ describe('Test live', function () { thumbnailfile: 'video_short1.webm.jpg' } - const res = await createLive(servers[0].url, servers[0].accessToken, attributes) - liveVideoUUID = res.body.video.uuid + const live = await commands[0].createLive({ fields: attributes }) + liveVideoUUID = live.uuid await waitJobs(servers) @@ -130,8 +127,7 @@ describe('Test live', function () { await testImage(server.url, 'video_short1-preview.webm', video.previewPath) await testImage(server.url, 'video_short1.webm', video.thumbnailPath) - const resLive = await getLive(server.url, server.accessToken, liveVideoUUID) - const live: LiveVideo = resLive.body + const live = await server.liveCommand.getLive({ videoId: liveVideoUUID }) if (server.url === servers[0].url) { expect(live.rtmpUrl).to.equal('rtmp://' + server.hostname + ':' + servers[0].rtmpPort + '/live') @@ -155,8 +151,8 @@ describe('Test live', function () { nsfw: true } - const res = await createLive(servers[0].url, servers[0].accessToken, attributes) - const videoId = res.body.video.uuid + const live = await commands[0].createLive({ fields: attributes }) + const videoId = live.uuid await waitJobs(servers) @@ -182,20 +178,19 @@ describe('Test live', function () { }) it('Should not be able to update a live of another server', async function () { - await updateLive(servers[1].url, servers[1].accessToken, liveVideoUUID, { saveReplay: false }, HttpStatusCode.FORBIDDEN_403) + await commands[1].updateLive({ videoId: liveVideoUUID, fields: { saveReplay: false }, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) }) it('Should update the live', async function () { this.timeout(10000) - await updateLive(servers[0].url, servers[0].accessToken, liveVideoUUID, { saveReplay: false }) + await commands[0].updateLive({ videoId: liveVideoUUID, fields: { saveReplay: false } }) await waitJobs(servers) }) it('Have the live updated', async function () { for (const server of servers) { - const res = await getLive(server.url, server.accessToken, liveVideoUUID) - const live: LiveVideo = res.body + const live = await server.liveCommand.getLive({ videoId: liveVideoUUID }) if (server.url === servers[0].url) { expect(live.rtmpUrl).to.equal('rtmp://' + server.hostname + ':' + servers[0].rtmpPort + '/live') @@ -219,13 +214,13 @@ describe('Test live', function () { it('Should have the live deleted', async function () { for (const server of servers) { await getVideo(server.url, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) - await getLive(server.url, server.accessToken, liveVideoUUID, HttpStatusCode.NOT_FOUND_404) + await server.liveCommand.getLive({ videoId: liveVideoUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) } }) }) describe('Live filters', function () { - let command: any + let ffmpegCommand: any let liveVideoId: string let vodVideoId: string @@ -235,10 +230,10 @@ describe('Test live', function () { vodVideoId = (await uploadVideoAndGetId({ server: servers[0], videoName: 'vod video' })).uuid const liveOptions = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: servers[0].videoChannel.id } - const resLive = await createLive(servers[0].url, servers[0].accessToken, liveOptions) - liveVideoId = resLive.body.video.uuid + const live = await commands[0].createLive({ fields: liveOptions }) + liveVideoId = live.uuid - command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId) + ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId }) await waitUntilLivePublishedOnAllServers(servers, liveVideoId) await waitJobs(servers) }) @@ -262,7 +257,7 @@ describe('Test live', function () { it('Should display my lives', async function () { this.timeout(60000) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) await waitJobs(servers) const res = await getMyVideosWithFilter(servers[0].url, servers[0].accessToken, { isLive: true }) @@ -302,13 +297,12 @@ describe('Test live', function () { saveReplay: false } - const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes) - const uuid = res.body.video.uuid + const { uuid } = await commands[0].createLive({ fields: liveAttributes }) - const resLive = await getLive(servers[0].url, servers[0].accessToken, uuid) + const live = await commands[0].getLive({ videoId: uuid }) const resVideo = await getVideo(servers[0].url, uuid) - return Object.assign(resVideo.body, resLive.body) as LiveVideo & VideoDetails + return Object.assign(resVideo.body as VideoDetails, live) } it('Should not allow a stream without the appropriate path', async function () { @@ -382,8 +376,8 @@ describe('Test live', function () { saveReplay } - const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes) - return res.body.video.uuid + const { uuid } = await commands[0].createLive({ fields: liveAttributes }) + return uuid } async function testVideoResolutions (liveVideoId: string, resolutions: number[]) { @@ -409,7 +403,7 @@ describe('Test live', function () { for (let i = 0; i < resolutions.length; i++) { const segmentNum = 3 const segmentName = `${i}-00000${segmentNum}.ts` - await waitUntilLiveSegmentGeneration(servers[0], video.uuid, i, segmentNum) + await commands[0].waitUntilLiveSegmentGeneration({ videoUUID: video.uuid, resolution: i, segment: segmentNum }) const res = await getPlaylist(`${servers[0].url}/static/streaming-playlists/hls/${video.uuid}/${i}.m3u8`) const subPlaylist = res.text @@ -454,13 +448,13 @@ describe('Test live', function () { liveVideoId = await createLiveWrapper(false) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId) + const ffmpegCommand = await commands[0].sendRTMPStreamInVideo({ videoId: liveVideoId }) await waitUntilLivePublishedOnAllServers(servers, liveVideoId) await waitJobs(servers) await testVideoResolutions(liveVideoId, [ 720 ]) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) it('Should enable transcoding with some resolutions', async function () { @@ -470,13 +464,13 @@ describe('Test live', function () { await updateConf(resolutions) liveVideoId = await createLiveWrapper(false) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId) + const ffmpegCommand = await commands[0].sendRTMPStreamInVideo({ videoId: liveVideoId }) await waitUntilLivePublishedOnAllServers(servers, liveVideoId) await waitJobs(servers) await testVideoResolutions(liveVideoId, resolutions) - await stopFfmpeg(command) + await stopFfmpeg(ffmpegCommand) }) it('Should enable transcoding with some resolutions and correctly save them', async function () { @@ -487,14 +481,14 @@ describe('Test live', function () { await updateConf(resolutions) liveVideoId = await createLiveWrapper(true) - const command = await sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId, 'video_short2.webm') + const ffmpegCommand = await commands[0].sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) await waitUntilLivePublishedOnAllServers(servers, liveVideoId) await waitJobs(servers) await testVideoResolutions(liveVideoId, resolutions) - await stopFfmpeg(command) - await waitUntilLiveEnded(servers[0].url, servers[0].accessToken, liveVideoId) + await stopFfmpeg(ffmpegCommand) + await commands[0].waitUntilLiveEnded({ videoId: liveVideoId }) await waitJobs(servers) @@ -565,8 +559,8 @@ describe('Test live', function () { saveReplay } - const res = await createLive(servers[0].url, servers[0].accessToken, liveAttributes) - return res.body.video.uuid + const { uuid } = await commands[0].createLive({ fields: liveAttributes }) + return uuid } before(async function () { @@ -576,17 +570,17 @@ describe('Test live', function () { liveVideoReplayId = await createLiveWrapper(true) await Promise.all([ - sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoId), - sendRTMPStreamInVideo(servers[0].url, servers[0].accessToken, liveVideoReplayId) + commands[0].sendRTMPStreamInVideo({ videoId: liveVideoId }), + commands[0].sendRTMPStreamInVideo({ videoId: liveVideoReplayId }) ]) await Promise.all([ - waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoId), - waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoReplayId) + commands[0].waitUntilLivePublished({ videoId: liveVideoId }), + commands[0].waitUntilLivePublished({ videoId: liveVideoReplayId }) ]) - await waitUntilLiveSegmentGeneration(servers[0], liveVideoId, 0, 2) - await waitUntilLiveSegmentGeneration(servers[0], liveVideoReplayId, 0, 2) + await commands[0].waitUntilLiveSegmentGeneration({ videoUUID: liveVideoId, resolution: 0, segment: 2 }) + await commands[0].waitUntilLiveSegmentGeneration({ videoUUID: liveVideoReplayId, resolution: 0, segment: 2 }) await killallServers([ servers[0] ]) await reRunServer(servers[0]) @@ -597,13 +591,13 @@ describe('Test live', function () { it('Should cleanup lives', async function () { this.timeout(60000) - await waitUntilLiveEnded(servers[0].url, servers[0].accessToken, liveVideoId) + await commands[0].waitUntilLiveEnded({ videoId: liveVideoId }) }) it('Should save a live replay', async function () { this.timeout(120000) - await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoReplayId) + await commands[0].waitUntilLivePublished({ videoId: liveVideoReplayId }) }) }) diff --git a/server/tests/api/search/search-videos.ts b/server/tests/api/search/search-videos.ts index 7dc89c447..af74b26a7 100644 --- a/server/tests/api/search/search-videos.ts +++ b/server/tests/api/search/search-videos.ts @@ -2,23 +2,20 @@ import 'mocha' import * as chai from 'chai' -import { VideoPrivacy } from '@shared/models' import { cleanupTests, - createLive, + createVideoCaption, flushAndRunServer, immutableAssign, SearchCommand, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, stopFfmpeg, uploadVideo, - wait, - waitUntilLivePublished -} from '../../../../shared/extra-utils' -import { createVideoCaption } from '../../../../shared/extra-utils/videos/video-captions' + wait +} from '@shared/extra-utils' +import { VideoPrivacy } from '@shared/models' const expect = chai.expect @@ -502,12 +499,13 @@ describe('Test videos search', function () { } { - const liveOptions = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: server.videoChannel.id } - const resLive = await createLive(server.url, server.accessToken, liveOptions) - const liveVideoId = resLive.body.video.uuid + const liveCommand = server.liveCommand + + const liveAttributes = { name: 'live', privacy: VideoPrivacy.PUBLIC, channelId: server.videoChannel.id } + const live = await liveCommand.createLive({ fields: liveAttributes }) - const ffmpegCommand = await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId) - await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) + const ffmpegCommand = await liveCommand.sendRTMPStreamInVideo({ videoId: live.id }) + await liveCommand.waitUntilLivePublished({ videoId: live.id }) const body = await command.advancedVideoSearch({ search: { isLive: true } }) diff --git a/server/tests/api/videos/video-change-ownership.ts b/server/tests/api/videos/video-change-ownership.ts index 89dba14b1..88e4d51a2 100644 --- a/server/tests/api/videos/video-change-ownership.ts +++ b/server/tests/api/videos/video-change-ownership.ts @@ -7,7 +7,6 @@ import { acceptChangeOwnership, changeVideoOwnership, cleanupTests, - createLive, createUser, doubleFollow, flushAndRunMultipleServers, @@ -112,9 +111,9 @@ describe('Test video change ownership - nominal', function () { { const attributes = { name: 'live', channelId: firstUserChannelId, privacy: VideoPrivacy.PUBLIC } - const res = await createLive(servers[0].url, firstUserAccessToken, attributes) + const video = await servers[0].liveCommand.createLive({ token: firstUserAccessToken, fields: attributes }) - liveId = res.body.video.id + liveId = video.id } await doubleFollow(servers[0], servers[1]) diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts index 0de5b523b..39266c62f 100644 --- a/server/tests/plugins/action-hooks.ts +++ b/server/tests/plugins/action-hooks.ts @@ -7,7 +7,6 @@ import { addVideoCommentThread, addVideoInPlaylist, blockUser, - createLive, createUser, createVideoPlaylist, deleteVideoComment, @@ -96,7 +95,7 @@ describe('Test plugin action hooks', function () { channelId: servers[0].videoChannel.id } - await createLive(servers[0].url, servers[0].accessToken, attributes) + await servers[0].liveCommand.createLive({ fields: attributes }) await checkHook('action:api.live-video.created') }) diff --git a/server/tests/plugins/filter-hooks.ts b/server/tests/plugins/filter-hooks.ts index e254046bf..e60bad38d 100644 --- a/server/tests/plugins/filter-hooks.ts +++ b/server/tests/plugins/filter-hooks.ts @@ -7,7 +7,6 @@ import { addVideoCommentReply, addVideoCommentThread, cleanupTests, - createLive, createVideoPlaylist, doubleFollow, flushAndRunMultipleServers, @@ -156,7 +155,7 @@ describe('Test plugin filter hooks', function () { channelId: servers[0].videoChannel.id } - await createLive(servers[0].url, servers[0].accessToken, attributes, HttpStatusCode.FORBIDDEN_403) + await servers[0].liveCommand.createLive({ fields: attributes, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) }) it('Should run filter:api.video.pre-import-url.accept.result', async function () { diff --git a/server/tests/plugins/plugin-transcoding.ts b/server/tests/plugins/plugin-transcoding.ts index 71c2adc72..65282419e 100644 --- a/server/tests/plugins/plugin-transcoding.ts +++ b/server/tests/plugins/plugin-transcoding.ts @@ -7,18 +7,15 @@ import { getAudioStream, getVideoFileFPS, getVideoStreamFromFile } from '@server import { buildServerDirectory, cleanupTests, - createLive, flushAndRunServer, getVideo, PluginsCommand, - sendRTMPStreamInVideo, ServerInfo, setAccessTokensToServers, setDefaultVideoChannel, testFfmpegStreamError, uploadVideoAndGetId, - waitJobs, - waitUntilLivePublished + waitJobs } from '@shared/extra-utils' import { VideoDetails, VideoPrivacy } from '@shared/models' @@ -29,8 +26,9 @@ async function createLiveWrapper (server: ServerInfo) { privacy: VideoPrivacy.PUBLIC } - const res = await createLive(server.url, server.accessToken, liveAttributes) - return res.body.video.uuid + const { uuid } = await server.liveCommand.createLive({ fields: liveAttributes }) + + return uuid } function updateConf (server: ServerInfo, vodProfile: string, liveProfile: string) { @@ -171,8 +169,8 @@ describe('Test transcoding plugins', function () { const liveVideoId = await createLiveWrapper(server) - await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId, 'video_short2.webm') - await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) + await server.liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) + await server.liveCommand.waitUntilLivePublished({ videoId: liveVideoId }) await waitJobs([ server ]) await checkLiveFPS(liveVideoId, 'above', 20) @@ -185,8 +183,8 @@ describe('Test transcoding plugins', function () { const liveVideoId = await createLiveWrapper(server) - await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId, 'video_short2.webm') - await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) + await server.liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) + await server.liveCommand.waitUntilLivePublished({ videoId: liveVideoId }) await waitJobs([ server ]) await checkLiveFPS(liveVideoId, 'below', 12) @@ -199,8 +197,8 @@ describe('Test transcoding plugins', function () { const liveVideoId = await createLiveWrapper(server) - await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId, 'video_short2.webm') - await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) + await server.liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) + await server.liveCommand.waitUntilLivePublished({ videoId: liveVideoId }) await waitJobs([ server ]) await checkLiveFPS(liveVideoId, 'below', 6) @@ -213,7 +211,7 @@ describe('Test transcoding plugins', function () { const liveVideoId = await createLiveWrapper(server) - const command = await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId, 'video_short2.webm') + const command = await server.liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) await testFfmpegStreamError(command, true) }) @@ -262,8 +260,8 @@ describe('Test transcoding plugins', function () { const liveVideoId = await createLiveWrapper(server) - await sendRTMPStreamInVideo(server.url, server.accessToken, liveVideoId, 'video_short2.webm') - await waitUntilLivePublished(server.url, server.accessToken, liveVideoId) + await server.liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoId, fixtureName: 'video_short2.webm' }) + await server.liveCommand.waitUntilLivePublished({ videoId: liveVideoId }) await waitJobs([ server ]) const playlistUrl = `${server.url}/static/streaming-playlists/hls/${liveVideoId}/0.m3u8` diff --git a/shared/extra-utils/index.ts b/shared/extra-utils/index.ts index 68900af26..4b3636d06 100644 --- a/shared/extra-utils/index.ts +++ b/shared/extra-utils/index.ts @@ -7,21 +7,9 @@ export * from './miscs' export * from './mock-servers' export * from './moderation' export * from './overviews' +export * from './requests' export * from './search' export * from './server' export * from './socket' export * from './users' - -export * from './requests/check-api-params' -export * from './requests/requests' - -export * from './videos/live' -export * from './videos/services' -export * from './videos/video-blacklist' -export * from './videos/video-captions' -export * from './videos/video-change-ownership' -export * from './videos/video-channels' -export * from './videos/video-comments' -export * from './videos/video-playlists' -export * from './videos/video-streaming-playlists' -export * from './videos/videos' +export * from './videos' diff --git a/shared/extra-utils/requests/index.ts b/shared/extra-utils/requests/index.ts new file mode 100644 index 000000000..501163f92 --- /dev/null +++ b/shared/extra-utils/requests/index.ts @@ -0,0 +1,3 @@ +// Don't include activitypub that import stuff from server +export * from './check-api-params' +export * from './requests' diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts index 57b37728a..eca0689aa 100644 --- a/shared/extra-utils/server/servers.ts +++ b/shared/extra-utils/server/servers.ts @@ -18,6 +18,7 @@ import { makeGetRequest } from '../requests/requests' import { SearchCommand } from '../search' import { SocketIOCommand } from '../socket' import { AccountsCommand, BlocklistCommand, SubscriptionsCommand } from '../users' +import { LiveCommand } from '../videos' import { ConfigCommand } from './config-command' import { ContactFormCommand } from './contact-form-command' import { DebugCommand } from './debug-command' @@ -99,6 +100,7 @@ interface ServerInfo { accountsCommand?: AccountsCommand blocklistCommand?: BlocklistCommand subscriptionsCommand?: SubscriptionsCommand + liveCommand?: LiveCommand } function parallelTests () { @@ -324,6 +326,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = [] server.accountsCommand = new AccountsCommand(server) server.blocklistCommand = new BlocklistCommand(server) server.subscriptionsCommand = new SubscriptionsCommand(server) + server.liveCommand = new LiveCommand(server) res(server) }) diff --git a/shared/extra-utils/shared/abstract-command.ts b/shared/extra-utils/shared/abstract-command.ts index dd4598a91..38129d559 100644 --- a/shared/extra-utils/shared/abstract-command.ts +++ b/shared/extra-utils/shared/abstract-command.ts @@ -1,5 +1,5 @@ import { HttpStatusCode } from '@shared/core-utils' -import { makeDeleteRequest, makeGetRequest, makePostBodyRequest, makePutBodyRequest, unwrapBody, unwrapText } from '../requests/requests' +import { makeDeleteRequest, makeGetRequest, makePostBodyRequest, makePutBodyRequest, makeUploadRequest, unwrapBody, unwrapText } from '../requests/requests' import { ServerInfo } from '../server/servers' export interface OverrideCommandOptions { @@ -86,6 +86,36 @@ abstract class AbstractCommand { }) } + protected postUploadRequest (options: CommonCommandOptions & { + fields?: { [ fieldName: string ]: any } + attaches?: any + }) { + const { fields, attaches } = options + + return makeUploadRequest({ + ...this.buildCommonRequestOptions(options), + + method: 'POST', + fields, + attaches + }) + } + + protected putUploadRequest (options: CommonCommandOptions & { + fields?: { [ fieldName: string ]: any } + attaches?: any + }) { + const { fields, attaches } = options + + return makeUploadRequest({ + ...this.buildCommonRequestOptions(options), + + method: 'PUT', + fields, + attaches + }) + } + private buildCommonRequestOptions (options: CommonCommandOptions) { const { token, expectedStatus, defaultExpectedStatus, path } = options diff --git a/shared/extra-utils/users/index.ts b/shared/extra-utils/users/index.ts index 94ad37242..9f760d7fd 100644 --- a/shared/extra-utils/users/index.ts +++ b/shared/extra-utils/users/index.ts @@ -1,7 +1,6 @@ export * from './accounts-command' export * from './accounts' export * from './blocklist-command' - export * from './login' export * from './user-notifications' export * from './subscriptions-command' diff --git a/shared/extra-utils/videos/index.ts b/shared/extra-utils/videos/index.ts new file mode 100644 index 000000000..c9c884285 --- /dev/null +++ b/shared/extra-utils/videos/index.ts @@ -0,0 +1,13 @@ +export * from './live-command' +export * from './live' +export * from './services' +export * from './video-blacklist' +export * from './video-captions' +export * from './video-change-ownership' +export * from './video-channels' +export * from './video-comments' +export * from './video-history' +export * from './video-imports' +export * from './video-playlists' +export * from './video-streaming-playlists' +export * from './videos' diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts new file mode 100644 index 000000000..55811b8ba --- /dev/null +++ b/shared/extra-utils/videos/live-command.ts @@ -0,0 +1,156 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import { readdir } from 'fs-extra' +import { omit } from 'lodash' +import { join } from 'path' +import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' +import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' +import { buildServerDirectory, wait } from '../miscs/miscs' +import { unwrapBody } from '../requests' +import { waitUntilLog } from '../server/servers' +import { AbstractCommand, OverrideCommandOptions } from '../shared' +import { sendRTMPStream, testFfmpegStreamError } from './live' +import { getVideoWithToken } from './videos' + +export class LiveCommand extends AbstractCommand { + + getLive (options: OverrideCommandOptions & { + videoId: number | string + }) { + const path = '/api/v1/videos/live' + + return this.getRequestBody({ + ...options, + + path: path + '/' + options.videoId, + defaultExpectedStatus: HttpStatusCode.OK_200 + }) + } + + updateLive (options: OverrideCommandOptions & { + videoId: number | string + fields: LiveVideoUpdate + }) { + const { videoId, fields } = options + const path = '/api/v1/videos/live' + + return this.putBodyRequest({ + ...options, + + path: path + '/' + videoId, + fields, + defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204 + }) + } + + async createLive (options: OverrideCommandOptions & { + fields: LiveVideoCreate + }) { + const { fields } = options + const path = '/api/v1/videos/live' + + const attaches: any = {} + if (fields.thumbnailfile) attaches.thumbnailfile = fields.thumbnailfile + if (fields.previewfile) attaches.previewfile = fields.previewfile + + const body = await unwrapBody<{ video: VideoCreateResult }>(this.postUploadRequest({ + ...options, + + path, + attaches, + fields: omit(fields, 'thumbnailfile', 'previewfile'), + defaultExpectedStatus: HttpStatusCode.OK_200 + })) + + return body.video + } + + async sendRTMPStreamInVideo (options: OverrideCommandOptions & { + videoId: number | string + fixtureName?: string + }) { + const { videoId, fixtureName } = options + const videoLive = await this.getLive({ videoId }) + + return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, fixtureName) + } + + async runAndTestFfmpegStreamError (options: OverrideCommandOptions & { + videoId: number | string + shouldHaveError: boolean + }) { + const command = await this.sendRTMPStreamInVideo(options) + + return testFfmpegStreamError(command, options.shouldHaveError) + } + + waitUntilLivePublished (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.PUBLISHED }) + } + + waitUntilLiveWaiting (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.WAITING_FOR_LIVE }) + } + + waitUntilLiveEnded (options: OverrideCommandOptions & { + videoId: number | string + }) { + const { videoId } = options + return this.waitUntilLiveState({ videoId, state: VideoState.LIVE_ENDED }) + } + + waitUntilLiveSegmentGeneration (options: OverrideCommandOptions & { + videoUUID: string + resolution: number + segment: number + }) { + const { resolution, segment, videoUUID } = options + const segmentName = `${resolution}-00000${segment}.ts` + + return waitUntilLog(this.server, `${videoUUID}/${segmentName}`, 2, false) + } + + async waitUntilLiveSaved (options: OverrideCommandOptions & { + videoId: number | string + }) { + let video: VideoDetails + + do { + const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) + video = res.body + + await wait(500) + } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) + } + + async getPlaylistsCount (options: OverrideCommandOptions & { + videoUUID: string + }) { + const basePath = buildServerDirectory(this.server, 'streaming-playlists') + const hlsPath = join(basePath, 'hls', options.videoUUID) + + const files = await readdir(hlsPath) + + return files.filter(f => f.endsWith('.m3u8')).length + } + + private async waitUntilLiveState (options: OverrideCommandOptions & { + videoId: number | string + state: VideoState + }) { + let video: VideoDetails + + do { + const res = await getVideoWithToken(this.server.url, options.token ?? this.server.accessToken, options.videoId) + video = res.body + + await wait(500) + } while (video.state.id !== options.state) + } +} diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index c0384769b..285a39c7e 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts @@ -3,69 +3,9 @@ import { expect } from 'chai' import * as ffmpeg from 'fluent-ffmpeg' import { pathExists, readdir } from 'fs-extra' -import { omit } from 'lodash' import { join } from 'path' -import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoDetails, VideoState } from '@shared/models' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' import { buildAbsoluteFixturePath, buildServerDirectory, wait } from '../miscs/miscs' -import { makeGetRequest, makePutBodyRequest, makeUploadRequest } from '../requests/requests' -import { ServerInfo, waitUntilLog } from '../server/servers' -import { getVideoWithToken } from './videos' - -function getLive (url: string, token: string, videoId: number | string, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/live' - - return makeGetRequest({ - url, - token, - path: path + '/' + videoId, - statusCodeExpected - }) -} - -function updateLive ( - url: string, - token: string, - videoId: number | string, - fields: LiveVideoUpdate, - statusCodeExpected = HttpStatusCode.NO_CONTENT_204 -) { - const path = '/api/v1/videos/live' - - return makePutBodyRequest({ - url, - token, - path: path + '/' + videoId, - fields, - statusCodeExpected - }) -} - -function createLive (url: string, token: string, fields: LiveVideoCreate, statusCodeExpected = HttpStatusCode.OK_200) { - const path = '/api/v1/videos/live' - - const attaches: any = {} - if (fields.thumbnailfile) attaches.thumbnailfile = fields.thumbnailfile - if (fields.previewfile) attaches.previewfile = fields.previewfile - - const updatedFields = omit(fields, 'thumbnailfile', 'previewfile') - - return makeUploadRequest({ - url, - path, - token, - attaches, - fields: updatedFields, - statusCodeExpected - }) -} - -async function sendRTMPStreamInVideo (url: string, token: string, videoId: number | string, fixtureName?: string) { - const res = await getLive(url, token, videoId) - const videoLive = res.body as LiveVideo - - return sendRTMPStream(videoLive.rtmpUrl, videoLive.streamKey, fixtureName) -} +import { ServerInfo } from '../server/servers' function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { const fixture = buildAbsoluteFixturePath(fixtureName) @@ -109,12 +49,6 @@ function waitFfmpegUntilError (command: ffmpeg.FfmpegCommand, successAfterMS = 1 }) } -async function runAndTestFfmpegStreamError (url: string, token: string, videoId: number | string, shouldHaveError: boolean) { - const command = await sendRTMPStreamInVideo(url, token, videoId) - - return testFfmpegStreamError(command, shouldHaveError) -} - async function testFfmpegStreamError (command: ffmpeg.FfmpegCommand, shouldHaveError: boolean) { let error: Error @@ -136,48 +70,9 @@ async function stopFfmpeg (command: ffmpeg.FfmpegCommand) { await wait(500) } -function waitUntilLivePublished (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.PUBLISHED) -} - -function waitUntilLiveWaiting (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.WAITING_FOR_LIVE) -} - -function waitUntilLiveEnded (url: string, token: string, videoId: number | string) { - return waitUntilLiveState(url, token, videoId, VideoState.LIVE_ENDED) -} - -function waitUntilLiveSegmentGeneration (server: ServerInfo, videoUUID: string, resolutionNum: number, segmentNum: number) { - const segmentName = `${resolutionNum}-00000${segmentNum}.ts` - return waitUntilLog(server, `${videoUUID}/${segmentName}`, 2, false) -} - -async function waitUntilLiveState (url: string, token: string, videoId: number | string, state: VideoState) { - let video: VideoDetails - - do { - const res = await getVideoWithToken(url, token, videoId) - video = res.body - - await wait(500) - } while (video.state.id !== state) -} - -async function waitUntilLiveSaved (url: string, token: string, videoId: number | string) { - let video: VideoDetails - - do { - const res = await getVideoWithToken(url, token, videoId) - video = res.body - - await wait(500) - } while (video.isLive === true && video.state.id !== VideoState.PUBLISHED) -} - async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoId: string) { for (const server of servers) { - await waitUntilLivePublished(server.url, server.accessToken, videoId) + await server.liveCommand.waitUntilLivePublished({ videoId }) } } @@ -206,33 +101,11 @@ async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resoluti expect(files).to.contain('segments-sha256.json') } -async function getPlaylistsCount (server: ServerInfo, videoUUID: string) { - const basePath = buildServerDirectory(server, 'streaming-playlists') - const hlsPath = join(basePath, 'hls', videoUUID) - - const files = await readdir(hlsPath) - - return files.filter(f => f.endsWith('.m3u8')).length -} - -// --------------------------------------------------------------------------- - export { - getLive, - getPlaylistsCount, - waitUntilLiveSaved, - waitUntilLivePublished, - updateLive, - createLive, - runAndTestFfmpegStreamError, - checkLiveCleanup, - waitUntilLiveSegmentGeneration, - stopFfmpeg, - waitUntilLiveWaiting, - sendRTMPStreamInVideo, - waitUntilLiveEnded, + sendRTMPStream, waitFfmpegUntilError, + testFfmpegStreamError, + stopFfmpeg, waitUntilLivePublishedOnAllServers, - sendRTMPStream, - testFfmpegStreamError + checkLiveCleanup } -- 2.41.0