diff options
author | Chocobozzz <me@florianbigard.com> | 2023-04-21 15:00:01 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2023-05-09 08:57:34 +0200 |
commit | d102de1b38f2877463529c3b27bd35ffef4fd8bf (patch) | |
tree | 31fa0bdf26ad7a2ee46d600d804a6f03260266c8 /server/tests/api/check-params | |
parent | 2fe978744e5b74eb824e4d79c1bb9b840169f125 (diff) | |
download | PeerTube-d102de1b38f2877463529c3b27bd35ffef4fd8bf.tar.gz PeerTube-d102de1b38f2877463529c3b27bd35ffef4fd8bf.tar.zst PeerTube-d102de1b38f2877463529c3b27bd35ffef4fd8bf.zip |
Add runner server tests
Diffstat (limited to 'server/tests/api/check-params')
-rw-r--r-- | server/tests/api/check-params/config.ts | 6 | ||||
-rw-r--r-- | server/tests/api/check-params/index.ts | 1 | ||||
-rw-r--r-- | server/tests/api/check-params/runners.ts | 702 | ||||
-rw-r--r-- | server/tests/api/check-params/video-blacklist.ts | 2 | ||||
-rw-r--r-- | server/tests/api/check-params/video-playlists.ts | 2 | ||||
-rw-r--r-- | server/tests/api/check-params/videos.ts | 10 |
6 files changed, 716 insertions, 7 deletions
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index f49a4b868..c5cda203e 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -103,6 +103,9 @@ describe('Test config API validators', function () { | |||
103 | }, | 103 | }, |
104 | transcoding: { | 104 | transcoding: { |
105 | enabled: true, | 105 | enabled: true, |
106 | remoteRunners: { | ||
107 | enabled: true | ||
108 | }, | ||
106 | allowAdditionalExtensions: true, | 109 | allowAdditionalExtensions: true, |
107 | allowAudioFiles: true, | 110 | allowAudioFiles: true, |
108 | concurrency: 1, | 111 | concurrency: 1, |
@@ -140,6 +143,9 @@ describe('Test config API validators', function () { | |||
140 | 143 | ||
141 | transcoding: { | 144 | transcoding: { |
142 | enabled: true, | 145 | enabled: true, |
146 | remoteRunners: { | ||
147 | enabled: true | ||
148 | }, | ||
143 | threads: 4, | 149 | threads: 4, |
144 | profile: 'live_profile', | 150 | profile: 'live_profile', |
145 | resolutions: { | 151 | resolutions: { |
diff --git a/server/tests/api/check-params/index.ts b/server/tests/api/check-params/index.ts index ddbcb42f8..400d312d3 100644 --- a/server/tests/api/check-params/index.ts +++ b/server/tests/api/check-params/index.ts | |||
@@ -16,6 +16,7 @@ import './my-user' | |||
16 | import './plugins' | 16 | import './plugins' |
17 | import './redundancy' | 17 | import './redundancy' |
18 | import './registrations' | 18 | import './registrations' |
19 | import './runners' | ||
19 | import './search' | 20 | import './search' |
20 | import './services' | 21 | import './services' |
21 | import './transcoding' | 22 | import './transcoding' |
diff --git a/server/tests/api/check-params/runners.ts b/server/tests/api/check-params/runners.ts new file mode 100644 index 000000000..4da6fd91d --- /dev/null +++ b/server/tests/api/check-params/runners.ts | |||
@@ -0,0 +1,702 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '@server/tests/shared' | ||
3 | import { HttpStatusCode, RunnerJob, RunnerJobState, RunnerJobSuccessPayload, RunnerJobUpdatePayload, VideoPrivacy } from '@shared/models' | ||
4 | import { | ||
5 | cleanupTests, | ||
6 | createSingleServer, | ||
7 | makePostBodyRequest, | ||
8 | PeerTubeServer, | ||
9 | sendRTMPStream, | ||
10 | setAccessTokensToServers, | ||
11 | setDefaultVideoChannel, | ||
12 | stopFfmpeg, | ||
13 | waitJobs | ||
14 | } from '@shared/server-commands' | ||
15 | |||
16 | const badUUID = '910ec12a-d9e6-458b-a274-0abb655f9464' | ||
17 | |||
18 | describe('Test managing runners', function () { | ||
19 | let server: PeerTubeServer | ||
20 | |||
21 | let userToken: string | ||
22 | |||
23 | let registrationTokenId: number | ||
24 | let registrationToken: string | ||
25 | |||
26 | let runnerToken: string | ||
27 | let runnerToken2: string | ||
28 | |||
29 | let completedJobToken: string | ||
30 | let completedJobUUID: string | ||
31 | |||
32 | let cancelledJobUUID: string | ||
33 | |||
34 | before(async function () { | ||
35 | this.timeout(120000) | ||
36 | |||
37 | const config = { | ||
38 | rates_limit: { | ||
39 | api: { | ||
40 | max: 5000 | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | server = await createSingleServer(1, config) | ||
46 | await setAccessTokensToServers([ server ]) | ||
47 | await setDefaultVideoChannel([ server ]) | ||
48 | |||
49 | userToken = await server.users.generateUserAndToken('user1') | ||
50 | |||
51 | const { data } = await server.runnerRegistrationTokens.list() | ||
52 | registrationToken = data[0].registrationToken | ||
53 | registrationTokenId = data[0].id | ||
54 | |||
55 | await server.config.enableTranscoding(true, true) | ||
56 | await server.config.enableRemoteTranscoding() | ||
57 | runnerToken = await server.runners.autoRegisterRunner() | ||
58 | runnerToken2 = await server.runners.autoRegisterRunner() | ||
59 | |||
60 | { | ||
61 | await server.videos.quickUpload({ name: 'video 1' }) | ||
62 | await server.videos.quickUpload({ name: 'video 2' }) | ||
63 | |||
64 | await waitJobs([ server ]) | ||
65 | |||
66 | { | ||
67 | const job = await server.runnerJobs.autoProcessWebVideoJob(runnerToken) | ||
68 | completedJobToken = job.jobToken | ||
69 | completedJobUUID = job.uuid | ||
70 | } | ||
71 | |||
72 | { | ||
73 | const { job } = await server.runnerJobs.autoAccept({ runnerToken }) | ||
74 | cancelledJobUUID = job.uuid | ||
75 | await server.runnerJobs.cancelByAdmin({ jobUUID: cancelledJobUUID }) | ||
76 | } | ||
77 | } | ||
78 | }) | ||
79 | |||
80 | describe('Managing runner registration tokens', function () { | ||
81 | |||
82 | describe('Common', function () { | ||
83 | |||
84 | it('Should fail to generate, list or delete runner registration token without oauth token', async function () { | ||
85 | const expectedStatus = HttpStatusCode.UNAUTHORIZED_401 | ||
86 | |||
87 | await server.runnerRegistrationTokens.generate({ token: null, expectedStatus }) | ||
88 | await server.runnerRegistrationTokens.list({ token: null, expectedStatus }) | ||
89 | await server.runnerRegistrationTokens.delete({ token: null, id: registrationTokenId, expectedStatus }) | ||
90 | }) | ||
91 | |||
92 | it('Should fail to generate, list or delete runner registration token without admin rights', async function () { | ||
93 | const expectedStatus = HttpStatusCode.FORBIDDEN_403 | ||
94 | |||
95 | await server.runnerRegistrationTokens.generate({ token: userToken, expectedStatus }) | ||
96 | await server.runnerRegistrationTokens.list({ token: userToken, expectedStatus }) | ||
97 | await server.runnerRegistrationTokens.delete({ token: userToken, id: registrationTokenId, expectedStatus }) | ||
98 | }) | ||
99 | }) | ||
100 | |||
101 | describe('Delete', function () { | ||
102 | |||
103 | it('Should fail to delete with a bad id', async function () { | ||
104 | await server.runnerRegistrationTokens.delete({ id: 404, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
105 | }) | ||
106 | }) | ||
107 | |||
108 | describe('List', function () { | ||
109 | const path = '/api/v1/runners/registration-tokens' | ||
110 | |||
111 | it('Should fail to list with a bad start pagination', async function () { | ||
112 | await checkBadStartPagination(server.url, path, server.accessToken) | ||
113 | }) | ||
114 | |||
115 | it('Should fail to list with a bad count pagination', async function () { | ||
116 | await checkBadCountPagination(server.url, path, server.accessToken) | ||
117 | }) | ||
118 | |||
119 | it('Should fail to list with an incorrect sort', async function () { | ||
120 | await checkBadSortPagination(server.url, path, server.accessToken) | ||
121 | }) | ||
122 | |||
123 | it('Should succeed to list with the correct params', async function () { | ||
124 | await server.runnerRegistrationTokens.list({ start: 0, count: 5, sort: '-createdAt' }) | ||
125 | }) | ||
126 | }) | ||
127 | }) | ||
128 | |||
129 | describe('Managing runners', function () { | ||
130 | let toDeleteId: number | ||
131 | |||
132 | describe('Register', function () { | ||
133 | const name = 'runner name' | ||
134 | |||
135 | it('Should fail with a bad registration token', async function () { | ||
136 | const expectedStatus = HttpStatusCode.BAD_REQUEST_400 | ||
137 | |||
138 | await server.runners.register({ name, registrationToken: 'a'.repeat(4000), expectedStatus }) | ||
139 | await server.runners.register({ name, registrationToken: null, expectedStatus }) | ||
140 | }) | ||
141 | |||
142 | it('Should fail with an unknown registration token', async function () { | ||
143 | await server.runners.register({ name, registrationToken: 'aaa', expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
144 | }) | ||
145 | |||
146 | it('Should fail with a bad name', async function () { | ||
147 | const expectedStatus = HttpStatusCode.BAD_REQUEST_400 | ||
148 | |||
149 | await server.runners.register({ name: '', registrationToken, expectedStatus }) | ||
150 | await server.runners.register({ name: 'a'.repeat(200), registrationToken, expectedStatus }) | ||
151 | }) | ||
152 | |||
153 | it('Should fail with an invalid description', async function () { | ||
154 | const expectedStatus = HttpStatusCode.BAD_REQUEST_400 | ||
155 | |||
156 | await server.runners.register({ name, description: '', registrationToken, expectedStatus }) | ||
157 | await server.runners.register({ name, description: 'a'.repeat(5000), registrationToken, expectedStatus }) | ||
158 | }) | ||
159 | |||
160 | it('Should succeed with the correct params', async function () { | ||
161 | const { id } = await server.runners.register({ name, description: 'super description', registrationToken }) | ||
162 | |||
163 | toDeleteId = id | ||
164 | }) | ||
165 | }) | ||
166 | |||
167 | describe('Delete', function () { | ||
168 | |||
169 | it('Should fail without oauth token', async function () { | ||
170 | await server.runners.delete({ token: null, id: toDeleteId, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
171 | }) | ||
172 | |||
173 | it('Should fail without admin rights', async function () { | ||
174 | await server.runners.delete({ token: userToken, id: toDeleteId, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
175 | }) | ||
176 | |||
177 | it('Should fail with a bad id', async function () { | ||
178 | await server.runners.delete({ id: 'hi' as any, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
179 | }) | ||
180 | |||
181 | it('Should fail with an unknown id', async function () { | ||
182 | await server.runners.delete({ id: 404, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
183 | }) | ||
184 | |||
185 | it('Should succeed with the correct params', async function () { | ||
186 | await server.runners.delete({ id: toDeleteId }) | ||
187 | }) | ||
188 | }) | ||
189 | |||
190 | describe('List', function () { | ||
191 | const path = '/api/v1/runners' | ||
192 | |||
193 | it('Should fail without oauth token', async function () { | ||
194 | await server.runners.list({ token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
195 | }) | ||
196 | |||
197 | it('Should fail without admin rights', async function () { | ||
198 | await server.runners.list({ token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
199 | }) | ||
200 | |||
201 | it('Should fail to list with a bad start pagination', async function () { | ||
202 | await checkBadStartPagination(server.url, path, server.accessToken) | ||
203 | }) | ||
204 | |||
205 | it('Should fail to list with a bad count pagination', async function () { | ||
206 | await checkBadCountPagination(server.url, path, server.accessToken) | ||
207 | }) | ||
208 | |||
209 | it('Should fail to list with an incorrect sort', async function () { | ||
210 | await checkBadSortPagination(server.url, path, server.accessToken) | ||
211 | }) | ||
212 | |||
213 | it('Should succeed to list with the correct params', async function () { | ||
214 | await server.runners.list({ start: 0, count: 5, sort: '-createdAt' }) | ||
215 | }) | ||
216 | }) | ||
217 | |||
218 | }) | ||
219 | |||
220 | describe('Runner jobs by admin', function () { | ||
221 | |||
222 | describe('Cancel', function () { | ||
223 | let jobUUID: string | ||
224 | |||
225 | before(async function () { | ||
226 | this.timeout(60000) | ||
227 | |||
228 | await server.videos.quickUpload({ name: 'video' }) | ||
229 | await waitJobs([ server ]) | ||
230 | |||
231 | const { availableJobs } = await server.runnerJobs.request({ runnerToken }) | ||
232 | jobUUID = availableJobs[0].uuid | ||
233 | }) | ||
234 | |||
235 | it('Should fail without oauth token', async function () { | ||
236 | await server.runnerJobs.cancelByAdmin({ token: null, jobUUID, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
237 | }) | ||
238 | |||
239 | it('Should fail without admin rights', async function () { | ||
240 | await server.runnerJobs.cancelByAdmin({ token: userToken, jobUUID, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
241 | }) | ||
242 | |||
243 | it('Should fail with a bad job uuid', async function () { | ||
244 | await server.runnerJobs.cancelByAdmin({ jobUUID: 'hello', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
245 | }) | ||
246 | |||
247 | it('Should fail with an unknown job uuid', async function () { | ||
248 | const jobUUID = badUUID | ||
249 | await server.runnerJobs.cancelByAdmin({ jobUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
250 | }) | ||
251 | |||
252 | it('Should succeed with the correct params', async function () { | ||
253 | await server.runnerJobs.cancelByAdmin({ jobUUID }) | ||
254 | }) | ||
255 | }) | ||
256 | |||
257 | describe('List', function () { | ||
258 | const path = '/api/v1/runners/jobs' | ||
259 | |||
260 | it('Should fail without oauth token', async function () { | ||
261 | await server.runnerJobs.list({ token: null, expectedStatus: HttpStatusCode.UNAUTHORIZED_401 }) | ||
262 | }) | ||
263 | |||
264 | it('Should fail without admin rights', async function () { | ||
265 | await server.runnerJobs.list({ token: userToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
266 | }) | ||
267 | |||
268 | it('Should fail to list with a bad start pagination', async function () { | ||
269 | await checkBadStartPagination(server.url, path, server.accessToken) | ||
270 | }) | ||
271 | |||
272 | it('Should fail to list with a bad count pagination', async function () { | ||
273 | await checkBadCountPagination(server.url, path, server.accessToken) | ||
274 | }) | ||
275 | |||
276 | it('Should fail to list with an incorrect sort', async function () { | ||
277 | await checkBadSortPagination(server.url, path, server.accessToken) | ||
278 | }) | ||
279 | |||
280 | it('Should succeed to list with the correct params', async function () { | ||
281 | await server.runnerJobs.list({ start: 0, count: 5, sort: '-createdAt' }) | ||
282 | }) | ||
283 | }) | ||
284 | |||
285 | }) | ||
286 | |||
287 | describe('Runner jobs by runners', function () { | ||
288 | let jobUUID: string | ||
289 | let jobToken: string | ||
290 | let videoUUID: string | ||
291 | |||
292 | let jobUUID2: string | ||
293 | let jobToken2: string | ||
294 | |||
295 | let videoUUID2: string | ||
296 | |||
297 | let pendingUUID: string | ||
298 | |||
299 | let liveAcceptedJob: RunnerJob & { jobToken: string } | ||
300 | |||
301 | async function fetchFiles (options: { | ||
302 | jobUUID: string | ||
303 | videoUUID: string | ||
304 | runnerToken: string | ||
305 | jobToken: string | ||
306 | expectedStatus: HttpStatusCode | ||
307 | }) { | ||
308 | const { jobUUID, expectedStatus, videoUUID, runnerToken, jobToken } = options | ||
309 | |||
310 | const basePath = '/api/v1/runners/jobs/' + jobUUID + '/files/videos/' + videoUUID | ||
311 | const paths = [ `${basePath}/max-quality`, `${basePath}/previews/max-quality` ] | ||
312 | |||
313 | for (const path of paths) { | ||
314 | await makePostBodyRequest({ url: server.url, path, fields: { runnerToken, jobToken }, expectedStatus }) | ||
315 | } | ||
316 | } | ||
317 | |||
318 | before(async function () { | ||
319 | this.timeout(120000) | ||
320 | |||
321 | { | ||
322 | await server.runnerJobs.cancelAllJobs({ state: RunnerJobState.PENDING }) | ||
323 | } | ||
324 | |||
325 | { | ||
326 | const { uuid } = await server.videos.quickUpload({ name: 'video' }) | ||
327 | videoUUID = uuid | ||
328 | |||
329 | await waitJobs([ server ]) | ||
330 | |||
331 | const { job } = await server.runnerJobs.autoAccept({ runnerToken }) | ||
332 | jobUUID = job.uuid | ||
333 | jobToken = job.jobToken | ||
334 | } | ||
335 | |||
336 | { | ||
337 | const { uuid } = await server.videos.quickUpload({ name: 'video' }) | ||
338 | videoUUID2 = uuid | ||
339 | |||
340 | await waitJobs([ server ]) | ||
341 | |||
342 | const { job } = await server.runnerJobs.autoAccept({ runnerToken: runnerToken2 }) | ||
343 | jobUUID2 = job.uuid | ||
344 | jobToken2 = job.jobToken | ||
345 | } | ||
346 | |||
347 | { | ||
348 | await server.videos.quickUpload({ name: 'video' }) | ||
349 | await waitJobs([ server ]) | ||
350 | |||
351 | const { availableJobs } = await server.runnerJobs.request({ runnerToken }) | ||
352 | pendingUUID = availableJobs[0].uuid | ||
353 | } | ||
354 | |||
355 | { | ||
356 | await server.config.enableLive({ | ||
357 | allowReplay: false, | ||
358 | resolutions: 'max', | ||
359 | transcoding: true | ||
360 | }) | ||
361 | |||
362 | const { live } = await server.live.quickCreate({ permanentLive: true, saveReplay: false, privacy: VideoPrivacy.PUBLIC }) | ||
363 | |||
364 | const ffmpegCommand = sendRTMPStream({ rtmpBaseUrl: live.rtmpUrl, streamKey: live.streamKey }) | ||
365 | await waitJobs([ server ]) | ||
366 | |||
367 | await server.runnerJobs.requestLiveJob(runnerToken) | ||
368 | |||
369 | const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'live-rtmp-hls-transcoding' }) | ||
370 | liveAcceptedJob = job | ||
371 | |||
372 | await stopFfmpeg(ffmpegCommand) | ||
373 | } | ||
374 | }) | ||
375 | |||
376 | describe('Common runner tokens validations', function () { | ||
377 | |||
378 | async function testEndpoints (options: { | ||
379 | jobUUID: string | ||
380 | runnerToken: string | ||
381 | jobToken: string | ||
382 | expectedStatus: HttpStatusCode | ||
383 | }) { | ||
384 | await fetchFiles({ ...options, videoUUID }) | ||
385 | |||
386 | await server.runnerJobs.abort({ ...options, reason: 'reason' }) | ||
387 | await server.runnerJobs.update({ ...options }) | ||
388 | await server.runnerJobs.error({ ...options, message: 'message' }) | ||
389 | await server.runnerJobs.success({ ...options, payload: { videoFile: 'video_short.mp4' } }) | ||
390 | } | ||
391 | |||
392 | it('Should fail with an invalid job uuid', async function () { | ||
393 | await testEndpoints({ jobUUID: 'a', runnerToken, jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
394 | }) | ||
395 | |||
396 | it('Should fail with an unknown job uuid', async function () { | ||
397 | const jobUUID = badUUID | ||
398 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
399 | }) | ||
400 | |||
401 | it('Should fail with an invalid runner token', async function () { | ||
402 | await testEndpoints({ jobUUID, runnerToken: '', jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
403 | }) | ||
404 | |||
405 | it('Should fail with an unknown runner token', async function () { | ||
406 | const runnerToken = badUUID | ||
407 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
408 | }) | ||
409 | |||
410 | it('Should fail with an invalid job token job uuid', async function () { | ||
411 | await testEndpoints({ jobUUID, runnerToken, jobToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
412 | }) | ||
413 | |||
414 | it('Should fail with an unknown job token job uuid', async function () { | ||
415 | const jobToken = badUUID | ||
416 | await testEndpoints({ jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
417 | }) | ||
418 | |||
419 | it('Should fail with a runner token not associated to this job', async function () { | ||
420 | await testEndpoints({ jobUUID, runnerToken: runnerToken2, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
421 | }) | ||
422 | |||
423 | it('Should fail with a job uuid not associated to the job token', async function () { | ||
424 | await testEndpoints({ jobUUID: jobUUID2, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
425 | await testEndpoints({ jobUUID, runnerToken, jobToken: jobToken2, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
426 | }) | ||
427 | }) | ||
428 | |||
429 | describe('Unregister', function () { | ||
430 | |||
431 | it('Should fail without a runner token', async function () { | ||
432 | await server.runners.unregister({ runnerToken: null, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
433 | }) | ||
434 | |||
435 | it('Should fail with a bad a runner token', async function () { | ||
436 | await server.runners.unregister({ runnerToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
437 | }) | ||
438 | |||
439 | it('Should fail with an unknown runner token', async function () { | ||
440 | await server.runners.unregister({ runnerToken: badUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
441 | }) | ||
442 | }) | ||
443 | |||
444 | describe('Request', function () { | ||
445 | |||
446 | it('Should fail without a runner token', async function () { | ||
447 | await server.runnerJobs.request({ runnerToken: null, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
448 | }) | ||
449 | |||
450 | it('Should fail with a bad a runner token', async function () { | ||
451 | await server.runnerJobs.request({ runnerToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
452 | }) | ||
453 | |||
454 | it('Should fail with an unknown runner token', async function () { | ||
455 | await server.runnerJobs.request({ runnerToken: badUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
456 | }) | ||
457 | }) | ||
458 | |||
459 | describe('Accept', function () { | ||
460 | |||
461 | it('Should fail with a bad a job uuid', async function () { | ||
462 | await server.runnerJobs.accept({ jobUUID: '', runnerToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
463 | }) | ||
464 | |||
465 | it('Should fail with an unknown job uuid', async function () { | ||
466 | await server.runnerJobs.accept({ jobUUID: badUUID, runnerToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
467 | }) | ||
468 | |||
469 | it('Should fail with a job not in pending state', async function () { | ||
470 | await server.runnerJobs.accept({ jobUUID: completedJobUUID, runnerToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
471 | await server.runnerJobs.accept({ jobUUID: cancelledJobUUID, runnerToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
472 | }) | ||
473 | |||
474 | it('Should fail without a runner token', async function () { | ||
475 | await server.runnerJobs.accept({ jobUUID: pendingUUID, runnerToken: null, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
476 | }) | ||
477 | |||
478 | it('Should fail with a bad a runner token', async function () { | ||
479 | await server.runnerJobs.accept({ jobUUID: pendingUUID, runnerToken: '', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
480 | }) | ||
481 | |||
482 | it('Should fail with an unknown runner token', async function () { | ||
483 | await server.runnerJobs.accept({ jobUUID: pendingUUID, runnerToken: badUUID, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
484 | }) | ||
485 | }) | ||
486 | |||
487 | describe('Abort', function () { | ||
488 | |||
489 | it('Should fail without a reason', async function () { | ||
490 | await server.runnerJobs.abort({ jobUUID, jobToken, runnerToken, reason: null, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
491 | }) | ||
492 | |||
493 | it('Should fail with a bad reason', async function () { | ||
494 | const reason = 'reason'.repeat(5000) | ||
495 | await server.runnerJobs.abort({ jobUUID, jobToken, runnerToken, reason, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
496 | }) | ||
497 | |||
498 | it('Should fail with a job not in processing state', async function () { | ||
499 | await server.runnerJobs.abort({ | ||
500 | jobUUID: completedJobUUID, | ||
501 | jobToken: completedJobToken, | ||
502 | runnerToken, | ||
503 | reason: 'reason', | ||
504 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
505 | }) | ||
506 | }) | ||
507 | }) | ||
508 | |||
509 | describe('Update', function () { | ||
510 | |||
511 | describe('Common', function () { | ||
512 | |||
513 | it('Should fail with an invalid progress', async function () { | ||
514 | await server.runnerJobs.update({ jobUUID, jobToken, runnerToken, progress: 101, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
515 | }) | ||
516 | |||
517 | it('Should fail with a job not in processing state', async function () { | ||
518 | await server.runnerJobs.update({ | ||
519 | jobUUID: completedJobUUID, | ||
520 | jobToken: completedJobToken, | ||
521 | runnerToken, | ||
522 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
523 | }) | ||
524 | }) | ||
525 | }) | ||
526 | |||
527 | describe('Live RTMP to HLS', function () { | ||
528 | const base: RunnerJobUpdatePayload = { | ||
529 | masterPlaylistFile: 'live/master.m3u8', | ||
530 | resolutionPlaylistFilename: '0.m3u8', | ||
531 | resolutionPlaylistFile: 'live/1.m3u8', | ||
532 | type: 'add-chunk', | ||
533 | videoChunkFile: 'live/1-000069.ts', | ||
534 | videoChunkFilename: '1-000068.ts' | ||
535 | } | ||
536 | |||
537 | function testUpdate (payload: RunnerJobUpdatePayload) { | ||
538 | return server.runnerJobs.update({ | ||
539 | jobUUID: liveAcceptedJob.uuid, | ||
540 | jobToken: liveAcceptedJob.jobToken, | ||
541 | payload, | ||
542 | runnerToken, | ||
543 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
544 | }) | ||
545 | } | ||
546 | |||
547 | it('Should fail with an invalid resolutionPlaylistFilename', async function () { | ||
548 | await testUpdate({ ...base, resolutionPlaylistFilename: undefined }) | ||
549 | await testUpdate({ ...base, resolutionPlaylistFilename: 'coucou/hello' }) | ||
550 | await testUpdate({ ...base, resolutionPlaylistFilename: 'hello' }) | ||
551 | }) | ||
552 | |||
553 | it('Should fail with an invalid videoChunkFilename', async function () { | ||
554 | await testUpdate({ ...base, resolutionPlaylistFilename: undefined }) | ||
555 | await testUpdate({ ...base, resolutionPlaylistFilename: 'coucou/hello' }) | ||
556 | await testUpdate({ ...base, resolutionPlaylistFilename: 'hello' }) | ||
557 | }) | ||
558 | |||
559 | it('Should fail with an invalid type', async function () { | ||
560 | await testUpdate({ ...base, type: undefined }) | ||
561 | await testUpdate({ ...base, type: 'toto' as any }) | ||
562 | }) | ||
563 | |||
564 | it('Should succeed with the correct params', async function () { | ||
565 | await server.runnerJobs.update({ | ||
566 | jobUUID: liveAcceptedJob.uuid, | ||
567 | jobToken: liveAcceptedJob.jobToken, | ||
568 | payload: base, | ||
569 | runnerToken | ||
570 | }) | ||
571 | |||
572 | await server.runnerJobs.update({ | ||
573 | jobUUID: liveAcceptedJob.uuid, | ||
574 | jobToken: liveAcceptedJob.jobToken, | ||
575 | payload: { ...base, masterPlaylistFile: undefined }, | ||
576 | runnerToken | ||
577 | }) | ||
578 | }) | ||
579 | }) | ||
580 | }) | ||
581 | |||
582 | describe('Error', function () { | ||
583 | |||
584 | it('Should fail with a missing error message', async function () { | ||
585 | await server.runnerJobs.error({ jobUUID, jobToken, runnerToken, message: null, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
586 | }) | ||
587 | |||
588 | it('Should fail with an invalid error messgae', async function () { | ||
589 | const message = 'a'.repeat(6000) | ||
590 | await server.runnerJobs.error({ jobUUID, jobToken, runnerToken, message, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
591 | }) | ||
592 | |||
593 | it('Should fail with a job not in processing state', async function () { | ||
594 | await server.runnerJobs.error({ | ||
595 | jobUUID: completedJobUUID, | ||
596 | jobToken: completedJobToken, | ||
597 | message: 'my message', | ||
598 | runnerToken, | ||
599 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
600 | }) | ||
601 | }) | ||
602 | }) | ||
603 | |||
604 | describe('Success', function () { | ||
605 | let vodJobUUID: string | ||
606 | let vodJobToken: string | ||
607 | |||
608 | describe('Common', function () { | ||
609 | |||
610 | it('Should fail with a job not in processing state', async function () { | ||
611 | await server.runnerJobs.success({ | ||
612 | jobUUID: completedJobUUID, | ||
613 | jobToken: completedJobToken, | ||
614 | payload: { videoFile: 'video_short.mp4' }, | ||
615 | runnerToken, | ||
616 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
617 | }) | ||
618 | }) | ||
619 | }) | ||
620 | |||
621 | describe('VOD', function () { | ||
622 | |||
623 | it('Should fail with an invalid vod web video payload', async function () { | ||
624 | const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'vod-web-video-transcoding' }) | ||
625 | |||
626 | await server.runnerJobs.success({ | ||
627 | jobUUID: job.uuid, | ||
628 | jobToken: job.jobToken, | ||
629 | payload: { hello: 'video_short.mp4' } as any, | ||
630 | runnerToken, | ||
631 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
632 | }) | ||
633 | |||
634 | vodJobUUID = job.uuid | ||
635 | vodJobToken = job.jobToken | ||
636 | }) | ||
637 | |||
638 | it('Should fail with an invalid vod hls payload', async function () { | ||
639 | // To create HLS jobs | ||
640 | const payload: RunnerJobSuccessPayload = { videoFile: 'video_short.mp4' } | ||
641 | await server.runnerJobs.success({ runnerToken, jobUUID: vodJobUUID, jobToken: vodJobToken, payload }) | ||
642 | |||
643 | await waitJobs([ server ]) | ||
644 | |||
645 | const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'vod-hls-transcoding' }) | ||
646 | |||
647 | await server.runnerJobs.success({ | ||
648 | jobUUID: job.uuid, | ||
649 | jobToken: job.jobToken, | ||
650 | payload: { videoFile: 'video_short.mp4' } as any, | ||
651 | runnerToken, | ||
652 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
653 | }) | ||
654 | }) | ||
655 | |||
656 | it('Should fail with an invalid vod audio merge payload', async function () { | ||
657 | const attributes = { name: 'audio_with_preview', previewfile: 'preview.jpg', fixture: 'sample.ogg' } | ||
658 | await server.videos.upload({ attributes, mode: 'legacy' }) | ||
659 | |||
660 | await waitJobs([ server ]) | ||
661 | |||
662 | const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'vod-audio-merge-transcoding' }) | ||
663 | |||
664 | await server.runnerJobs.success({ | ||
665 | jobUUID: job.uuid, | ||
666 | jobToken: job.jobToken, | ||
667 | payload: { hello: 'video_short.mp4' } as any, | ||
668 | runnerToken, | ||
669 | expectedStatus: HttpStatusCode.BAD_REQUEST_400 | ||
670 | }) | ||
671 | }) | ||
672 | }) | ||
673 | }) | ||
674 | |||
675 | describe('Job files', function () { | ||
676 | |||
677 | describe('Video files', function () { | ||
678 | |||
679 | it('Should fail with an invalid video id', async function () { | ||
680 | await fetchFiles({ videoUUID: 'a', jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | ||
681 | }) | ||
682 | |||
683 | it('Should fail with an unknown video id', async function () { | ||
684 | const videoUUID = '910ec12a-d9e6-458b-a274-0abb655f9464' | ||
685 | await fetchFiles({ videoUUID, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.NOT_FOUND_404 }) | ||
686 | }) | ||
687 | |||
688 | it('Should fail with a video id not associated to this job', async function () { | ||
689 | await fetchFiles({ videoUUID: videoUUID2, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.FORBIDDEN_403 }) | ||
690 | }) | ||
691 | |||
692 | it('Should succeed with the correct params', async function () { | ||
693 | await fetchFiles({ videoUUID, jobUUID, runnerToken, jobToken, expectedStatus: HttpStatusCode.OK_200 }) | ||
694 | }) | ||
695 | }) | ||
696 | }) | ||
697 | }) | ||
698 | |||
699 | after(async function () { | ||
700 | await cleanupTests([ server ]) | ||
701 | }) | ||
702 | }) | ||
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts index 4dc84d3f2..8e9f61596 100644 --- a/server/tests/api/check-params/video-blacklist.ts +++ b/server/tests/api/check-params/video-blacklist.ts | |||
@@ -278,7 +278,7 @@ describe('Test video blacklist API validators', function () { | |||
278 | }) | 278 | }) |
279 | 279 | ||
280 | it('Should fail with an invalid type', async function () { | 280 | it('Should fail with an invalid type', async function () { |
281 | await servers[0].blacklist.list({ type: 0, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 281 | await servers[0].blacklist.list({ type: 0 as any, expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) |
282 | }) | 282 | }) |
283 | 283 | ||
284 | it('Should succeed with the correct parameters', async function () { | 284 | it('Should succeed with the correct parameters', async function () { |
diff --git a/server/tests/api/check-params/video-playlists.ts b/server/tests/api/check-params/video-playlists.ts index 6cb34c8a1..8090897c1 100644 --- a/server/tests/api/check-params/video-playlists.ts +++ b/server/tests/api/check-params/video-playlists.ts | |||
@@ -239,7 +239,7 @@ describe('Test video playlists API validator', function () { | |||
239 | }) | 239 | }) |
240 | 240 | ||
241 | it('Should fail with an incorrect privacy', async function () { | 241 | it('Should fail with an incorrect privacy', async function () { |
242 | const params = getBase({ privacy: 45 }) | 242 | const params = getBase({ privacy: 45 as any }) |
243 | 243 | ||
244 | await command.create(params) | 244 | await command.create(params) |
245 | await command.update(getUpdate(params, playlist.shortUUID)) | 245 | await command.update(getUpdate(params, playlist.shortUUID)) |
diff --git a/server/tests/api/check-params/videos.ts b/server/tests/api/check-params/videos.ts index 2a83143e2..572ca8997 100644 --- a/server/tests/api/check-params/videos.ts +++ b/server/tests/api/check-params/videos.ts | |||
@@ -421,9 +421,9 @@ describe('Test videos API validator', function () { | |||
421 | const error = body as unknown as PeerTubeProblemDocument | 421 | const error = body as unknown as PeerTubeProblemDocument |
422 | 422 | ||
423 | if (mode === 'legacy') { | 423 | if (mode === 'legacy') { |
424 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api/rest-reference.html#operation/uploadLegacy') | 424 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/uploadLegacy') |
425 | } else { | 425 | } else { |
426 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api/rest-reference.html#operation/uploadResumableInit') | 426 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/uploadResumableInit') |
427 | } | 427 | } |
428 | 428 | ||
429 | expect(error.type).to.equal('about:blank') | 429 | expect(error.type).to.equal('about:blank') |
@@ -680,7 +680,7 @@ describe('Test videos API validator', function () { | |||
680 | const res = await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields }) | 680 | const res = await makePutBodyRequest({ url: server.url, path: path + video.shortUUID, token: server.accessToken, fields }) |
681 | const error = res.body as PeerTubeProblemDocument | 681 | const error = res.body as PeerTubeProblemDocument |
682 | 682 | ||
683 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api/rest-reference.html#operation/putVideo') | 683 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/putVideo') |
684 | 684 | ||
685 | expect(error.type).to.equal('about:blank') | 685 | expect(error.type).to.equal('about:blank') |
686 | expect(error.title).to.equal('Bad Request') | 686 | expect(error.title).to.equal('Bad Request') |
@@ -729,7 +729,7 @@ describe('Test videos API validator', function () { | |||
729 | const body = await server.videos.get({ id: 'hi', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 729 | const body = await server.videos.get({ id: 'hi', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) |
730 | const error = body as unknown as PeerTubeProblemDocument | 730 | const error = body as unknown as PeerTubeProblemDocument |
731 | 731 | ||
732 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api/rest-reference.html#operation/getVideo') | 732 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/getVideo') |
733 | 733 | ||
734 | expect(error.type).to.equal('about:blank') | 734 | expect(error.type).to.equal('about:blank') |
735 | expect(error.title).to.equal('Bad Request') | 735 | expect(error.title).to.equal('Bad Request') |
@@ -835,7 +835,7 @@ describe('Test videos API validator', function () { | |||
835 | const body = await server.videos.remove({ id: 'hello', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) | 835 | const body = await server.videos.remove({ id: 'hello', expectedStatus: HttpStatusCode.BAD_REQUEST_400 }) |
836 | const error = body as PeerTubeProblemDocument | 836 | const error = body as PeerTubeProblemDocument |
837 | 837 | ||
838 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api/rest-reference.html#operation/delVideo') | 838 | expect(error.docs).to.equal('https://docs.joinpeertube.org/api-rest-reference.html#operation/delVideo') |
839 | 839 | ||
840 | expect(error.type).to.equal('about:blank') | 840 | expect(error.type).to.equal('about:blank') |
841 | expect(error.title).to.equal('Bad Request') | 841 | expect(error.title).to.equal('Bad Request') |