/*
* Copyright (C) 2020 Linux Studio Plugins Project
* (C) 2020 Vladimir Sadovnikov
*
* This file is part of lsp-plugins
* Created on: 11 февр. 2019 г.
*
* lsp-plugins is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* lsp-plugins is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with lsp-plugins. If not, see .
*/
#ifndef TEST_MAIN_CONFIG_H_
#define TEST_MAIN_CONFIG_H_
#include
#include
#include
#include
#include
#include
#include
namespace lsp
{
enum test_mode_t
{
UNKNOWN,
PTEST,
UTEST,
MTEST
};
typedef struct config_t
{
public:
mode_t mode;
bool fork;
bool verbose;
bool debug;
bool list_all;
bool mtrace;
bool ilist;
bool sysinfo;
bool is_child;
size_t threads;
const char *executable;
const char *outfile;
const char *tracepath;
cvector list;
cvector ignore;
cvector args;
#ifdef PLATFORM_WINDOWS
size_t utf8_argc;
char **utf8_argv;
#endif /* PLATFORM_WINDOWS */
public:
explicit config_t();
~config_t() { clear(); }
status_t parse(FILE *out, int argc, const char **argv);
status_t print_usage(FILE *out, bool detailed=false);
void clear();
} config_t;
status_t config_t::print_usage(FILE *out, bool detailed)
{
fputs("USAGE: {utest|ptest|mtest} [args...] [test name...]\n", out);
if (!detailed)
return STATUS_INSUFFICIENT;
fputs(" First argument:\n", out);
fputs(" utest Unit testing subsystem\n", out);
fputs(" ptest Performance testing subsystem\n", out);
fputs(" mtest Manual testing subsystem\n", out);
fputs(" Additional arguments:\n", out);
fputs(" -a, --args [args...] Pass arguments to test\n", out);
fputs(" -d, --debug Disable time restrictions for unit tests\n", out);
fputs(" for debugging purposes\n", out);
fputs(" -e, --execute Launch tests specified after this switch\n", out);
fputs(" -f, --fork Fork child processes (opposite to --nofork)\n", out);
fputs(" -h, --help Display help\n", out);
fputs(" -i, --ignore Ignore tests specified after this switch\n", out);
fputs(" -j, --jobs Set number of job workers for unit tests\n", out);
fputs(" -l, --list List all available tests\n", out);
#ifdef PLATFORM_LINUX
fputs(" -mt, --mtrace Enable mtrace log\n", out);
#endif /* PLATFORM_LINUX */
fputs(" -nf, --nofork Do not fork child processes (for better \n", out);
fputs(" debugging capabilities)\n", out);
#ifdef PLATFORM_LINUX
fputs(" -nt, --nomtrace Disable mtrace log\n", out);
#endif /* PLATFORM_LINUX */
fputs(" -nsi, --nosysinfo Do not output system information\n", out);
fputs(" -o, --outfile file Output performance test statistics to specified file\n", out);
fputs(" -s, --silent Do not output additional information from tests\n", out);
fputs(" -si, --sysinfo Output system information\n", out);
fputs(" -t, --tracepath path Override default trace path with specified value\n", out);
fputs(" -v, --verbose Output additional information from tests\n", out);
return STATUS_INSUFFICIENT;
}
status_t config_t::parse(FILE *out, int argc, const char **argv)
{
clear();
#if defined(PLATFORM_WINDOWS)
// Get number of processors for system
SYSTEM_INFO os_sysinfo;
GetSystemInfo(&os_sysinfo);
threads = os_sysinfo.dwNumberOfProcessors;
// Get command line
LPWSTR cmdline = GetCommandLineW();
int nargs = 0;
LPWSTR *arglist = CommandLineToArgvW(cmdline, &nargs);
if ((arglist == NULL) || (nargs < 1))
{
fprintf(stderr, "Error obtaining command-line arguments\n");
fflush(stderr);
return STATUS_UNKNOWN_ERR;
}
// Convert UTF-16-encoded command line arguments to UTF-8-encoded
utf8_argc = nargs;
utf8_argv = reinterpret_cast(malloc(nargs * sizeof(char *)));
for (size_t i=0; i(utf8_argv);
#else
threads = sysconf(_SC_NPROCESSORS_ONLN);
#endif /* PLATFORM_WINDOWS */
if (argc < 2)
return print_usage(out);
executable = argv[0];
if (!strcmp(argv[1], "ptest"))
mode = PTEST;
else if (!strcmp(argv[1], "utest"))
mode = UTEST;
else if (!strcmp(argv[1], "mtest"))
mode = MTEST;
else if ((!strcmp(argv[1], "--help")) || ((!strcmp(argv[1], "-h"))))
return print_usage(out, true);
else
return print_usage(out);
for (int i=2; i= argc)
{
fprintf(stderr, "Not specified trace path\n");
return STATUS_INVALID_VALUE;
}
tracepath = argv[i];
}
else if ((!strcmp(argv[i], "--outfile")) || (!strcmp(argv[i], "-o")))
{
if ((++i) >= argc)
{
fprintf(stderr, "Not specified name of output file\n");
return STATUS_INVALID_VALUE;
}
outfile = argv[i];
}
else if ((!strcmp(argv[i], "--args")) || (!strcmp(argv[i], "-a")))
{
while (++i < argc)
args.add(const_cast(argv[i]));
}
else if ((!strcmp(argv[i], "--jobs")) || (!strcmp(argv[i], "-j")))
{
if ((++i) >= argc)
{
fprintf(stderr, "Not specified number of jobs for --jobs parameter\n");
return STATUS_INVALID_VALUE;
}
errno = 0;
char *end = NULL;
long jobs = strtol(argv[i], &end, 10);
if ((errno != 0) || ((*end) != '\0') || (jobs <= 0))
{
fprintf(stderr, "Invalid value for --jobs parameter: %s\n", argv[i]);
return STATUS_INVALID_VALUE;
}
threads = size_t(jobs);
}
else if ((!strcmp(argv[i], "--help")) || ((!strcmp(argv[i], "-h"))))
return print_usage(out, true);
else if ((!strcmp(argv[i], "--ignore")) || ((!strcmp(argv[i], "-i"))))
ilist = true;
else if ((!strcmp(argv[i], "--execute")) || ((!strcmp(argv[i], "-e"))))
ilist = false;
#ifdef PLATFORM_WINDOWS
else if (!strcmp(argv[i], "--run-as-nested-process"))
is_child = true;
#endif /* PLATFORM_WINDOWS */
else
{
if (ilist)
ignore.add(const_cast(argv[i]));
else
list.add(const_cast(argv[i]));
}
}
return 0;
}
config_t::config_t()
{
mode = UNKNOWN;
fork = true;
verbose = false;
debug = false;
list_all = false;
mtrace = false;
ilist = false;
sysinfo = true;
is_child = false;
executable = NULL;
tracepath = "/tmp/lsp-plugins-trace";
outfile = NULL;
threads = 1;
#if defined(PLATFORM_WINDOWS)
utf8_argc = 0;
utf8_argv = NULL;
#endif
}
void config_t::clear()
{
#if defined(PLATFORM_WINDOWS)
if (utf8_argv != NULL)
{
for (size_t i=0; i