X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Ftests%2Fshared%2Flive.ts;h=31f92ef19a568b5c5396d58d31eba97784b9924a;hb=d102de1b38f2877463529c3b27bd35ffef4fd8bf;hp=72e3e27f61e21143a15a3c452c8b9bcefc65114b;hpb=c3edc5b074aa4bb1861ed0a94d3713808e87170f;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/tests/shared/live.ts b/server/tests/shared/live.ts index 72e3e27f6..31f92ef19 100644 --- a/server/tests/shared/live.ts +++ b/server/tests/shared/live.ts @@ -3,25 +3,147 @@ import { expect } from 'chai' import { pathExists, readdir } from 'fs-extra' import { join } from 'path' -import { PeerTubeServer } from '@shared/server-commands' +import { sha1 } from '@shared/extra-utils' +import { LiveVideo, VideoStreamingPlaylistType } from '@shared/models' +import { ObjectStorageCommand, PeerTubeServer } from '@shared/server-commands' +import { SQLCommand } from './sql-command' +import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist } from './streaming-playlists' + +async function checkLiveCleanup (options: { + server: PeerTubeServer + videoUUID: string + permanent: boolean + savedResolutions?: number[] +}) { + const { server, videoUUID, permanent, savedResolutions = [] } = options -async function checkLiveCleanupAfterSave (server: PeerTubeServer, videoUUID: string, resolutions: number[] = []) { const basePath = server.servers.buildDirectory('streaming-playlists') const hlsPath = join(basePath, 'hls', videoUUID) - if (resolutions.length === 0) { - const result = await pathExists(hlsPath) - expect(result).to.be.false + if (permanent) { + if (!await pathExists(hlsPath)) return + const files = await readdir(hlsPath) + expect(files).to.have.lengthOf(0) return } + if (savedResolutions.length === 0) { + return checkUnsavedLiveCleanup(server, videoUUID, hlsPath) + } + + return checkSavedLiveCleanup(hlsPath, savedResolutions) +} + +// --------------------------------------------------------------------------- + +async function testLiveVideoResolutions (options: { + sqlCommand: SQLCommand + originServer: PeerTubeServer + + servers: PeerTubeServer[] + liveVideoId: string + resolutions: number[] + transcoded: boolean + + objectStorage: boolean + objectStorageBaseUrl?: string +}) { + const { + originServer, + sqlCommand, + servers, + liveVideoId, + resolutions, + transcoded, + objectStorage, + objectStorageBaseUrl = ObjectStorageCommand.getMockPlaylistBaseUrl() + } = options + + for (const server of servers) { + const { data } = await server.videos.list() + expect(data.find(v => v.uuid === liveVideoId)).to.exist + + const video = await server.videos.get({ id: liveVideoId }) + expect(video.streamingPlaylists).to.have.lengthOf(1) + + const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS) + expect(hlsPlaylist).to.exist + expect(hlsPlaylist.files).to.have.lengthOf(0) // Only fragmented mp4 files are displayed + + await checkResolutionsInMasterPlaylist({ + server, + playlistUrl: hlsPlaylist.playlistUrl, + resolutions, + transcoded, + withRetry: objectStorage + }) + + if (objectStorage) { + expect(hlsPlaylist.playlistUrl).to.contain(objectStorageBaseUrl) + } + + for (let i = 0; i < resolutions.length; i++) { + const segmentNum = 3 + const segmentName = `${i}-00000${segmentNum}.ts` + await originServer.live.waitUntilSegmentGeneration({ + server: originServer, + videoUUID: video.uuid, + playlistNumber: i, + segment: segmentNum, + objectStorage, + objectStorageBaseUrl + }) + + const baseUrl = objectStorage + ? join(objectStorageBaseUrl, 'hls') + : originServer.url + '/static/streaming-playlists/hls' + + if (objectStorage) { + expect(hlsPlaylist.segmentsSha256Url).to.contain(objectStorageBaseUrl) + } + + const subPlaylist = await originServer.streamingPlaylists.get({ + url: `${baseUrl}/${video.uuid}/${i}.m3u8`, + withRetry: objectStorage // With object storage, the request may fail because of inconsistent data in S3 + }) + + expect(subPlaylist).to.contain(segmentName) + + await checkLiveSegmentHash({ + server, + baseUrlSegment: baseUrl, + videoUUID: video.uuid, + segmentName, + hlsPlaylist + }) + + if (originServer.internalServerNumber === server.internalServerNumber) { + const infohash = sha1(`${2 + hlsPlaylist.playlistUrl}+V${i}`) + const dbInfohashes = await sqlCommand.getPlaylistInfohash(hlsPlaylist.id) + + expect(dbInfohashes).to.include(infohash) + } + } + } +} + +// --------------------------------------------------------------------------- + +export { + checkLiveCleanup, + testLiveVideoResolutions +} + +// --------------------------------------------------------------------------- + +async function checkSavedLiveCleanup (hlsPath: string, savedResolutions: number[] = []) { const files = await readdir(hlsPath) // fragmented file and playlist per resolution + master playlist + segments sha256 json file - expect(files).to.have.lengthOf(resolutions.length * 2 + 2) + expect(files).to.have.lengthOf(savedResolutions.length * 2 + 2) - for (const resolution of resolutions) { + for (const resolution of savedResolutions) { const fragmentedFile = files.find(f => f.endsWith(`-${resolution}-fragmented.mp4`)) expect(fragmentedFile).to.exist @@ -36,6 +158,27 @@ async function checkLiveCleanupAfterSave (server: PeerTubeServer, videoUUID: str expect(shaFile).to.exist } -export { - checkLiveCleanupAfterSave +async function checkUnsavedLiveCleanup (server: PeerTubeServer, videoUUID: string, hlsPath: string) { + let live: LiveVideo + + try { + live = await server.live.get({ videoId: videoUUID }) + } catch {} + + if (live?.permanentLive) { + expect(await pathExists(hlsPath)).to.be.true + + const hlsFiles = await readdir(hlsPath) + expect(hlsFiles).to.have.lengthOf(1) // Only replays directory + + const replayDir = join(hlsPath, 'replay') + expect(await pathExists(replayDir)).to.be.true + + const replayFiles = await readdir(join(hlsPath, 'replay')) + expect(replayFiles).to.have.lengthOf(0) + + return + } + + expect(await pathExists(hlsPath)).to.be.false }