aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/shared/live.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-10-04 10:03:17 +0200
committerChocobozzz <me@florianbigard.com>2022-10-04 10:03:17 +0200
commitcfd57d2ca0bb058087f7dc90fcc3e8442b0288e1 (patch)
treedc899a1504ecac588e5580553e02571e0f5d7e4b /server/tests/shared/live.ts
parent9c0cdc5047918b959ebd5e075ddad81eb7fb93f0 (diff)
downloadPeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.tar.gz
PeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.tar.zst
PeerTube-cfd57d2ca0bb058087f7dc90fcc3e8442b0288e1.zip
Live supports object storage
* Sync live files (segments, master playlist, resolution playlist, segment sha file) into object storage * Automatically delete them when the live ends * Segment sha file is now a file on disk, and not stored in memory anymore
Diffstat (limited to 'server/tests/shared/live.ts')
-rw-r--r--server/tests/shared/live.ts116
1 files changed, 95 insertions, 21 deletions
diff --git a/server/tests/shared/live.ts b/server/tests/shared/live.ts
index 4bd4786fc..aa79622cb 100644
--- a/server/tests/shared/live.ts
+++ b/server/tests/shared/live.ts
@@ -3,39 +3,92 @@
3import { expect } from 'chai' 3import { expect } from 'chai'
4import { pathExists, readdir } from 'fs-extra' 4import { pathExists, readdir } from 'fs-extra'
5import { join } from 'path' 5import { join } from 'path'
6import { LiveVideo } from '@shared/models' 6import { wait } from '@shared/core-utils'
7import { PeerTubeServer } from '@shared/server-commands' 7import { LiveVideo, VideoStreamingPlaylistType } from '@shared/models'
8import { ObjectStorageCommand, PeerTubeServer } from '@shared/server-commands'
9import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist } from './streaming-playlists'
8 10
9async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, savedResolutions: number[] = []) { 11async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, savedResolutions: number[] = []) {
10 let live: LiveVideo
11
12 try {
13 live = await server.live.get({ videoId: videoUUID })
14 } catch {}
15
16 const basePath = server.servers.buildDirectory('streaming-playlists') 12 const basePath = server.servers.buildDirectory('streaming-playlists')
17 const hlsPath = join(basePath, 'hls', videoUUID) 13 const hlsPath = join(basePath, 'hls', videoUUID)
18 14
19 if (savedResolutions.length === 0) { 15 if (savedResolutions.length === 0) {
16 return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
17 }
18
19 return checkSavedLiveCleanup(hlsPath, savedResolutions)
20}
21
22// ---------------------------------------------------------------------------
20 23
21 if (live?.permanentLive) { 24async function testVideoResolutions (options: {
22 expect(await pathExists(hlsPath)).to.be.true 25 originServer: PeerTubeServer
26 servers: PeerTubeServer[]
27 liveVideoId: string
28 resolutions: number[]
29 transcoded: boolean
30 objectStorage: boolean
31}) {
32 const { originServer, servers, liveVideoId, resolutions, transcoded, objectStorage } = options
23 33
24 const hlsFiles = await readdir(hlsPath) 34 for (const server of servers) {
25 expect(hlsFiles).to.have.lengthOf(1) // Only replays directory 35 const { data } = await server.videos.list()
36 expect(data.find(v => v.uuid === liveVideoId)).to.exist
26 37
27 const replayDir = join(hlsPath, 'replay') 38 const video = await server.videos.get({ id: liveVideoId })
28 expect(await pathExists(replayDir)).to.be.true 39 expect(video.streamingPlaylists).to.have.lengthOf(1)
29 40
30 const replayFiles = await readdir(join(hlsPath, 'replay')) 41 const hlsPlaylist = video.streamingPlaylists.find(s => s.type === VideoStreamingPlaylistType.HLS)
31 expect(replayFiles).to.have.lengthOf(0) 42 expect(hlsPlaylist).to.exist
32 } else { 43 expect(hlsPlaylist.files).to.have.lengthOf(0) // Only fragmented mp4 files are displayed
33 expect(await pathExists(hlsPath)).to.be.false 44
45 await checkResolutionsInMasterPlaylist({ server, playlistUrl: hlsPlaylist.playlistUrl, resolutions, transcoded })
46
47 if (objectStorage) {
48 expect(hlsPlaylist.playlistUrl).to.contain(ObjectStorageCommand.getPlaylistBaseUrl())
34 } 49 }
35 50
36 return 51 for (let i = 0; i < resolutions.length; i++) {
52 const segmentNum = 3
53 const segmentName = `${i}-00000${segmentNum}.ts`
54 await originServer.live.waitUntilSegmentGeneration({ videoUUID: video.uuid, playlistNumber: i, segment: segmentNum })
55
56 const baseUrl = objectStorage
57 ? ObjectStorageCommand.getPlaylistBaseUrl() + 'hls'
58 : originServer.url + '/static/streaming-playlists/hls'
59
60 if (objectStorage) {
61 // Playlist file upload
62 await wait(500)
63
64 expect(hlsPlaylist.segmentsSha256Url).to.contain(ObjectStorageCommand.getPlaylistBaseUrl())
65 }
66
67 const subPlaylist = await originServer.streamingPlaylists.get({ url: `${baseUrl}/${video.uuid}/${i}.m3u8` })
68
69 expect(subPlaylist).to.contain(segmentName)
70
71 await checkLiveSegmentHash({
72 server,
73 baseUrlSegment: baseUrl,
74 videoUUID: video.uuid,
75 segmentName,
76 hlsPlaylist
77 })
78 }
37 } 79 }
80}
81
82// ---------------------------------------------------------------------------
83
84export {
85 checkLiveCleanup,
86 testVideoResolutions
87}
38 88
89// ---------------------------------------------------------------------------
90
91async function checkSavedLiveCleanup (hlsPath: string, savedResolutions: number[] = []) {
39 const files = await readdir(hlsPath) 92 const files = await readdir(hlsPath)
40 93
41 // fragmented file and playlist per resolution + master playlist + segments sha256 json file 94 // fragmented file and playlist per resolution + master playlist + segments sha256 json file
@@ -56,6 +109,27 @@ async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, save
56 expect(shaFile).to.exist 109 expect(shaFile).to.exist
57} 110}
58 111
59export { 112async function checkUnsavedLiveCleanup (server: PeerTubeServer, videoUUID: string, hlsPath: string) {
60 checkLiveCleanup 113 let live: LiveVideo
114
115 try {
116 live = await server.live.get({ videoId: videoUUID })
117 } catch {}
118
119 if (live?.permanentLive) {
120 expect(await pathExists(hlsPath)).to.be.true
121
122 const hlsFiles = await readdir(hlsPath)
123 expect(hlsFiles).to.have.lengthOf(1) // Only replays directory
124
125 const replayDir = join(hlsPath, 'replay')
126 expect(await pathExists(replayDir)).to.be.true
127
128 const replayFiles = await readdir(join(hlsPath, 'replay'))
129 expect(replayFiles).to.have.lengthOf(0)
130
131 return
132 }
133
134 expect(await pathExists(hlsPath)).to.be.false
61} 135}