]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - scripts/benchmark.ts
Update translations
[github/Chocobozzz/PeerTube.git] / scripts / benchmark.ts
CommitLineData
736c64ca 1import autocannon, { printResult } from 'autocannon'
4abbeff5 2import { writeJson } from 'fs-extra'
12edc149 3import { Video, VideoPrivacy } from '@shared/models'
f8360396 4import { createSingleServer, killallServers, PeerTubeServer, setAccessTokensToServers } from '@shared/server-commands'
4abbeff5 5
254d3579 6let server: PeerTubeServer
4abbeff5
C
7let video: Video
8let threadId: number
9
10const outfile = process.argv[2]
11
12run()
13 .catch(err => console.error(err))
14 .finally(() => {
9293139f 15 if (server) return killallServers([ server ])
4abbeff5
C
16 })
17
18function buildAuthorizationHeader () {
19 return {
20 Authorization: 'Bearer ' + server.accessToken
21 }
22}
23
0ce8d34e
C
24function buildAPHeader () {
25 return {
26 Accept: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
27 }
28}
29
4abbeff5
C
30async function run () {
31 console.log('Preparing server...')
32
33 await prepare()
34
35 const tests = [
0ce8d34e
C
36 {
37 title: 'AP - account peertube',
38 path: '/accounts/peertube',
39 headers: buildAPHeader(),
47099aba
C
40 expecter: (body, status) => {
41 return status === 200 && body.startsWith('{"type":')
0ce8d34e
C
42 }
43 },
44 {
45 title: 'AP - video',
46 path: '/videos/watch/' + video.uuid,
47 headers: buildAPHeader(),
47099aba
C
48 expecter: (body, status) => {
49 return status === 200 && body.startsWith('{"type":"Video"')
0ce8d34e
C
50 }
51 },
52 {
53 title: 'Misc - webfinger peertube',
54 path: '/.well-known/webfinger?resource=acct:peertube@' + server.host,
47099aba
C
55 expecter: (body, status) => {
56 return status === 200 && body.startsWith('{"subject":')
0ce8d34e
C
57 }
58 },
4abbeff5
C
59 {
60 title: 'API - unread notifications',
61 path: '/api/v1/users/me/notifications?start=0&count=0&unread=true',
62 headers: buildAuthorizationHeader(),
47099aba
C
63 expecter: (_body, status) => {
64 return status === 200
4abbeff5
C
65 }
66 },
67 {
68 title: 'API - me',
69 path: '/api/v1/users/me',
70 headers: buildAuthorizationHeader(),
47099aba
C
71 expecter: (body, status) => {
72 return status === 200 && body.startsWith('{"id":')
4abbeff5
C
73 }
74 },
75 {
76 title: 'API - videos list',
77 path: '/api/v1/videos',
47099aba
C
78 expecter: (body, status) => {
79 return status === 200 && body.startsWith('{"total":10')
4abbeff5
C
80 }
81 },
82 {
83 title: 'API - video get',
84 path: '/api/v1/videos/' + video.uuid,
47099aba
C
85 expecter: (body, status) => {
86 return status === 200 && body.startsWith('{"id":')
4abbeff5
C
87 }
88 },
89 {
90 title: 'API - video captions',
91 path: '/api/v1/videos/' + video.uuid + '/captions',
47099aba
C
92 expecter: (body, status) => {
93 return status === 200 && body.startsWith('{"total":4')
4abbeff5
C
94 }
95 },
96 {
97 title: 'API - video threads',
98 path: '/api/v1/videos/' + video.uuid + '/comment-threads',
47099aba
C
99 expecter: (body, status) => {
100 return status === 200 && body.startsWith('{"total":10')
4abbeff5
C
101 }
102 },
103 {
104 title: 'API - video replies',
105 path: '/api/v1/videos/' + video.uuid + '/comment-threads/' + threadId,
47099aba
C
106 expecter: (body, status) => {
107 return status === 200 && body.startsWith('{"comment":{')
4abbeff5
C
108 }
109 },
110 {
111 title: 'HTML - video watch',
112 path: '/videos/watch/' + video.uuid,
47099aba
C
113 expecter: (body, status) => {
114 return status === 200 && body.includes('<title>my super')
4abbeff5
C
115 }
116 },
0ce8d34e
C
117 {
118 title: 'HTML - video embed',
119 path: '/videos/embed/' + video.uuid,
47099aba
C
120 expecter: (body, status) => {
121 return status === 200 && body.includes('embed')
0ce8d34e
C
122 }
123 },
4abbeff5
C
124 {
125 title: 'HTML - homepage',
126 path: '/',
47099aba
C
127 expecter: (_body, status) => {
128 return status === 200
4abbeff5
C
129 }
130 },
131 {
132 title: 'API - config',
133 path: '/api/v1/config',
47099aba 134 expecter: (body, status) => {
cf0c8ee5 135 return status === 200 && body.startsWith('{"client":')
4abbeff5
C
136 }
137 }
138 ]
139
140 const finalResult: any[] = []
141
142 for (const test of tests) {
143 console.log('Running against %s.', test.path)
144 const testResult = await runBenchmark(test)
145
146 Object.assign(testResult, { title: test.title, path: test.path })
147 finalResult.push(testResult)
148
736c64ca 149 console.log(printResult(testResult))
4abbeff5
C
150 }
151
152 if (outfile) await writeJson(outfile, finalResult)
153}
154
155function runBenchmark (options: {
156 path: string
157 headers?: { [ id: string ]: string }
158 expecter: Function
159}) {
160 const { path, expecter, headers } = options
161
162 return new Promise((res, rej) => {
47099aba 163 autocannon({
4abbeff5
C
164 url: server.url + path,
165 connections: 20,
166 headers,
167 pipelining: 1,
47099aba
C
168 duration: 10,
169 requests: [
170 {
171 onResponse: (status, body) => {
172 if (expecter(body, status) !== true) {
173 console.error('Expected result failed.', { body, status })
174 throw new Error('Invalid expectation')
175 }
176 }
177 }
178 ]
4abbeff5
C
179 }, (err, result) => {
180 if (err) return rej(err)
181
182 return res(result)
183 })
4abbeff5
C
184 })
185}
186
187async function prepare () {
254d3579 188 server = await createSingleServer(1, {
4abbeff5
C
189 rates_limit: {
190 api: {
191 max: 5_000_000
192 }
193 }
194 })
195 await setAccessTokensToServers([ server ])
196
d23dd9fb 197 const attributes = {
4abbeff5
C
198 name: 'my super video',
199 category: 2,
200 nsfw: true,
201 licence: 6,
202 language: 'fr',
203 privacy: VideoPrivacy.PUBLIC,
204 support: 'please give me a coffee',
205 description: 'my super description'.repeat(10),
206 tags: [ 'tag1', 'tag2', 'tag3' ]
207 }
208
209 for (let i = 0; i < 10; i++) {
89d241a7 210 await server.videos.upload({ attributes: { ...attributes, name: 'my super video ' + i } })
4abbeff5
C
211 }
212
89d241a7 213 const { data } = await server.videos.list()
d23dd9fb 214 video = data.find(v => v.name === 'my super video 1')
4abbeff5
C
215
216 for (let i = 0; i < 10; i++) {
217 const text = 'my super first comment'
89d241a7 218 const created = await server.comments.createThread({ videoId: video.id, text })
12edc149 219 threadId = created.id
4abbeff5
C
220
221 const text1 = 'my super answer to thread 1'
89d241a7 222 const child = await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text1 })
4abbeff5
C
223
224 const text2 = 'my super answer to answer of thread 1'
89d241a7 225 await server.comments.addReply({ videoId: video.id, toCommentId: child.id, text: text2 })
4abbeff5
C
226
227 const text3 = 'my second answer to thread 1'
89d241a7 228 await server.comments.addReply({ videoId: video.id, toCommentId: threadId, text: text3 })
4abbeff5
C
229 }
230
231 for (const caption of [ 'ar', 'fr', 'en', 'zh' ]) {
c63830f1 232 await server.captions.add({
4abbeff5
C
233 language: caption,
234 videoId: video.id,
235 fixture: 'subtitle-good2.vtt'
236 })
237 }
238
239 return { server, video, threadId }
240}