]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/tests/shared/live.ts
Add runner server tests
[github/Chocobozzz/PeerTube.git] / server / tests / shared / live.ts
index 4bd4786fc18564d8951a3e0037f64b75e1e8e861..31f92ef19a568b5c5396d58d31eba97784b9924a 100644 (file)
 import { expect } from 'chai'
 import { pathExists, readdir } from 'fs-extra'
 import { join } from 'path'
-import { LiveVideo } from '@shared/models'
-import { PeerTubeServer } from '@shared/server-commands'
-
-async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, savedResolutions: number[] = []) {
-  let live: LiveVideo
-
-  try {
-    live = await server.live.get({ videoId: videoUUID })
-  } catch {}
+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
 
   const basePath = server.servers.buildDirectory('streaming-playlists')
   const hlsPath = join(basePath, 'hls', videoUUID)
 
-  if (savedResolutions.length === 0) {
+  if (permanent) {
+    if (!await pathExists(hlsPath)) return
 
-    if (live?.permanentLive) {
-      expect(await pathExists(hlsPath)).to.be.true
+    const files = await readdir(hlsPath)
+    expect(files).to.have.lengthOf(0)
+    return
+  }
 
-      const hlsFiles = await readdir(hlsPath)
-      expect(hlsFiles).to.have.lengthOf(1) // Only replays directory
+  if (savedResolutions.length === 0) {
+    return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
+  }
 
-      const replayDir = join(hlsPath, 'replay')
-      expect(await pathExists(replayDir)).to.be.true
+  return checkSavedLiveCleanup(hlsPath, savedResolutions)
+}
 
-      const replayFiles = await readdir(join(hlsPath, 'replay'))
-      expect(replayFiles).to.have.lengthOf(0)
-    } else {
-      expect(await pathExists(hlsPath)).to.be.false
+// ---------------------------------------------------------------------------
+
+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)
     }
 
-    return
+    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
@@ -56,6 +158,27 @@ async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, save
   expect(shaFile).to.exist
 }
 
-export {
-  checkLiveCleanup
+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
 }