<commit_before>#ifndef _TEST_MANAGER_H_INCLUDED_
#define _TEST_MANAGER_H_INCLUDED_

#include "app.h"
#include "p2p_network_interface.h"
#include "p2p_main_server.h"

#include <thread>
#include <mutex>
#include <utility>

typedef std::pair<bool, std::string> TestError;

std::unique_ptr<App> createApp(int fileMgrPort, int p2pPort, int msPort, std::string savePath);

TestError filesEqual(const std::string & left, const std::string & right);
TestError generateFile(const std::string & path, uint64_t size, const std::string & data = "abcdefghijklmnopqrstuvwxyz");
TestError removeFile(const std::string & path);

class InstanceManager {
public:
	/**
	* @brief Shared pointers created from InstanceManager will clean all files left
	* by the App class
	*/
	typedef std::shared_ptr<App> AppPtr;

	AppPtr nextNonColidingApp();

	void startMs();
	void stopMs();

	static InstanceManager & getInstance();

	void clear();

	InstanceManager(const InstanceManager &) = delete;
	InstanceManager & operator=(InstanceManager &) = delete;

	~InstanceManager();
private:
	InstanceManager() {}

private:
	static const int msPort = 2000;
	static int startPort;
	static int startSavePath;

	std::mutex mx;
	std::vector<std::shared_ptr<App>> apps;
	std::unique_ptr<P2PMainServer> ms;
	std::thread worker;
	bool isRunning;
};


class TestCaseBase {
public:

	// on Error in setUp, tearDown and run should not be called
	virtual TestError setUp() { return TestError{true, ""}; }
	virtual TestError tearDown() { return TestError{true, ""}; }
	virtual TestError run() = 0;

	virtual ~TestCaseBase() {}
};


#endif // _TEST_MANAGER_H_INCLUDED_<commit_msg>Add vector of cleanup funcs at dtor time<commit_after>#ifndef _TEST_MANAGER_H_INCLUDED_
#define _TEST_MANAGER_H_INCLUDED_

#include "app.h"
#include "p2p_network_interface.h"
#include "p2p_main_server.h"

#include <thread>
#include <mutex>
#include <utility>

typedef std::pair<bool, std::string> TestError;

std::unique_ptr<App> createApp(int fileMgrPort, int p2pPort, int msPort, std::string savePath);

TestError filesEqual(const std::string & left, const std::string & right);
TestError generateFile(const std::string & path, uint64_t size, const std::string & data = "abcdefghijklmnopqrstuvwxyz");
TestError removeFile(const std::string & path);

class InstanceManager {
public:
	/**
	* @brief Shared pointers created from InstanceManager will clean all files left
	* by the App class
	*/
	typedef std::shared_ptr<App> AppPtr;

	AppPtr nextNonColidingApp();

	void startMs();
	void stopMs();

	static InstanceManager & getInstance();

	void clear();

	InstanceManager(const InstanceManager &) = delete;
	InstanceManager & operator=(InstanceManager &) = delete;

	~InstanceManager();
private:
	InstanceManager() {}

private:
	static const int msPort = 2000;
	static int startPort;
	static int startSavePath;

	std::mutex mx;
	std::vector<std::shared_ptr<App>> apps;
	std::unique_ptr<P2PMainServer> ms;
	std::thread worker;
	bool isRunning;
};


class TestCaseBase {
public:

	// on Error in setUp, tearDown and run should not be called
	virtual TestError setUp() { return TestError{true, ""}; }
	virtual TestError tearDown() { return TestError{true, ""}; }
	virtual TestError run() = 0;

	virtual ~TestCaseBase() {
        for (auto & cb : atDtor) {
            cb();
        }
    }
protected:
    std::vector<std::function<void()>> atDtor;
};


#endif // _TEST_MANAGER_H_INCLUDED_
{'fraction_non_alphanumeric': 0.12021058789119625, 'fraction_numerical': 0.006434630008774495, 'mean_word_length': 5.564299424184261, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7626171', 'n_tokens_mistral': 1171, 'n_tokens_neox': 1132, 'n_words': 304}