From 4ec52d04dcc5d664612331f8e08d7d90da990415 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 21 Apr 2022 09:06:52 +0200 Subject: Add ability to save replay of permanent lives --- server/tests/api/live/live-save-replay.ts | 155 ++++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 18 deletions(-) (limited to 'server/tests/api/live/live-save-replay.ts') diff --git a/server/tests/api/live/live-save-replay.ts b/server/tests/api/live/live-save-replay.ts index 95a342b01..ba68a4287 100644 --- a/server/tests/api/live/live-save-replay.ts +++ b/server/tests/api/live/live-save-replay.ts @@ -3,7 +3,7 @@ import 'mocha' import * as chai from 'chai' import { FfmpegCommand } from 'fluent-ffmpeg' -import { checkLiveCleanupAfterSave } from '@server/tests/shared' +import { checkLiveCleanup } from '@server/tests/shared' import { wait } from '@shared/core-utils' import { HttpStatusCode, LiveVideoCreate, VideoPrivacy, VideoState } from '@shared/models' import { @@ -11,6 +11,7 @@ import { ConfigCommand, createMultipleServers, doubleFollow, + findExternalSavedVideo, PeerTubeServer, setAccessTokensToServers, setDefaultVideoChannel, @@ -18,7 +19,8 @@ import { testFfmpegStreamError, waitJobs, waitUntilLivePublishedOnAllServers, - waitUntilLiveSavedOnAllServers + waitUntilLiveReplacedByReplayOnAllServers, + waitUntilLiveWaitingOnAllServers } from '@shared/server-commands' const expect = chai.expect @@ -28,7 +30,7 @@ describe('Save replay setting', function () { let liveVideoUUID: string let ffmpegCommand: FfmpegCommand - async function createLiveWrapper (saveReplay: boolean) { + async function createLiveWrapper (options: { permanent: boolean, replay: boolean }) { if (liveVideoUUID) { try { await servers[0].videos.remove({ id: liveVideoUUID }) @@ -40,7 +42,8 @@ describe('Save replay setting', function () { channelId: servers[0].store.channel.id, privacy: VideoPrivacy.PUBLIC, name: 'my super live', - saveReplay + saveReplay: options.replay, + permanentLive: options.permanent } const { uuid } = await servers[0].live.create({ fields: attributes }) @@ -104,7 +107,7 @@ describe('Save replay setting', function () { it('Should correctly create and federate the "waiting for stream" live', async function () { this.timeout(20000) - liveVideoUUID = await createLiveWrapper(false) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: false }) await waitJobs(servers) @@ -140,13 +143,13 @@ describe('Save replay setting', function () { await checkVideoState(liveVideoUUID, VideoState.LIVE_ENDED) // No resolutions saved since we did not save replay - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, []) + await checkLiveCleanup(servers[0], liveVideoUUID, []) }) it('Should correctly terminate the stream on blacklist and delete the live', async function () { this.timeout(40000) - liveVideoUUID = await createLiveWrapper(false) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: false }) ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) @@ -169,13 +172,13 @@ describe('Save replay setting', function () { await wait(5000) await waitJobs(servers) - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, []) + await checkLiveCleanup(servers[0], liveVideoUUID, []) }) it('Should correctly terminate the stream on delete and delete the video', async function () { this.timeout(40000) - liveVideoUUID = await createLiveWrapper(false) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: false }) ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) @@ -193,16 +196,16 @@ describe('Save replay setting', function () { await waitJobs(servers) await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, []) + await checkLiveCleanup(servers[0], liveVideoUUID, []) }) }) - describe('With save replay enabled', function () { + describe('With save replay enabled on non permanent live', function () { it('Should correctly create and federate the "waiting for stream" live', async function () { this.timeout(20000) - liveVideoUUID = await createLiveWrapper(true) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: true }) await waitJobs(servers) @@ -227,7 +230,7 @@ describe('Save replay setting', function () { await stopFfmpeg(ffmpegCommand) - await waitUntilLiveSavedOnAllServers(servers, liveVideoUUID) + await waitUntilLiveReplacedByReplayOnAllServers(servers, liveVideoUUID) await waitJobs(servers) // Live has been transcoded @@ -249,13 +252,13 @@ describe('Save replay setting', function () { }) it('Should have cleaned up the live files', async function () { - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, [ 720 ]) + await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) }) it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () { this.timeout(40000) - liveVideoUUID = await createLiveWrapper(true) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: true }) ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) @@ -277,13 +280,13 @@ describe('Save replay setting', function () { await wait(5000) await waitJobs(servers) - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, [ 720 ]) + await checkLiveCleanup(servers[0], liveVideoUUID, [ 720 ]) }) it('Should correctly terminate the stream on delete and delete the video', async function () { this.timeout(40000) - liveVideoUUID = await createLiveWrapper(true) + liveVideoUUID = await createLiveWrapper({ permanent: false, replay: true }) ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) @@ -300,7 +303,123 @@ describe('Save replay setting', function () { await waitJobs(servers) await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) - await checkLiveCleanupAfterSave(servers[0], liveVideoUUID, []) + await checkLiveCleanup(servers[0], liveVideoUUID, []) + }) + }) + + describe('With save replay enabled on permanent live', function () { + let lastReplayUUID: string + + it('Should correctly create and federate the "waiting for stream" live', async function () { + this.timeout(20000) + + liveVideoUUID = await createLiveWrapper({ permanent: true, replay: true }) + + await waitJobs(servers) + + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.OK_200) + await checkVideoState(liveVideoUUID, VideoState.WAITING_FOR_LIVE) + }) + + it('Should correctly have updated the live and federated it when streaming in the live', async function () { + this.timeout(20000) + + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + await waitJobs(servers) + + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + await checkVideoState(liveVideoUUID, VideoState.PUBLISHED) + }) + + it('Should correctly have saved the live and federated it after the streaming', async function () { + this.timeout(30000) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await stopFfmpeg(ffmpegCommand) + + await waitUntilLiveWaitingOnAllServers(servers, liveVideoUUID) + await waitJobs(servers) + + const video = await findExternalSavedVideo(servers[0], liveDetails) + expect(video).to.exist + + for (const server of servers) { + await server.videos.get({ id: video.uuid }) + } + + lastReplayUUID = video.uuid + }) + + it('Should have cleaned up the live files', async function () { + await checkLiveCleanup(servers[0], liveVideoUUID, []) + }) + + it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () { + this.timeout(60000) + + await servers[0].videos.remove({ id: lastReplayUUID }) + + liveVideoUUID = await createLiveWrapper({ permanent: true, replay: true }) + + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await waitJobs(servers) + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + + await Promise.all([ + servers[0].blacklist.add({ videoId: liveVideoUUID, reason: 'bad live', unfederate: true }), + testFfmpegStreamError(ffmpegCommand, true) + ]) + + await waitJobs(servers) + await wait(5000) + await waitJobs(servers) + + const replay = await findExternalSavedVideo(servers[0], liveDetails) + expect(replay).to.exist + + for (const videoId of [ liveVideoUUID, replay.uuid ]) { + await checkVideosExist(videoId, false) + + await servers[0].videos.get({ id: videoId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) + await servers[1].videos.get({ id: videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) + } + + await checkLiveCleanup(servers[0], liveVideoUUID, []) + }) + + it('Should correctly terminate the stream on delete and not save the video', async function () { + this.timeout(40000) + + liveVideoUUID = await createLiveWrapper({ permanent: true, replay: true }) + + ffmpegCommand = await servers[0].live.sendRTMPStreamInVideo({ videoId: liveVideoUUID }) + await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID) + + const liveDetails = await servers[0].videos.get({ id: liveVideoUUID }) + + await waitJobs(servers) + await checkVideosExist(liveVideoUUID, true, HttpStatusCode.OK_200) + + await Promise.all([ + servers[0].videos.remove({ id: liveVideoUUID }), + testFfmpegStreamError(ffmpegCommand, true) + ]) + + await wait(5000) + await waitJobs(servers) + + const replay = await findExternalSavedVideo(servers[0], liveDetails) + expect(replay).to.not.exist + + await checkVideosExist(liveVideoUUID, false, HttpStatusCode.NOT_FOUND_404) + await checkLiveCleanup(servers[0], liveVideoUUID, []) }) }) -- cgit v1.2.3