]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - scripts/benchmark.ts
Fix lint
[github/Chocobozzz/PeerTube.git] / scripts / benchmark.ts
index 69d902b5c1cc7dbb7f6edcfbe5e0d92dbd4924fa..f7f9ad1bf6c600ccb0da1d164c5e747683b7144e 100644 (file)
@@ -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('<title>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,
+      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 }
 }