]>
Commit | Line | Data |
---|---|---|
a1587156 | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
9ee83eb9 | 2 | |
7b0956ec | 3 | import * as chai from 'chai' |
ca5c612b C |
4 | import * as ffmpeg from 'fluent-ffmpeg' |
5 | import { ensureDir, pathExists, readFile, stat } from 'fs-extra' | |
2284f202 | 6 | import { basename, dirname, isAbsolute, join, resolve } from 'path' |
9ee83eb9 | 7 | import * as request from 'supertest' |
0e1dc3e7 | 8 | import * as WebTorrent from 'webtorrent' |
2d53be02 | 9 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' |
0e1dc3e7 | 10 | |
7b0956ec | 11 | const expect = chai.expect |
8d2be0ed | 12 | let webtorrent: WebTorrent.Instance |
0e1dc3e7 | 13 | |
a1587156 | 14 | function 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 | 19 | function 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 | ||
26 | function wait (milliseconds: number) { | |
27 | return new Promise(resolve => setTimeout(resolve, milliseconds)) | |
28 | } | |
29 | ||
30 | function 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 | 39 | function 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 |
48 | function buildServerDirectory (server: { internalServerNumber: number }, directory: string) { |
49 | return join(root(), 'test' + server.internalServerNumber, directory) | |
e2600d8b C |
50 | } |
51 | ||
9ee83eb9 | 52 | async 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 | |
e6dfa586 RK |
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") | |
9ee83eb9 C |
65 | } |
66 | ||
2284f202 | 67 | function buildAbsoluteFixturePath (path: string, customCIPath = false) { |
b488ba1e | 68 | if (isAbsolute(path)) return path |
ac81d1a0 | 69 | |
07491f4b C |
70 | if (customCIPath && process.env.GITHUB_WORKSPACE) { |
71 | return join(process.env.GITHUB_WORKSPACE, 'fixtures', path) | |
c928e136 | 72 | } |
c1c86c15 | 73 | |
2a8c5d0a | 74 | return join(root(), 'server', 'tests', 'fixtures', path) |
ac81d1a0 C |
75 | } |
76 | ||
b488ba1e C |
77 | function areHttpImportTestsDisabled () { |
78 | const disabled = process.env.DISABLE_HTTP_IMPORT_TESTS === 'true' | |
79 | ||
80 | if (disabled) console.log('Import tests are disabled') | |
81 | ||
82 | return disabled | |
83 | } | |
84 | ||
74cd011b C |
85 | async function generateHighBitrateVideo () { |
86 | const tempFixturePath = buildAbsoluteFixturePath('video_high_bitrate_1080p.mp4', true) | |
87 | ||
2284f202 C |
88 | await ensureDir(dirname(tempFixturePath)) |
89 | ||
74cd011b C |
90 | const exists = await pathExists(tempFixturePath) |
91 | if (!exists) { | |
9e3e4adc | 92 | console.log('Generating high bitrate video.') |
74cd011b C |
93 | |
94 | // Generate a random, high bitrate video on the fly, so we don't have to include | |
95 | // a large file in the repo. The video needs to have a certain minimum length so | |
96 | // that FFmpeg properly applies bitrate limits. | |
97 | // https://stackoverflow.com/a/15795112 | |
a1587156 | 98 | return new Promise<string>((res, rej) => { |
74cd011b C |
99 | ffmpeg() |
100 | .outputOptions([ '-f rawvideo', '-video_size 1920x1080', '-i /dev/urandom' ]) | |
101 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) | |
102 | .outputOptions([ '-maxrate 10M', '-bufsize 10M' ]) | |
103 | .output(tempFixturePath) | |
104 | .on('error', rej) | |
105 | .on('end', () => res(tempFixturePath)) | |
106 | .run() | |
107 | }) | |
108 | } | |
109 | ||
110 | return tempFixturePath | |
111 | } | |
112 | ||
837666fe RK |
113 | async function generateVideoWithFramerate (fps = 60) { |
114 | const tempFixturePath = buildAbsoluteFixturePath(`video_${fps}fps.mp4`, true) | |
115 | ||
116 | await ensureDir(dirname(tempFixturePath)) | |
117 | ||
118 | const exists = await pathExists(tempFixturePath) | |
119 | if (!exists) { | |
9e3e4adc C |
120 | console.log('Generating video with framerate %d.', fps) |
121 | ||
a1587156 | 122 | return new Promise<string>((res, rej) => { |
837666fe | 123 | ffmpeg() |
c7f36e4f | 124 | .outputOptions([ '-f rawvideo', '-video_size 1280x720', '-i /dev/urandom' ]) |
837666fe RK |
125 | .outputOptions([ '-ac 2', '-f s16le', '-i /dev/urandom', '-t 10' ]) |
126 | .outputOptions([ `-r ${fps}` ]) | |
127 | .output(tempFixturePath) | |
128 | .on('error', rej) | |
129 | .on('end', () => res(tempFixturePath)) | |
130 | .run() | |
131 | }) | |
132 | } | |
133 | ||
134 | return tempFixturePath | |
135 | } | |
136 | ||
d218e7de C |
137 | async function getFileSize (path: string) { |
138 | const stats = await stat(path) | |
139 | ||
140 | return stats.size | |
141 | } | |
142 | ||
0e1dc3e7 C |
143 | // --------------------------------------------------------------------------- |
144 | ||
145 | export { | |
0e1dc3e7 C |
146 | dateIsValid, |
147 | wait, | |
b488ba1e | 148 | areHttpImportTestsDisabled, |
e2600d8b | 149 | buildServerDirectory, |
26d21b78 | 150 | webtorrentAdd, |
d218e7de | 151 | getFileSize, |
f05a1c30 | 152 | immutableAssign, |
9ee83eb9 | 153 | testImage, |
ac81d1a0 | 154 | buildAbsoluteFixturePath, |
74cd011b | 155 | root, |
837666fe RK |
156 | generateHighBitrateVideo, |
157 | generateVideoWithFramerate | |
0e1dc3e7 | 158 | } |