Writing fast tests that check timed behavior - c++

I have the following class (dumbed down for the example, of course):
class file_handler_c {
public:
err_t init(int msecs);
err_t write(byte* buffer);
}
This class requires init to be called before any writes and then you can use this class to write to a file. However, after msecs milliseconds have passed, write stops writing to the file and returns an error.
My question is - how do you create a fast unit test for this behavior? Any small enough value will create a non-deterministic test that will sometimes fail due to other processes running on the machine. However, I want tests to be as fast as possible and not include any sleep or similar. I am using Google Test and Google Mock.

First of all I have to divert a little bit from your actual question. Please don't create interfaces like that. Whenever an object has been created, all its functions have to be callable until its lifetime ends. Informal lifetime constraints like "init() has to be called before write()", or even worse "always call close() before the destructor" can not be checked by the compiler and therefore are error prone.
Therefore I don't think, you should try to solve that issue in the test, but in the design of the code under test. Whenever it is hard to write a test, it is a sure bet, that your interfaces are flawed.
My suggestion is to separate timing and writing. Create a timer class like e.g. this one:
#include <memory>
#include <chrono>
template<typename T>
class Timer {
private:
std::chrono::milliseconds time_to_live;
std::shared_ptr<T> timed_object;
public:
template<typename... Arg>
Timer(std::chrono::milliseconds ttl, Arg... args):
time_to_live{ttl},
timed_object{std::make_shared<T>(args...)} {};
std::weak_ptr<T> get() { return {timed_object}; };
// ...
// when the defined time is over, timed_object will be set to nullptr somehow.
};
Use it like this:
#include <chrono>
#include <iostream>
#include <fstream>
int main(int, char**)
{
using namespace std::literals::chrono_literals;
auto timed_ostream = Timer<std::ofstream>{42ms, "filename"};
if( !timed_ostream.get().expired() ) {
// os is a shared_ptr. That guarantees, that the ostream will not
// be closed while you are still writing.
auto os = timed_ostream.get().lock();
(*os) << "whatever";
} // now os will be destroyed. The ofstream might be destroyed
// as well now, when the 42ms are over.
} // OK, here we destroy the timer and therefore the ofstream,
// if it is still alive.
With that interface you can easily write a simple test case with something else than an ostream, e.g. an int:
#include <chrono>
#include <cassert>
using namespace std::literals::chrono_literals;
void test_timed_object_valid_after_init()
{
auto clock = std::chrono::high_resolution_clock{};
auto start = clock.now();
auto timed_int = Timer<int>{2000ms,42}; // valid for 2000ms
assert(timed_int.get().expired()); // should still be here
} // The timer will be destroyed here. That destroys the shared_ptr
// and the object as well. The long lifetime does not matter.
void test_timed_object_invalid_after_time()
{
auto clock = std::chrono::high_resolution_clock{};
auto start = clock.now();
auto timed_int = Timer<int>{1ms,42}; // valid for 1ms
// you did not want sleep(), so we do busy waiting.
// Prefer usleep() instead.
// busy wait 1ms as exactly as possible.
while( clock.now() - start < 1ms ) {}
assert(timed_int.get().expired()); // should be gone now.
}
Note, that each testcase checks one single scenario here. Don't try and test the two requirements in a single test case. Then you either have to take a long lifetime for your object to check safely that it is there after initialization, or choose a short lifetime to check it is gone afterwards.
Beware: all the code in this posting should compile, but there might of course still be bugs somewhere. These are left as an exercise for the student ;-)

Related

How to use an executor from a boost::asio object to dispatch stuff into the same execution thread?

Ok, I don't have enough code yet for a fully working program, but I'm already running into issues with "executors".
EDIT: this is Boost 1.74 -- Debian doesn't give me anything more current. Which causes problems elsewhere, but I hope it had working executors back then as well :-)
Following one of the beast examples, I'm assigning a "strand" to a number of objects (a resolver and a stream) to be slightly more future-proof in case I need to go a multithreaded-route. But that's not actually the problem here, just the reason why I used a strand.
Now, I have this object that has a number of asio "subobjects" which are all initialized with that executor. No issues there, at least on the compiler side (I don't know whether the code does the intended stuff yet... it's heavily based on a beast example, though, so it's not completely random).
So, I want to send data to that object now. The assumption here is that the entire executor stuff is kind of pointless if I just randomly manipulate stuff from the "outside", so I wanted to "dispatch" my changes to the executor to it plays nicely with the async stuff that might be going on, especially when/if threads come into play. And since all the asio objects know their executor, I figured I wouldn't need to remember it myself.
Here some random self-contained example that shows the problem I'm having.
#include <boost/asio.hpp>
/************************************************************************/
class Test
{
private:
boost::asio::ip::tcp::resolver resolver;
public:
Test(boost::asio::any_io_executor executor)
: resolver(executor)
{
}
public:
void doSomething()
{
std::function<void(void)> function;
// Doesn't compile: no "dispatch" member
resolver.get_executor().dispatch(function);
// Doesn't compile: "target" is a template, needs a type
resolver.get_executor().target()->dispatch(function);
// Compiles, but I don't like having to know that it's a strand?
// How can the asio objects use the executor without me telling them the type?
// NOTE: I don't know whether it does the right thing!
resolver.get_executor().target<boost::asio::io_context::strand>()->dispatch(function);
}
};
/************************************************************************/
void test()
{
boost::asio::io_context ioContext;
Test test(boost::asio::make_strand(ioContext));
}
It's actually all in the "doSomething()" function: how do I "dispatch" something to the same executor that some asio object uses, without having to know exactly what that executor is?
Yes, I can do the workaround and pass the "strand" object instead of any_executor, and store that with the other stuff so I have something to call directly. But since every asio object has an executor and also manages to use it properly... I should be able to do the same thing, no?
Post, defer and dispatch are free functions:
boost::asio::dispatch(resolver.get_executor(), function);
Live: http://coliru.stacked-crooked.com/a/c39d263a99fbe3fd
#include <boost/asio.hpp>
#include <iostream>
struct Test {
Test(boost::asio::any_io_executor executor) : resolver(executor) {}
void doSomething() {
boost::asio::dispatch(resolver.get_executor(), [] {std::cout << "Hello world\n";});
}
private:
boost::asio::ip::tcp::resolver resolver;
};
int main() {
boost::asio::io_context ioContext;
Test test(make_strand(ioContext));
test.doSomething();
ioContext.run();
}
Prints
Hello world

Is this attempt at a more python style decorator in c++ reliable / safe

Coming to c++ from python, this is as close as I can get to a python like decorator.
This solution feels a bit like a hack because the code to be run after the function to be decorated, in the Timer destructor is call implicitly. It does work though.
My question is:
Is this safe and reliable, or more specifically is the destructor of the Timer class guaranteed to be called directly after the function returns (the Timer instance going out of scope).
class Timer{
time_t time;
std::string name;
public:
Timer(std::string name): name(name)
{
time = now();
}
~Timer()
{
printf("time taken by \"%s\" was: %d\n", name.c_str(), (now() - time));
}
};
void my_function(){
Timer _(__func__);
// function code
}
First answer your question, yes it's safe.
I just write this, I think this more like python decorator (like you can change parameter).
*Not well tested, just demonstrate the idea.
#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;
template<typename T>
auto TimeIt(T callable){
return [=](auto&&... args){
auto start = std::chrono::system_clock::now();
callable(args...);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end-start;
std::cout << diff.count() << "s\n";
};
}
void my_function(){
// function code
std::this_thread::sleep_for(0.5s);
}
auto my_function_2 = TimeIt(my_function); //you cannot reuse the name, though
int main(){
my_function_2();
}
Wandbox
Yep, that is a safe, reliable and conventional way to do this.
It kind of is a bit of a hack, because destructors are designed to do cleanup tasks rather than produce key output, but it's a hack that everybody uses and is happy with.
Well done!

Thread safety and std::move

Preface:
When I'm typing out new code, I declare my functions as pass-by-reference-to-const without thinking (out of habit), and sometimes have to go back and change it when I realize it's not what I meant to do.
I'm writing a worker-thread class that runs indefinitely, and is fed strings (from another thread) for processing. When I realized that I had declared the function as pass-by-ref, I went back to change it to pass-by-value, for thread-safety.
But, since I would like to squeeze out as much speed and efficiency as possible, I stopped myself to first explore the options. I wrote a little test routine - and discovered that I'm fuzzy on some key concepts.
To the point: I first wrote the test code below without the commented line:
// std::thread _thread(workthread, move(str)); // Thread safe (contents are moved)
So, ignore that line for now.
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
std::atomic<bool> done = false;
void workthread(const std::string &str)
{
std::string &s = const_cast<std::string &>(str);
s = "Work Thread"; // test to see if this changes the main thread's string
}
// This just watches for <enter> on the keyboard in order to quit the program.
void quitmonitor()
{
std::getchar();
done = true;
}
int main(int argc, char **argv)
{
std::thread _monitor(quitmonitor);
std::string str("Main Thread");
std::thread _thread([&]{workthread(std::move(str));}); // Not thread safe (address is copied)
// std::thread _thread(workthread, move(str)); // Thread safe (contents are moved)
const auto minlen(str.length());
const auto maxlen(minlen ? minlen*2 : 15);
bool going_up = true;
while (!done) {
if (going_up)
str.push_back('+');
else
str.pop_back();
if (str.length() == minlen)
going_up = true;
if (str.length() == maxlen)
going_up = false;
std::cout << str << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
_thread.join();
_monitor.join();
}
All main() does is create a string "Main Thread", and moves it to the thread function void workthread(const std::string &). The thread function then changes the lvalue's data and returns. The main continues on to a loop which just prints its local string to console (with some additional eye-candy to make it easy to see things happening on the screen). Here's the output:
So, it didn't work as I had expected. I had thought that the thread instantiation would "move" str to the thread function (emptying its data in the process), and the thread's assignment to the function's string argument would have no affect. But clearly it did, as demonstrated by the output.
This must have something to do with the fact that I constructed _thread with a lambda:
std::thread _thread([&]{workthread(std::move(str));}); // Not thread safe (address is copied)
So then I changed the instantiation to:
std::thread _thread(workthread, move(str)); // Thread safe (contents are moved)
and it worked as expected:
Q1: Why do the two instances, lambda vs bind(I guess?), yield different results?
Q2: Am I actually buying myself anything by declaring this as pass-by-reference?
I should note that the actual program is quite time critical, and is intended to run uninterrupted for years on a dedicated server. I'm trying to make the software as low-overhead as possible, to ensure that it can stay in sync (with an external clock), and not accumulate time errors.
std::thread _thread([&]{workthread(std::move(str));});
When _thread is created, it calls your lambda function, which calls workthread(std::move(str)). Note that std::move doesn't actually do anything; it's just a cast to rvalue reference. You never move from str, you just cast the reference to a std::string& in a roundabout way and assign to it.
This also means that you have a data race on str because you have unsynchronized access between the main thread and _thread.
This code moved from the string, though:
std::thread _thread(workthread, move(str));
If you look at std::thread's constructor (it's (3) on that list), you'll see that it "copies" the arguments to the function call; it calls roughly:
workthread(decay_copy(std::move(str)))
This decay_copy actually does move from the string, as it returns by value:
template <class T>
std::decay_t<T> decay_copy(T&& v) { return std::forward<T>(v); }
This is why you see str as being moved from. However, your program is actually relying on unspecified behavior, as – after moving from a std::string – the string is left in a "valid but unspecified state" (std::string's move constructor and move assignment operator). You can't expect str to be an empty string after it's been moved from.

std::function With Member Function For Timer C++

I have A timer class that I have set up to be able to bind to a free floating function using the std::function template. I would Like to modify the class to be able to support using both free floating functions and class member functions. I know that std::function can bind to a member function using std::bind but I am not sure how to set this up with the code I have:
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <atomic>
namespace Engine {
template<class return_type,class...arguments>
class Timer{
typedef std::function<return_type(arguments...)> _function_t;
public:
Timer(size_t interval,bool autoRun,_function_t function,arguments...args){
_function = function;
_interval = interval;
if (autoRun) {
Enable(args...);
}
}
~Timer(){
if (Running()) {
Disable();
}
}
void Enable(arguments...args){
if (!Running()) {
_running=true;
enable(_interval, _function, args...);
}
}
void Disable(){
if (Running()) {
_running=false;
}
}
std::atomic_bool const& Running()const{
return _running;
}
protected:
void enable(size_t interval,_function_t func,arguments...args){
_thread =std::thread([&,func,interval,args...](){
std::chrono::duration<long long,std::nano> inter(interval);
auto __interval = std::chrono::microseconds(interval);
auto deadline = std::chrono::steady_clock::now();
while (_running) {
func(args...);
std::this_thread::sleep_until(deadline+=__interval);
}
});
_thread.detach();
}
protected:
_function_t _function;
std::atomic_bool _running;
size_t _interval;
std::thread _thread;
};
}
Any suggestions would be great. Let me know if I need to clarify anything.
Thanks
To pass a member function to this, pass a pointer to the unbound member function (&Engine::SceneManager::Update), and then the first parameter is a pointer to the object who should have the member called (a pointer to a SceneManager object, this is the "hidden" this pointer). This is how bind works, so no changes are needed to your code. As a simple alternative, pass a lambda.
http://coliru.stacked-crooked.com/a/7c6335d4f94b9f93 (though it isn't running as expected and I don't know why)
Also, I'm confused by the fact your code takes interal as a size_t, then converts it to nanoseconds, then converts that to microseconds, and then uses it. Why not just use microseconds the whole way through?
Your destructor has a race condition. Disable should stall until the thread has finished executing. I haven't used std::thread much, but I'd guess one place to start is if (_thread.is_joinable()) _thread.join(); As part of this, it might be useful to have the thread only sleep for 100ms at a time or so, and periodically check if it's supposed to be shutting down.
Enable should stop the existing thread, before starting a new one. Better yet, reuse the same thread. Unfortunately, there's no easy way to have an existing thread switch tasks, so it's easiest to simply Disable and then keep your existing code.

class member mutex assertion failed

I'm trying to implement what I think is a fairly simple design. I have a bunch of objects, each containing a std::map and there will be multiple processes accessing them. I want to make sure that there is only one insert/erase to each of these maps at a time.
So I've been reading about boost::thread and class member mutexes and using bind to pass to class member which are all new things to me. I started with a simple example from a Dr. Dobbs article and tried modifying that. I was getting all kinds of compiler errors due to my Threaded object having to be noncopyable. After reading up on that, I decided I can avoid the hassle by keeping a pointer to a mutex instead. So now I have code that compiles but results in the following error:
/usr/include/boost/shared_ptr.hpp:419:
T* boost::shared_ptr< <template-parameter-1-1> >::operator->() const
[with T = boost::mutex]: Assertion `px != 0' failed. Abort
Now I'm really stuck and would really appreciate help with the code as well as comments on where I'm going wrong conceptually. I realize there are some answered questions around these issues here already but I guess I'm still missing something.
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <map>
using namespace std;
class Threaded {
public:
std::map<int,int> _tsMap;
void count(int id) {
for (int i = 0; i < 100; ++i) {
_mx->lock();
//std::cout << id << ": " << i << std::endl;
_tsMap[i] ++;
_mx->unlock();
}
}
private:
boost::shared_ptr<boost::mutex> _mx;
};
int main(int argc, char* argv[]) {
Threaded th;
int i = 1;
boost::thread thrd1(boost::bind(&Threaded::count, &th, 1));
//boost::thread thrd2(boost::bind(&th.count, 2));
thrd1.join();
//thrd2.join();
return 0;
}
It looks like you're missing a constructor in your Threaded class that creates the mutex that _mx is intended to point at. In its current state (assuming you ran this code just as it is), the default constructor for Threaded calls the default constructor for shared_ptr, resulting in a null pointer (which is then dereferenced in your count() function.
You should add a constructor along the following lines:
Threaded::Threaded(int id)
: _mx(new boost::mutex())
, _mID(id)
{
}
Then you could remove the argument from your count function as well.
A mutex is non-copyable for good reasons. Trying to outsmart the compiler by using a pointer to a mutex is a really bad idea. If you succeed, the compiler will fail to notice the problems, but they will still be there and will turn round and bite you at runtime.
There are two solutions
store the mutex in your class as a static
store the mutex outside your class.
There are advantages for both - I prefer the second.
For some more discussion of this, see my answer here mutexes with objects
Conceptually, I think you do have a problem. Copying a std::shared_ptr will just increase its reference count, and the different objects will all use the same underlying mutex - meaning that whenever one of your objects is used, none of the rest of them can be used.
You, on the other hand, need each object to get its own mutex guard which is unrelated to other objects mutex guards.
What you need is to keep the mutex defined in the class private section as it is - but ensure that your copy constructor and copy assignment operator are overloaded to create a new one from scratch - one bearing no relation to the mutex in the object being copied/assigned from.