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/miscs | |
parent | 0d8ecb7592577f54012413a2b5a9b159cfc90399 (diff) | |
download | PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.gz PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.zst PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.zip |
Introduce server commands
Diffstat (limited to 'shared/extra-utils/miscs')
-rw-r--r-- | shared/extra-utils/miscs/checks.ts | 46 | ||||
-rw-r--r-- | shared/extra-utils/miscs/generate.ts | 61 | ||||
-rw-r--r-- | shared/extra-utils/miscs/index.ts | 6 | ||||
-rw-r--r-- | shared/extra-utils/miscs/miscs.ts | 170 | ||||
-rw-r--r-- | shared/extra-utils/miscs/sql-command.ts | 2 | ||||
-rw-r--r-- | shared/extra-utils/miscs/stubs.ts | 7 | ||||
-rw-r--r-- | shared/extra-utils/miscs/tests.ts | 62 | ||||
-rw-r--r-- | shared/extra-utils/miscs/webtorrent.ts | 16 |
8 files changed, 190 insertions, 180 deletions
diff --git a/shared/extra-utils/miscs/checks.ts b/shared/extra-utils/miscs/checks.ts new file mode 100644 index 000000000..86b861cd2 --- /dev/null +++ b/shared/extra-utils/miscs/checks.ts | |||
@@ -0,0 +1,46 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/no-floating-promises */ | ||
2 | |||
3 | import { expect } from 'chai' | ||
4 | import { pathExists, readFile } from 'fs-extra' | ||
5 | import { join } from 'path' | ||
6 | import { root } from '@server/helpers/core-utils' | ||
7 | import { HttpStatusCode } from '@shared/core-utils' | ||
8 | import { makeGetRequest } from '../requests' | ||
9 | import { ServerInfo } from '../server' | ||
10 | |||
11 | // Default interval -> 5 minutes | ||
12 | function dateIsValid (dateString: string, interval = 300000) { | ||
13 | const dateToCheck = new Date(dateString) | ||
14 | const now = new Date() | ||
15 | |||
16 | return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval | ||
17 | } | ||
18 | |||
19 | async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') { | ||
20 | const res = await makeGetRequest({ | ||
21 | url, | ||
22 | path: imagePath, | ||
23 | statusCodeExpected: HttpStatusCode.OK_200 | ||
24 | }) | ||
25 | |||
26 | const body = res.body | ||
27 | |||
28 | const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension)) | ||
29 | const minLength = body.length - ((30 * body.length) / 100) | ||
30 | const maxLength = body.length + ((30 * body.length) / 100) | ||
31 | |||
32 | expect(data.length).to.be.above(minLength, 'the generated image is way smaller than the recorded fixture') | ||
33 | expect(data.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture') | ||
34 | } | ||
35 | |||
36 | async function testFileExistsOrNot (server: ServerInfo, directory: string, filePath: string, exist: boolean) { | ||
37 | const base = server.serversCommand.buildDirectory(directory) | ||
38 | |||
39 | expect(await pathExists(join(base, filePath))).to.equal(exist) | ||
40 | } | ||
41 | |||
42 | export { | ||
43 | dateIsValid, | ||
44 | testImage, | ||
45 | testFileExistsOrNot | ||
46 | } | ||
diff --git a/shared/extra-utils/miscs/generate.ts b/shared/extra-utils/miscs/generate.ts new file mode 100644 index 000000000..4e70ab853 --- /dev/null +++ b/shared/extra-utils/miscs/generate.ts | |||
@@ -0,0 +1,61 @@ | |||
1 | import { ensureDir, pathExists } from 'fs-extra' | ||
2 | import { dirname } from 'path' | ||
3 | import { buildAbsoluteFixturePath } from './tests' | ||
4 | import * as ffmpeg from 'fluent-ffmpeg' | ||
5 | |||
6 | async function generateHighBitrateVideo () { | ||
7 | const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true) | ||
8 | |||
9 | await ensureDir(dirname(tempFixturePath)) | ||
10 | |||
11 | const exists = await pathExists(tempFixturePath) | ||
12 | if (!exists) { | ||
13 | console.log('Generating high bitrate video.') | ||
14 | |||
15 | // Generate a random, high bitrate video on the fly, so we don't have to include | ||
16 | // a large file in the repo. The video needs to have a certain minimum length so | ||
17 | // that FFmpeg properly applies bitrate limits. | ||
18 | // https://stackoverflow.com/a/15795112 | ||
19 | return new Promise<string>((res, rej) => { | ||
20 | ffmpeg() | ||
21 | .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ]) | ||
22 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
23 | .outputOptions([ '-maxrate 10M', '-bufsize 10M' ]) | ||
24 | .output(tempFixturePath) | ||
25 | .on('error', rej) | ||
26 | .on('end', () => res(tempFixturePath)) | ||
27 | .run() | ||
28 | }) | ||
29 | } | ||
30 | |||
31 | return tempFixturePath | ||
32 | } | ||
33 | |||
34 | async function generateVideoWithFramerate (fps = 60) { | ||
35 | const tempFixturePath = buildAbsoluteFixturePath(`video_${fps}fps.mp4`, true) | ||
36 | |||
37 | await ensureDir(dirname(tempFixturePath)) | ||
38 | |||
39 | const exists = await pathExists(tempFixturePath) | ||
40 | if (!exists) { | ||
41 | console.log('Generating video with framerate %d.', fps) | ||
42 | |||
43 | return new Promise<string>((res, rej) => { | ||
44 | ffmpeg() | ||
45 | .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ]) | ||
46 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
47 | .outputOptions([ `-r ${fps}` ]) | ||
48 | .output(tempFixturePath) | ||
49 | .on('error', rej) | ||
50 | .on('end', () => res(tempFixturePath)) | ||
51 | .run() | ||
52 | }) | ||
53 | } | ||
54 | |||
55 | return tempFixturePath | ||
56 | } | ||
57 | |||
58 | export { | ||
59 | generateHighBitrateVideo, | ||
60 | generateVideoWithFramerate | ||
61 | } | ||
diff --git a/shared/extra-utils/miscs/index.ts b/shared/extra-utils/miscs/index.ts index 7e236c329..4474661de 100644 --- a/shared/extra-utils/miscs/index.ts +++ b/shared/extra-utils/miscs/index.ts | |||
@@ -1,3 +1,5 @@ | |||
1 | export * from './miscs' | 1 | export * from './checks' |
2 | export * from './generate' | ||
2 | export * from './sql-command' | 3 | export * from './sql-command' |
3 | export * from './stubs' | 4 | export * from './tests' |
5 | export * from './webtorrent' | ||
diff --git a/shared/extra-utils/miscs/miscs.ts b/shared/extra-utils/miscs/miscs.ts deleted file mode 100644 index 462b914d4..000000000 --- a/shared/extra-utils/miscs/miscs.ts +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | ||
2 | |||
3 | import * as chai from 'chai' | ||
4 | import * as ffmpeg from 'fluent-ffmpeg' | ||
5 | import { ensureDir, pathExists, readFile, stat } from 'fs-extra' | ||
6 | import { basename, dirname, isAbsolute, join, resolve } from 'path' | ||
7 | import * as request from 'supertest' | ||
8 | import * as WebTorrent from 'webtorrent' | ||
9 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
10 | |||
11 | const expect = chai.expect | ||
12 | let webtorrent: WebTorrent.Instance | ||
13 | |||
14 | function immutableAssign<T, U> (target: T, source: U) { | ||
15 | return Object.assign<{}, T, U>({}, target, source) | ||
16 | } | ||
17 | |||
18 | // Default interval -> 5 minutes | ||
19 | function dateIsValid (dateString: string, interval = 300000) { | ||
20 | const dateToCheck = new Date(dateString) | ||
21 | const now = new Date() | ||
22 | |||
23 | return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval | ||
24 | } | ||
25 | |||
26 | function wait (milliseconds: number) { | ||
27 | return new Promise(resolve => setTimeout(resolve, milliseconds)) | ||
28 | } | ||
29 | |||
30 | function webtorrentAdd (torrent: string, refreshWebTorrent = false) { | ||
31 | const WebTorrent = require('webtorrent') | ||
32 | |||
33 | if (!webtorrent) webtorrent = new WebTorrent() | ||
34 | if (refreshWebTorrent === true) webtorrent = new WebTorrent() | ||
35 | |||
36 | return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res)) | ||
37 | } | ||
38 | |||
39 | function root () { | ||
40 | // We are in /miscs | ||
41 | let root = join(__dirname, '..', '..', '..') | ||
42 | |||
43 | if (basename(root) === 'dist') root = resolve(root, '..') | ||
44 | |||
45 | return root | ||
46 | } | ||
47 | |||
48 | function buildServerDirectory (server: { internalServerNumber: number }, directory: string) { | ||
49 | return join(root(), 'test' + server.internalServerNumber, directory) | ||
50 | } | ||
51 | |||
52 | async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') { | ||
53 | const res = await request(url) | ||
54 | .get(imagePath) | ||
55 | .expect(HttpStatusCode.OK_200) | ||
56 | |||
57 | const body = res.body | ||
58 | |||
59 | const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension)) | ||
60 | const minLength = body.length - ((30 * body.length) / 100) | ||
61 | const maxLength = body.length + ((30 * body.length) / 100) | ||
62 | |||
63 | expect(data.length).to.be.above(minLength, 'the generated image is way smaller than the recorded fixture') | ||
64 | expect(data.length).to.be.below(maxLength, 'the generated image is way larger than the recorded fixture') | ||
65 | } | ||
66 | |||
67 | async function testFileExistsOrNot (server: { internalServerNumber: number }, directory: string, filePath: string, exist: boolean) { | ||
68 | const base = buildServerDirectory(server, directory) | ||
69 | |||
70 | expect(await pathExists(join(base, filePath))).to.equal(exist) | ||
71 | } | ||
72 | |||
73 | function isGithubCI () { | ||
74 | return !!process.env.GITHUB_WORKSPACE | ||
75 | } | ||
76 | |||
77 | function buildAbsoluteFixturePath (path: string, customCIPath = false) { | ||
78 | if (isAbsolute(path)) return path | ||
79 | |||
80 | if (customCIPath && process.env.GITHUB_WORKSPACE) { | ||
81 | return join(process.env.GITHUB_WORKSPACE, 'fixtures', path) | ||
82 | } | ||
83 | |||
84 | return join(root(), 'server', 'tests', 'fixtures', path) | ||
85 | } | ||
86 | |||
87 | function areHttpImportTestsDisabled () { | ||
88 | const disabled = process.env.DISABLE_HTTP_IMPORT_TESTS === 'true' | ||
89 | |||
90 | if (disabled) console.log('Import tests are disabled') | ||
91 | |||
92 | return disabled | ||
93 | } | ||
94 | |||
95 | async function generateHighBitrateVideo () { | ||
96 | const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true) | ||
97 | |||
98 | await ensureDir(dirname(tempFixturePath)) | ||
99 | |||
100 | const exists = await pathExists(tempFixturePath) | ||
101 | if (!exists) { | ||
102 | console.log('Generating high bitrate video.') | ||
103 | |||
104 | // Generate a random, high bitrate video on the fly, so we don't have to include | ||
105 | // a large file in the repo. The video needs to have a certain minimum length so | ||
106 | // that FFmpeg properly applies bitrate limits. | ||
107 | // https://stackoverflow.com/a/15795112 | ||
108 | return new Promise<string>((res, rej) => { | ||
109 | ffmpeg() | ||
110 | .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ]) | ||
111 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
112 | .outputOptions([ '-maxrate 10M', '-bufsize 10M' ]) | ||
113 | .output(tempFixturePath) | ||
114 | .on('error', rej) | ||
115 | .on('end', () => res(tempFixturePath)) | ||
116 | .run() | ||
117 | }) | ||
118 | } | ||
119 | |||
120 | return tempFixturePath | ||
121 | } | ||
122 | |||
123 | async function generateVideoWithFramerate (fps = 60) { | ||
124 | const tempFixturePath = buildAbsoluteFixturePath(`video_${fps}fps.mp4`, true) | ||
125 | |||
126 | await ensureDir(dirname(tempFixturePath)) | ||
127 | |||
128 | const exists = await pathExists(tempFixturePath) | ||
129 | if (!exists) { | ||
130 | console.log('Generating video with framerate %d.', fps) | ||
131 | |||
132 | return new Promise<string>((res, rej) => { | ||
133 | ffmpeg() | ||
134 | .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ]) | ||
135 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | ||
136 | .outputOptions([ `-r ${fps}` ]) | ||
137 | .output(tempFixturePath) | ||
138 | .on('error', rej) | ||
139 | .on('end', () => res(tempFixturePath)) | ||
140 | .run() | ||
141 | }) | ||
142 | } | ||
143 | |||
144 | return tempFixturePath | ||
145 | } | ||
146 | |||
147 | async function getFileSize (path: string) { | ||
148 | const stats = await stat(path) | ||
149 | |||
150 | return stats.size | ||
151 | } | ||
152 | |||
153 | // --------------------------------------------------------------------------- | ||
154 | |||
155 | export { | ||
156 | dateIsValid, | ||
157 | wait, | ||
158 | areHttpImportTestsDisabled, | ||
159 | buildServerDirectory, | ||
160 | webtorrentAdd, | ||
161 | getFileSize, | ||
162 | immutableAssign, | ||
163 | testImage, | ||
164 | isGithubCI, | ||
165 | buildAbsoluteFixturePath, | ||
166 | testFileExistsOrNot, | ||
167 | root, | ||
168 | generateHighBitrateVideo, | ||
169 | generateVideoWithFramerate | ||
170 | } | ||
diff --git a/shared/extra-utils/miscs/sql-command.ts b/shared/extra-utils/miscs/sql-command.ts index 2a3e9e607..80c8cd271 100644 --- a/shared/extra-utils/miscs/sql-command.ts +++ b/shared/extra-utils/miscs/sql-command.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { QueryTypes, Sequelize } from 'sequelize' | 1 | import { QueryTypes, Sequelize } from 'sequelize' |
2 | import { AbstractCommand } from '../shared' | 2 | import { AbstractCommand } from '../shared/abstract-command' |
3 | 3 | ||
4 | export class SQLCommand extends AbstractCommand { | 4 | export class SQLCommand extends AbstractCommand { |
5 | private sequelize: Sequelize | 5 | private sequelize: Sequelize |
diff --git a/shared/extra-utils/miscs/stubs.ts b/shared/extra-utils/miscs/stubs.ts deleted file mode 100644 index 940e4bf29..000000000 --- a/shared/extra-utils/miscs/stubs.ts +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | function buildRequestStub (): any { | ||
2 | return { } | ||
3 | } | ||
4 | |||
5 | export { | ||
6 | buildRequestStub | ||
7 | } | ||
diff --git a/shared/extra-utils/miscs/tests.ts b/shared/extra-utils/miscs/tests.ts new file mode 100644 index 000000000..8f7a2f92b --- /dev/null +++ b/shared/extra-utils/miscs/tests.ts | |||
@@ -0,0 +1,62 @@ | |||
1 | import { stat } from 'fs-extra' | ||
2 | import { basename, isAbsolute, join, resolve } from 'path' | ||
3 | |||
4 | function parallelTests () { | ||
5 | return process.env.MOCHA_PARALLEL === 'true' | ||
6 | } | ||
7 | |||
8 | function isGithubCI () { | ||
9 | return !!process.env.GITHUB_WORKSPACE | ||
10 | } | ||
11 | |||
12 | function areHttpImportTestsDisabled () { | ||
13 | const disabled = process.env.DISABLE_HTTP_IMPORT_TESTS === 'true' | ||
14 | |||
15 | if (disabled) console.log('Import tests are disabled') | ||
16 | |||
17 | return disabled | ||
18 | } | ||
19 | |||
20 | function buildAbsoluteFixturePath (path: string, customCIPath = false) { | ||
21 | if (isAbsolute(path)) return path | ||
22 | |||
23 | if (customCIPath && process.env.GITHUB_WORKSPACE) { | ||
24 | return join(process.env.GITHUB_WORKSPACE, 'fixtures', path) | ||
25 | } | ||
26 | |||
27 | return join(root(), 'server', 'tests', 'fixtures', path) | ||
28 | } | ||
29 | |||
30 | function root () { | ||
31 | // We are in /miscs | ||
32 | let root = join(__dirname, '..', '..', '..') | ||
33 | |||
34 | if (basename(root) === 'dist') root = resolve(root, '..') | ||
35 | |||
36 | return root | ||
37 | } | ||
38 | |||
39 | function wait (milliseconds: number) { | ||
40 | return new Promise(resolve => setTimeout(resolve, milliseconds)) | ||
41 | } | ||
42 | |||
43 | async function getFileSize (path: string) { | ||
44 | const stats = await stat(path) | ||
45 | |||
46 | return stats.size | ||
47 | } | ||
48 | |||
49 | function buildRequestStub (): any { | ||
50 | return { } | ||
51 | } | ||
52 | |||
53 | export { | ||
54 | parallelTests, | ||
55 | isGithubCI, | ||
56 | areHttpImportTestsDisabled, | ||
57 | buildAbsoluteFixturePath, | ||
58 | getFileSize, | ||
59 | buildRequestStub, | ||
60 | wait, | ||
61 | root | ||
62 | } | ||
diff --git a/shared/extra-utils/miscs/webtorrent.ts b/shared/extra-utils/miscs/webtorrent.ts new file mode 100644 index 000000000..82548946d --- /dev/null +++ b/shared/extra-utils/miscs/webtorrent.ts | |||
@@ -0,0 +1,16 @@ | |||
1 | import * as WebTorrent from 'webtorrent' | ||
2 | |||
3 | let webtorrent: WebTorrent.Instance | ||
4 | |||
5 | function webtorrentAdd (torrent: string, refreshWebTorrent = false) { | ||
6 | const WebTorrent = require('webtorrent') | ||
7 | |||
8 | if (!webtorrent) webtorrent = new WebTorrent() | ||
9 | if (refreshWebTorrent === true) webtorrent = new WebTorrent() | ||
10 | |||
11 | return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res)) | ||
12 | } | ||
13 | |||
14 | export { | ||
15 | webtorrentAdd | ||
16 | } | ||