]>
Commit | Line | Data |
---|---|---|
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | |
2 | ||
3 | import 'mocha' | |
4 | import * as chai from 'chai' | |
5 | import { HttpStatusCode, VideoFile } from '@shared/models' | |
6 | import { | |
7 | areObjectStorageTestsDisabled, | |
8 | cleanupTests, | |
9 | createMultipleServers, | |
10 | doubleFollow, | |
11 | expectStartWith, | |
12 | makeRawRequest, | |
13 | ObjectStorageCommand, | |
14 | PeerTubeServer, | |
15 | setAccessTokensToServers, | |
16 | waitJobs | |
17 | } from '../../../shared/extra-utils' | |
18 | ||
19 | const expect = chai.expect | |
20 | ||
21 | async function checkFilesInObjectStorage (files: VideoFile[], type: 'webtorrent' | 'playlist') { | |
22 | for (const file of files) { | |
23 | const shouldStartWith = type === 'webtorrent' | |
24 | ? ObjectStorageCommand.getWebTorrentBaseUrl() | |
25 | : ObjectStorageCommand.getPlaylistBaseUrl() | |
26 | ||
27 | expectStartWith(file.fileUrl, shouldStartWith) | |
28 | ||
29 | await makeRawRequest(file.fileUrl, HttpStatusCode.OK_200) | |
30 | } | |
31 | } | |
32 | ||
33 | function runTests (objectStorage: boolean) { | |
34 | let servers: PeerTubeServer[] = [] | |
35 | const videosUUID: string[] = [] | |
36 | const publishedAt: string[] = [] | |
37 | ||
38 | before(async function () { | |
39 | this.timeout(120000) | |
40 | ||
41 | const config = objectStorage | |
42 | ? ObjectStorageCommand.getDefaultConfig() | |
43 | : {} | |
44 | ||
45 | // Run server 2 to have transcoding enabled | |
46 | servers = await createMultipleServers(2, config) | |
47 | await setAccessTokensToServers(servers) | |
48 | ||
49 | await servers[0].config.disableTranscoding() | |
50 | ||
51 | await doubleFollow(servers[0], servers[1]) | |
52 | ||
53 | if (objectStorage) await ObjectStorageCommand.prepareDefaultBuckets() | |
54 | ||
55 | for (let i = 1; i <= 5; i++) { | |
56 | const { uuid, shortUUID } = await servers[0].videos.upload({ attributes: { name: 'video' + i } }) | |
57 | ||
58 | await waitJobs(servers) | |
59 | ||
60 | const video = await servers[0].videos.get({ id: uuid }) | |
61 | publishedAt.push(video.publishedAt as string) | |
62 | ||
63 | if (i > 2) { | |
64 | videosUUID.push(uuid) | |
65 | } else { | |
66 | videosUUID.push(shortUUID) | |
67 | } | |
68 | } | |
69 | ||
70 | await waitJobs(servers) | |
71 | }) | |
72 | ||
73 | it('Should have two video files on each server', async function () { | |
74 | this.timeout(30000) | |
75 | ||
76 | for (const server of servers) { | |
77 | const { data } = await server.videos.list() | |
78 | expect(data).to.have.lengthOf(videosUUID.length) | |
79 | ||
80 | for (const video of data) { | |
81 | const videoDetail = await server.videos.get({ id: video.uuid }) | |
82 | expect(videoDetail.files).to.have.lengthOf(1) | |
83 | expect(videoDetail.streamingPlaylists).to.have.lengthOf(0) | |
84 | } | |
85 | } | |
86 | }) | |
87 | ||
88 | it('Should run a transcoding job on video 2', async function () { | |
89 | this.timeout(60000) | |
90 | ||
91 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[1]}`) | |
92 | await waitJobs(servers) | |
93 | ||
94 | for (const server of servers) { | |
95 | const { data } = await server.videos.list() | |
96 | ||
97 | let infoHashes: { [id: number]: string } | |
98 | ||
99 | for (const video of data) { | |
100 | const videoDetails = await server.videos.get({ id: video.uuid }) | |
101 | ||
102 | if (video.shortUUID === videosUUID[1] || video.uuid === videosUUID[1]) { | |
103 | expect(videoDetails.files).to.have.lengthOf(4) | |
104 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(0) | |
105 | ||
106 | if (objectStorage) await checkFilesInObjectStorage(videoDetails.files, 'webtorrent') | |
107 | ||
108 | if (!infoHashes) { | |
109 | infoHashes = {} | |
110 | ||
111 | for (const file of videoDetails.files) { | |
112 | infoHashes[file.resolution.id.toString()] = file.magnetUri | |
113 | } | |
114 | } else { | |
115 | for (const resolution of Object.keys(infoHashes)) { | |
116 | const file = videoDetails.files.find(f => f.resolution.id.toString() === resolution) | |
117 | expect(file.magnetUri).to.equal(infoHashes[resolution]) | |
118 | } | |
119 | } | |
120 | } else { | |
121 | expect(videoDetails.files).to.have.lengthOf(1) | |
122 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(0) | |
123 | } | |
124 | } | |
125 | } | |
126 | }) | |
127 | ||
128 | it('Should run a transcoding job on video 1 with resolution', async function () { | |
129 | this.timeout(60000) | |
130 | ||
131 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[0]} -r 480`) | |
132 | ||
133 | await waitJobs(servers) | |
134 | ||
135 | for (const server of servers) { | |
136 | const { data } = await server.videos.list() | |
137 | expect(data).to.have.lengthOf(videosUUID.length) | |
138 | ||
139 | const videoDetails = await server.videos.get({ id: videosUUID[0] }) | |
140 | ||
141 | expect(videoDetails.files).to.have.lengthOf(2) | |
142 | expect(videoDetails.files[0].resolution.id).to.equal(720) | |
143 | expect(videoDetails.files[1].resolution.id).to.equal(480) | |
144 | ||
145 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(0) | |
146 | ||
147 | if (objectStorage) await checkFilesInObjectStorage(videoDetails.files, 'webtorrent') | |
148 | } | |
149 | }) | |
150 | ||
151 | it('Should generate an HLS resolution', async function () { | |
152 | this.timeout(120000) | |
153 | ||
154 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[2]} --generate-hls -r 480`) | |
155 | ||
156 | await waitJobs(servers) | |
157 | ||
158 | for (const server of servers) { | |
159 | const videoDetails = await server.videos.get({ id: videosUUID[2] }) | |
160 | ||
161 | expect(videoDetails.files).to.have.lengthOf(1) | |
162 | if (objectStorage) await checkFilesInObjectStorage(videoDetails.files, 'webtorrent') | |
163 | ||
164 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(1) | |
165 | ||
166 | const files = videoDetails.streamingPlaylists[0].files | |
167 | expect(files).to.have.lengthOf(1) | |
168 | expect(files[0].resolution.id).to.equal(480) | |
169 | ||
170 | if (objectStorage) await checkFilesInObjectStorage(files, 'playlist') | |
171 | } | |
172 | }) | |
173 | ||
174 | it('Should not duplicate an HLS resolution', async function () { | |
175 | this.timeout(120000) | |
176 | ||
177 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[2]} --generate-hls -r 480`) | |
178 | ||
179 | await waitJobs(servers) | |
180 | ||
181 | for (const server of servers) { | |
182 | const videoDetails = await server.videos.get({ id: videosUUID[2] }) | |
183 | ||
184 | const files = videoDetails.streamingPlaylists[0].files | |
185 | expect(files).to.have.lengthOf(1) | |
186 | expect(files[0].resolution.id).to.equal(480) | |
187 | ||
188 | if (objectStorage) await checkFilesInObjectStorage(files, 'playlist') | |
189 | } | |
190 | }) | |
191 | ||
192 | it('Should generate all HLS resolutions', async function () { | |
193 | this.timeout(120000) | |
194 | ||
195 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[3]} --generate-hls`) | |
196 | ||
197 | await waitJobs(servers) | |
198 | ||
199 | for (const server of servers) { | |
200 | const videoDetails = await server.videos.get({ id: videosUUID[3] }) | |
201 | ||
202 | expect(videoDetails.files).to.have.lengthOf(1) | |
203 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(1) | |
204 | ||
205 | const files = videoDetails.streamingPlaylists[0].files | |
206 | expect(files).to.have.lengthOf(4) | |
207 | ||
208 | if (objectStorage) await checkFilesInObjectStorage(files, 'playlist') | |
209 | } | |
210 | }) | |
211 | ||
212 | it('Should optimize the video file and generate HLS videos if enabled in config', async function () { | |
213 | this.timeout(120000) | |
214 | ||
215 | await servers[0].config.enableTranscoding() | |
216 | await servers[0].cli.execWithEnv(`npm run create-transcoding-job -- -v ${videosUUID[4]}`) | |
217 | ||
218 | await waitJobs(servers) | |
219 | ||
220 | for (const server of servers) { | |
221 | const videoDetails = await server.videos.get({ id: videosUUID[4] }) | |
222 | ||
223 | expect(videoDetails.files).to.have.lengthOf(5) | |
224 | expect(videoDetails.streamingPlaylists).to.have.lengthOf(1) | |
225 | expect(videoDetails.streamingPlaylists[0].files).to.have.lengthOf(5) | |
226 | ||
227 | if (objectStorage) { | |
228 | await checkFilesInObjectStorage(videoDetails.files, 'webtorrent') | |
229 | await checkFilesInObjectStorage(videoDetails.streamingPlaylists[0].files, 'playlist') | |
230 | } | |
231 | } | |
232 | }) | |
233 | ||
234 | it('Should not have updated published at attributes', async function () { | |
235 | for (const id of videosUUID) { | |
236 | const video = await servers[0].videos.get({ id }) | |
237 | ||
238 | expect(publishedAt.some(p => video.publishedAt === p)).to.be.true | |
239 | } | |
240 | }) | |
241 | ||
242 | after(async function () { | |
243 | await cleanupTests(servers) | |
244 | }) | |
245 | } | |
246 | ||
247 | describe('Test create transcoding jobs', function () { | |
248 | ||
249 | describe('On filesystem', function () { | |
250 | runTests(false) | |
251 | }) | |
252 | ||
253 | describe('On object storage', function () { | |
254 | if (areObjectStorageTestsDisabled()) return | |
255 | ||
256 | runTests(true) | |
257 | }) | |
258 | }) |