diff options
Diffstat (limited to 'server/tests/shared')
-rw-r--r-- | server/tests/shared/live.ts | 116 | ||||
-rw-r--r-- | server/tests/shared/streaming-playlists.ts | 13 |
2 files changed, 102 insertions, 27 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 @@ | |||
3 | import { expect } from 'chai' | 3 | import { expect } from 'chai' |
4 | import { pathExists, readdir } from 'fs-extra' | 4 | import { pathExists, readdir } from 'fs-extra' |
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { LiveVideo } from '@shared/models' | 6 | import { wait } from '@shared/core-utils' |
7 | import { PeerTubeServer } from '@shared/server-commands' | 7 | import { LiveVideo, VideoStreamingPlaylistType } from '@shared/models' |
8 | import { ObjectStorageCommand, PeerTubeServer } from '@shared/server-commands' | ||
9 | import { checkLiveSegmentHash, checkResolutionsInMasterPlaylist } from './streaming-playlists' | ||
8 | 10 | ||
9 | async function checkLiveCleanup (server: PeerTubeServer, videoUUID: string, savedResolutions: number[] = []) { | 11 | async 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) { | 24 | async 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 | |||
84 | export { | ||
85 | checkLiveCleanup, | ||
86 | testVideoResolutions | ||
87 | } | ||
38 | 88 | ||
89 | // --------------------------------------------------------------------------- | ||
90 | |||
91 | async 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 | ||
59 | export { | 112 | async 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 | } |
diff --git a/server/tests/shared/streaming-playlists.ts b/server/tests/shared/streaming-playlists.ts index 4d82b3654..eff34944b 100644 --- a/server/tests/shared/streaming-playlists.ts +++ b/server/tests/shared/streaming-playlists.ts | |||
@@ -26,7 +26,7 @@ async function checkSegmentHash (options: { | |||
26 | const offset = parseInt(matches[2], 10) | 26 | const offset = parseInt(matches[2], 10) |
27 | const range = `${offset}-${offset + length - 1}` | 27 | const range = `${offset}-${offset + length - 1}` |
28 | 28 | ||
29 | const segmentBody = await command.getSegment({ | 29 | const segmentBody = await command.getFragmentedSegment({ |
30 | url: `${baseUrlSegment}/${videoName}`, | 30 | url: `${baseUrlSegment}/${videoName}`, |
31 | expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, | 31 | expectedStatus: HttpStatusCode.PARTIAL_CONTENT_206, |
32 | range: `bytes=${range}` | 32 | range: `bytes=${range}` |
@@ -46,7 +46,7 @@ async function checkLiveSegmentHash (options: { | |||
46 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options | 46 | const { server, baseUrlSegment, videoUUID, segmentName, hlsPlaylist } = options |
47 | const command = server.streamingPlaylists | 47 | const command = server.streamingPlaylists |
48 | 48 | ||
49 | const segmentBody = await command.getSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) | 49 | const segmentBody = await command.getFragmentedSegment({ url: `${baseUrlSegment}/${videoUUID}/${segmentName}` }) |
50 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) | 50 | const shaBody = await command.getSegmentSha256({ url: hlsPlaylist.segmentsSha256Url }) |
51 | 51 | ||
52 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) | 52 | expect(sha256(segmentBody)).to.equal(shaBody[segmentName]) |
@@ -56,15 +56,16 @@ async function checkResolutionsInMasterPlaylist (options: { | |||
56 | server: PeerTubeServer | 56 | server: PeerTubeServer |
57 | playlistUrl: string | 57 | playlistUrl: string |
58 | resolutions: number[] | 58 | resolutions: number[] |
59 | transcoded?: boolean // default true | ||
59 | }) { | 60 | }) { |
60 | const { server, playlistUrl, resolutions } = options | 61 | const { server, playlistUrl, resolutions, transcoded = true } = options |
61 | 62 | ||
62 | const masterPlaylist = await server.streamingPlaylists.get({ url: playlistUrl }) | 63 | const masterPlaylist = await server.streamingPlaylists.get({ url: playlistUrl }) |
63 | 64 | ||
64 | for (const resolution of resolutions) { | 65 | for (const resolution of resolutions) { |
65 | const reg = new RegExp( | 66 | const reg = transcoded |
66 | '#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"' | 67 | ? new RegExp('#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + ',(FRAME-RATE=\\d+,)?CODECS="avc1.64001f,mp4a.40.2"') |
67 | ) | 68 | : new RegExp('#EXT-X-STREAM-INF:BANDWIDTH=\\d+,RESOLUTION=\\d+x' + resolution + '') |
68 | 69 | ||
69 | expect(masterPlaylist).to.match(reg) | 70 | expect(masterPlaylist).to.match(reg) |
70 | } | 71 | } |