aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/extra-utils/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-07-13 09:43:59 +0200
committerChocobozzz <me@florianbigard.com>2021-07-20 15:27:18 +0200
commit6c5065a011b099618681a37bd77eaa7bd3db752e (patch)
tree352252a00b25013c4b1902f6bcd9668aba295c7b /shared/extra-utils/server
parent0d8ecb7592577f54012413a2b5a9b159cfc90399 (diff)
downloadPeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.gz
PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.zst
PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.zip
Introduce server commands
Diffstat (limited to 'shared/extra-utils/server')
-rw-r--r--shared/extra-utils/server/directories.ts34
-rw-r--r--shared/extra-utils/server/index.ts2
-rw-r--r--shared/extra-utils/server/jobs.ts2
-rw-r--r--shared/extra-utils/server/plugins-command.ts3
-rw-r--r--shared/extra-utils/server/servers-command.ts81
-rw-r--r--shared/extra-utils/server/servers.ts108
6 files changed, 130 insertions, 100 deletions
diff --git a/shared/extra-utils/server/directories.ts b/shared/extra-utils/server/directories.ts
new file mode 100644
index 000000000..3cd38a561
--- /dev/null
+++ b/shared/extra-utils/server/directories.ts
@@ -0,0 +1,34 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { pathExists, readdir } from 'fs-extra'
5import { join } from 'path'
6import { root } from '@server/helpers/core-utils'
7import { ServerInfo } from './servers'
8
9async function checkTmpIsEmpty (server: ServerInfo) {
10 await checkDirectoryIsEmpty(server, 'tmp', [ 'plugins-global.css', 'hls', 'resumable-uploads' ])
11
12 if (await pathExists(join('test' + server.internalServerNumber, 'tmp', 'hls'))) {
13 await checkDirectoryIsEmpty(server, 'tmp/hls')
14 }
15}
16
17async function checkDirectoryIsEmpty (server: ServerInfo, directory: string, exceptions: string[] = []) {
18 const testDirectory = 'test' + server.internalServerNumber
19
20 const directoryPath = join(root(), testDirectory, directory)
21
22 const directoryExists = await pathExists(directoryPath)
23 expect(directoryExists).to.be.true
24
25 const files = await readdir(directoryPath)
26 const filtered = files.filter(f => exceptions.includes(f) === false)
27
28 expect(filtered).to.have.lengthOf(0)
29}
30
31export {
32 checkTmpIsEmpty,
33 checkDirectoryIsEmpty
34}
diff --git a/shared/extra-utils/server/index.ts b/shared/extra-utils/server/index.ts
index 03c3b0123..669b004cd 100644
--- a/shared/extra-utils/server/index.ts
+++ b/shared/extra-utils/server/index.ts
@@ -1,6 +1,7 @@
1export * from './config-command' 1export * from './config-command'
2export * from './contact-form-command' 2export * from './contact-form-command'
3export * from './debug-command' 3export * from './debug-command'
4export * from './directories'
4export * from './follows-command' 5export * from './follows-command'
5export * from './follows' 6export * from './follows'
6export * from './jobs' 7export * from './jobs'
@@ -8,5 +9,6 @@ export * from './jobs-command'
8export * from './plugins-command' 9export * from './plugins-command'
9export * from './plugins' 10export * from './plugins'
10export * from './redundancy-command' 11export * from './redundancy-command'
12export * from './servers-command'
11export * from './servers' 13export * from './servers'
12export * from './stats-command' 14export * from './stats-command'
diff --git a/shared/extra-utils/server/jobs.ts b/shared/extra-utils/server/jobs.ts
index b4b3d52e7..36ef882b3 100644
--- a/shared/extra-utils/server/jobs.ts
+++ b/shared/extra-utils/server/jobs.ts
@@ -1,6 +1,6 @@
1 1
2import { JobState } from '../../models' 2import { JobState } from '../../models'
3import { wait } from '../miscs/miscs' 3import { wait } from '../miscs'
4import { ServerInfo } from './servers' 4import { ServerInfo } from './servers'
5 5
6async function waitJobs (serversArg: ServerInfo[] | ServerInfo) { 6async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
diff --git a/shared/extra-utils/server/plugins-command.ts b/shared/extra-utils/server/plugins-command.ts
index ff49d58c4..5bed51d1a 100644
--- a/shared/extra-utils/server/plugins-command.ts
+++ b/shared/extra-utils/server/plugins-command.ts
@@ -15,7 +15,6 @@ import {
15 RegisteredServerSettings, 15 RegisteredServerSettings,
16 ResultList 16 ResultList
17} from '@shared/models' 17} from '@shared/models'
18import { buildServerDirectory } from '../miscs'
19import { AbstractCommand, OverrideCommandOptions } from '../shared' 18import { AbstractCommand, OverrideCommandOptions } from '../shared'
20 19
21export class PluginsCommand extends AbstractCommand { 20export class PluginsCommand extends AbstractCommand {
@@ -252,6 +251,6 @@ export class PluginsCommand extends AbstractCommand {
252 } 251 }
253 252
254 private getPackageJSONPath (npmName: string) { 253 private getPackageJSONPath (npmName: string) {
255 return buildServerDirectory(this.server, join('plugins', 'node_modules', npmName, 'package.json')) 254 return this.server.serversCommand.buildDirectory(join('plugins', 'node_modules', npmName, 'package.json'))
256 } 255 }
257} 256}
diff --git a/shared/extra-utils/server/servers-command.ts b/shared/extra-utils/server/servers-command.ts
new file mode 100644
index 000000000..9ef68fede
--- /dev/null
+++ b/shared/extra-utils/server/servers-command.ts
@@ -0,0 +1,81 @@
1import { exec } from 'child_process'
2import { copy, ensureDir, readFile, remove } from 'fs-extra'
3import { join } from 'path'
4import { root } from '@server/helpers/core-utils'
5import { HttpStatusCode } from '@shared/core-utils'
6import { getFileSize } from '@uploadx/core'
7import { isGithubCI, wait } from '../miscs'
8import { AbstractCommand, OverrideCommandOptions } from '../shared'
9
10export class ServersCommand extends AbstractCommand {
11
12 static flushTests (internalServerNumber: number) {
13 return new Promise<void>((res, rej) => {
14 const suffix = ` -- ${internalServerNumber}`
15
16 return exec('npm run clean:server:test' + suffix, (err, _stdout, stderr) => {
17 if (err || stderr) return rej(err || new Error(stderr))
18
19 return res()
20 })
21 })
22 }
23
24 ping (options: OverrideCommandOptions = {}) {
25 return this.getRequestBody({
26 ...options,
27
28 path: '/api/v1/ping',
29 implicitToken: false,
30 defaultExpectedStatus: HttpStatusCode.OK_200
31 })
32 }
33
34 async cleanupTests () {
35 const p: Promise<any>[] = []
36
37 if (isGithubCI()) {
38 await ensureDir('artifacts')
39
40 const origin = this.server.serversCommand.buildDirectory('logs/peertube.log')
41 const destname = `peertube-${this.server.internalServerNumber}.log`
42 console.log('Saving logs %s.', destname)
43
44 await copy(origin, join('artifacts', destname))
45 }
46
47 if (this.server.parallel) {
48 p.push(ServersCommand.flushTests(this.server.internalServerNumber))
49 }
50
51 if (this.server.customConfigFile) {
52 p.push(remove(this.server.customConfigFile))
53 }
54
55 return p
56 }
57
58 async waitUntilLog (str: string, count = 1, strictCount = true) {
59 const logfile = this.server.serversCommand.buildDirectory('logs/peertube.log')
60
61 while (true) {
62 const buf = await readFile(logfile)
63
64 const matches = buf.toString().match(new RegExp(str, 'g'))
65 if (matches && matches.length === count) return
66 if (matches && strictCount === false && matches.length >= count) return
67
68 await wait(1000)
69 }
70 }
71
72 buildDirectory (directory: string) {
73 return join(root(), 'test' + this.server.internalServerNumber, directory)
74 }
75
76 async getServerFileSize (subPath: string) {
77 const path = this.server.serversCommand.buildDirectory(subPath)
78
79 return getFileSize(path)
80 }
81}
diff --git a/shared/extra-utils/server/servers.ts b/shared/extra-utils/server/servers.ts
index e0e49d2c4..f5dc0326f 100644
--- a/shared/extra-utils/server/servers.ts
+++ b/shared/extra-utils/server/servers.ts
@@ -1,9 +1,9 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */
2 2
3import { expect } from 'chai' 3import { ChildProcess, fork } from 'child_process'
4import { ChildProcess, exec, fork } from 'child_process' 4import { copy, ensureDir } from 'fs-extra'
5import { copy, ensureDir, pathExists, readdir, readFile, remove } from 'fs-extra'
6import { join } from 'path' 5import { join } from 'path'
6import { root } from '@server/helpers/core-utils'
7import { randomInt } from '../../core-utils/miscs/miscs' 7import { randomInt } from '../../core-utils/miscs/miscs'
8import { VideoChannel } from '../../models/videos' 8import { VideoChannel } from '../../models/videos'
9import { BulkCommand } from '../bulk' 9import { BulkCommand } from '../bulk'
@@ -11,11 +11,9 @@ import { CLICommand } from '../cli'
11import { CustomPagesCommand } from '../custom-pages' 11import { CustomPagesCommand } from '../custom-pages'
12import { FeedCommand } from '../feeds' 12import { FeedCommand } from '../feeds'
13import { LogsCommand } from '../logs' 13import { LogsCommand } from '../logs'
14import { SQLCommand } from '../miscs' 14import { isGithubCI, parallelTests, SQLCommand } from '../miscs'
15import { buildServerDirectory, getFileSize, isGithubCI, root, wait } from '../miscs/miscs'
16import { AbusesCommand } from '../moderation' 15import { AbusesCommand } from '../moderation'
17import { OverviewsCommand } from '../overviews' 16import { OverviewsCommand } from '../overviews'
18import { makeGetRequest } from '../requests/requests'
19import { SearchCommand } from '../search' 17import { SearchCommand } from '../search'
20import { SocketIOCommand } from '../socket' 18import { SocketIOCommand } from '../socket'
21import { AccountsCommand, BlocklistCommand, NotificationsCommand, SubscriptionsCommand } from '../users' 19import { AccountsCommand, BlocklistCommand, NotificationsCommand, SubscriptionsCommand } from '../users'
@@ -39,6 +37,7 @@ import { FollowsCommand } from './follows-command'
39import { JobsCommand } from './jobs-command' 37import { JobsCommand } from './jobs-command'
40import { PluginsCommand } from './plugins-command' 38import { PluginsCommand } from './plugins-command'
41import { RedundancyCommand } from './redundancy-command' 39import { RedundancyCommand } from './redundancy-command'
40import { ServersCommand } from './servers-command'
42import { StatsCommand } from './stats-command' 41import { StatsCommand } from './stats-command'
43 42
44interface ServerInfo { 43interface ServerInfo {
@@ -126,10 +125,7 @@ interface ServerInfo {
126 commentsCommand?: CommentsCommand 125 commentsCommand?: CommentsCommand
127 sqlCommand?: SQLCommand 126 sqlCommand?: SQLCommand
128 notificationsCommand?: NotificationsCommand 127 notificationsCommand?: NotificationsCommand
129} 128 serversCommand?: ServersCommand
130
131function parallelTests () {
132 return process.env.MOCHA_PARALLEL === 'true'
133} 129}
134 130
135function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) { 131function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) {
@@ -151,18 +147,6 @@ function flushAndRunMultipleServers (totalServers: number, configOverride?: Obje
151 }) 147 })
152} 148}
153 149
154function flushTests (serverNumber?: number) {
155 return new Promise<void>((res, rej) => {
156 const suffix = serverNumber ? ` -- ${serverNumber}` : ''
157
158 return exec('npm run clean:server:test' + suffix, (err, _stdout, stderr) => {
159 if (err || stderr) return rej(err || new Error(stderr))
160
161 return res()
162 })
163 })
164}
165
166function randomServer () { 150function randomServer () {
167 const low = 10 151 const low = 10
168 const high = 10000 152 const high = 10000
@@ -189,7 +173,7 @@ async function flushAndRunServer (serverNumber: number, configOverride?: Object,
189 const rtmpPort = parallel ? randomRTMP() : 1936 173 const rtmpPort = parallel ? randomRTMP() : 1936
190 const port = 9000 + internalServerNumber 174 const port = 9000 + internalServerNumber
191 175
192 await flushTests(internalServerNumber) 176 await ServersCommand.flushTests(internalServerNumber)
193 177
194 const server: ServerInfo = { 178 const server: ServerInfo = {
195 app: null, 179 app: null,
@@ -372,6 +356,7 @@ function assignCommands (server: ServerInfo) {
372 server.commentsCommand = new CommentsCommand(server) 356 server.commentsCommand = new CommentsCommand(server)
373 server.sqlCommand = new SQLCommand(server) 357 server.sqlCommand = new SQLCommand(server)
374 server.notificationsCommand = new NotificationsCommand(server) 358 server.notificationsCommand = new NotificationsCommand(server)
359 server.serversCommand = new ServersCommand(server)
375} 360}
376 361
377async function reRunServer (server: ServerInfo, configOverride?: any) { 362async function reRunServer (server: ServerInfo, configOverride?: any) {
@@ -381,28 +366,6 @@ async function reRunServer (server: ServerInfo, configOverride?: any) {
381 return server 366 return server
382} 367}
383 368
384async function checkTmpIsEmpty (server: ServerInfo) {
385 await checkDirectoryIsEmpty(server, 'tmp', [ 'plugins-global.css', 'hls', 'resumable-uploads' ])
386
387 if (await pathExists(join('test' + server.internalServerNumber, 'tmp', 'hls'))) {
388 await checkDirectoryIsEmpty(server, 'tmp/hls')
389 }
390}
391
392async function checkDirectoryIsEmpty (server: ServerInfo, directory: string, exceptions: string[] = []) {
393 const testDirectory = 'test' + server.internalServerNumber
394
395 const directoryPath = join(root(), testDirectory, directory)
396
397 const directoryExists = await pathExists(directoryPath)
398 expect(directoryExists).to.be.true
399
400 const files = await readdir(directoryPath)
401 const filtered = files.filter(f => exceptions.includes(f) === false)
402
403 expect(filtered).to.have.lengthOf(0)
404}
405
406async function killallServers (servers: ServerInfo[]) { 369async function killallServers (servers: ServerInfo[]) {
407 for (const server of servers) { 370 for (const server of servers) {
408 if (!server.app) continue 371 if (!server.app) continue
@@ -422,71 +385,22 @@ async function cleanupTests (servers: ServerInfo[]) {
422 await ensureDir('artifacts') 385 await ensureDir('artifacts')
423 } 386 }
424 387
425 const p: Promise<any>[] = [] 388 let p: Promise<any>[] = []
426 for (const server of servers) { 389 for (const server of servers) {
427 if (isGithubCI()) { 390 p = p.concat(server.serversCommand.cleanupTests())
428 const origin = await buildServerDirectory(server, 'logs/peertube.log')
429 const destname = `peertube-${server.internalServerNumber}.log`
430 console.log('Saving logs %s.', destname)
431
432 await copy(origin, join('artifacts', destname))
433 }
434
435 if (server.parallel) {
436 p.push(flushTests(server.internalServerNumber))
437 }
438
439 if (server.customConfigFile) {
440 p.push(remove(server.customConfigFile))
441 }
442 } 391 }
443 392
444 return Promise.all(p) 393 return Promise.all(p)
445} 394}
446 395
447async function waitUntilLog (server: ServerInfo, str: string, count = 1, strictCount = true) {
448 const logfile = buildServerDirectory(server, 'logs/peertube.log')
449
450 while (true) {
451 const buf = await readFile(logfile)
452
453 const matches = buf.toString().match(new RegExp(str, 'g'))
454 if (matches && matches.length === count) return
455 if (matches && strictCount === false && matches.length >= count) return
456
457 await wait(1000)
458 }
459}
460
461async function getServerFileSize (server: ServerInfo, subPath: string) {
462 const path = buildServerDirectory(server, subPath)
463
464 return getFileSize(path)
465}
466
467function makePingRequest (server: ServerInfo) {
468 return makeGetRequest({
469 url: server.url,
470 path: '/api/v1/ping',
471 statusCodeExpected: 200
472 })
473}
474
475// --------------------------------------------------------------------------- 396// ---------------------------------------------------------------------------
476 397
477export { 398export {
478 checkDirectoryIsEmpty,
479 checkTmpIsEmpty,
480 getServerFileSize,
481 ServerInfo, 399 ServerInfo,
482 parallelTests,
483 cleanupTests, 400 cleanupTests,
484 flushAndRunMultipleServers, 401 flushAndRunMultipleServers,
485 flushTests,
486 makePingRequest,
487 flushAndRunServer, 402 flushAndRunServer,
488 killallServers, 403 killallServers,
489 reRunServer, 404 reRunServer,
490 assignCommands, 405 assignCommands
491 waitUntilLog
492} 406}