Google benchmark custom main - c++

I would like to have a custom main function called before the benchmark starts to run with Google's benchmark library. So that I could setup several things. I've searched for quite a bit but I wasn't able to find anything. Should I simply modify the macro manually? Or simply use my main function and initialize the benchmark myself. Would that affect the library initialization in any way? Is there another way without requiring me to modify that macro or copying it's contents?
benchmark\benchmark_api.h
// Helper macro to create a main routine in a test that runs the benchmarks
#define BENCHMARK_MAIN() \
int main(int argc, char** argv) { \
::benchmark::Initialize(&argc, argv); \
::benchmark::RunSpecifiedBenchmarks(); \
}

BENCHMARK_MAIN() is just a helper macro, so you should be able to define your own version of main() like this:
int main(int argc, char** argv)
{
your_custom_init();
::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks();
}
Edit: you can also define global object and perform your custom initialization within its constructor. I usually do it this way, e.g. to initialize global array with input data:
int data[10];
class MyInit
{
public:
MyInit()
{
for (int n = 0; n < 10; ++n)
data[n] = n;
}
};
MyInit my_init;

Related

How can I combine many C++ main() functions into a single binary?

I'm working with a large C++ project that presently produces 66 different binaries. Each entrypoint contains its own global variables and main() function, though there's a lot of common code that's provided through a shared library.
For ease of distribution, I would like to distribute a single statically-linked binary, like you'd get from a Go or Rust project. Instead of invoking:
./ProgramFoo
./ProgramBar
I'd like to have a single combined binary that "execs" itself into one of those tools behind the scenes based on argv parameters, sort of like how busybox works:
./CombinedProgram ProgramFoo
./CombinedProgram ProgramBar
Look, I get that there's a "right" way to do this — refactor all 66 source files. Replace all global state with class singletons. Replace all the main() functions with entrypoint functions that could be dispatched from a single, unifying main() function. That sounds like a lot of work and a fair amount of disruption to all the other developers on the project. Is there truly no alternative on the compiler/linker level?
(I also don't want to just archive the binaries inside the CombinedProgram, write them to disk, and exec them. Boo. If I wanted a tarball, I'd just use a tarball.)
My understanding of C/C++ binary production is that the compiler will insert a crt0 startup routine that will initialize all my global state and then invoke main() with the appropriate parameters. Could I... perhaps... sneak some code in before that crt0 that peeks at argv and then proceeds down the correct code path?
Is there truly no alternative on the compiler/linker level?
Not really. Refactoring is the best / least work way to accomplish your task.
% cc -o one busy.c ; ln one two ; ./one ; ./two
one
two
The main() needs to look at ARGV[0] to determine how it was called. Then act on that information.
Simplest example:
#include <stdio.h>
#include <string.h>
int one(int argc, char **argv) {
printf("one\n");
return 1;
}
int two(int argc, char **argv) {
printf("two\n");
return 2;
}
int main(int argc, char **argv) {
char *end = argv[0];
int len = strlen(end);
end += len; // jump to the end of the command.
if (argc >= 1) {
if (!strcmp(end-3, "one")) {
return one(argc, argv);
} else if (!strcmp(end-3, "two")) {
return two(argc, argv);
}
}
}
I don't know of a tool that automatically refactors the commands into functions. The alternative is having one file determine what to do and then exec one of the 66 other statically-linked binaries.

How do I use if statement outside a function in C++

I want to check the value of a variable that I set inside the main function, but the if statement is not inside a function.
Here is what I have so far.
bool condition;
#if(condition)
:
:
:
some code
#endif
int main(int argc, char *argv[])
{
condition = processArgs(argc, argv);
}
From my understanding macros are executed during compilation time and not run time. Is there another way to check the value of the variable condition outside functions. The value of the variable condition is set depending on the command line arguments passed by the user.
So how do I use if statements outside the scope of functions? Because macro if does not work.
If you are doing those tasks using macros(I guessed from the question) then you can try doing:
#define _condition(x) Condition(x)
bool Condition(bool result)
{
if(!result)
{
///some code
}
return false;
}
int main(int argc, char *argv[])
{
bool result=processArgs(argc, argv);
_condition(result);
}
This way you'll be defining a macro for checking the value of the result variable that I added. The macro _condition will call the function for you and you can add any more code in the function without making a mess of the macro because one cant possibly put a function like defining a macro. If you were not doing macros then you can try calling the function directly and not using macros. Macros are a very useful yet complicated stuff so it is hard to make such large functions that you did in the function
You want to add a function:
void myFunction(bool condition)
{
if (condition)
{
// some code
}
// some code
}
int main(int argc, char *argv[])
{
bool condition = processArgs(argc, argv);
myFunction(condition);
}
that way, you tell the compiler when to run it, and what condition to use.

Using gtest specific parameters inside the testcase

Im using gtest as the test framework for my project and I need to use the following parameter value which is passed as a gtest parameter, inside the test case
./gtest_bin --gtest_repeat=5
Currently what I'm doing is, I've created a custom Listener extended from "EmptyTestEventListener" and pass the iteration value to a global variable when the callback to the following function is received as following,
customListener class
class customListener : public testing::EmptyTestEventListener
{
customListener(int *iteration) : m_iteration(iteration) {}
virtual void OnTestIterationStart(const testing::UnitTest& unit_test, int iteration)
{
*m_iteration = iteration;
}
}
main
int g_iteration;
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
if(argc > 1)
g_array_length = atoi(argv[1]);
testing::TestEventListeners& listners = testing::UnitTest::GetInstance()->listeners();
listners.Append(new printers::customListener(&g_iteration));
return RUN_ALL_TESTS();
}
Is there an easier way to get this gtest parameter value?
If generalized, Is there a way to get any gtest specific parameter value that can used inside a testcase?
IMPORTANT NOTE
Please use with great care - as this is not documented feature and
might be changed (i.e. it might stop working) in next gtest/gmock
versions.
You can access any flag by ::testing::GTEST_FLAG(flag_name) - in your case - ::testing::GTEST_FLAG(repeat).
I got this information indirectly from this manual and by examining gtest.h file.

Is it possible to envoke Boost.UnitTest tests within main in a way similar to the Boost.MinimalTestFacility?

I am extending a library for computational fluid dynamics, so I am dealing with legacy code. The applications involve initializing sometimes very large objects, most of which are codependent. The initialization is dependent on configuration and input files stored in a directory.
Trying to use a testing framework compared to my own testing hacked libs should make sense, since there are various test cases and families, and tests, and I could benefit from having the test tree and shiny reports + ability to automatize the tests.
However, I heve encountered a problem when trying to call specific tests at specific points in the program. This problem has occured already when I tried using Google Test - see this question.
Here is a model of the problem using Boost.Test:
#define BOOST_TEST_MODULE hugeObjectEvenTest
#define BOOST_TEST_NO_MAIN
#include <boost/test/included/unit_test.hpp>
#include<random>
#include<iostream>
BOOST_AUTO_TEST_SUITE (hugeObjectEvenTest)
BOOST_AUTO_TEST_CASE (test1)
{
BOOST_CHECK(hugeObject.value() % 2 == 0);
}
BOOST_AUTO_TEST_SUITE_END()
class HugeClass
{
int value_ = 0;
public:
HugeClass() = default;
HugeClass(int x) : value_(x) {};
int value () { return value_; }
void setValue (int val) { value_ = val; }
};
int main(int argc, const char *argv[])
{
HugeClass hugeObject;
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> dist(0,100);
for(int i = 0; i < 10; ++i)
{
hugeObject.setValue(dist(e1));
std::cout << hugeObject.value() << std::endl;
}
return 0;
}
This is merely a model of a numerical solver application, like the one found here.
What I think I need is a global fixture, that is able to take a reference to the hugeObject.
The instances just like hugeObject are modified (modeled with random number generation) during the simulation, within the simulation loop (modeled with the for loop).
All I want to do, is to execute specific tests at specific points within main, and benefit from having a test tree, and all the other perks of using a testing framework. Something similar to the functionality of the Minimal Test Facility.
Is this at all possible with Boost.Test? Like Google Test, selecting specific tests can be done by parsing during execution. This is of no use whatsoever for my problem. I have used both GTest and BoostTest for unit tests, where the initialization of fixtures is local and not dependent on main (argc, argv, configuration and input files), and I had no problems.
Edit: I will get flamed for this probably, but when dealing with legacy code, I believe it would be beneficial to somehow be able to access the objects in main via const refs (to ensure that the tests don't modify objects), in a simpler way than inheriting from fixture classes. In my case, doing that means a day of work, compared to simple BOOST_TEST_REQUIRE placed within main when using the minimal testing framework. Of course, with the minimal framework I have no test tree, etc, so I am back where I started: at my own hacked test lib.
One possible way to do this is to perform your own manual test registration, separate the tests you want to execute together into suites and run them manually. For example:
using namespace boost::unit_test;
void test1() { std::cout << "Running test 1\n"; }
void test2() { std::cout << "Running test 2\n"; }
void test3() { std::cout << "Running test 3\n"; }
void init_test_tree() {
test_suite *ts1 = BOOST_TEST_SUITE( "suite_a");
ts1->add( BOOST_TEST_CASE( &test1 ) );
ts1->add(BOOST_TEST_CASE( &test2 ));
framework::master_test_suite().add(ts1);
test_suite *ts2 = BOOST_TEST_SUITE( "suite_b");
ts2->add( BOOST_TEST_CASE( &test3 ) );
framework::master_test_suite().add(ts2);
}
bool empty_init() { return true; }
int main( int argc, char *argv[] ) {
init_test_tree();
std::cout << "Run suite a\n";
framework::run( framework::master_test_suite().get("suite_a"));
std::cout << "Run suite b\n";
framework::run( framework::master_test_suite().get("suite_b"));
std::cout << "Run the tree\n";
// pass empty initialization function as we've already constructed the test tree
return unit_test_main(&empty_init, argc, argv);
}
Registering your own test cases manually is tedious, boring and error-prone and I don't recommend it. Instead, you can simply define your own main() instead of having Boost.Test provide it for you. Write a main that looks like this:
HugeClass hugeObject;
boost::unit_test::test_suite *init_function(int argc, char *argv[])
{
// create test cases and suites and return a pointer to any enclosing
// suite, or 0.
return 0;
}
int main(int argc, const char *argv[])
{
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> dist(0,100);
for(int i = 0; i < 10; ++i)
{
hugeObject.setValue(dist(e1));
std::cout << hugeObject.value() << std::endl;
}
return boost::unit_test::unit_test_main(init_function, argc, argv);
}
If you do this, you get:
Automatic test case registration
Use of test suites
The ability to do any special stuff first in main() before any part of Boost.Test runs
One annoying side-effect of writing your own main: the signature for the init_function is different depending on if you linked with the static version of Boost.Test or the shared library (dynamic) version of Boost.Test. The differences are discussed in my Boost.Test documentation rewrite in the sections on the static library and the shared library.

Sublime C++ pointer support

class Test
{
public:
int i;
};
int main(int argc, char const *argv[])
{
Test *i = new Test;
return 0;
}
Is it possible to get support for the arrow notation? So if I write i. it automatically gets expand to i->
I am using SublimeClang. If something like this doesn't exist, would it be possible it create such a plugin?
Take a look at Autohotkey for windows, using this tutorial. or on Linux use Autokey, by following this tutorial.
However, how hard can typing one extra character be as chris said? What if not everything is a pointer?