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 | |
parent | 0d8ecb7592577f54012413a2b5a9b159cfc90399 (diff) | |
download | PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.gz PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.tar.zst PeerTube-6c5065a011b099618681a37bd77eaa7bd3db752e.zip |
Introduce server commands
Diffstat (limited to 'shared/extra-utils')
23 files changed, 345 insertions, 323 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 | } | ||
diff --git a/shared/extra-utils/mock-servers/mock-email.ts b/shared/extra-utils/mock-servers/mock-email.ts index 9fc9a5ad0..ffd62e325 100644 --- a/shared/extra-utils/mock-servers/mock-email.ts +++ b/shared/extra-utils/mock-servers/mock-email.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { ChildProcess } from 'child_process' | 1 | import { ChildProcess } from 'child_process' |
2 | import { randomInt } from '../../core-utils/miscs/miscs' | 2 | import { randomInt } from '@shared/core-utils' |
3 | import { parallelTests } from '../server/servers' | 3 | import { parallelTests } from '../miscs' |
4 | 4 | ||
5 | const MailDev = require('maildev') | 5 | const MailDev = require('maildev') |
6 | 6 | ||
diff --git a/shared/extra-utils/requests/check-api-params.ts b/shared/extra-utils/requests/check-api-params.ts index 7f5ff775c..7df63b004 100644 --- a/shared/extra-utils/requests/check-api-params.ts +++ b/shared/extra-utils/requests/check-api-params.ts | |||
@@ -1,13 +1,12 @@ | |||
1 | import { HttpStatusCode } from '@shared/core-utils' | ||
1 | import { makeGetRequest } from './requests' | 2 | import { makeGetRequest } from './requests' |
2 | import { immutableAssign } from '../miscs/miscs' | ||
3 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
4 | 3 | ||
5 | function checkBadStartPagination (url: string, path: string, token?: string, query = {}) { | 4 | function checkBadStartPagination (url: string, path: string, token?: string, query = {}) { |
6 | return makeGetRequest({ | 5 | return makeGetRequest({ |
7 | url, | 6 | url, |
8 | path, | 7 | path, |
9 | token, | 8 | token, |
10 | query: immutableAssign(query, { start: 'hello' }), | 9 | query: { ...query, start: 'hello' }, |
11 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 | 10 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 |
12 | }) | 11 | }) |
13 | } | 12 | } |
@@ -17,7 +16,7 @@ async function checkBadCountPagination (url: string, path: string, token?: strin | |||
17 | url, | 16 | url, |
18 | path, | 17 | path, |
19 | token, | 18 | token, |
20 | query: immutableAssign(query, { count: 'hello' }), | 19 | query: { ...query, count: 'hello' }, |
21 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 | 20 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 |
22 | }) | 21 | }) |
23 | 22 | ||
@@ -25,7 +24,7 @@ async function checkBadCountPagination (url: string, path: string, token?: strin | |||
25 | url, | 24 | url, |
26 | path, | 25 | path, |
27 | token, | 26 | token, |
28 | query: immutableAssign(query, { count: 2000 }), | 27 | query: { ...query, count: 2000 }, |
29 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 | 28 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 |
30 | }) | 29 | }) |
31 | } | 30 | } |
@@ -35,7 +34,7 @@ function checkBadSortPagination (url: string, path: string, token?: string, quer | |||
35 | url, | 34 | url, |
36 | path, | 35 | path, |
37 | token, | 36 | token, |
38 | query: immutableAssign(query, { sort: 'hello' }), | 37 | query: { ...query, sort: 'hello' }, |
39 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 | 38 | statusCodeExpected: HttpStatusCode.BAD_REQUEST_400 |
40 | }) | 39 | }) |
41 | } | 40 | } |
diff --git a/shared/extra-utils/requests/requests.ts b/shared/extra-utils/requests/requests.ts index 3fbaa31d6..f9d112aca 100644 --- a/shared/extra-utils/requests/requests.ts +++ b/shared/extra-utils/requests/requests.ts | |||
@@ -4,8 +4,8 @@ import { isAbsolute, join } from 'path' | |||
4 | import { decode } from 'querystring' | 4 | import { decode } from 'querystring' |
5 | import * as request from 'supertest' | 5 | import * as request from 'supertest' |
6 | import { URL } from 'url' | 6 | import { URL } from 'url' |
7 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | 7 | import { HttpStatusCode } from '@shared/core-utils' |
8 | import { buildAbsoluteFixturePath, root } from '../miscs/miscs' | 8 | import { buildAbsoluteFixturePath, root } from '../miscs/tests' |
9 | 9 | ||
10 | function get4KFileUrl () { | 10 | function get4KFileUrl () { |
11 | return 'https://download.cpy.re/peertube/4k_file.txt' | 11 | return 'https://download.cpy.re/peertube/4k_file.txt' |
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 | } |
diff --git a/shared/extra-utils/shared/abstract-command.ts b/shared/extra-utils/shared/abstract-command.ts index fd2deb57e..4e61554a2 100644 --- a/shared/extra-utils/shared/abstract-command.ts +++ b/shared/extra-utils/shared/abstract-command.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { isAbsolute, join } from 'path' | 1 | import { isAbsolute, join } from 'path' |
2 | import { HttpStatusCode } from '@shared/core-utils' | 2 | import { HttpStatusCode } from '@shared/core-utils' |
3 | import { root } from '../miscs/miscs' | 3 | import { root } from '../miscs/tests' |
4 | import { | 4 | import { |
5 | makeDeleteRequest, | 5 | makeDeleteRequest, |
6 | makeGetRequest, | 6 | makeGetRequest, |
diff --git a/shared/extra-utils/videos/captions-command.ts b/shared/extra-utils/videos/captions-command.ts index 908b6dae6..ac3bde7a9 100644 --- a/shared/extra-utils/videos/captions-command.ts +++ b/shared/extra-utils/videos/captions-command.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { HttpStatusCode } from '@shared/core-utils' | ||
1 | import { ResultList, VideoCaption } from '@shared/models' | 2 | import { ResultList, VideoCaption } from '@shared/models' |
2 | import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' | 3 | import { buildAbsoluteFixturePath } from '../miscs' |
3 | import { buildAbsoluteFixturePath } from '../miscs/miscs' | ||
4 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 4 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
5 | 5 | ||
6 | export class CaptionsCommand extends AbstractCommand { | 6 | export class CaptionsCommand extends AbstractCommand { |
diff --git a/shared/extra-utils/videos/live-command.ts b/shared/extra-utils/videos/live-command.ts index 4f03c9127..a494e60fa 100644 --- a/shared/extra-utils/videos/live-command.ts +++ b/shared/extra-utils/videos/live-command.ts | |||
@@ -5,9 +5,8 @@ import { omit } from 'lodash' | |||
5 | import { join } from 'path' | 5 | import { join } from 'path' |
6 | import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' | 6 | import { LiveVideo, LiveVideoCreate, LiveVideoUpdate, VideoCreateResult, VideoDetails, VideoState } from '@shared/models' |
7 | import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' | 7 | import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes' |
8 | import { buildServerDirectory, wait } from '../miscs/miscs' | 8 | import { wait } from '../miscs' |
9 | import { unwrapBody } from '../requests' | 9 | import { unwrapBody } from '../requests' |
10 | import { waitUntilLog } from '../server/servers' | ||
11 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | 10 | import { AbstractCommand, OverrideCommandOptions } from '../shared' |
12 | import { sendRTMPStream, testFfmpegStreamError } from './live' | 11 | import { sendRTMPStream, testFfmpegStreamError } from './live' |
13 | import { getVideoWithToken } from './videos' | 12 | import { getVideoWithToken } from './videos' |
@@ -116,7 +115,7 @@ export class LiveCommand extends AbstractCommand { | |||
116 | const { resolution, segment, videoUUID } = options | 115 | const { resolution, segment, videoUUID } = options |
117 | const segmentName = `${resolution}-00000${segment}.ts` | 116 | const segmentName = `${resolution}-00000${segment}.ts` |
118 | 117 | ||
119 | return waitUntilLog(this.server, `${videoUUID}/${segmentName}`, 2, false) | 118 | return this.server.serversCommand.waitUntilLog(`${videoUUID}/${segmentName}`, 2, false) |
120 | } | 119 | } |
121 | 120 | ||
122 | async waitUntilSaved (options: OverrideCommandOptions & { | 121 | async waitUntilSaved (options: OverrideCommandOptions & { |
@@ -135,7 +134,7 @@ export class LiveCommand extends AbstractCommand { | |||
135 | async countPlaylists (options: OverrideCommandOptions & { | 134 | async countPlaylists (options: OverrideCommandOptions & { |
136 | videoUUID: string | 135 | videoUUID: string |
137 | }) { | 136 | }) { |
138 | const basePath = buildServerDirectory(this.server, 'streaming-playlists') | 137 | const basePath = this.server.serversCommand.buildDirectory('streaming-playlists') |
139 | const hlsPath = join(basePath, 'hls', options.videoUUID) | 138 | const hlsPath = join(basePath, 'hls', options.videoUUID) |
140 | 139 | ||
141 | const files = await readdir(hlsPath) | 140 | const files = await readdir(hlsPath) |
diff --git a/shared/extra-utils/videos/live.ts b/shared/extra-utils/videos/live.ts index 92cb9104c..0efcc2883 100644 --- a/shared/extra-utils/videos/live.ts +++ b/shared/extra-utils/videos/live.ts | |||
@@ -4,7 +4,7 @@ import { expect } from 'chai' | |||
4 | import * as ffmpeg from 'fluent-ffmpeg' | 4 | import * as ffmpeg from 'fluent-ffmpeg' |
5 | import { pathExists, readdir } from 'fs-extra' | 5 | import { pathExists, readdir } from 'fs-extra' |
6 | import { join } from 'path' | 6 | import { join } from 'path' |
7 | import { buildAbsoluteFixturePath, buildServerDirectory, wait } from '../miscs/miscs' | 7 | import { buildAbsoluteFixturePath, wait } from '../miscs' |
8 | import { ServerInfo } from '../server/servers' | 8 | import { ServerInfo } from '../server/servers' |
9 | 9 | ||
10 | function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { | 10 | function sendRTMPStream (rtmpBaseUrl: string, streamKey: string, fixtureName = 'video_short.mp4') { |
@@ -77,7 +77,7 @@ async function waitUntilLivePublishedOnAllServers (servers: ServerInfo[], videoI | |||
77 | } | 77 | } |
78 | 78 | ||
79 | async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { | 79 | async function checkLiveCleanup (server: ServerInfo, videoUUID: string, resolutions: number[] = []) { |
80 | const basePath = buildServerDirectory(server, 'streaming-playlists') | 80 | const basePath = server.serversCommand.buildDirectory('streaming-playlists') |
81 | const hlsPath = join(basePath, 'hls', videoUUID) | 81 | const hlsPath = join(basePath, 'hls', videoUUID) |
82 | 82 | ||
83 | if (resolutions.length === 0) { | 83 | if (resolutions.length === 0) { |
diff --git a/shared/extra-utils/videos/playlists.ts b/shared/extra-utils/videos/playlists.ts index 023333c87..3dde52bb9 100644 --- a/shared/extra-utils/videos/playlists.ts +++ b/shared/extra-utils/videos/playlists.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { expect } from 'chai' | 1 | import { expect } from 'chai' |
2 | import { readdir } from 'fs-extra' | 2 | import { readdir } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { root } from '../' | 4 | import { root } from '../miscs' |
5 | 5 | ||
6 | async function checkPlaylistFilesWereRemoved ( | 6 | async function checkPlaylistFilesWereRemoved ( |
7 | playlistUUID: string, | 7 | playlistUUID: string, |
diff --git a/shared/extra-utils/videos/videos.ts b/shared/extra-utils/videos/videos.ts index 920c93072..5dd71ce8b 100644 --- a/shared/extra-utils/videos/videos.ts +++ b/shared/extra-utils/videos/videos.ts | |||
@@ -13,15 +13,7 @@ import { HttpStatusCode } from '@shared/core-utils' | |||
13 | import { BooleanBothQuery, VideosCommonQuery } from '@shared/models' | 13 | import { BooleanBothQuery, VideosCommonQuery } from '@shared/models' |
14 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' | 14 | import { loadLanguages, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../../server/initializers/constants' |
15 | import { VideoDetails, VideoPrivacy } from '../../models/videos' | 15 | import { VideoDetails, VideoPrivacy } from '../../models/videos' |
16 | import { | 16 | import { buildAbsoluteFixturePath, dateIsValid, testImage, wait, webtorrentAdd } from '../miscs' |
17 | buildAbsoluteFixturePath, | ||
18 | buildServerDirectory, | ||
19 | dateIsValid, | ||
20 | immutableAssign, | ||
21 | testImage, | ||
22 | wait, | ||
23 | webtorrentAdd | ||
24 | } from '../miscs/miscs' | ||
25 | import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' | 17 | import { makeGetRequest, makePutBodyRequest, makeRawRequest, makeUploadRequest } from '../requests/requests' |
26 | import { waitJobs } from '../server/jobs' | 18 | import { waitJobs } from '../server/jobs' |
27 | import { ServerInfo } from '../server/servers' | 19 | import { ServerInfo } from '../server/servers' |
@@ -165,7 +157,7 @@ function getVideosListWithToken (url: string, token: string, query: { nsfw?: Boo | |||
165 | return request(url) | 157 | return request(url) |
166 | .get(path) | 158 | .get(path) |
167 | .set('Authorization', 'Bearer ' + token) | 159 | .set('Authorization', 'Bearer ' + token) |
168 | .query(immutableAssign(query, { sort: 'name' })) | 160 | .query({ sort: 'name', ...query }) |
169 | .set('Accept', 'application/json') | 161 | .set('Accept', 'application/json') |
170 | .expect(HttpStatusCode.OK_200) | 162 | .expect(HttpStatusCode.OK_200) |
171 | .expect('Content-Type', /json/) | 163 | .expect('Content-Type', /json/) |
@@ -228,11 +220,7 @@ function getAccountVideos ( | |||
228 | return makeGetRequest({ | 220 | return makeGetRequest({ |
229 | url, | 221 | url, |
230 | path, | 222 | path, |
231 | query: immutableAssign(query, { | 223 | query: { ...query, start, count, sort }, |
232 | start, | ||
233 | count, | ||
234 | sort | ||
235 | }), | ||
236 | token: accessToken, | 224 | token: accessToken, |
237 | statusCodeExpected: HttpStatusCode.OK_200 | 225 | statusCodeExpected: HttpStatusCode.OK_200 |
238 | }) | 226 | }) |
@@ -252,11 +240,7 @@ function getVideoChannelVideos ( | |||
252 | return makeGetRequest({ | 240 | return makeGetRequest({ |
253 | url, | 241 | url, |
254 | path, | 242 | path, |
255 | query: immutableAssign(query, { | 243 | query: { ...query, start, count, sort }, |
256 | start, | ||
257 | count, | ||
258 | sort | ||
259 | }), | ||
260 | token: accessToken, | 244 | token: accessToken, |
261 | statusCodeExpected: HttpStatusCode.OK_200 | 245 | statusCodeExpected: HttpStatusCode.OK_200 |
262 | }) | 246 | }) |
@@ -320,7 +304,7 @@ async function removeAllVideos (server: ServerInfo) { | |||
320 | 304 | ||
321 | async function checkVideoFilesWereRemoved ( | 305 | async function checkVideoFilesWereRemoved ( |
322 | videoUUID: string, | 306 | videoUUID: string, |
323 | serverNumber: number, | 307 | server: ServerInfo, |
324 | directories = [ | 308 | directories = [ |
325 | 'redundancy', | 309 | 'redundancy', |
326 | 'videos', | 310 | 'videos', |
@@ -333,7 +317,7 @@ async function checkVideoFilesWereRemoved ( | |||
333 | ] | 317 | ] |
334 | ) { | 318 | ) { |
335 | for (const directory of directories) { | 319 | for (const directory of directories) { |
336 | const directoryPath = buildServerDirectory({ internalServerNumber: serverNumber }, directory) | 320 | const directoryPath = server.serversCommand.buildDirectory(directory) |
337 | 321 | ||
338 | const directoryExists = await pathExists(directoryPath) | 322 | const directoryExists = await pathExists(directoryPath) |
339 | if (directoryExists === false) continue | 323 | if (directoryExists === false) continue |
@@ -607,7 +591,7 @@ function rateVideo (url: string, accessToken: string, id: number | string, ratin | |||
607 | function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { | 591 | function parseTorrentVideo (server: ServerInfo, videoUUID: string, resolution: number) { |
608 | return new Promise<any>((res, rej) => { | 592 | return new Promise<any>((res, rej) => { |
609 | const torrentName = videoUUID + '-' + resolution + '.torrent' | 593 | const torrentName = videoUUID + '-' + resolution + '.torrent' |
610 | const torrentPath = buildServerDirectory(server, join('torrents', torrentName)) | 594 | const torrentPath = server.serversCommand.buildDirectory(join('torrents', torrentName)) |
611 | 595 | ||
612 | readFile(torrentPath, (err, data) => { | 596 | readFile(torrentPath, (err, data) => { |
613 | if (err) return rej(err) | 597 | if (err) return rej(err) |