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