added testing of clang-tidy invocation to executor tests / also some cleanups (#5514)
This commit is contained in:
parent
eb076d877b
commit
8dee551cad
4
Makefile
4
Makefile
|
@ -802,7 +802,7 @@ test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkpo
|
|||
test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp
|
||||
|
||||
test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h
|
||||
test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp
|
||||
|
||||
test/testsettings.o: test/testsettings.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
|
||||
|
@ -841,7 +841,7 @@ test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/ex
|
|||
test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp
|
||||
|
||||
test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h
|
||||
test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp
|
||||
|
||||
test/testtimer.o: test/testtimer.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h
|
||||
|
|
|
@ -325,9 +325,9 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
|
|||
returnValue = executor.check();
|
||||
} else {
|
||||
#if defined(THREADING_MODEL_THREAD)
|
||||
ThreadExecutor executor(mFiles, settings, settings.nomsg, *this);
|
||||
ThreadExecutor executor(mFiles, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
|
||||
#elif defined(THREADING_MODEL_FORK)
|
||||
ProcessExecutor executor(mFiles, settings, settings.nomsg, *this);
|
||||
ProcessExecutor executor(mFiles, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
|
||||
#endif
|
||||
returnValue = executor.check();
|
||||
}
|
||||
|
|
|
@ -62,8 +62,9 @@ enum class Color;
|
|||
using std::memset;
|
||||
|
||||
|
||||
ProcessExecutor::ProcessExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
|
||||
ProcessExecutor::ProcessExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand)
|
||||
: Executor(files, settings, suppressions, errorLogger)
|
||||
, mExecuteCommand(std::move(executeCommand))
|
||||
{
|
||||
assert(mSettings.jobs > 1);
|
||||
}
|
||||
|
@ -272,7 +273,7 @@ unsigned int ProcessExecutor::check()
|
|||
close(pipes[0]);
|
||||
|
||||
PipeWriter pipewriter(pipes[1]);
|
||||
CppCheck fileChecker(pipewriter, false, CppCheckExecutor::executeCommand);
|
||||
CppCheck fileChecker(pipewriter, false, mExecuteCommand);
|
||||
fileChecker.settings() = mSettings;
|
||||
unsigned int resultOfCheck = 0;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef PROCESSEXECUTOR_H
|
||||
#define PROCESSEXECUTOR_H
|
||||
|
||||
#include "cppcheck.h"
|
||||
#include "executor.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
@ -38,7 +39,7 @@ class Suppressions;
|
|||
*/
|
||||
class ProcessExecutor : public Executor {
|
||||
public:
|
||||
ProcessExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
|
||||
ProcessExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand);
|
||||
ProcessExecutor(const ProcessExecutor &) = delete;
|
||||
void operator=(const ProcessExecutor &) = delete;
|
||||
|
||||
|
@ -63,6 +64,8 @@ private:
|
|||
* @param msg The error message
|
||||
*/
|
||||
void reportInternalChildErr(const std::string &childname, const std::string &msg);
|
||||
|
||||
CppCheck::ExecuteCmdFn mExecuteCommand;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -41,8 +41,9 @@
|
|||
|
||||
enum class Color;
|
||||
|
||||
ThreadExecutor::ThreadExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger)
|
||||
ThreadExecutor::ThreadExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand)
|
||||
: Executor(files, settings, suppressions, errorLogger)
|
||||
, mExecuteCommand(std::move(executeCommand))
|
||||
{
|
||||
assert(mSettings.jobs > 1);
|
||||
}
|
||||
|
@ -82,8 +83,8 @@ private:
|
|||
class ThreadData
|
||||
{
|
||||
public:
|
||||
ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::map<std::string, std::size_t> &files, const std::list<ImportProject::FileSettings> &fileSettings)
|
||||
: mFiles(files), mFileSettings(fileSettings), mSettings(settings), logForwarder(threadExecutor, errorLogger)
|
||||
ThreadData(ThreadExecutor &threadExecutor, ErrorLogger &errorLogger, const Settings &settings, const std::map<std::string, std::size_t> &files, const std::list<ImportProject::FileSettings> &fileSettings, CppCheck::ExecuteCmdFn executeCommand)
|
||||
: mFiles(files), mFileSettings(fileSettings), mSettings(settings), mExecuteCommand(std::move(executeCommand)), logForwarder(threadExecutor, errorLogger)
|
||||
{
|
||||
mItNextFile = mFiles.begin();
|
||||
mItNextFileSettings = mFileSettings.begin();
|
||||
|
@ -115,7 +116,7 @@ public:
|
|||
}
|
||||
|
||||
unsigned int check(ErrorLogger &errorLogger, const std::string *file, const ImportProject::FileSettings *fs) const {
|
||||
CppCheck fileChecker(errorLogger, false, CppCheckExecutor::executeCommand);
|
||||
CppCheck fileChecker(errorLogger, false, mExecuteCommand);
|
||||
fileChecker.settings() = mSettings; // this is a copy
|
||||
|
||||
unsigned int result;
|
||||
|
@ -153,6 +154,7 @@ private:
|
|||
|
||||
std::mutex mFileSync;
|
||||
const Settings &mSettings;
|
||||
CppCheck::ExecuteCmdFn mExecuteCommand;
|
||||
|
||||
public:
|
||||
SyncLogForwarder logForwarder;
|
||||
|
@ -180,7 +182,7 @@ unsigned int ThreadExecutor::check()
|
|||
std::vector<std::future<unsigned int>> threadFutures;
|
||||
threadFutures.reserve(mSettings.jobs);
|
||||
|
||||
ThreadData data(*this, mErrorLogger, mSettings, mFiles, mSettings.project.fileSettings);
|
||||
ThreadData data(*this, mErrorLogger, mSettings, mFiles, mSettings.project.fileSettings, mExecuteCommand);
|
||||
|
||||
for (unsigned int i = 0; i < mSettings.jobs; ++i) {
|
||||
try {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef THREADEXECUTOR_H
|
||||
#define THREADEXECUTOR_H
|
||||
|
||||
#include "cppcheck.h"
|
||||
#include "executor.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
@ -37,14 +38,16 @@ class Suppressions;
|
|||
* all files using threads.
|
||||
*/
|
||||
class ThreadExecutor : public Executor {
|
||||
friend class SyncLogForwarder;
|
||||
|
||||
public:
|
||||
ThreadExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger);
|
||||
ThreadExecutor(const std::map<std::string, std::size_t> &files, const Settings &settings, Suppressions &suppressions, ErrorLogger &errorLogger, CppCheck::ExecuteCmdFn executeCommand);
|
||||
ThreadExecutor(const ThreadExecutor &) = delete;
|
||||
void operator=(const ThreadExecutor &) = delete;
|
||||
|
||||
unsigned int check() override;
|
||||
|
||||
friend class SyncLogForwarder;
|
||||
CppCheck::ExecuteCmdFn mExecuteCommand;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -54,8 +54,8 @@ class CPPCHECKLIB Library {
|
|||
// TODO: get rid of this
|
||||
friend class TestSymbolDatabase; // For testing only
|
||||
friend class TestSingleExecutorBase; // For testing only
|
||||
friend class TestThreadExecutor; // For testing only
|
||||
friend class TestProcessExecutor; // For testing only
|
||||
friend class TestThreadExecutorBase; // For testing only
|
||||
friend class TestProcessExecutorBase; // For testing only
|
||||
|
||||
public:
|
||||
Library() = default;
|
||||
|
|
|
@ -34,15 +34,18 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class TestProcessExecutor : public TestFixture {
|
||||
class TestProcessExecutorBase : public TestFixture {
|
||||
public:
|
||||
TestProcessExecutor() : TestFixture("TestProcessExecutor") {}
|
||||
TestProcessExecutorBase(const char * const name, bool useFS) : TestFixture(name), useFS(useFS) {}
|
||||
|
||||
private:
|
||||
Settings settings = settingsBuilder().library("std.cfg").build();
|
||||
bool useFS;
|
||||
|
||||
static std::string fprefix()
|
||||
std::string fprefix() const
|
||||
{
|
||||
if (useFS)
|
||||
return "processfs";
|
||||
return "process";
|
||||
}
|
||||
|
||||
|
@ -53,6 +56,10 @@ private:
|
|||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
bool clangTidy = false;
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
std::vector<std::string> args;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -63,35 +70,67 @@ private:
|
|||
errout.str("");
|
||||
output.str("");
|
||||
|
||||
Settings s = settings;
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
std::ostringstream oss;
|
||||
oss << fprefix() << "_" << i << ".cpp";
|
||||
filemap[oss.str()] = data.size();
|
||||
std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp";
|
||||
filemap[f_s] = data.size();
|
||||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = std::move(f_s);
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& f : opt.filesList)
|
||||
{
|
||||
filemap[f] = data.size();
|
||||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = f;
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings s = settings;
|
||||
s.jobs = jobs;
|
||||
s.showtime = opt.showtime;
|
||||
settings.quiet = opt.quiet;
|
||||
s.quiet = opt.quiet;
|
||||
if (opt.plistOutput)
|
||||
s.plistOutput = opt.plistOutput;
|
||||
// TODO: test with settings.project.fileSettings;
|
||||
ProcessExecutor executor(filemap, s, s.nomsg, *this);
|
||||
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
std::vector<std::string> args;
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
auto executeFn = [&executeCommandCalled, &exe, &args](std::string e,std::vector<std::string> a,std::string,std::string&){
|
||||
executeCommandCalled = true;
|
||||
exe = std::move(e);
|
||||
args = std::move(a);
|
||||
return EXIT_SUCCESS;
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
scopedfiles.reserve(filemap.size());
|
||||
for (std::map<std::string, std::size_t>::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)
|
||||
scopedfiles.emplace_back(new ScopedFile(i->first, data));
|
||||
|
||||
// clear files list so only fileSettings are used
|
||||
if (useFS)
|
||||
filemap.clear();
|
||||
|
||||
ProcessExecutor executor(filemap, s, s.nomsg, *this, executeFn);
|
||||
ASSERT_EQUALS(result, executor.check());
|
||||
ASSERT_EQUALS(opt.executeCommandCalled, executeCommandCalled);
|
||||
ASSERT_EQUALS(opt.exe, exe);
|
||||
ASSERT_EQUALS(opt.args.size(), args.size());
|
||||
for (int i = 0; i < args.size(); ++i)
|
||||
{
|
||||
ASSERT_EQUALS(opt.args[i], args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void run() override {
|
||||
|
@ -106,6 +145,7 @@ private:
|
|||
TEST_CASE(one_error_less_files);
|
||||
TEST_CASE(one_error_several_files);
|
||||
TEST_CASE(markup);
|
||||
TEST_CASE(clangTidy);
|
||||
TEST_CASE(showtime_top5_file);
|
||||
TEST_CASE(showtime_top5_summary);
|
||||
TEST_CASE(showtime_file);
|
||||
|
@ -148,7 +188,7 @@ private:
|
|||
}
|
||||
|
||||
void many_threads_plist() {
|
||||
const char plistOutput[] = "plist_process/";
|
||||
const std::string plistOutput = "plist_" + fprefix() + "/";
|
||||
ScopedFile plistFile("dummy", "", plistOutput);
|
||||
|
||||
check(16, 100, 100,
|
||||
|
@ -156,7 +196,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput));
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput.c_str()));
|
||||
}
|
||||
|
||||
void no_errors_more_files() {
|
||||
|
@ -241,6 +281,34 @@ private:
|
|||
settings = settingsOld;
|
||||
}
|
||||
|
||||
void clangTidy() {
|
||||
// TODO: we currently only invoke it with ImportProject::FileSettings
|
||||
if (!useFS)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
const char exe[] = "clang-tidy.exe";
|
||||
#else
|
||||
const char exe[] = "clang-tidy";
|
||||
#endif
|
||||
(void)exe;
|
||||
|
||||
const std::string file = fprefix() + "_1.cpp";
|
||||
// TODO: the invocation cannot be checked as the code is called in the forked process
|
||||
check(2, 1, 0,
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
dinit(CheckOptions,
|
||||
$.quiet = false,
|
||||
$.clangTidy = true /*,
|
||||
$.executeCommandCalled = true,
|
||||
$.exe = exe,
|
||||
$.args = {"-quiet", "-checks=*,-clang-analyzer-*,-llvm*", file, "--"}*/));
|
||||
ASSERT_EQUALS("Checking " + file + " ...\n", output.str());
|
||||
}
|
||||
|
||||
// TODO: provide data which actually shows values above 0
|
||||
|
||||
// TODO: should this be logged only once like summary?
|
||||
|
@ -303,8 +371,18 @@ private:
|
|||
TODO_ASSERT(output_s.find("Check time: " + fprefix() + "_2.cpp: ") != std::string::npos);
|
||||
}
|
||||
|
||||
// TODO: test clang-tidy
|
||||
// TODO: test whole program analysis
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestProcessExecutor)
|
||||
class TestProcessExecutorFiles : public TestProcessExecutorBase {
|
||||
public:
|
||||
TestProcessExecutorFiles() : TestProcessExecutorBase("TestProcessExecutorFiles", false) {}
|
||||
};
|
||||
|
||||
class TestProcessExecutorFS : public TestProcessExecutorBase {
|
||||
public:
|
||||
TestProcessExecutorFS() : TestProcessExecutorBase("TestProcessExecutorFS", true) {}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestProcessExecutorFiles)
|
||||
REGISTER_TEST(TestProcessExecutorFS)
|
||||
|
|
|
@ -68,6 +68,7 @@ private:
|
|||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
bool clangTidy = false;
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
std::vector<std::string> args;
|
||||
|
@ -76,17 +77,18 @@ private:
|
|||
void check(int files, int result, const std::string &data, const CheckOptions& opt = make_default_obj{}) {
|
||||
errout.str("");
|
||||
output.str("");
|
||||
settings.project.fileSettings.clear();
|
||||
|
||||
Settings s = settings;
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
const std::string s = fprefix() + "_" + zpad3(i) + ".cpp";
|
||||
filemap[s] = data.size();
|
||||
std::string f_s = fprefix() + "_" + zpad3(i) + ".cpp";
|
||||
filemap[f_s] = data.size();
|
||||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = s;
|
||||
settings.project.fileSettings.emplace_back(std::move(fs));
|
||||
fs.filename = std::move(f_s);
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,15 +99,16 @@ private:
|
|||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = f;
|
||||
settings.project.fileSettings.emplace_back(std::move(fs));
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings.showtime = opt.showtime;
|
||||
settings.quiet = opt.quiet;
|
||||
s.showtime = opt.showtime;
|
||||
s.quiet = opt.quiet;
|
||||
if (opt.plistOutput)
|
||||
settings.plistOutput = opt.plistOutput;
|
||||
s.plistOutput = opt.plistOutput;
|
||||
s.clangTidy = opt.clangTidy;
|
||||
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
|
@ -117,7 +120,7 @@ private:
|
|||
args = std::move(a);
|
||||
return EXIT_SUCCESS;
|
||||
});
|
||||
cppcheck.settings() = settings;
|
||||
cppcheck.settings() = s;
|
||||
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
scopedfiles.reserve(filemap.size());
|
||||
|
@ -128,8 +131,7 @@ private:
|
|||
if (useFS)
|
||||
filemap.clear();
|
||||
|
||||
// TODO: test with settings.project.fileSettings;
|
||||
SingleExecutor executor(cppcheck, filemap, settings, settings.nomsg, *this);
|
||||
SingleExecutor executor(cppcheck, filemap, s, s.nomsg, *this);
|
||||
ASSERT_EQUALS(result, executor.check());
|
||||
ASSERT_EQUALS(opt.executeCommandCalled, executeCommandCalled);
|
||||
ASSERT_EQUALS(opt.exe, exe);
|
||||
|
@ -274,9 +276,6 @@ private:
|
|||
if (!useFS)
|
||||
return;
|
||||
|
||||
const Settings settingsOld = settings;
|
||||
settings.clangTidy = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
const char exe[] = "clang-tidy.exe";
|
||||
#else
|
||||
|
@ -291,11 +290,11 @@ private:
|
|||
"}",
|
||||
dinit(CheckOptions,
|
||||
$.quiet = false,
|
||||
$.clangTidy = true,
|
||||
$.executeCommandCalled = true,
|
||||
$.exe = exe,
|
||||
$.args = {"-quiet", "-checks=*,-clang-analyzer-*,-llvm*", file, "--"}));
|
||||
ASSERT_EQUALS("Checking " + file + " ...\n", output.str());
|
||||
settings = settingsOld;
|
||||
}
|
||||
|
||||
// TODO: provide data which actually shows values above 0
|
||||
|
|
|
@ -235,7 +235,7 @@ private:
|
|||
if (!suppression.empty()) {
|
||||
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
|
||||
}
|
||||
ThreadExecutor executor(files, settings, settings.nomsg, *this);
|
||||
ThreadExecutor executor(files, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
scopedfiles.reserve(files.size());
|
||||
for (std::map<std::string, std::size_t>::const_iterator i = files.cbegin(); i != files.cend(); ++i)
|
||||
|
@ -263,7 +263,7 @@ private:
|
|||
if (!suppression.empty()) {
|
||||
EXPECT_EQ("", settings.nomsg.addSuppressionLine(suppression));
|
||||
}
|
||||
ProcessExecutor executor(files, settings, settings.nomsg, *this);
|
||||
ProcessExecutor executor(files, settings, settings.nomsg, *this, CppCheckExecutor::executeCommand);
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
scopedfiles.reserve(files.size());
|
||||
for (std::map<std::string, std::size_t>::const_iterator i = files.cbegin(); i != files.cend(); ++i)
|
||||
|
|
|
@ -34,15 +34,18 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class TestThreadExecutor : public TestFixture {
|
||||
class TestThreadExecutorBase : public TestFixture {
|
||||
public:
|
||||
TestThreadExecutor() : TestFixture("TestThreadExecutor") {}
|
||||
TestThreadExecutorBase(const char * const name, bool useFS) : TestFixture(name), useFS(useFS) {}
|
||||
|
||||
private:
|
||||
Settings settings = settingsBuilder().library("std.cfg").build();
|
||||
bool useFS;
|
||||
|
||||
static std::string fprefix()
|
||||
std::string fprefix() const
|
||||
{
|
||||
if (useFS)
|
||||
return "threadfs";
|
||||
return "thread";
|
||||
}
|
||||
|
||||
|
@ -53,6 +56,10 @@ private:
|
|||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
bool clangTidy = false;
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
std::vector<std::string> args;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -63,35 +70,68 @@ private:
|
|||
errout.str("");
|
||||
output.str("");
|
||||
|
||||
Settings s = settings;
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
std::ostringstream oss;
|
||||
oss << fprefix() << "_" << i << ".cpp";
|
||||
filemap[oss.str()] = data.size();
|
||||
std::string f_s = fprefix() + "_" + std::to_string(i) + ".cpp";
|
||||
filemap[f_s] = data.size();
|
||||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = std::move(f_s);
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& f : opt.filesList)
|
||||
{
|
||||
filemap[f] = data.size();
|
||||
if (useFS) {
|
||||
ImportProject::FileSettings fs;
|
||||
fs.filename = f;
|
||||
s.project.fileSettings.emplace_back(std::move(fs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings settings1 = settings;
|
||||
settings1.jobs = jobs;
|
||||
settings1.showtime = opt.showtime;
|
||||
settings1.quiet = opt.quiet;
|
||||
s.jobs = jobs;
|
||||
s.showtime = opt.showtime;
|
||||
s.quiet = opt.quiet;
|
||||
if (opt.plistOutput)
|
||||
settings1.plistOutput = opt.plistOutput;
|
||||
// TODO: test with settings.project.fileSettings;
|
||||
ThreadExecutor executor(filemap, settings1, settings1.nomsg, *this);
|
||||
s.plistOutput = opt.plistOutput;
|
||||
s.clangTidy = opt.clangTidy;
|
||||
|
||||
bool executeCommandCalled = false;
|
||||
std::string exe;
|
||||
std::vector<std::string> args;
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
auto executeFn = [&executeCommandCalled, &exe, &args](std::string e,std::vector<std::string> a,std::string,std::string&){
|
||||
executeCommandCalled = true;
|
||||
exe = std::move(e);
|
||||
args = std::move(a);
|
||||
return EXIT_SUCCESS;
|
||||
};
|
||||
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
scopedfiles.reserve(filemap.size());
|
||||
for (std::map<std::string, std::size_t>::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)
|
||||
scopedfiles.emplace_back(new ScopedFile(i->first, data));
|
||||
|
||||
// clear files list so only fileSettings are used
|
||||
if (useFS)
|
||||
filemap.clear();
|
||||
|
||||
ThreadExecutor executor(filemap, s, s.nomsg, *this, executeFn);
|
||||
ASSERT_EQUALS(result, executor.check());
|
||||
ASSERT_EQUALS(opt.executeCommandCalled, executeCommandCalled);
|
||||
ASSERT_EQUALS(opt.exe, exe);
|
||||
ASSERT_EQUALS(opt.args.size(), args.size());
|
||||
for (int i = 0; i < args.size(); ++i)
|
||||
{
|
||||
ASSERT_EQUALS(opt.args[i], args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void run() override {
|
||||
|
@ -105,6 +145,7 @@ private:
|
|||
TEST_CASE(one_error_less_files);
|
||||
TEST_CASE(one_error_several_files);
|
||||
TEST_CASE(markup);
|
||||
TEST_CASE(clangTidy);
|
||||
TEST_CASE(showtime_top5_file);
|
||||
TEST_CASE(showtime_top5_summary);
|
||||
TEST_CASE(showtime_file);
|
||||
|
@ -142,12 +183,11 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", dinit(CheckOptions,
|
||||
$.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY));
|
||||
"}", dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY));
|
||||
}
|
||||
|
||||
void many_threads_plist() {
|
||||
const char plistOutput[] = "plist_thread/";
|
||||
const std::string plistOutput = "plist_" + fprefix() + "/";
|
||||
ScopedFile plistFile("dummy", "", plistOutput);
|
||||
|
||||
check(16, 100, 100,
|
||||
|
@ -155,8 +195,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", dinit(CheckOptions,
|
||||
$.plistOutput = plistOutput));
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput.c_str()));
|
||||
}
|
||||
|
||||
void no_errors_more_files() {
|
||||
|
@ -217,7 +256,9 @@ private:
|
|||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
dinit(CheckOptions, $.filesList = files));
|
||||
dinit(CheckOptions,
|
||||
$.quiet = false,
|
||||
$.filesList = files));
|
||||
// TODO: order of "Checking" and "checked" is affected by thread
|
||||
/*TODO_ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
|
||||
"1/4 files checked 25% done\n"
|
||||
|
@ -239,6 +280,31 @@ private:
|
|||
settings = settingsOld;
|
||||
}
|
||||
|
||||
void clangTidy() {
|
||||
// TODO: we currently only invoke it with ImportProject::FileSettings
|
||||
if (!useFS)
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
const char exe[] = "clang-tidy.exe";
|
||||
#else
|
||||
const char exe[] = "clang-tidy";
|
||||
#endif
|
||||
|
||||
const std::string file = fprefix() + "_1.cpp";
|
||||
check(2, 1, 0,
|
||||
"int main()\n"
|
||||
"{\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
dinit(CheckOptions,
|
||||
$.quiet = false,
|
||||
$.clangTidy = true,
|
||||
$.executeCommandCalled = true,
|
||||
$.exe = exe,
|
||||
$.args = {"-quiet", "-checks=*,-clang-analyzer-*,-llvm*", file, "--"}));
|
||||
ASSERT_EQUALS("Checking " + file + " ...\n", output.str());
|
||||
}
|
||||
|
||||
// TODO: provide data which actually shows values above 0
|
||||
|
||||
|
@ -302,8 +368,18 @@ private:
|
|||
ASSERT(output_s.find("Check time: " + fprefix() + "_2.cpp: ") != std::string::npos);
|
||||
}
|
||||
|
||||
// TODO: test clang-tidy
|
||||
// TODO: test whole program analysis
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestThreadExecutor)
|
||||
class TestThreadExecutorFiles : public TestThreadExecutorBase {
|
||||
public:
|
||||
TestThreadExecutorFiles() : TestThreadExecutorBase("TestThreadExecutorFiles", false) {}
|
||||
};
|
||||
|
||||
class TestThreadExecutorFS : public TestThreadExecutorBase {
|
||||
public:
|
||||
TestThreadExecutorFS() : TestThreadExecutorBase("TestThreadExecutorFS", true) {}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestThreadExecutorFiles)
|
||||
REGISTER_TEST(TestThreadExecutorFS)
|
||||
|
|
Loading…
Reference in New Issue