diff options
author | Chocobozzz <me@florianbigard.com> | 2021-07-13 09:43:59 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-07-20 15:27:18 +0200 |
commit | 6c5065a011b099618681a37bd77eaa7bd3db752e (patch) | |
tree | 352252a00b25013c4b1902f6bcd9668aba295c7b /shared/extra-utils/server | |
parent | 0d8ecb7592577f54012413a2b5a9b159cfc90399 (diff) | |
download | PeerTube-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.ts | 34 | ||||
-rw-r--r-- | shared/extra-utils/server/index.ts | 2 | ||||
-rw-r--r-- | shared/extra-utils/server/jobs.ts | 2 | ||||
-rw-r--r-- | shared/extra-utils/server/plugins-command.ts | 3 | ||||
-rw-r--r-- | shared/extra-utils/server/servers-command.ts | 81 | ||||
-rw-r--r-- | shared/extra-utils/server/servers.ts | 108 |
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 | |||
3 | import { expect } from 'chai' | ||
4 | import { pathExists, readdir } from 'fs-extra' | ||
5 | import { join } from 'path' | ||
6 | import { root } from '@server/helpers/core-utils' | ||
7 | import { ServerInfo } from './servers' | ||
8 | |||
9 | async 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 | |||
17 | async 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 | |||
31 | export { | ||
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 @@ | |||
1 | export * from './config-command' | 1 | export * from './config-command' |
2 | export * from './contact-form-command' | 2 | export * from './contact-form-command' |
3 | export * from './debug-command' | 3 | export * from './debug-command' |
4 | export * from './directories' | ||
4 | export * from './follows-command' | 5 | export * from './follows-command' |
5 | export * from './follows' | 6 | export * from './follows' |
6 | export * from './jobs' | 7 | export * from './jobs' |
@@ -8,5 +9,6 @@ export * from './jobs-command' | |||
8 | export * from './plugins-command' | 9 | export * from './plugins-command' |
9 | export * from './plugins' | 10 | export * from './plugins' |
10 | export * from './redundancy-command' | 11 | export * from './redundancy-command' |
12 | export * from './servers-command' | ||
11 | export * from './servers' | 13 | export * from './servers' |
12 | export * from './stats-command' | 14 | export * 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 | ||
2 | import { JobState } from '../../models' | 2 | import { JobState } from '../../models' |
3 | import { wait } from '../miscs/miscs' | 3 | import { wait } from '../miscs' |
4 | import { ServerInfo } from './servers' | 4 | import { ServerInfo } from './servers' |
5 | 5 | ||
6 | async function waitJobs (serversArg: ServerInfo[] | ServerInfo) { | 6 | async 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' |
18 | import { buildServerDirectory } from '../miscs' | ||
19 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 18 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
20 | 19 | ||
21 | export class PluginsCommand extends AbstractCommand { | 20 | export 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 @@ | |||
1 | import { exec } from 'child_process' | ||
2 | import { copy, ensureDir, readFile, remove } from 'fs-extra' | ||
3 | import { join } from 'path' | ||
4 | import { root } from '@server/helpers/core-utils' | ||
5 | import { HttpStatusCode } from '@shared/core-utils' | ||
6 | import { getFileSize } from '@uploadx/core' | ||
7 | import { isGithubCI, wait } from '../miscs' | ||
8 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | ||
9 | |||
10 | export 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 | ||
3 | import { expect } from 'chai' | 3 | import { ChildProcess, fork } from 'child_process' |
4 | import { ChildProcess, exec, fork } from 'child_process' | 4 | import { copy, ensureDir } from 'fs-extra' |
5 | import { copy, ensureDir, pathExists, readdir, readFile, remove } from 'fs-extra' | ||
6 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { root } from '@server/helpers/core-utils' | ||
7 | import { randomInt } from '../../core-utils/miscs/miscs' | 7 | import { randomInt } from '../../core-utils/miscs/miscs' |
8 | import { VideoChannel } from '../../models/videos' | 8 | import { VideoChannel } from '../../models/videos' |
9 | import { BulkCommand } from '../bulk' | 9 | import { BulkCommand } from '../bulk' |
@@ -11,11 +11,9 @@ import { CLICommand } from '../cli' | |||
11 | import { CustomPagesCommand } from '../custom-pages' | 11 | import { CustomPagesCommand } from '../custom-pages' |
12 | import { FeedCommand } from '../feeds' | 12 | import { FeedCommand } from '../feeds' |
13 | import { LogsCommand } from '../logs' | 13 | import { LogsCommand } from '../logs' |
14 | import { SQLCommand } from '../miscs' | 14 | import { isGithubCI, parallelTests, SQLCommand } from '../miscs' |
15 | import { buildServerDirectory, getFileSize, isGithubCI, root, wait } from '../miscs/miscs' | ||
16 | import { AbusesCommand } from '../moderation' | 15 | import { AbusesCommand } from '../moderation' |
17 | import { OverviewsCommand } from '../overviews' | 16 | import { OverviewsCommand } from '../overviews' |
18 | import { makeGetRequest } from '../requests/requests' | ||
19 | import { SearchCommand } from '../search' | 17 | import { SearchCommand } from '../search' |
20 | import { SocketIOCommand } from '../socket' | 18 | import { SocketIOCommand } from '../socket' |
21 | import { AccountsCommand, BlocklistCommand, NotificationsCommand, SubscriptionsCommand } from '../users' | 19 | import { AccountsCommand, BlocklistCommand, NotificationsCommand, SubscriptionsCommand } from '../users' |
@@ -39,6 +37,7 @@ import { FollowsCommand } from './follows-command' | |||
39 | import { JobsCommand } from './jobs-command' | 37 | import { JobsCommand } from './jobs-command' |
40 | import { PluginsCommand } from './plugins-command' | 38 | import { PluginsCommand } from './plugins-command' |
41 | import { RedundancyCommand } from './redundancy-command' | 39 | import { RedundancyCommand } from './redundancy-command' |
40 | import { ServersCommand } from './servers-command' | ||
42 | import { StatsCommand } from './stats-command' | 41 | import { StatsCommand } from './stats-command' |
43 | 42 | ||
44 | interface ServerInfo { | 43 | interface 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 | |||
131 | function parallelTests () { | ||
132 | return process.env.MOCHA_PARALLEL === 'true' | ||
133 | } | 129 | } |
134 | 130 | ||
135 | function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) { | 131 | function flushAndRunMultipleServers (totalServers: number, configOverride?: Object) { |
@@ -151,18 +147,6 @@ function flushAndRunMultipleServers (totalServers: number, configOverride?: Obje | |||
151 | }) | 147 | }) |
152 | } | 148 | } |
153 | 149 | ||
154 | function 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 | |||
166 | function randomServer () { | 150 | function 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 | ||
377 | async function reRunServer (server: ServerInfo, configOverride?: any) { | 362 | async 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 | ||
384 | async 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 | |||
392 | async 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 | |||
406 | async function killallServers (servers: ServerInfo[]) { | 369 | async 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 | ||
447 | async 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 | |||
461 | async function getServerFileSize (server: ServerInfo, subPath: string) { | ||
462 | const path = buildServerDirectory(server, subPath) | ||
463 | |||
464 | return getFileSize(path) | ||
465 | } | ||
466 | |||
467 | function 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 | ||
477 | export { | 398 | export { |
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 | } |