X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=scripts%2Fbenchmark.ts;h=4a414a2fa1e734af0dc686e064235edc09db1896;hb=db9e40cc0fcdc2849fe18fdf5e32f9799759b5c5;hp=69d902b5c1cc7dbb7f6edcfbe5e0d92dbd4924fa;hpb=4abbeff5758daad6d0639cc61a0ae27f9bb758da;p=github%2FChocobozzz%2FPeerTube.git diff --git a/scripts/benchmark.ts b/scripts/benchmark.ts index 69d902b5c..4a414a2fa 100644 --- a/scripts/benchmark.ts +++ b/scripts/benchmark.ts @@ -1,31 +1,29 @@ -import { registerTSPaths } from '../server/helpers/register-ts-paths' -registerTSPaths() - -import * as autocannon from 'autocannon' -import { - addVideoCommentReply, - addVideoCommentThread, - createVideoCaption, - flushAndRunServer, - getVideosList, - killallServers, - ServerInfo, - setAccessTokensToServers, - uploadVideo -} from '@shared/extra-utils' -import { Video, VideoPrivacy } from '@shared/models' +import autocannon, { printResult } from 'autocannon' +import { program } from 'commander' import { writeJson } from 'fs-extra' +import { Video, VideoPrivacy } from '@shared/models' +import { createMultipleServers, doubleFollow, killallServers, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands' -let server: ServerInfo +let servers: PeerTubeServer[] +// First server +let server: PeerTubeServer let video: Video let threadId: number -const outfile = process.argv[2] +program + .option('-o, --outfile [outfile]', 'Outfile') + .option('--grep [string]', 'Filter tests you want to execute') + .description('Run API REST benchmark') + .parse(process.argv) + +const options = program.opts() + +const outfile = options.outfile run() .catch(err => console.error(err)) .finally(() => { - if (server) killallServers([ server ]) + if (servers) return killallServers(servers) }) function buildAuthorizationHeader () { @@ -34,101 +32,154 @@ function buildAuthorizationHeader () { } } +function buildAPHeader () { + return { + Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' + } +} + +function buildJSONHeader () { + return { + 'Content-Type': 'application/json' + } +} + async function run () { console.log('Preparing server...') await prepare() const tests = [ + { + title: 'AP - account peertube', + path: '/accounts/peertube', + headers: buildAPHeader(), + expecter: (body, status) => { + return status === 200 && body.startsWith('{"@context":') + } + }, + { + title: 'AP - video', + path: '/videos/watch/' + video.uuid, + headers: buildAPHeader(), + expecter: (body, status) => { + return status === 200 && body.startsWith('{"@context":') + } + }, + { + title: 'Misc - webfinger peertube', + path: '/.well-known/webfinger?resource=acct:peertube@' + server.host, + expecter: (body, status) => { + return status === 200 && body.startsWith('{"subject":') + } + }, { title: 'API - unread notifications', path: '/api/v1/users/me/notifications?start=0&count=0&unread=true', headers: buildAuthorizationHeader(), - expecter: (_client, statusCode) => { - return statusCode === 200 + expecter: (_body, status) => { + return status === 200 } }, { title: 'API - me', path: '/api/v1/users/me', headers: buildAuthorizationHeader(), - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"id":') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"id":') } }, { title: 'API - videos list', path: '/api/v1/videos', - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"total":10') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"total":10') } }, { title: 'API - video get', path: '/api/v1/videos/' + video.uuid, - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"id":') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"id":') } }, { title: 'API - video captions', path: '/api/v1/videos/' + video.uuid + '/captions', - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"total":4') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"total":4') } }, { title: 'API - video threads', path: '/api/v1/videos/' + video.uuid + '/comment-threads', - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"total":10') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"total":10') } }, { title: 'API - video replies', path: '/api/v1/videos/' + video.uuid + '/comment-threads/' + threadId, - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"comment":{') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"comment":{') } }, { title: 'HTML - video watch', path: '/videos/watch/' + video.uuid, - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.includes('my super') + expecter: (body, status) => { + return status === 200 && body.includes('<title>my super') + } + }, + { + title: 'HTML - video embed', + path: '/videos/embed/' + video.uuid, + expecter: (body, status) => { + return status === 200 && body.includes('embed') } }, { title: 'HTML - homepage', path: '/', - expecter: (_client, statusCode) => { - return statusCode === 200 + expecter: (_body, status) => { + return status === 200 } }, { title: 'API - config', path: '/api/v1/config', - expecter: (client, statusCode) => { - const body = client.resData[0].body - - return statusCode === 200 && body.startsWith('{"instance":') + expecter: (body, status) => { + return status === 200 && body.startsWith('{"client":') + } + }, + { + title: 'API - views with token', + method: 'PUT', + headers: { + ...buildAuthorizationHeader(), + ...buildJSONHeader() + }, + body: JSON.stringify({ currentTime: 2 }), + path: '/api/v1/videos/' + video.uuid + '/views', + expecter: (body, status) => { + return status === 204 + } + }, + { + title: 'API - views without token', + method: 'POST', + headers: buildJSONHeader(), + body: JSON.stringify({ currentTime: 2 }), + path: '/api/v1/videos/' + video.uuid + '/views', + expecter: (body, status) => { + return status === 204 } } - ] + ].filter(t => { + if (!options.grep) return true + + return t.title.includes(options.grep) + }) const finalResult: any[] = [] @@ -139,7 +190,7 @@ async function run () { Object.assign(testResult, { title: test.title, path: test.path }) finalResult.push(testResult) - console.log(autocannon.printResult(testResult)) + console.log(printResult(testResult)) } if (outfile) await writeJson(outfile, finalResult) @@ -147,44 +198,55 @@ async function run () { function runBenchmark (options: { path: string + method?: string + body?: string headers?: { [ id: string ]: string } expecter: Function }) { - const { path, expecter, headers } = options + const { method = 'GET', path, body, expecter, headers } = options return new Promise((res, rej) => { - const instance = autocannon({ + autocannon({ url: server.url + path, + method: method, + body, connections: 20, headers, pipelining: 1, - duration: 10 + duration: 10, + requests: [ + { + onResponse: (status, body) => { + if (expecter(body, status) !== true) { + console.error('Expected result failed.', { body, status }) + throw new Error('Invalid expectation') + } + } + } + ] }, (err, result) => { if (err) return rej(err) return res(result) }) - - instance.on('response', (client, statusCode) => { - if (expecter(client, statusCode) !== true) { - console.error('Expected result failed.', { data: client.resData }) - process.exit(-1) - } - }) }) } async function prepare () { - server = await flushAndRunServer(1, { + servers = await createMultipleServers(3, { rates_limit: { api: { max: 5_000_000 } } }) - await setAccessTokensToServers([ server ]) + server = servers[0] - const videoAttributes = { + await setAccessTokensToServers(servers) + await doubleFollow(servers[0], servers[1]) + await doubleFollow(servers[0], servers[2]) + + const attributes = { name: 'my super video', category: 2, nsfw: true, @@ -192,43 +254,37 @@ async function prepare () { language: 'fr', privacy: VideoPrivacy.PUBLIC, support: 'please give me a coffee', - description: 'my super description'.repeat(10), + description: 'my super description\n'.repeat(10) + ' * list1\n * list 2\n * list 3', tags: [ 'tag1', 'tag2', 'tag3' ] } for (let i = 0; i < 10; i++) { - Object.assign(videoAttributes, { name: 'my super video ' + i }) - await uploadVideo(server.url, server.accessToken, videoAttributes) + await server.videos.upload({ attributes: { ...attributes, name: 'my super video ' + i } }) } - const resVideos = await getVideosList(server.url) - video = resVideos.body.data.find(v => v.name === 'my super video 1') + const { data } = await server.videos.list() + video = data.find(v => v.name === 'my super video 1') for (let i = 0; i < 10; i++) { const text = 'my super first comment' - const res = await addVideoCommentThread(server.url, server.accessToken, video.id, text) - threadId = res.body.comment.id + const created = await server.comments.createThread({ videoId: video.id, text }) + threadId = created.id const text1 = 'my super answer to thread 1' - const childCommentRes = await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text1) - const childCommentId = childCommentRes.body.comment.id + const child = await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text1 }) const text2 = 'my super answer to answer of thread 1' - await addVideoCommentReply(server.url, server.accessToken, video.id, childCommentId, text2) + await server.comments.addReply({ videoId: video.id, toCommentId: child.id, text: text2 }) const text3 = 'my second answer to thread 1' - await addVideoCommentReply(server.url, server.accessToken, video.id, threadId, text3) + await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text3 }) } for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) { - await createVideoCaption({ - url: server.url, - accessToken: server.accessToken, + await server.captions.add({ language: caption, videoId: video.id, fixture: 'subtitle-good2.vtt' }) } - - return { server, video, threadId } }