]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/extra-utils/miscs/miscs.ts
Fix CLI tools
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / miscs / miscs.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
9ee83eb9 2
7b0956ec 3import * as chai from 'chai'
ca5c612b 4import * as ffmpeg from 'fluent-ffmpeg'
f6c1251d 5import { ensureDir, pathExists, readFile, stat } from 'fs-extra'
2284f202 6import { basename, dirname, isAbsolute, join, resolve } from 'path'
9ee83eb9 7import * as request from 'supertest'
0e1dc3e7 8import * as WebTorrent from 'webtorrent'
2d53be02 9import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
0e1dc3e7 10
7b0956ec 11const expect = chai.expect
8d2be0ed 12let webtorrent: WebTorrent.Instance
0e1dc3e7 13
a1587156 14function immutableAssign<T, U> (target: T, source: U) {
26d21b78
C
15 return Object.assign<{}, T, U>({}, target, source)
16}
17
a1587156 18// Default interval -> 5 minutes
b1f5b93e 19function dateIsValid (dateString: string, interval = 300000) {
0e1dc3e7
C
20 const dateToCheck = new Date(dateString)
21 const now = new Date()
22
23 return Math.abs(now.getTime() - dateToCheck.getTime()) <= interval
24}
25
26function wait (milliseconds: number) {
27 return new Promise(resolve => setTimeout(resolve, milliseconds))
28}
29
30function webtorrentAdd (torrent: string, refreshWebTorrent = false) {
8d2be0ed
C
31 const WebTorrent = require('webtorrent')
32
33 if (!webtorrent) webtorrent = new WebTorrent()
0e1dc3e7
C
34 if (refreshWebTorrent === true) webtorrent = new WebTorrent()
35
36 return new Promise<WebTorrent.Torrent>(res => webtorrent.add(torrent, res))
37}
38
f05a1c30 39function root () {
94565d52 40 // We are in /miscs
1a12f66d
C
41 let root = join(__dirname, '..', '..', '..')
42
43 if (basename(root) === 'dist') root = resolve(root, '..')
44
45 return root
f05a1c30
C
46}
47
ca5c612b
C
48function buildServerDirectory (server: { internalServerNumber: number }, directory: string) {
49 return join(root(), 'test' + server.internalServerNumber, directory)
e2600d8b
C
50}
51
9ee83eb9 52async function testImage (url: string, imageName: string, imagePath: string, extension = '.jpg') {
288178bf
C
53 const res = await request(url)
54 .get(imagePath)
2d53be02 55 .expect(HttpStatusCode.OK_200)
288178bf
C
56
57 const body = res.body
58
2a8c5d0a 59 const data = await readFile(join(root(), 'server', 'tests', 'fixtures', imageName + extension))
e6dfa586
RK
60 const minLength = body.length - ((30 * body.length) / 100)
61 const maxLength = body.length + ((30 * body.length) / 100)
288178bf 62
06c27593
C
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
67async 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)
9ee83eb9
C
71}
72
83ef31fe
C
73function isGithubCI () {
74 return !!process.env.GITHUB_WORKSPACE
75}
76
2284f202 77function buildAbsoluteFixturePath (path: string, customCIPath = false) {
b488ba1e 78 if (isAbsolute(path)) return path
ac81d1a0 79
07491f4b
C
80 if (customCIPath && process.env.GITHUB_WORKSPACE) {
81 return join(process.env.GITHUB_WORKSPACE, 'fixtures', path)
c928e136 82 }
c1c86c15 83
2a8c5d0a 84 return join(root(), 'server', 'tests', 'fixtures', path)
ac81d1a0
C
85}
86
b488ba1e
C
87function 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
74cd011b
C
95async function generateHighBitrateVideo () {
96 const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true)
97
2284f202
C
98 await ensureDir(dirname(tempFixturePath))
99
74cd011b
C
100 const exists = await pathExists(tempFixturePath)
101 if (!exists) {
9e3e4adc 102 console.log('Generating high bitrate video.')
74cd011b
C
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
a1587156 108 return new Promise<string>((res, rej) => {
74cd011b
C
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
837666fe
RK
123async 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) {
9e3e4adc
C
130 console.log('Generating video with framerate %d.', fps)
131
a1587156 132 return new Promise<string>((res, rej) => {
837666fe 133 ffmpeg()
c7f36e4f 134 .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ])
837666fe
RK
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
d218e7de
C
147async function getFileSize (path: string) {
148 const stats = await stat(path)
149
150 return stats.size
151}
152
0e1dc3e7
C
153// ---------------------------------------------------------------------------
154
155export {
0e1dc3e7
C
156 dateIsValid,
157 wait,
b488ba1e 158 areHttpImportTestsDisabled,
e2600d8b 159 buildServerDirectory,
26d21b78 160 webtorrentAdd,
d218e7de 161 getFileSize,
f05a1c30 162 immutableAssign,
9ee83eb9 163 testImage,
83ef31fe 164 isGithubCI,
ac81d1a0 165 buildAbsoluteFixturePath,
06c27593 166 testFileExistsOrNot,
74cd011b 167 root,
837666fe
RK
168 generateHighBitrateVideo,
169 generateVideoWithFramerate
0e1dc3e7 170}