@vpalmisano/webrtcperf 4.3.2 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/src/app.js CHANGED
@@ -19,6 +19,7 @@ const vmaf_1 = require("./vmaf");
19
19
  const path_1 = __importDefault(require("path"));
20
20
  const marked_terminal_1 = require("marked-terminal");
21
21
  const events_1 = require("events");
22
+ const docker_1 = require("./docker");
22
23
  // eslint-disable-next-line @typescript-eslint/no-require-imports
23
24
  const { marked } = require('marked');
24
25
  marked.use((0, marked_terminal_1.markedTerminal)({ reflowText: true, tab: 2 }));
@@ -188,12 +189,22 @@ exports.Application = Application;
188
189
  */
189
190
  async function main() {
190
191
  showHelpOrVersion();
192
+ const argv = process.argv.slice(2);
193
+ // Handle docker run.
194
+ if (argv.includes('--docker')) {
195
+ try {
196
+ await (0, docker_1.runWithDocker)(argv);
197
+ }
198
+ catch (err) {
199
+ log.error(`runWithDocker error: ${err.stack}`);
200
+ process.exit(1);
201
+ }
202
+ process.exit(0);
203
+ }
191
204
  let configs;
192
- if (process.argv.slice(2).includes('--prompt')) {
193
- const params = await (0, config_1.loadConfigFromPrompt)(process.argv
194
- .slice(2)
195
- .filter(s => !['--prompt', '--dry-run'].includes(s))
196
- .join(' '));
205
+ // Handle prompt.
206
+ if (argv.includes('--prompt')) {
207
+ const params = await (0, config_1.loadConfigFromPrompt)(argv.filter(s => !['--prompt', '--dry-run'].includes(s)).join(' '));
197
208
  if (process.argv.slice(2).includes('--dry-run')) {
198
209
  console.log(json5_1.default.stringify(params, null, 2));
199
210
  process.exit(0);
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSessionThrottleIndex, startThrottle, stopThrottle } from '@vpalmisano/throttler'\nimport { paramCase } from 'change-case'\nimport fs from 'fs'\nimport json5 from 'json5'\n\nimport { Config, getConfigDocs, loadConfig, loadConfigFromPrompt } from './config'\nimport { MediaPath, prepareFakeMedia } from './media'\nimport { Server } from './server'\nimport { Session } from './session'\nimport { Stats } from './stats'\nimport {\n checkChromeExecutable,\n getDockerLogsPath,\n logger,\n registerExitHandler,\n resolvePackagePath,\n sleep,\n startRandomActivateAudio,\n stopRandomActivateAudio,\n stopTimers,\n} from './utils'\nimport { calculateVisqolScore } from './visqol'\nimport { calculateVmafScore, convertToIvf, prepareVideo } from './vmaf'\nimport path from 'path'\nimport { markedTerminal } from 'marked-terminal'\nimport { EventEmitter } from 'events'\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst { marked } = require('marked')\nmarked.use(markedTerminal({ reflowText: true, tab: 2 }))\n\nconst log = logger('webrtcperf')\n\nfunction showHelpOrVersion(): void {\n if (process.argv.includes('--help') || process.argv.includes('-h')) {\n const docs = getConfigDocs()\n let out = marked.parse(`**Webrtcperf parameters**\n\n\\`--version\\` It shows the package version.\n`)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(docs).forEach(([name, value]: [string, any]) => {\n out += marked.parse(\n `\n\\`--${paramCase(name)}\\`\n${value.doc}\nDefault value: \\`${value.default}\\`\n`,\n )\n })\n console.log(out)\n process.exit(0)\n } else if (process.argv.includes('--version') || process.argv.includes('-v')) {\n const version = json5.parse(fs.readFileSync(resolvePackagePath('package.json')).toString()).version\n console.log(version)\n process.exit(0)\n }\n}\n\nexport class Application extends EventEmitter {\n readonly config: Config\n readonly stats: Stats\n readonly server?: Server\n private mediaPaths: MediaPath[] = []\n\n constructor(config: Config) {\n super()\n if (!config.startTimestamp) {\n config.startTimestamp = Date.now()\n }\n this.config = config\n this.stats = new Stats(config)\n if (config.serverPort) {\n this.server = new Server(config, this.stats)\n }\n }\n\n async start() {\n log.debug(`start (runDuration: ${this.config.runDuration})`)\n await this.stats.start()\n if (this.server) {\n await this.server.start()\n }\n const config = this.config\n\n // Handle vmaf commands.\n if (config.vmafPrepareVideo) {\n await prepareVideo(config, true)\n }\n if (config.vmafProcessVideo) {\n await convertToIvf(\n config.vmafProcessVideo,\n config.vmafVideoCrop,\n config.vmafKeepSourceFiles,\n config.vmafSkipDuplicated,\n )\n }\n\n // Handle sessions.\n if (config.sessions > 0) {\n // Prepare fake video and audio.\n if (config.videoPath && !this.mediaPaths.length) {\n for (const videoPath of config.videoPath.split(',')) {\n const ret = await prepareFakeMedia({ ...config, videoPath })\n this.mediaPaths.push(ret)\n }\n }\n\n // Network throttle.\n if (config.throttleConfig) {\n await startThrottle(config.throttleConfig)\n }\n\n // Download browser if necessary.\n if (!config.chromiumUrl && !config.chromiumPath) {\n await checkChromeExecutable()\n }\n\n // Start the local sessions.\n if (config.randomAudioPeriod) {\n startRandomActivateAudio(\n this.stats.sessions,\n config.randomAudioPeriod,\n config.randomAudioProbability,\n config.randomAudioRange,\n )\n }\n const spawnPeriod = 1000 / config.spawnRate\n log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`)\n const startTime = Date.now()\n for (let i = 0; i < config.sessions; i += 1) {\n const id = this.stats.consumeSessionId(config.tabsPerSession)\n await this.startSession(id, spawnPeriod)\n // If not the last session, sleep.\n if (i < config.sessions - 1) {\n await sleep(spawnPeriod)\n }\n }\n const elapsed = Math.round((Date.now() - startTime) / 1000)\n const spawnRate = (config.sessions * config.tabsPerSession) / elapsed\n log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`)\n }\n\n if (config.runDuration || config.vmafPath || config.visqolPath) {\n setTimeout(() => this.stop(), config.runDuration * 1000)\n }\n }\n\n private async startSession(id: number, spawnPeriod: number) {\n log.debug(`startSession ${id}`)\n const throttleIndex = getSessionThrottleIndex(id)\n const mediaPath = this.mediaPaths.length ? this.mediaPaths[id % this.mediaPaths.length] : undefined\n const session = new Session({\n ...this.config,\n mediaPath,\n spawnPeriod,\n id,\n throttleIndex,\n })\n session.once('stop', () => {\n console.warn(`Session ${id} stopped, reloading...`)\n setTimeout(() => this.startSession(id, spawnPeriod), spawnPeriod)\n })\n this.stats.addSession(session)\n await session.start()\n }\n\n private async postTest() {\n log.debug('postTest')\n\n // vmaf score.\n if (this.config.vmafPath) {\n console.log('Calculating VMAF score...')\n try {\n await calculateVmafScore(this.config)\n } catch (err: unknown) {\n log.error(`vmaf score error: ${(err as Error).stack}`)\n }\n }\n\n // visqol score\n if (this.config.visqolPath) {\n console.log('Calculating Visqol score...')\n try {\n await calculateVisqolScore(this.config)\n } catch (err: unknown) {\n log.error(`visqol score error: ${(err as Error).stack}`)\n }\n }\n }\n\n async stop(canceled = false) {\n log.debug(`stop (canceled: ${canceled})`)\n\n stopRandomActivateAudio()\n\n await this.stats.stop()\n\n if (this.config.throttleConfig) {\n await stopThrottle()\n }\n\n stopTimers()\n\n await this.postTest()\n\n // Copy docker logs to data directory.\n if (this.config.pageLogPath) {\n try {\n const logPath = await getDockerLogsPath()\n const dataDir = path.dirname(this.config.pageLogPath)\n await fs.promises.cp(logPath, path.resolve(dataDir, 'docker.log'))\n } catch (err: unknown) {\n log.debug(`docker logs not found: ${(err as Error).message}`)\n }\n }\n\n this.server?.stop()\n\n this.emit('stop', canceled)\n }\n}\n\n/**\n * Main function\n */\nasync function main(): Promise<void> {\n showHelpOrVersion()\n\n let configs: Config[]\n\n if (process.argv.slice(2).includes('--prompt')) {\n const params = await loadConfigFromPrompt(\n process.argv\n .slice(2)\n .filter(s => !['--prompt', '--dry-run'].includes(s))\n .join(' '),\n )\n if (process.argv.slice(2).includes('--dry-run')) {\n console.log(json5.stringify(params, null, 2))\n process.exit(0)\n }\n configs = await loadConfig(undefined, params)\n } else {\n configs = await loadConfig(process.argv[2])\n }\n\n if (!configs.length) throw new Error('No configuration found')\n\n let application: Application\n const runNext = () => {\n const config = configs.splice(0, 1)[0]\n\n application = new Application(config)\n application.once('stop', canceled => {\n if (!canceled && configs.length) {\n log.info(`Application stopped, running next (${configs.length} left)...`)\n runNext()\n } else {\n process.exit(0)\n }\n })\n return application.start()\n }\n\n const stop = async () => {\n console.log('Exiting...')\n await application.stop(true)\n }\n registerExitHandler(() => stop())\n\n await runNext()\n\n // Command line interface.\n if (process.stdin && process.stdin.setRawMode) {\n console.log('Press [q] to quit or [x] to exit immediately')\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on('data', async data => {\n log.debug('[stdin]', data[0])\n if (data[0] === 'q'.charCodeAt(0)) {\n try {\n await stop()\n } catch (err: unknown) {\n log.error(`stop error: ${(err as Error).stack}`)\n process.exit(1)\n }\n } else if (data[0] === 'x'.charCodeAt(0)) {\n process.exit(1)\n }\n })\n }\n}\n\nif (require.main === module) {\n main().catch(err => {\n console.error(err)\n process.exit(-1)\n })\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSessionThrottleIndex, startThrottle, stopThrottle } from '@vpalmisano/throttler'\nimport { paramCase } from 'change-case'\nimport fs from 'fs'\nimport json5 from 'json5'\n\nimport { Config, getConfigDocs, loadConfig, loadConfigFromPrompt } from './config'\nimport { MediaPath, prepareFakeMedia } from './media'\nimport { Server } from './server'\nimport { Session } from './session'\nimport { Stats } from './stats'\nimport {\n checkChromeExecutable,\n getDockerLogsPath,\n logger,\n registerExitHandler,\n resolvePackagePath,\n sleep,\n startRandomActivateAudio,\n stopRandomActivateAudio,\n stopTimers,\n} from './utils'\nimport { calculateVisqolScore } from './visqol'\nimport { calculateVmafScore, convertToIvf, prepareVideo } from './vmaf'\nimport path from 'path'\nimport { markedTerminal } from 'marked-terminal'\nimport { EventEmitter } from 'events'\nimport { runWithDocker } from './docker'\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst { marked } = require('marked')\nmarked.use(markedTerminal({ reflowText: true, tab: 2 }))\n\nconst log = logger('webrtcperf')\n\nfunction showHelpOrVersion(): void {\n if (process.argv.includes('--help') || process.argv.includes('-h')) {\n const docs = getConfigDocs()\n let out = marked.parse(`**Webrtcperf parameters**\n\n\\`--version\\` It shows the package version.\n`)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Object.entries(docs).forEach(([name, value]: [string, any]) => {\n out += marked.parse(\n `\n\\`--${paramCase(name)}\\`\n${value.doc}\nDefault value: \\`${value.default}\\`\n`,\n )\n })\n console.log(out)\n process.exit(0)\n } else if (process.argv.includes('--version') || process.argv.includes('-v')) {\n const version = json5.parse(fs.readFileSync(resolvePackagePath('package.json')).toString()).version\n console.log(version)\n process.exit(0)\n }\n}\n\nexport class Application extends EventEmitter {\n readonly config: Config\n readonly stats: Stats\n readonly server?: Server\n private mediaPaths: MediaPath[] = []\n\n constructor(config: Config) {\n super()\n if (!config.startTimestamp) {\n config.startTimestamp = Date.now()\n }\n this.config = config\n this.stats = new Stats(config)\n if (config.serverPort) {\n this.server = new Server(config, this.stats)\n }\n }\n\n async start() {\n log.debug(`start (runDuration: ${this.config.runDuration})`)\n await this.stats.start()\n if (this.server) {\n await this.server.start()\n }\n const config = this.config\n\n // Handle vmaf commands.\n if (config.vmafPrepareVideo) {\n await prepareVideo(config, true)\n }\n if (config.vmafProcessVideo) {\n await convertToIvf(\n config.vmafProcessVideo,\n config.vmafVideoCrop,\n config.vmafKeepSourceFiles,\n config.vmafSkipDuplicated,\n )\n }\n\n // Handle sessions.\n if (config.sessions > 0) {\n // Prepare fake video and audio.\n if (config.videoPath && !this.mediaPaths.length) {\n for (const videoPath of config.videoPath.split(',')) {\n const ret = await prepareFakeMedia({ ...config, videoPath })\n this.mediaPaths.push(ret)\n }\n }\n\n // Network throttle.\n if (config.throttleConfig) {\n await startThrottle(config.throttleConfig)\n }\n\n // Download browser if necessary.\n if (!config.chromiumUrl && !config.chromiumPath) {\n await checkChromeExecutable()\n }\n\n // Start the local sessions.\n if (config.randomAudioPeriod) {\n startRandomActivateAudio(\n this.stats.sessions,\n config.randomAudioPeriod,\n config.randomAudioProbability,\n config.randomAudioRange,\n )\n }\n const spawnPeriod = 1000 / config.spawnRate\n log.debug(`Starting ${config.sessions} sessions (spawnPeriod: ${spawnPeriod}ms)`)\n const startTime = Date.now()\n for (let i = 0; i < config.sessions; i += 1) {\n const id = this.stats.consumeSessionId(config.tabsPerSession)\n await this.startSession(id, spawnPeriod)\n // If not the last session, sleep.\n if (i < config.sessions - 1) {\n await sleep(spawnPeriod)\n }\n }\n const elapsed = Math.round((Date.now() - startTime) / 1000)\n const spawnRate = (config.sessions * config.tabsPerSession) / elapsed\n log.debug(`${config.sessions * config.tabsPerSession} pages started in ${elapsed}s (${spawnRate.toFixed(2)}/s)`)\n }\n\n if (config.runDuration || config.vmafPath || config.visqolPath) {\n setTimeout(() => this.stop(), config.runDuration * 1000)\n }\n }\n\n private async startSession(id: number, spawnPeriod: number) {\n log.debug(`startSession ${id}`)\n const throttleIndex = getSessionThrottleIndex(id)\n const mediaPath = this.mediaPaths.length ? this.mediaPaths[id % this.mediaPaths.length] : undefined\n const session = new Session({\n ...this.config,\n mediaPath,\n spawnPeriod,\n id,\n throttleIndex,\n })\n session.once('stop', () => {\n console.warn(`Session ${id} stopped, reloading...`)\n setTimeout(() => this.startSession(id, spawnPeriod), spawnPeriod)\n })\n this.stats.addSession(session)\n await session.start()\n }\n\n private async postTest() {\n log.debug('postTest')\n\n // vmaf score.\n if (this.config.vmafPath) {\n console.log('Calculating VMAF score...')\n try {\n await calculateVmafScore(this.config)\n } catch (err: unknown) {\n log.error(`vmaf score error: ${(err as Error).stack}`)\n }\n }\n\n // visqol score\n if (this.config.visqolPath) {\n console.log('Calculating Visqol score...')\n try {\n await calculateVisqolScore(this.config)\n } catch (err: unknown) {\n log.error(`visqol score error: ${(err as Error).stack}`)\n }\n }\n }\n\n async stop(canceled = false) {\n log.debug(`stop (canceled: ${canceled})`)\n\n stopRandomActivateAudio()\n\n await this.stats.stop()\n\n if (this.config.throttleConfig) {\n await stopThrottle()\n }\n\n stopTimers()\n\n await this.postTest()\n\n // Copy docker logs to data directory.\n if (this.config.pageLogPath) {\n try {\n const logPath = await getDockerLogsPath()\n const dataDir = path.dirname(this.config.pageLogPath)\n await fs.promises.cp(logPath, path.resolve(dataDir, 'docker.log'))\n } catch (err: unknown) {\n log.debug(`docker logs not found: ${(err as Error).message}`)\n }\n }\n\n this.server?.stop()\n\n this.emit('stop', canceled)\n }\n}\n\n/**\n * Main function\n */\nasync function main(): Promise<void> {\n showHelpOrVersion()\n\n const argv = process.argv.slice(2)\n\n // Handle docker run.\n if (argv.includes('--docker')) {\n try {\n await runWithDocker(argv)\n } catch (err: unknown) {\n log.error(`runWithDocker error: ${(err as Error).stack}`)\n process.exit(1)\n }\n process.exit(0)\n }\n\n let configs: Config[]\n\n // Handle prompt.\n if (argv.includes('--prompt')) {\n const params = await loadConfigFromPrompt(argv.filter(s => !['--prompt', '--dry-run'].includes(s)).join(' '))\n if (process.argv.slice(2).includes('--dry-run')) {\n console.log(json5.stringify(params, null, 2))\n process.exit(0)\n }\n configs = await loadConfig(undefined, params)\n } else {\n configs = await loadConfig(process.argv[2])\n }\n\n if (!configs.length) throw new Error('No configuration found')\n\n let application: Application\n const runNext = () => {\n const config = configs.splice(0, 1)[0]\n\n application = new Application(config)\n application.once('stop', canceled => {\n if (!canceled && configs.length) {\n log.info(`Application stopped, running next (${configs.length} left)...`)\n runNext()\n } else {\n process.exit(0)\n }\n })\n return application.start()\n }\n\n const stop = async () => {\n console.log('Exiting...')\n await application.stop(true)\n }\n registerExitHandler(() => stop())\n\n await runNext()\n\n // Command line interface.\n if (process.stdin && process.stdin.setRawMode) {\n console.log('Press [q] to quit or [x] to exit immediately')\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on('data', async data => {\n log.debug('[stdin]', data[0])\n if (data[0] === 'q'.charCodeAt(0)) {\n try {\n await stop()\n } catch (err: unknown) {\n log.error(`stop error: ${(err as Error).stack}`)\n process.exit(1)\n }\n } else if (data[0] === 'x'.charCodeAt(0)) {\n process.exit(1)\n }\n })\n }\n}\n\nif (require.main === module) {\n main().catch(err => {\n console.error(err)\n process.exit(-1)\n })\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function runWithDocker(argv: string[]): Promise<void>;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runWithDocker = runWithDocker;
7
+ const path_1 = __importDefault(require("path"));
8
+ const dockerode_1 = __importDefault(require("dockerode"));
9
+ const utils_1 = require("./utils");
10
+ const config_1 = require("./config");
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const log = (0, utils_1.logger)('webrtcperf:docker');
13
+ async function runWithDocker(argv) {
14
+ const docker = new dockerode_1.default();
15
+ const configPath = argv.filter(s => s !== '--docker')[0];
16
+ if (!configPath)
17
+ throw new Error('No configuration file specified');
18
+ const configName = path_1.default.basename(configPath);
19
+ const config = (await (0, config_1.loadConfig)(configPath))[0];
20
+ const startTimestamp = Date.now();
21
+ const dataDir = path_1.default.resolve(path_1.default.dirname(configPath), 'logs', `${startTimestamp}`);
22
+ await fs_1.default.promises.mkdir(dataDir, { recursive: true });
23
+ const binds = [
24
+ `${path_1.default.resolve(configPath)}:/config/${configName}:ro`,
25
+ '/dev/shm:/dev/shm',
26
+ `${dataDir}:/data`,
27
+ '/tmp/webrtcperf-cache:/root/.webrtcperf',
28
+ ];
29
+ if (config.scriptPath) {
30
+ const scriptName = path_1.default.basename(config.scriptPath);
31
+ binds.push(`${path_1.default.resolve(config.scriptPath)}:/scripts/${scriptName}:ro`);
32
+ }
33
+ if (process.env.DEBUG_SRC) {
34
+ binds.push(`${(0, utils_1.resolvePackagePath)('app.min.js')}:/app/app.min.js:ro`);
35
+ }
36
+ const portBindings = {};
37
+ const exposedPorts = {};
38
+ if (config.debuggingPort) {
39
+ for (let i = 0; i < config.sessions; i++) {
40
+ const port = `${config.debuggingPort + i}/tcp`;
41
+ portBindings[port] = [{ HostPort: `${config.debuggingPort + i}` }];
42
+ exposedPorts[port] = {};
43
+ }
44
+ }
45
+ const env = [
46
+ `DEBUG_LEVEL=${process.env.DEBUG_LEVEL || 'info'}`,
47
+ 'SHOW_PAGE_LOG=false',
48
+ 'SHOW_STATS=false',
49
+ 'SERVER_PORT=5000',
50
+ 'SERVER_USE_HTTPS=true',
51
+ 'SERVER_DATA=/data',
52
+ `START_TIMESTAMP=${startTimestamp}`,
53
+ `STATS_PATH=/data/stats.csv`,
54
+ `PAGE_LOG_PATH=/data/page.log`,
55
+ `DETAILED_STATS_PATH=/data/detailed-stats.csv`,
56
+ ];
57
+ if (config.scriptPath) {
58
+ const scriptName = path_1.default.basename(config.scriptPath);
59
+ env.push(`SCRIPT_PATH=/scripts/${scriptName}`);
60
+ }
61
+ if (config.debuggingPort) {
62
+ env.push(`DEBUGGING_PORT=${config.debuggingPort}`);
63
+ }
64
+ if (config.prometheusPushgateway.startsWith('http://localhost')) {
65
+ env.push('PROMETHEUS_PUSHGATEWAY=http://pushgateway:9091');
66
+ }
67
+ const containerConfig = {
68
+ Image: 'ghcr.io/vpalmisano/webrtcperf:devel',
69
+ name: 'webrtcperf',
70
+ Cmd: [`/config/${configName}`],
71
+ HostConfig: {
72
+ Binds: binds,
73
+ PortBindings: portBindings,
74
+ CapAdd: ['NET_ADMIN'],
75
+ NetworkMode: config.prometheusPushgateway.startsWith('http://localhost') ? 'prometheus-stack_default' : 'bridge',
76
+ },
77
+ Env: env,
78
+ AttachStdin: true,
79
+ AttachStdout: true,
80
+ AttachStderr: true,
81
+ Tty: true,
82
+ OpenStdin: true,
83
+ StdinOnce: true,
84
+ ExposedPorts: exposedPorts,
85
+ };
86
+ try {
87
+ if (!process.env.DEBUG_SRC) {
88
+ log.info('Pulling latest development image...');
89
+ await docker.pull('ghcr.io/vpalmisano/webrtcperf:devel');
90
+ }
91
+ try {
92
+ const existingContainer = await docker.getContainer('webrtcperf');
93
+ await existingContainer.remove({ force: true });
94
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
95
+ }
96
+ catch (err) {
97
+ // Container doesn't exist, continue
98
+ }
99
+ const container = await docker.createContainer(containerConfig);
100
+ await container.start();
101
+ const stream = await container.attach({
102
+ stream: true,
103
+ stdin: true,
104
+ stdout: true,
105
+ stderr: true,
106
+ });
107
+ process.stdin.pipe(stream);
108
+ stream.pipe(process.stdout);
109
+ await new Promise(resolve => {
110
+ container.wait((err, data) => {
111
+ if (err)
112
+ log.error('Error waiting for container:', data, err.stack);
113
+ resolve(data);
114
+ });
115
+ });
116
+ await container.remove();
117
+ }
118
+ catch (error) {
119
+ log.error('Docker operation failed:', error);
120
+ throw error;
121
+ }
122
+ }
123
+ //# sourceMappingURL=docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/docker.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path'\nimport Docker from 'dockerode'\nimport { logger, resolvePackagePath } from './utils'\nimport { loadConfig } from './config'\nimport fs from 'fs'\n\nconst log = logger('webrtcperf:docker')\n\nexport async function runWithDocker(argv: string[]) {\n const docker = new Docker()\n const configPath = argv.filter(s => s !== '--docker')[0]\n if (!configPath) throw new Error('No configuration file specified')\n const configName = path.basename(configPath)\n const config = (await loadConfig(configPath))[0]\n\n const startTimestamp = Date.now()\n const dataDir = path.resolve(path.dirname(configPath), 'logs', `${startTimestamp}`)\n await fs.promises.mkdir(dataDir, { recursive: true })\n\n const binds: string[] = [\n `${path.resolve(configPath)}:/config/${configName}:ro`,\n '/dev/shm:/dev/shm',\n `${dataDir}:/data`,\n '/tmp/webrtcperf-cache:/root/.webrtcperf',\n ]\n\n if (config.scriptPath) {\n const scriptName = path.basename(config.scriptPath)\n binds.push(`${path.resolve(config.scriptPath)}:/scripts/${scriptName}:ro`)\n }\n\n if (process.env.DEBUG_SRC) {\n binds.push(`${resolvePackagePath('app.min.js')}:/app/app.min.js:ro`)\n }\n\n const portBindings: Docker.PortMap = {}\n const exposedPorts: { [portAndProtocol: string]: object } = {}\n if (config.debuggingPort) {\n for (let i = 0; i < config.sessions; i++) {\n const port = `${config.debuggingPort + i}/tcp`\n portBindings[port] = [{ HostPort: `${config.debuggingPort + i}` }]\n exposedPorts[port] = {}\n }\n }\n\n const env = [\n `DEBUG_LEVEL=${process.env.DEBUG_LEVEL || 'info'}`,\n 'SHOW_PAGE_LOG=false',\n 'SHOW_STATS=false',\n 'SERVER_PORT=5000',\n 'SERVER_USE_HTTPS=true',\n 'SERVER_DATA=/data',\n `START_TIMESTAMP=${startTimestamp}`,\n `STATS_PATH=/data/stats.csv`,\n `PAGE_LOG_PATH=/data/page.log`,\n `DETAILED_STATS_PATH=/data/detailed-stats.csv`,\n ]\n\n if (config.scriptPath) {\n const scriptName = path.basename(config.scriptPath)\n env.push(`SCRIPT_PATH=/scripts/${scriptName}`)\n }\n\n if (config.debuggingPort) {\n env.push(`DEBUGGING_PORT=${config.debuggingPort}`)\n }\n\n if (config.prometheusPushgateway.startsWith('http://localhost')) {\n env.push('PROMETHEUS_PUSHGATEWAY=http://pushgateway:9091')\n }\n\n const containerConfig: Docker.ContainerCreateOptions = {\n Image: 'ghcr.io/vpalmisano/webrtcperf:devel',\n name: 'webrtcperf',\n Cmd: [`/config/${configName}`],\n HostConfig: {\n Binds: binds,\n PortBindings: portBindings,\n CapAdd: ['NET_ADMIN'],\n NetworkMode: config.prometheusPushgateway.startsWith('http://localhost') ? 'prometheus-stack_default' : 'bridge',\n },\n Env: env,\n AttachStdin: true,\n AttachStdout: true,\n AttachStderr: true,\n Tty: true,\n OpenStdin: true,\n StdinOnce: true,\n ExposedPorts: exposedPorts,\n }\n\n try {\n if (!process.env.DEBUG_SRC) {\n log.info('Pulling latest development image...')\n await docker.pull('ghcr.io/vpalmisano/webrtcperf:devel')\n }\n\n try {\n const existingContainer = await docker.getContainer('webrtcperf')\n await existingContainer.remove({ force: true })\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (err: unknown) {\n // Container doesn't exist, continue\n }\n\n const container = await docker.createContainer(containerConfig)\n await container.start()\n\n const stream = await container.attach({\n stream: true,\n stdin: true,\n stdout: true,\n stderr: true,\n })\n\n process.stdin.pipe(stream)\n stream.pipe(process.stdout)\n\n await new Promise(resolve => {\n container.wait((err: Error, data: { StatusCode: number }) => {\n if (err) log.error('Error waiting for container:', data, err.stack)\n resolve(data)\n })\n })\n\n await container.remove()\n } catch (error) {\n log.error('Docker operation failed:', error)\n throw error\n }\n}\n"]}
@@ -405,7 +405,7 @@ class Session extends events_1.default {
405
405
  deviceScaleFactor: this.deviceScaleFactor,
406
406
  isMobile: false,
407
407
  hasTouch: false,
408
- isLandscape: false,
408
+ isLandscape: true,
409
409
  },
410
410
  });
411
411
  }
@@ -525,7 +525,7 @@ try {
525
525
  } catch (err) {
526
526
  console.error('[webrtcperf] Error parsing scriptParams:', err);
527
527
  webrtcperf.params = {};
528
- }
528
+ };
529
529
  `;
530
530
  if (this.serverPort) {
531
531
  cmd += `\
@@ -611,15 +611,22 @@ webrtcperf.config.AUDIO_URL = "http${this.serverUseHttps ? 's' : ''}://localhost
611
611
  if (this.localStorage) {
612
612
  log.debug('Using localStorage:', this.localStorage);
613
613
  Object.entries(this.localStorage).map(([key, value]) => {
614
- cmd += `localStorage.setItem('${key}', '${JSON.stringify(value)}');\n`;
614
+ cmd += `window.localStorage.setItem('${key}', ${JSON.stringify(value)});\n`;
615
615
  });
616
616
  }
617
617
  if (this.sessionStorage) {
618
618
  log.debug('Using sessionStorage:', this.sessionStorage);
619
619
  Object.entries(this.sessionStorage).map(([key, value]) => {
620
- cmd += `sessionStorage.setItem('${key}', '${JSON.stringify(value)}');\n`;
620
+ cmd += `window.sessionStorage.setItem('${key}', ${JSON.stringify(value)});\n`;
621
621
  });
622
622
  }
623
+ cmd += `
624
+ Object.defineProperty(window.screen, 'width', { value: ${this.windowWidth}, writable: false });
625
+ Object.defineProperty(window.screen, 'height', { value: ${this.windowHeight}, writable: false });
626
+ Object.defineProperty(window.screen, 'availWidth', { value: ${this.windowWidth}, writable: false });
627
+ Object.defineProperty(window.screen, 'availHeight', { value: ${this.windowHeight}, writable: false });
628
+ Object.defineProperty(window.screen.orientation, 'type', { value: 'landscape-primary', writable: false });
629
+ `;
623
630
  log.debug('init command:', cmd);
624
631
  await page.evaluateOnNewDocument(cmd);
625
632
  // Clear cookies.
@@ -962,7 +969,7 @@ webrtcperf.config.AUDIO_URL = "http${this.serverUseHttps ? 's' : ''}://localhost
962
969
  if (this.showPageLog || saveFile) {
963
970
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
964
971
  page.on('pageerror', async (error) => {
965
- const text = `pageerror: ${error.message?.message || error.message} - ${error.message?.stack || error.stack}`;
972
+ const text = `pageerror: ${error?.message?.message || error?.message || error} - ${error?.message?.stack || error?.stack}`;
966
973
  await this.onPageMessage(index, 'error', text, saveFile);
967
974
  });
968
975
  page.on('requestfailed', async (request) => {