how to change gmock verbosity level - c++

I want to change gmock warnings into errors in all uninteresting gmock function calls.
I search some and I found that i should use --gmock_verbose=LEVEL flag but where should I add this flag?
Unfortunately I couldn't change all NiceMocks to StrictMocks.

where should I add this flag?
You can add gmock flags like --gmock_verbose=error directly in the command line.
Otherwise, you can always specify verbosity on a per test basis by putting ::testing::FLAGS_gmock_verbose = "error"; in the test code itself.
Source: http://google.github.io/googletest/gmock_cook_book.html#controlling-how-much-information-gmock-prints

Related

How to get loopinfo in Module Pass

I want to get loopinfo in each function by iterating through functions in Module Pass. My code is as follows:
for (auto &F:M) {
if(!F.isDeclaration()){
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>(F).getLoopInfo();
}
}
However, there is an error, I think my variable Settings should conform to the first function definition, how should I resolve.
clang-12: /llvmtest/llvm/lib/IR/LegacyPassManager.cpp:1645: virtual
std::tuple<llvm::Pass*, bool>
{anonymous}::MPPassManager::getOnTheFlyPass(llvm::Pass*,
llvm::AnalysisID, llvm::Function&): Assertion `FPP && “Unable to find
on the fly pass”’ failed. PLEASE submit a bug report to
https://bugs.llvm.org/ and include the crash backtrace, preprocessed
source, and associated run script.
You can not do this with the legacy pass manager. In the legacy pass manager, every pass could only get info from same-scoped passes -- module from module, function from function, loop from loop, plus one exception allowing function passes to get data from module passes.
With the new pass manager, you'd create a LoopAnalysisManager and add the analysis pass you want and run it. See https://llvm.org/docs/NewPassManager.html#using-analyses .
Note that most of LLVM is presently written to support both pass managers at once. If you do this, you'll need to write your pass differently from most of LLVM's passes, you can't use the types with names like "WrapperPass" that exist to support both legacy and new pass managers.

How to test a command line options parser using GTest

I am developing a command line options processor for my app. I have decided to use GTest to test it. It's implementation has been shown below in brief:
int main(int argv, char **argv)
{
if (!ProcessOptions(argc, argv)
{
return 1;
}
// Some more code here
return 0;
}
int ProcessOptions(int argc, char **argv)
{
for (int i = 1; i < argc; ++i)
{
CheckOption(argv[i]);
CheckArgument();
if (Success)
{
EnableOption();
}
}
}
The code runs as expected, but the problem is: I want to test this using GTest by supplying different options (valid and invalid) to it. The GTest manual reads:
The ::testing::InitGoogleTest() function parses the command line for
googletest flags, and removes all recognized flags. This allows the
user to control a test program's behavior via various flags, which
we'll cover in the AdvancedGuide. You must call this function before
calling RUN_ALL_TESTS(), or the flags won't be properly initialized.
But this way, I will be able to test just one sequence. I want to do this multiple times for different options. How do I do that?
Is there any better strategy to achieve this? Can I do this using test fixtures?
Have you considered a value-parameterized test? They sound perfect for your situation:
Value-parameterized tests allow you to test your code with different parameters without writing multiple copies of the same test. This is useful in a number of situations, for example:
You have a piece of code whose behavior is affected by one or more command-line flags.
You want to test different implementations of an OO interface.
You want to make sure your code performs correctly for various values of those flags.
You could write one or more test(s) which define the expected behaviour of the command line argument parser and then pass the command line flags down to it this way.
A full code example is shown in the link to the Google Test GitHub docs, but here's a quick outline:
Create a test class inheriting testing::TestWithParam<T>.
Use TEST_P and within it, the GetParam() method to access the parameter value.
You can instantiate your tests with INSTANTIATE_TEST_SUITE_P. Use the testing::Values method to supply values.

How to get the current spdlog level?

I need to turn off the spdlog level before some code then return it to the previous value after.
How do I get the current level before turning it off?
To get current level of logger use logger::level().
To set new level use logger::set_level().
Scenario 1: User-constructed logger
If you have a spdlog::logger object you're using (say, my_logger), then:
You can obtain the level with: my_logger.level().
If you just want to know whether a certain-level message would be logged, then use my_logger.should_log(some_level) where some_level could be, for example spdlog::level::debug.
Scenario 2: The global logger
Now suppose you're using the global logger (e.g. you emit log messages using spdlog::info(), spdlog::error() and such).
spdlog version 1.8.0 and later
You can obtain the global log level with a call to spdlog::get_level() (which is a freestanding function, not a method).
spdlog versions before 1.8.0
You need to get your hand on the implicit logger object - by callingspdlog::default_logger_raw() (it gets you a pointer.) Now just proceed as in Scenario 1 above.
There seems now to be a function to get the global logging level:
spdlog::get_level();

disable gcov coverage at run-time

I'm writing some Test in C++ and I'm using gcov (actually lcov but I think it's beside the point) to get informations about coverage.
Is there any way to disable the information record at run-time?
E.G. :
bool myTest() {
ObjectToTest obj;
/* Enable gcov... */
obj.FunctionToTest();
/* ...Disable gcov */
if(obj.GetStatus() != WHATEVER)
return false;
else
return true;
}
In this case I would like gcov to display as "covered" just FunctionToTest but leave ObjectToTest constructor and GetStatus "uncovered".
Thanks in advance!
No, in case of gcov we don't have any such option.
I have seen such options in some coverage tools like clover, which works by instrumenting source code directly though.
Beside a solution to your problem will be to write that part of code into a different source file and then call it inside your desired source file by including it.
I am suggesting this because when you generate coverage report later using LCOV or GCOVR they both provide the option to exclude specified files from coverage report by passing them to certain switches.
LCOV:
-r tracefile pattern
--remove tracefile pattern
Remove data from tracefile.
GCOVR:
-e EXCLUDE, --exclude=EXCLUDE
Exclude data files that match this regular expression
Although I agree with what #VikasTawniya said, you can also mock the functions you don't like to track in your test code.
#ifdev NO_COV
#include mock.h // mock of obj.FunctionToTest(); does nothing
#else
#include real.h // real implementation of obj.FunctionToTest();
#endif
Now your coverage result is not spoiled with the call of obj.FunctionToTest()
Feasible solution now (2023),
void some_function() {
__gcov_reset(); // this will reset all profile counters
do_something();
__gcov_flush(); // this will flush all counters (note: this flush is incremental and will not overwrite existing profile data)
}
// To prevent other parts of profile data from being flushed
void __attribute__((destructor)) clear_redundant_gcov() {
__gcov_reset();
}
Additional explanation: when you compile your source code with gcov, gcc will insert a lot of API calls (such as __gcov_inc_counter(xxx), just an example), and it is possible to invoke these gcov API calls within your source code.

Integrating LLVM passes

This maybe a rookie question but is there a way to integrate my LLVM modulepass to be called by default during the transformation phase?
Right now I am using this syntax to load my pass and register it
~/llvm/llvm/build/Debug+Asserts/bin/clang -Xclang -load -Xclang ~/llvm/llvm/build/Debug+Asserts/lib/SOMEPASSLIB.so
(The problem is when I want to build some package with this pass, the compiler accepts it when I say, pass the loading part as CFLAGS env variable, but some makefiles use CFLAGS for linking too, and the linker has no idea what it can do with this information and fails the build :\ )
There are couple of files you need to modify in order to define your pass inside LLVM core:
i) inside your pass: loadable pass is registered like this (assuming your pass name is FunctionInfo):
char FunctionInfo::ID = 0;
RegisterPass<FunctionInfo> X("function-info", "Functions Information");
you need to change it to be like this:
char FunctionInfo::ID = 0;
INITIALIZE_PASS_BEGIN(FunctionInfo, "function-info", "Gathering Function info", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
.... // initialize all passes which your pass needs
INITIALIZE_PASS_END(FunctionInfo, "function-info", "gathering function info", false, false)
ModulePass *llvm::createFunctionInfoPass() { return new FunctionInfo(); }
ii) you need to register your pass inside llvm as well, at least in InitializePasses.h and LinkAllPasses.h.
in LinkAllPasses.h you should add :
(void)llvm::createFunctionInfoPass();
and in InitializePasses.h add :
void initializeFunctionInfoPass(PassRegistry &);
iii) beside this modifications you might need to change another file depend on where you are going to add your pass. for instance if you are going to add it in lib/Analysis/ you also need to add one line to Analysis.cpp as below :
initializeFunctionInfoPass(Registry);
or if you are going to add it as new Scalar Transform you need to modify both Scalar.h and Scalar.cpp likewise.