<commit_before>/*
Copyright libCellML Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "gtest/gtest.h"

#include <iostream>
#include <libcellml>

/*
 * The tests in this file are here to catch any branches of code that
 * are not picked up by the main tests testing the API of the library
 */
TEST(Coverage, import)
{
    const std::string id = "id";
    libcellml::ImportSource i;
    libcellml::ImportSource im;

    i.setId(id);

    im = std::move(i);

    EXPECT_EQ(id, im.getId());
}

TEST(Coverage, printer)
{
    libcellml::Printer p;
    libcellml::Printer pm;

    libcellml::ErrorPtr error = std::make_shared<libcellml::Error>();

    p.addError(error);

    pm = std::move(p);

    EXPECT_EQ(size_t(1), pm.errorCount());
}

TEST(Coverage, units)
{
    const std::string n = "dimensionless";
    libcellml::Units u;
    libcellml::Units um;

    u.setName("dimensionless");

    um = std::move(u);

    EXPECT_EQ(n, um.getName());
}

TEST(Coverage, when)
{
    const std::string id = "id";
    libcellml::When w;
    libcellml::When wm;

    w.setId(id);

    wm = std::move(w);

    EXPECT_EQ(id, wm.getId());
}

TEST(Coverage, unitsGetVariations)
{
    libcellml::Model m;

    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
    u->setName("a_unit");

    u->addUnit(libcellml::Units::StandardUnit::AMPERE, "micro");
    m.addUnits(u);

    libcellml::UnitsPtr un = m.getUnits(0);
    EXPECT_EQ("a_unit", un->getName());
    libcellml::UnitsPtr uSn = static_cast<const libcellml::Model>(m).getUnits(0);
    EXPECT_EQ("a_unit", uSn->getName());

    libcellml::UnitsPtr uns = m.getUnits("a_unit");
    EXPECT_EQ("a_unit", uns->getName());
    libcellml::UnitsPtr uSns = static_cast<const libcellml::Model>(m).getUnits("a_unit");
    EXPECT_EQ("a_unit", uSns->getName());

    EXPECT_EQ(nullptr, m.getUnits("b_unit"));
    EXPECT_EQ(nullptr, m.getUnits(4));
}

TEST(Coverage, prefixToString)
{
    libcellml::Model m;
    libcellml::Printer printer;

    std::vector<std::string> prefixString =
        {"atto",
         "centi",
         "deca",
         "deci",
         "exa",
         "femto",
         "giga",
         "hecto",
         "kilo",
         "mega",
         "micro",
         "milli",
         "nano",
         "peta",
         "pico",
         "tera",
         "yocto",
         "yotta",
         "zepto",
         "zetta"};
    std::vector<libcellml::Prefix> prefixEnum =
        {libcellml::Prefix::ATTO,
         libcellml::Prefix::CENTI,
         libcellml::Prefix::DECA,
         libcellml::Prefix::DECI,
         libcellml::Prefix::EXA,
         libcellml::Prefix::FEMTO,
         libcellml::Prefix::GIGA,
         libcellml::Prefix::HECTO,
         libcellml::Prefix::KILO,
         libcellml::Prefix::MEGA,
         libcellml::Prefix::MICRO,
         libcellml::Prefix::MILLI,
         libcellml::Prefix::NANO,
         libcellml::Prefix::PETA,
         libcellml::Prefix::PICO,
         libcellml::Prefix::TERA,
         libcellml::Prefix::YOCTO,
         libcellml::Prefix::YOTTA,
         libcellml::Prefix::ZEPTO,
         libcellml::Prefix::ZETTA};
    for (std::vector<std::string>::size_type i = 0; i != prefixString.size(); ++i) {
        libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
        u->setName("abcdefg");
        u->addUnit("empty", prefixEnum[i]);

        m.addUnits(u);

        const std::string a = printer.printModel(m);
        std::size_t found = a.find(prefixString[i]);
        EXPECT_NE(std::string::npos, found);
        m.removeAllUnits();
    }
}

TEST(Coverage, variable)
{
    const std::string e = "<variable units=\"dimensionless\" initial_value=\"1\" interface=\"public\"/>\n";
    libcellml::Variable v;
    libcellml::Variable vm;
    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();

    v.setInitialValue(1.0);
    v.setInterfaceType("public");
    u->setName("dimensionless");
    v.setUnits(u);

    vm = std::move(v);

    // Copy constructor
    libcellml::Variable vc(vm);

    libcellml::Printer printer;
    const std::string a = printer.printVariable(vc);
    EXPECT_EQ(e, a);
}

TEST(Coverage, component)
{
    const std::string n = "name";
    const std::string e =
        "<component name=\"name\">\n"
        "  <variable/>\n"
        "  <1+1=2>\n"
        "</component>\n";
    const std::string math = "<1+1=2>\n";

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr cm;
    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();

    c->setName(n);
    c->addVariable(v);
    c->setMath(math);

    libcellml::Printer printer;
    std::string a = printer.printComponent(c);
    EXPECT_EQ(e, a);

    cm = std::move(c);
    a = printer.printComponent(cm);
    EXPECT_EQ(e, a);

    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Component> vec;
    vec.emplace_back();

    libcellml::Component rc;
    libcellml::Component ao;

    rc.setName(n);

    ao = rc;

    EXPECT_EQ(n, ao.getName());
}

TEST(Coverage, error)
{
    libcellml::ErrorPtr err = std::make_shared<libcellml::Error>();
    libcellml::Error e;
    libcellml::Error em;
    const std::string description = "test";

    e.setDescription(description);
    e.setKind(libcellml::Error::Kind::XML);

    em = std::move(e);
    // Copy constructor
    libcellml::Error ec(em);

    EXPECT_EQ(description, ec.getDescription());
    EXPECT_EQ(libcellml::Error::Kind::XML, ec.getKind());
}

TEST(Coverage, model)
{
    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Model> vec;
    vec.emplace_back();

    libcellml::Model rm;
    libcellml::Model ao;

    ao = rm;
}
<commit_msg>Coverage tests: removed the unitsGetVariations test, which adds nothing.<commit_after>/*
Copyright libCellML Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "gtest/gtest.h"

#include <iostream>
#include <libcellml>

/*
 * The tests in this file are here to catch any branches of code that
 * are not picked up by the main tests testing the API of the library
 */
TEST(Coverage, import)
{
    const std::string id = "id";
    libcellml::ImportSource i;
    libcellml::ImportSource im;

    i.setId(id);

    im = std::move(i);

    EXPECT_EQ(id, im.getId());
}

TEST(Coverage, printer)
{
    libcellml::Printer p;
    libcellml::Printer pm;

    libcellml::ErrorPtr error = std::make_shared<libcellml::Error>();

    p.addError(error);

    pm = std::move(p);

    EXPECT_EQ(size_t(1), pm.errorCount());
}

TEST(Coverage, units)
{
    const std::string n = "dimensionless";
    libcellml::Units u;
    libcellml::Units um;

    u.setName("dimensionless");

    um = std::move(u);

    EXPECT_EQ(n, um.getName());
}

TEST(Coverage, when)
{
    const std::string id = "id";
    libcellml::When w;
    libcellml::When wm;

    w.setId(id);

    wm = std::move(w);

    EXPECT_EQ(id, wm.getId());
}

TEST(Coverage, prefixToString)
{
    libcellml::Model m;
    libcellml::Printer printer;

    std::vector<std::string> prefixString =
        {"atto",
         "centi",
         "deca",
         "deci",
         "exa",
         "femto",
         "giga",
         "hecto",
         "kilo",
         "mega",
         "micro",
         "milli",
         "nano",
         "peta",
         "pico",
         "tera",
         "yocto",
         "yotta",
         "zepto",
         "zetta"};
    std::vector<libcellml::Prefix> prefixEnum =
        {libcellml::Prefix::ATTO,
         libcellml::Prefix::CENTI,
         libcellml::Prefix::DECA,
         libcellml::Prefix::DECI,
         libcellml::Prefix::EXA,
         libcellml::Prefix::FEMTO,
         libcellml::Prefix::GIGA,
         libcellml::Prefix::HECTO,
         libcellml::Prefix::KILO,
         libcellml::Prefix::MEGA,
         libcellml::Prefix::MICRO,
         libcellml::Prefix::MILLI,
         libcellml::Prefix::NANO,
         libcellml::Prefix::PETA,
         libcellml::Prefix::PICO,
         libcellml::Prefix::TERA,
         libcellml::Prefix::YOCTO,
         libcellml::Prefix::YOTTA,
         libcellml::Prefix::ZEPTO,
         libcellml::Prefix::ZETTA};
    for (std::vector<std::string>::size_type i = 0; i != prefixString.size(); ++i) {
        libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();
        u->setName("abcdefg");
        u->addUnit("empty", prefixEnum[i]);

        m.addUnits(u);

        const std::string a = printer.printModel(m);
        std::size_t found = a.find(prefixString[i]);
        EXPECT_NE(std::string::npos, found);
        m.removeAllUnits();
    }
}

TEST(Coverage, variable)
{
    const std::string e = "<variable units=\"dimensionless\" initial_value=\"1\" interface=\"public\"/>\n";
    libcellml::Variable v;
    libcellml::Variable vm;
    libcellml::UnitsPtr u = std::make_shared<libcellml::Units>();

    v.setInitialValue(1.0);
    v.setInterfaceType("public");
    u->setName("dimensionless");
    v.setUnits(u);

    vm = std::move(v);

    // Copy constructor
    libcellml::Variable vc(vm);

    libcellml::Printer printer;
    const std::string a = printer.printVariable(vc);
    EXPECT_EQ(e, a);
}

TEST(Coverage, component)
{
    const std::string n = "name";
    const std::string e =
        "<component name=\"name\">\n"
        "  <variable/>\n"
        "  <1+1=2>\n"
        "</component>\n";
    const std::string math = "<1+1=2>\n";

    libcellml::ComponentPtr c = std::make_shared<libcellml::Component>();
    libcellml::ComponentPtr cm;
    libcellml::VariablePtr v = std::make_shared<libcellml::Variable>();

    c->setName(n);
    c->addVariable(v);
    c->setMath(math);

    libcellml::Printer printer;
    std::string a = printer.printComponent(c);
    EXPECT_EQ(e, a);

    cm = std::move(c);
    a = printer.printComponent(cm);
    EXPECT_EQ(e, a);

    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Component> vec;
    vec.emplace_back();

    libcellml::Component rc;
    libcellml::Component ao;

    rc.setName(n);

    ao = rc;

    EXPECT_EQ(n, ao.getName());
}

TEST(Coverage, error)
{
    libcellml::ErrorPtr err = std::make_shared<libcellml::Error>();
    libcellml::Error e;
    libcellml::Error em;
    const std::string description = "test";

    e.setDescription(description);
    e.setKind(libcellml::Error::Kind::XML);

    em = std::move(e);
    // Copy constructor
    libcellml::Error ec(em);

    EXPECT_EQ(description, ec.getDescription());
    EXPECT_EQ(libcellml::Error::Kind::XML, ec.getKind());
}

TEST(Coverage, model)
{
    // Move constructor, assignment operator and swap method
    std::vector<libcellml::Model> vec;
    vec.emplace_back();

    libcellml::Model rm;
    libcellml::Model ao;

    ao = rm;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <log4cxx/logger.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/simplelayout.h>
#include <log4cxx/helpers/exception.h>

using namespace log4cxx;
using namespace log4cxx::helpers;

int main()
{
	int ret = EXIT_SUCCESS;

	try
	{
		LayoutPtr layout = new SimpleLayout();

		FileAppender *fileAppender =
			new FileAppender(layout, _T("result"), false);

		LoggerPtr rootLogger = Logger::getRootLogger();
		rootLogger->addAppender(fileAppender);

		rootLogger->debug(_T("debug message"));
		rootLogger->info(_T("info message"));
		rootLogger->warn(_T("warn message"));
		rootLogger->error(_T("error message"));
		rootLogger->fatal(_T("fatal message"));

		fileAppender->close();

		std::ofstream witness("witness", std::ios::out|std::ios::trunc);
		witness << _T("DEBUG - debug message") << std::endl;
		witness << _T("INFO - info message") << std::endl;
		witness << _T("WARN - warn message") << std::endl;
		witness << _T("ERROR - error message") << std::endl;
		witness << _T("FATAL - fatal message") << std::endl;
		witness.close();

#ifdef UNICODE
		std::wifstream inr, inw;
#else
		std::ifstream inr, inw;
#endif
		inr.open("result", std::ios::in|std::ios::binary);
		inw.open("witness", std::ios::in|std::ios::binary);
		if (inr.fail() || inw.fail())
		{
			ret = EXIT_FAILURE;
		}
		else
		{
			inr.seekg(0, std::ios_base::end);
			int sizer = inr.tellg();
			inr.seekg(0, std::ios_base::beg);

			inw.seekg(0, std::ios_base::end);
			int sizew = inw.tellg();
			inw.seekg(0, std::ios_base::beg);

			if (sizer != sizew)
			{
				ret = EXIT_FAILURE;
			}
			else
			{
				unsigned char * result = new unsigned char[sizer];
				unsigned char * witness = new unsigned char[sizer];
				memset(result, (sizer) * sizeof(TCHAR), 0);
				memset(witness, (sizer) * sizeof(TCHAR), 0);
				inr.read((TCHAR *)result, sizer);
				inw.read((TCHAR *)witness, sizer);

				if (memcmp(result, witness, sizer) != 0)
				{
					ret = EXIT_FAILURE;
				}

				delete [] result;
				delete [] witness;

				inr.close();
				inw.close();
			}
		}
	}
	catch(Exception&)
	{
		ret = EXIT_FAILURE;
	}

	return ret;
}
<commit_msg>fixed UNICODE problem<commit_after>#include <stdlib.h>
#include <log4cxx/logger.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/simplelayout.h>
#include <log4cxx/helpers/exception.h>

using namespace log4cxx;
using namespace log4cxx::helpers;

int main()
{
	int ret = EXIT_SUCCESS;

	try
	{
		LayoutPtr layout = new SimpleLayout();

		FileAppender *fileAppender =
			new FileAppender(layout, _T("result"), false);

		LoggerPtr rootLogger = Logger::getRootLogger();
		rootLogger->addAppender(fileAppender);

		rootLogger->debug(_T("debug message"));
		rootLogger->info(_T("info message"));
		rootLogger->warn(_T("warn message"));
		rootLogger->error(_T("error message"));
		rootLogger->fatal(_T("fatal message"));

		fileAppender->close();

#ifdef UNICODE
		std::wofstream witness;
#else
		std::ofstream witness;
#endif
		witness.open("witness", std::ios::out|std::ios::trunc);
		witness << _T("DEBUG - debug message") << std::endl;
		witness << _T("INFO - info message") << std::endl;
		witness << _T("WARN - warn message") << std::endl;
		witness << _T("ERROR - error message") << std::endl;
		witness << _T("FATAL - fatal message") << std::endl;
		witness.close();

#ifdef UNICODE
		std::wifstream inr, inw;
#else
		std::ifstream inr, inw;
#endif
		inr.open("result", std::ios::in|std::ios::binary);
		inw.open("witness", std::ios::in|std::ios::binary);
		if (inr.fail() || inw.fail())
		{
			ret = EXIT_FAILURE;
		}
		else
		{
			inr.seekg(0, std::ios_base::end);
			int sizer = inr.tellg();
			inr.seekg(0, std::ios_base::beg);

			inw.seekg(0, std::ios_base::end);
			int sizew = inw.tellg();
			inw.seekg(0, std::ios_base::beg);

			if (sizer != sizew)
			{
				ret = EXIT_FAILURE;
			}
			else
			{
				unsigned char * result = new unsigned char[sizer];
				unsigned char * witness = new unsigned char[sizer];
				memset(result, (sizer) * sizeof(TCHAR), 0);
				memset(witness, (sizer) * sizeof(TCHAR), 0);
				inr.read((TCHAR *)result, sizer);
				inw.read((TCHAR *)witness, sizer);

				if (memcmp(result, witness, sizer) != 0)
				{
					ret = EXIT_FAILURE;
				}

				delete [] result;
				delete [] witness;

				inr.close();
				inw.close();
			}
		}
	}
	catch(Exception&)
	{
		ret = EXIT_FAILURE;
	}

	return ret;
}
<|endoftext|>


<commit_before>/**
 * \file cvmfs_sync.cc
 *
 * This tool makes the changes to a repository based on the cvmfsflt
 * kernel module log.
 * We call the user's working directoy "shadow directory".  This shadow
 * directory is synchronized with a CVMFS2 repository.  The .cvmfscatalog
 * magic file is translated into nested catalogs.
 *
 * On the repository side we have a catalogs directory that mimicks the
 * shadow directory structure and stores compressed and uncompressed
 * versions of all catalogs.  The raw data are stored in the data
 * subdirectory in zlib-compressed form.  They are named with their SHA1
 * hash of the compressed file (like in CVMFS client cache, but with a
 * 2-level cache hierarchy).  Symlinks from the catalog directory to the
 * data directory form the connection. If necessary, add a .htaccess file
 * to allow Apache to follow the symlinks.
 *
 * Developed by Jakob Blomer 2010 at CERN
 * jakob.blomer@cern.ch
 */

#define _FILE_OFFSET_BITS 64

#include "cvmfs_config.h"

#include "cvmfs_sync_aufs.h"
#include "cvmfs_sync.h"

#include <string>
#include <iostream>
#include <sstream>
#include <set>

#include "util.h"
#include "monitor.h"

//#include "cvmfs_sync_catalog.h"

#include "compat.h"

using namespace std;
using namespace cvmfs;

static void usage() {
   cout << "CernVM-FS sync shadow tree with repository" << endl;
   cout << "Usage: cvmfs_sync -s <union volume> -o <overlay directory> -c <cvmfs mounted volume> -r <repository store>" << endl
        << "                  [-p(rint change set)] [-d(ry run)] [-i <immutable dir(,dir)*>]" << endl
        << "                  [-k(ey file)] [-z (lazy attach of catalogs)] [-b(ookkeeping of dirty catalogs)]" << endl
        << "                  [-t <threads>] [-m(ucatalogs)]" << endl << endl
        << "Make sure that a 'data' and a 'catalogs' subdirectory exist in your repository store." << endl
        << "Also, your webserver must be able to follow symlinks in the catalogs subdirectory." << endl
        << "For Apache, you can add 'Options +FollowSymLinks' to a '.htaccess' file."
        << endl << endl;
}

bool parseParameters(int argc, char **argv, SyncParameters *p) {
	// print some help if needed
	if ((argc < 2) || (string(argv[1]) == "-h") || (string(argv[1]) == "--help") ||
		(string(argv[1]) == "-v") || (string(argv[1]) == "--version")){
		usage();
		return false;
	}

	// set defaults
	p->print_changeset = false;
	p->dry_run = false;
	p->lazy_attach = false;
	p->sync_threads = 0;
	p->mucatalogs = false;

	// read the parameters
	char c;
	while ((c = getopt(argc, argv, "s:o:c:r:pdi:k:zbt:m")) != -1) {
		switch (c) {

		// directories
		case 's':
			p->dir_shadow = canonical_path(optarg);
			break;
		case 'c':
			p->dir_cvmfs = canonical_path(optarg);
			break;
		case 'r': {
			const string path = canonical_path(optarg);
			p->dir_data = path + "/data";
			p->dir_catalogs = path + "/catalogs";
			break;
		}
		case 'o':
			p->dir_overlay = canonical_path(optarg);
			break;

		// switches
		case 'p':
			p->print_changeset = true;
			break;
		case 'd':
			p->dry_run = true;
			break;
		case 'z':
			p->lazy_attach = true;
			break;
		case 'm':
			p->mucatalogs = true;
			break;

		// misc
		case 'i': {
			char *token = strtok(optarg, ",");
			while (token != NULL) {
				p->immutables.insert(canonical_path(token));
				token = strtok(NULL, ",");
			}
			break;
		}
		case 'k':
			p->keyfile = optarg;
			break;
		case 't':
			p->sync_threads = atoi(optarg);
			break;
		case '?':
		default:
			usage();
			return false;
		}
	}

	return true;
}

bool initWatchdog() {
	umask(022);

	if (!monitor::init(".", false)) {
		printError("Failed to init watchdog");
		return false;
	}
	monitor::spawn();

	return true;
}

bool doSanityChecks(SyncParameters *p) {
	if (not directory_exists(p->dir_overlay)) {
		printError("overlay (copy on write) directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_shadow)) {
		printError("shadow directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_cvmfs)) {
		printError("mounted cvmfs repository does not exist");
		return false;
	}

	if (not directory_exists(p->dir_data)) {
		printError("data store directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_catalogs)) {
		printError("catalog store directory does not exist");
		return false;
	}

	return true;
}

bool createCacheDir(SyncParameters *p) {
	if (!make_cache_dir(p->dir_data, 0755)) {
		printError("could not initialize data store");
		return false;
	}

	return true;
}

int main(int argc, char **argv) {
	SyncParameters parameters;

	// do some initialization
	if (not parseParameters(argc, argv, &parameters)) return 1;
	if (not initWatchdog()) return 1;
	if (not doSanityChecks(&parameters)) return 2;
	if (not createCacheDir(&parameters)) return 3;

	// create worker objects
	CatalogHandler *catalogHandler = new CatalogHandler(&parameters);
	SyncMediator *mediator = new SyncMediator(catalogHandler, &parameters);
	SyncAufs1::initialize(mediator, &parameters);

	// sync
	if (not cvmfs::UnionSync::sharedInstance()->doYourMagic()) {
		printError("something went wrong during sync");
		return 4;
	}

	// clean up
	UnionSync::sharedInstance()->fini();
	delete mediator;
	delete catalogHandler;
	monitor::fini();

	return 0;
}
<commit_msg>fixed include to support ubuntu<commit_after>/**
 * \file cvmfs_sync.cc
 *
 * This tool makes the changes to a repository based on the cvmfsflt
 * kernel module log.
 * We call the user's working directoy "shadow directory".  This shadow
 * directory is synchronized with a CVMFS2 repository.  The .cvmfscatalog
 * magic file is translated into nested catalogs.
 *
 * On the repository side we have a catalogs directory that mimicks the
 * shadow directory structure and stores compressed and uncompressed
 * versions of all catalogs.  The raw data are stored in the data
 * subdirectory in zlib-compressed form.  They are named with their SHA1
 * hash of the compressed file (like in CVMFS client cache, but with a
 * 2-level cache hierarchy).  Symlinks from the catalog directory to the
 * data directory form the connection. If necessary, add a .htaccess file
 * to allow Apache to follow the symlinks.
 *
 * Developed by Jakob Blomer 2010 at CERN
 * jakob.blomer@cern.ch
 */

#define _FILE_OFFSET_BITS 64

#include "cvmfs_config.h"

#include "cvmfs_sync_aufs.h"
#include "cvmfs_sync.h"

#include <string>
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <set>

#include "util.h"
#include "monitor.h"

//#include "cvmfs_sync_catalog.h"

#include "compat.h"

using namespace std;
using namespace cvmfs;

static void usage() {
   cout << "CernVM-FS sync shadow tree with repository" << endl;
   cout << "Usage: cvmfs_sync -s <union volume> -o <overlay directory> -c <cvmfs mounted volume> -r <repository store>" << endl
        << "                  [-p(rint change set)] [-d(ry run)] [-i <immutable dir(,dir)*>]" << endl
        << "                  [-k(ey file)] [-z (lazy attach of catalogs)] [-b(ookkeeping of dirty catalogs)]" << endl
        << "                  [-t <threads>] [-m(ucatalogs)]" << endl << endl
        << "Make sure that a 'data' and a 'catalogs' subdirectory exist in your repository store." << endl
        << "Also, your webserver must be able to follow symlinks in the catalogs subdirectory." << endl
        << "For Apache, you can add 'Options +FollowSymLinks' to a '.htaccess' file."
        << endl << endl;
}

bool parseParameters(int argc, char **argv, SyncParameters *p) {
	// print some help if needed
	if ((argc < 2) || (string(argv[1]) == "-h") || (string(argv[1]) == "--help") ||
		(string(argv[1]) == "-v") || (string(argv[1]) == "--version")){
		usage();
		return false;
	}

	// set defaults
	p->print_changeset = false;
	p->dry_run = false;
	p->lazy_attach = false;
	p->sync_threads = 0;
	p->mucatalogs = false;

	// read the parameters
	char c;
	while ((c = getopt(argc, argv, "s:o:c:r:pdi:k:zbt:m")) != -1) {
		switch (c) {

		// directories
		case 's':
			p->dir_shadow = canonical_path(optarg);
			break;
		case 'c':
			p->dir_cvmfs = canonical_path(optarg);
			break;
		case 'r': {
			const string path = canonical_path(optarg);
			p->dir_data = path + "/data";
			p->dir_catalogs = path + "/catalogs";
			break;
		}
		case 'o':
			p->dir_overlay = canonical_path(optarg);
			break;

		// switches
		case 'p':
			p->print_changeset = true;
			break;
		case 'd':
			p->dry_run = true;
			break;
		case 'z':
			p->lazy_attach = true;
			break;
		case 'm':
			p->mucatalogs = true;
			break;

		// misc
		case 'i': {
			char *token = strtok(optarg, ",");
			while (token != NULL) {
				p->immutables.insert(canonical_path(token));
				token = strtok(NULL, ",");
			}
			break;
		}
		case 'k':
			p->keyfile = optarg;
			break;
		case 't':
			p->sync_threads = atoi(optarg);
			break;
		case '?':
		default:
			usage();
			return false;
		}
	}

	return true;
}

bool initWatchdog() {
	umask(022);

	if (!monitor::init(".", false)) {
		printError("Failed to init watchdog");
		return false;
	}
	monitor::spawn();

	return true;
}

bool doSanityChecks(SyncParameters *p) {
	if (not directory_exists(p->dir_overlay)) {
		printError("overlay (copy on write) directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_shadow)) {
		printError("shadow directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_cvmfs)) {
		printError("mounted cvmfs repository does not exist");
		return false;
	}

	if (not directory_exists(p->dir_data)) {
		printError("data store directory does not exist");
		return false;
	}

	if (not directory_exists(p->dir_catalogs)) {
		printError("catalog store directory does not exist");
		return false;
	}

	return true;
}

bool createCacheDir(SyncParameters *p) {
	if (!make_cache_dir(p->dir_data, 0755)) {
		printError("could not initialize data store");
		return false;
	}

	return true;
}

int main(int argc, char **argv) {
	SyncParameters parameters;

	// do some initialization
	if (not parseParameters(argc, argv, &parameters)) return 1;
	if (not initWatchdog()) return 1;
	if (not doSanityChecks(&parameters)) return 2;
	if (not createCacheDir(&parameters)) return 3;

	// create worker objects
	CatalogHandler *catalogHandler = new CatalogHandler(&parameters);
	SyncMediator *mediator = new SyncMediator(catalogHandler, &parameters);
	SyncAufs1::initialize(mediator, &parameters);

	// sync
	if (not cvmfs::UnionSync::sharedInstance()->doYourMagic()) {
		printError("something went wrong during sync");
		return 4;
	}

	// clean up
	UnionSync::sharedInstance()->fini();
	delete mediator;
	delete catalogHandler;
	monitor::fini();

	return 0;
}
<|endoftext|>


<commit_before>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "eventview.h"

#include <qtextdocument.h>
#include <qtextcursor.h>
#include <qtextobject.h>
#include <qtimer.h>
#include <qscrollbar.h>
#include <qdebug.h>

using namespace QAccessibleClient;
QAccessible::UpdateHandler EventsWidget::m_originalAccessibilityUpdateHandler = 0;
QObject *EventsWidget::m_textEditForAccessibilityUpdateHandler = 0;

EventsWidget::EventsWidget(QAccessibleClient::Registry *registry, QWidget *parent)
    : QWidget(parent), m_registry(registry), m_selectedEvents(AllEvents) {
    m_ui.setupUi(this);

    m_ui.eventTextBrowser->setAccessibleName(QLatin1String("Events View"));
    m_ui.eventTextBrowser->setAccessibleDescription(QString("Displays all received events"));
    m_ui.eventTextBrowser->setOpenLinks(false);
    connect(m_ui.eventTextBrowser, SIGNAL(anchorClicked(QUrl)), this, SIGNAL(anchorClicked(QUrl)));
    connect(m_ui.clearButton, SIGNAL(clicked()), m_ui.eventTextBrowser, SLOT(clear()));
    connect(m_ui.eventSelectionTree->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(checkStateChanged()));

    m_textEditForAccessibilityUpdateHandler = m_ui.eventTextBrowser;

    // We need to wait for a11y to be active for this hack.
    QTimer::singleShot(500, this, SLOT(installUpdateHandler()));
}

void EventsWidget::installUpdateHandler()
{
    m_originalAccessibilityUpdateHandler = QAccessible::installUpdateHandler(customUpdateHandler);
    if (!m_originalAccessibilityUpdateHandler)
        QTimer::singleShot(500, this, SLOT(installUpdateHandler()));
}

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
void EventsWidget::customUpdateHandler(QAccessibleEvent *event)
{
    QObject *object = event->object();
#else
void EventsWidget::customUpdateHandler(QObject *object, int who, QAccessible::Event reason)
{
#endif
    if (object == m_textEditForAccessibilityUpdateHandler)
        return;
    //if (m_originalAccessibilityUpdateHandler)
    //    m_originalAccessibilityUpdateHandler(object, who, reason);
}

void EventsWidget::addLog(const QAccessibleClient::AccessibleObject &object, EventsWidget::EventTypes eventType, const QString &text)
{
    if (!object.isValid())
        return;
    if (object.name() == m_ui.eventTextBrowser->accessibleName() && object.description() == m_ui.eventTextBrowser->accessibleDescription())
        return;

    if (!(m_selectedEvents & eventType))
        return;

    QString eventName;
    switch (eventType) {
    case Focus:              eventName = QLatin1String("Focus event"); break;
    case StateChanged:       eventName = QLatin1String("State changed"); break;
    case NameChanged:        eventName = QLatin1String("Name changed"); break;
    case DescriptionChanged: eventName = QLatin1String("Description changed"); break;
    case Window:             eventName = QLatin1String("Window event"); break;
    case Document:           eventName = QLatin1String("Document event"); break;
    case Object:             eventName = QLatin1String("Object event"); break;
    case Text:               eventName = QLatin1String("Text event"); break;
    case Table:              eventName = QLatin1String("Table event"); break;
    }

    bool wasMax = m_ui.eventTextBrowser->verticalScrollBar()->value() == m_ui.eventTextBrowser->verticalScrollBar()->maximum();

    QTextDocument *doc = m_ui.eventTextBrowser->document();
    doc->blockSignals(true); // to prevent infinte TextCaretMoved events
    QTextCursor cursor(doc->lastBlock());
    cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);

    cursor.insertText(eventName.trimmed() + QLatin1String(": "));
    if (!text.isEmpty())
        cursor.insertText(text + QLatin1Char(' '));
    QString url = m_registry->url(object).toString();
    QString objectString = object.name() + QString(" [%1]").arg(object.roleName());
    cursor.insertHtml(QString("%2 ").arg(url).arg(objectString));

    AccessibleObject app = object.application();
    if (app.isValid()) {
        cursor.insertText(" (" + app.name() + ")");
    } else {
        qDebug() << "Invalid parent: " << object;
        cursor.insertText(" (invalid application)");
    }

    cursor.insertBlock();

    doc->blockSignals(false);

    if (wasMax) // scroll down if we where before scrolled down too
        m_ui.eventTextBrowser->verticalScrollBar()->setValue(m_ui.eventTextBrowser->verticalScrollBar()->maximum());
}

void EventsWidget::checkStateChanged()
{
    m_selectedEvents = NoEvents;
    QAbstractItemModel *model = m_ui.eventSelectionTree->model();
    for (int i = 0; i < model->rowCount(); ++i) {
        QModelIndex index = model->index(i, 0);
        bool checked = model->data(index, Qt::CheckStateRole).toBool();
        if (checked) {
            if (model->data(index) == "Window")
                m_selectedEvents = m_selectedEvents | Window;
            if (model->data(index) == "Name Changed")
                m_selectedEvents = m_selectedEvents | NameChanged;
            if (model->data(index) == "Description Changed")
                m_selectedEvents = m_selectedEvents | DescriptionChanged;
            if (model->data(index) == "State Changed")
                m_selectedEvents = m_selectedEvents | StateChanged;
            if (model->data(index) == "Focus")
                m_selectedEvents = m_selectedEvents | Focus;
            if (model->data(index) == "Text")
                m_selectedEvents = m_selectedEvents | Text;
            if (model->data(index) == "Document")
                m_selectedEvents = m_selectedEvents | Document;
            if (model->data(index) == "Object")
                m_selectedEvents = m_selectedEvents | Object;
            if (model->data(index) == "Others")
                m_selectedEvents = m_selectedEvents | Others;
        }
    }
}
<commit_msg>Only show events that are selected when starting.<commit_after>/*
    Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "eventview.h"

#include <qtextdocument.h>
#include <qtextcursor.h>
#include <qtextobject.h>
#include <qtimer.h>
#include <qscrollbar.h>
#include <qdebug.h>

using namespace QAccessibleClient;
QAccessible::UpdateHandler EventsWidget::m_originalAccessibilityUpdateHandler = 0;
QObject *EventsWidget::m_textEditForAccessibilityUpdateHandler = 0;

EventsWidget::EventsWidget(QAccessibleClient::Registry *registry, QWidget *parent)
    : QWidget(parent), m_registry(registry), m_selectedEvents(AllEvents) {
    m_ui.setupUi(this);

    m_ui.eventTextBrowser->setAccessibleName(QLatin1String("Events View"));
    m_ui.eventTextBrowser->setAccessibleDescription(QString("Displays all received events"));
    m_ui.eventTextBrowser->setOpenLinks(false);
    connect(m_ui.eventTextBrowser, SIGNAL(anchorClicked(QUrl)), this, SIGNAL(anchorClicked(QUrl)));
    connect(m_ui.clearButton, SIGNAL(clicked()), m_ui.eventTextBrowser, SLOT(clear()));
    connect(m_ui.eventSelectionTree->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(checkStateChanged()));

    m_textEditForAccessibilityUpdateHandler = m_ui.eventTextBrowser;
    checkStateChanged();

    // We need to wait for a11y to be active for this hack.
    QTimer::singleShot(500, this, SLOT(installUpdateHandler()));
}

void EventsWidget::installUpdateHandler()
{
    m_originalAccessibilityUpdateHandler = QAccessible::installUpdateHandler(customUpdateHandler);
    if (!m_originalAccessibilityUpdateHandler)
        QTimer::singleShot(500, this, SLOT(installUpdateHandler()));
}

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
void EventsWidget::customUpdateHandler(QAccessibleEvent *event)
{
    QObject *object = event->object();
#else
void EventsWidget::customUpdateHandler(QObject *object, int who, QAccessible::Event reason)
{
#endif
    if (object == m_textEditForAccessibilityUpdateHandler)
        return;
    //if (m_originalAccessibilityUpdateHandler)
    //    m_originalAccessibilityUpdateHandler(object, who, reason);
}

void EventsWidget::addLog(const QAccessibleClient::AccessibleObject &object, EventsWidget::EventTypes eventType, const QString &text)
{
    if (!object.isValid())
        return;
    if (object.name() == m_ui.eventTextBrowser->accessibleName() && object.description() == m_ui.eventTextBrowser->accessibleDescription())
        return;

    if (!(m_selectedEvents & eventType))
        return;

    QString eventName;
    switch (eventType) {
    case Focus:              eventName = QLatin1String("Focus event"); break;
    case StateChanged:       eventName = QLatin1String("State changed"); break;
    case NameChanged:        eventName = QLatin1String("Name changed"); break;
    case DescriptionChanged: eventName = QLatin1String("Description changed"); break;
    case Window:             eventName = QLatin1String("Window event"); break;
    case Document:           eventName = QLatin1String("Document event"); break;
    case Object:             eventName = QLatin1String("Object event"); break;
    case Text:               eventName = QLatin1String("Text event"); break;
    case Table:              eventName = QLatin1String("Table event"); break;
    }

    bool wasMax = m_ui.eventTextBrowser->verticalScrollBar()->value() == m_ui.eventTextBrowser->verticalScrollBar()->maximum();

    QTextDocument *doc = m_ui.eventTextBrowser->document();
    doc->blockSignals(true); // to prevent infinte TextCaretMoved events
    QTextCursor cursor(doc->lastBlock());
    cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);

    cursor.insertText(eventName.trimmed() + QLatin1String(": "));
    if (!text.isEmpty())
        cursor.insertText(text + QLatin1Char(' '));
    QString url = m_registry->url(object).toString();
    QString objectString = object.name() + QString(" [%1]").arg(object.roleName());
    cursor.insertHtml(QString("%2 ").arg(url).arg(objectString));

    AccessibleObject app = object.application();
    if (app.isValid()) {
        cursor.insertText(" (" + app.name() + ")");
    } else {
        qDebug() << "Invalid parent: " << object;
        cursor.insertText(" (invalid application)");
    }

    cursor.insertBlock();

    doc->blockSignals(false);

    if (wasMax) // scroll down if we where before scrolled down too
        m_ui.eventTextBrowser->verticalScrollBar()->setValue(m_ui.eventTextBrowser->verticalScrollBar()->maximum());
}

void EventsWidget::checkStateChanged()
{
    m_selectedEvents = NoEvents;
    QAbstractItemModel *model = m_ui.eventSelectionTree->model();
    for (int i = 0; i < model->rowCount(); ++i) {
        QModelIndex index = model->index(i, 0);
        bool checked = model->data(index, Qt::CheckStateRole).toBool();
        if (checked) {
            if (model->data(index) == "Window")
                m_selectedEvents = m_selectedEvents | Window;
            if (model->data(index) == "Name Changed")
                m_selectedEvents = m_selectedEvents | NameChanged;
            if (model->data(index) == "Description Changed")
                m_selectedEvents = m_selectedEvents | DescriptionChanged;
            if (model->data(index) == "State Changed")
                m_selectedEvents = m_selectedEvents | StateChanged;
            if (model->data(index) == "Focus")
                m_selectedEvents = m_selectedEvents | Focus;
            if (model->data(index) == "Text")
                m_selectedEvents = m_selectedEvents | Text;
            if (model->data(index) == "Document")
                m_selectedEvents = m_selectedEvents | Document;
            if (model->data(index) == "Object")
                m_selectedEvents = m_selectedEvents | Object;
            if (model->data(index) == "Others")
                m_selectedEvents = m_selectedEvents | Others;
        }
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <unordered_map>
#include <map>
#include <tuple>
#include <type_traits>
#include "base/header.hpp"
#include "base/function_traits.hpp"
#include "base/thread_pool.hpp"
#include "base/logger.hpp"
#include "base/singleton.hpp"
#include "base/serialize_util.hpp"
#include "connection.hpp"

namespace czrpc
{
namespace server
{
class invoker_function
{
public:
    using function_t = std::function<void(const message_ptr&, message_ptr&)>;
    invoker_function() = default;
    invoker_function(const function_t& func) : func_(func) {}

    void operator()(const request_content& content, const connection_ptr& conn)
    {
        try
        {
            message_ptr out_message;
            func_(serialize_util::singleton::get()->deserialize(content.message_name, content.body), out_message);
            if (out_message == nullptr)
            {
                log_warn("Out message is nullptr");
                return;
            }
            std::string in_message_name = out_message->GetDescriptor()->full_name();
            std::string in_body = serialize_util::singleton::get()->serialize(out_message);
            if (!in_message_name.empty() && !in_body.empty())
            {
                conn->async_write(response_content{ content.call_id, in_message_name, in_body });
            }
        }
        catch (std::exception& e)
        {
            log_warn(e.what());
            conn->disconnect();
        }
    }

private:
    function_t func_ = nullptr;
};

class invoker_function_raw
{
public:
    using function_t = std::function<void(const std::string&, std::string&)>;
    invoker_function_raw() = default;
    invoker_function_raw(const function_t& func) : func_(func) {}

    void operator()(const request_content& content, const connection_ptr& conn)
    {
        try
        {
            std::string out_body;
            func_(content.body, out_body);
            if (!out_body.empty())
            {
                conn->async_write(response_content{ content.call_id, "", out_body });
            }
        }
        catch (std::exception& e)
        {
            log_warn(e.what());
            conn->disconnect();
        }
    }

private:
    function_t func_ = nullptr;
};

class router
{
    DEFINE_SINGLETON(router);
public:
    router() = default;

    void multithreaded(std::size_t num)
    {
        threadpool_.init_thread_num(num);
    }

    void stop()
    {
        threadpool_.stop();
    }

    template<typename Function>
    void bind(const std::string& protocol, const Function& func)
    {
        bind_non_member_func(protocol, func);
    }

    template<typename Function, typename Self>
    void bind(const std::string& protocol, const Function& func, Self* self)
    {
        bind_member_func(protocol, func, self);
    }

    void unbind(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.erase(protocol);
    }

    bool is_bind(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        auto iter = invoker_map_.find(protocol);
        if (iter != invoker_map_.end())
        {
            return true;
        }
        return false;
    }

    template<typename Function>
    void bind_raw(const std::string& protocol, const Function& func)
    {
        bind_non_member_func_raw(protocol, func);
    }

    template<typename Function, typename Self>
    void bind_raw(const std::string& protocol, const Function& func, Self* self)
    {
        bind_member_func_raw(protocol, func, self);
    }

    void unbind_raw(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.erase(protocol);
    }

    bool is_bind_raw(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        auto iter = invoker_raw_map_.find(protocol);
        if (iter != invoker_raw_map_.end())
        {
            return true;
        }
        return false;
    }

    bool route(const request_content& content, const client_flag& flag, const connection_ptr& conn)
    {
        if (flag.type == client_type::rpc_client || flag.type == client_type::async_rpc_client)
        {
            return route_rpc_client(content, flag, conn);
        }
        else if (flag.type == client_type::pub_client)
        {
            return route_pub_client(content, flag);
        }
        else if (flag.type == client_type::sub_client)
        {
            return route_sub_client(content, conn);
        }
        return false;
    }

private:
    template<typename Function>
    static typename std::enable_if<std::is_void<typename std::result_of<Function(const message_ptr&)>::type>::value>::type
    call(const Function& func, const message_ptr& in_message, message_ptr&)
    {
        func(in_message);
    }

    template<typename Function>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(const message_ptr&)>::type>::value>::type
    call(const Function& func, const message_ptr& in_message, message_ptr& out_message)
    {
        out_message = func(in_message);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<std::is_void<typename std::result_of<Function(Self, const message_ptr&)>::type>::value>::type
    call_member(const Function& func, Self* self, const message_ptr& in_message, message_ptr&)
    {
        (*self.*func)(in_message);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(Self, const message_ptr&)>::type>::value>::type
    call_member(const Function& func, Self* self, const message_ptr& in_message, message_ptr& out_message)
    {
        out_message = (*self.*func)(in_message);
    }

    template<typename Function>
    static typename std::enable_if<std::is_void<typename std::result_of<Function(const std::string&)>::type>::value>::type
    call_raw(const Function& func, const std::string& body, std::string&)
    {
        func(body);
    }

    template<typename Function>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(const std::string&)>::type>::value>::type
    call_raw(const Function& func, const std::string& body, std::string& out_body)
    {
        out_body = func(body);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<std::is_void<typename std::result_of<Function(Self, const std::string&)>::type>::value>::type
    call_member_raw(const Function& func, Self* self, const std::string& body, std::string&)
    {
        (*self.*func)(body);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(Self, const std::string&)>::type>::value>::type
    call_member_raw(const Function& func, Self* self, const std::string& body, std::string& out_body)
    {
        out_body = (*self.*func)(body);
    }

private:
    template<typename Function>
    class invoker
    {
    public:
        static void apply(const Function& func, const message_ptr& in_message, message_ptr& out_message)
        {
            try
            {
                call(func, in_message, out_message);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }

        template<typename Self>
        static void apply_member(const Function& func, Self* self, const message_ptr& in_message, message_ptr& out_message)
        {
            try
            {
                call_member(func, self, in_message, out_message);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }
    };

    template<typename Function>
    class invoker_raw
    {
    public:
        static void apply(const Function& func, const std::string& body, std::string& out_body)
        {
            try
            {
                call_raw(func, body, out_body);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }

        template<typename Self>
        static void apply_member(const Function& func, Self* self, const std::string& body, std::string& out_body)
        {
            try
            {
                call_member_raw(func, self, body, out_body);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }
    };

    struct pub_coming_helper
    {
        void operator()(serialize_mode mode, const push_content& content)
        {
            router::singleton::get()->publisher_coming_(mode, content);
        }
    };

    struct sub_coming_helper
    {
        void operator()(const std::string& topic_name, const std::string& body, const connection_ptr& conn)
        {
            router::singleton::get()->subscriber_coming_(topic_name, body, conn);
        }
    };

private:
    template<typename Function>
    void bind_non_member_func(const std::string& protocol, const Function& func)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.emplace(protocol, invoker_function{ std::bind(&invoker<Function>::apply,
                                                                   func, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function, typename Self>
    void bind_member_func(const std::string& protocol, const Function& func, Self* self)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.emplace(protocol, invoker_function{ std::bind(&invoker<Function>::template apply_member<Self>,
                                                                   func, self, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function>
    void bind_non_member_func_raw(const std::string& protocol, const Function& func)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.emplace(protocol, invoker_function_raw{ std::bind(&invoker_raw<Function>::apply,
                                                                           func, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function, typename Self>
    void bind_member_func_raw(const std::string& protocol, const Function& func, Self* self)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.emplace(protocol, invoker_function_raw{ std::bind(&invoker_raw<Function>::template apply_member<Self>,
                                                                           func, self, std::placeholders::_1, std::placeholders::_2) });
    }

    bool route_rpc_client(const request_content& content, const client_flag& flag, const connection_ptr& conn)
    {
        if (flag.mode == serialize_mode::serialize)
        {
            std::lock_guard<std::mutex> lock(map_mutex_);
            auto iter = invoker_map_.find(content.protocol);
            if (iter != invoker_map_.end())
            {
                threadpool_.add_task(iter->second, content, conn);
                return true;
            }
        }
        else if (flag.mode == serialize_mode::non_serialize)
        {
            std::lock_guard<std::mutex> lock(raw_map_mutex_);
            auto iter = invoker_raw_map_.find(content.protocol);
            if (iter != invoker_raw_map_.end())
            {
                threadpool_.add_task(iter->second, content, conn);
                return true;
            }
        }
        log_warn("Route failed, not found this protocol: {}", content.protocol);
        return false;
    }

    bool route_pub_client(const request_content& content, const client_flag& flag)
    {
        push_content ctx { content.protocol, content.message_name, content.body };
        threadpool_.add_task(pub_coming_helper_, flag.mode, ctx);
        return true;
    }

    bool route_sub_client(const request_content& content, const connection_ptr& conn)
    {
        threadpool_.add_task(sub_coming_helper_, content.protocol, content.body, conn);
        return true;
    }

public:
    using pub_comming_callback = std::function<void(serialize_mode, const push_content&)>;
    using sub_comming_callback = std::function<void(const std::string&, const std::string&, const connection_ptr&)>;
    pub_comming_callback publisher_coming_ = nullptr;
    sub_comming_callback subscriber_coming_ = nullptr;

private:
    thread_pool threadpool_;
    std::unordered_map<std::string, invoker_function> invoker_map_;
    std::unordered_map<std::string, invoker_function_raw> invoker_raw_map_;
    std::mutex map_mutex_;
    std::mutex raw_map_mutex_;
    pub_coming_helper pub_coming_helper_;
    sub_coming_helper sub_coming_helper_;
};

}
}

<commit_msg>update router<commit_after>#pragma once

#include <iostream>
#include <unordered_map>
#include <map>
#include <tuple>
#include <type_traits>
#include "base/header.hpp"
#include "base/function_traits.hpp"
#include "base/thread_pool.hpp"
#include "base/logger.hpp"
#include "base/singleton.hpp"
#include "base/serialize_util.hpp"
#include "connection.hpp"

namespace czrpc
{
namespace server
{
class invoker_function
{
public:
    using function_t = std::function<void(const message_ptr&, message_ptr&)>;
    invoker_function() = default;
    invoker_function(const function_t& func) : func_(func) {}

    void operator()(const request_content& content, const connection_ptr& conn)
    {
        try
        {
            message_ptr out_message;
            func_(serialize_util::singleton::get()->deserialize(content.message_name, content.body), out_message);
            if (out_message == nullptr)
            {
                log_warn("Out message is nullptr");
                return;
            }
            std::string in_message_name = out_message->GetDescriptor()->full_name();
            std::string in_body = serialize_util::singleton::get()->serialize(out_message);
            if (!in_message_name.empty() && !in_body.empty())
            {
                conn->async_write(response_content{ content.call_id, in_message_name, in_body });
            }
        }
        catch (std::exception& e)
        {
            log_warn(e.what());
            conn->disconnect();
        }
    }

private:
    function_t func_ = nullptr;
};

class invoker_function_raw
{
public:
    using function_t = std::function<void(const std::string&, std::string&)>;
    invoker_function_raw() = default;
    invoker_function_raw(const function_t& func) : func_(func) {}

    void operator()(const request_content& content, const connection_ptr& conn)
    {
        try
        {
            std::string out_body;
            func_(content.body, out_body);
            if (!out_body.empty())
            {
                conn->async_write(response_content{ content.call_id, "", out_body });
            }
        }
        catch (std::exception& e)
        {
            log_warn(e.what());
            conn->disconnect();
        }
    }

private:
    function_t func_ = nullptr;
};

class router
{
    DEFINE_SINGLETON(router);
public:
    router() = default;

    void multithreaded(std::size_t num)
    {
        threadpool_.init_thread_num(num);
    }

    void stop()
    {
        threadpool_.stop();
    }

    template<typename Function>
    void bind(const std::string& protocol, const Function& func)
    {
        bind_non_member_func(protocol, func);
    }

    template<typename Function, typename Self>
    void bind(const std::string& protocol, const Function& func, Self* self)
    {
        bind_member_func(protocol, func, self);
    }

    void unbind(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.erase(protocol);
    }

    bool is_bind(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        auto iter = invoker_map_.find(protocol);
        if (iter != invoker_map_.end())
        {
            return true;
        }
        return false;
    }

    template<typename Function>
    void bind_raw(const std::string& protocol, const Function& func)
    {
        bind_non_member_func_raw(protocol, func);
    }

    template<typename Function, typename Self>
    void bind_raw(const std::string& protocol, const Function& func, Self* self)
    {
        bind_member_func_raw(protocol, func, self);
    }

    void unbind_raw(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.erase(protocol);
    }

    bool is_bind_raw(const std::string& protocol)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        auto iter = invoker_raw_map_.find(protocol);
        if (iter != invoker_raw_map_.end())
        {
            return true;
        }
        return false;
    }

    bool route(const request_content& content, const client_flag& flag, const connection_ptr& conn)
    {
        if (flag.type == client_type::rpc_client || flag.type == client_type::async_rpc_client)
        {
            return route_rpc_client(content, flag, conn);
        }
        else if (flag.type == client_type::pub_client)
        {
            return route_pub_client(content, flag);
        }
        else if (flag.type == client_type::sub_client)
        {
            return route_sub_client(content, conn);
        }
        return false;
    }

private:
    template<typename Function>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(const message_ptr&)>::type>::value>::type
    call(const Function& func, const message_ptr& in_message, message_ptr& out_message)
    {
        out_message = func(in_message);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(Self, const message_ptr&)>::type>::value>::type
    call_member(const Function& func, Self* self, const message_ptr& in_message, message_ptr& out_message)
    {
        out_message = (*self.*func)(in_message);
    }

    template<typename Function>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(const std::string&)>::type>::value>::type
    call_raw(const Function& func, const std::string& body, std::string& out_body)
    {
        out_body = func(body);
    }

    template<typename Function, typename Self>
    static typename std::enable_if<!std::is_void<typename std::result_of<Function(Self, const std::string&)>::type>::value>::type
    call_member_raw(const Function& func, Self* self, const std::string& body, std::string& out_body)
    {
        out_body = (*self.*func)(body);
    }

private:
    template<typename Function>
    class invoker
    {
    public:
        static void apply(const Function& func, const message_ptr& in_message, message_ptr& out_message)
        {
            try
            {
                call(func, in_message, out_message);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }

        template<typename Self>
        static void apply_member(const Function& func, Self* self, const message_ptr& in_message, message_ptr& out_message)
        {
            try
            {
                call_member(func, self, in_message, out_message);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }
    };

    template<typename Function>
    class invoker_raw
    {
    public:
        static void apply(const Function& func, const std::string& body, std::string& out_body)
        {
            try
            {
                call_raw(func, body, out_body);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }

        template<typename Self>
        static void apply_member(const Function& func, Self* self, const std::string& body, std::string& out_body)
        {
            try
            {
                call_member_raw(func, self, body, out_body);
            }
            catch (std::exception& e)
            {
                log_warn(e.what());
            }
        }
    };

    struct pub_coming_helper
    {
        void operator()(serialize_mode mode, const push_content& content)
        {
            router::singleton::get()->publisher_coming_(mode, content);
        }
    };

    struct sub_coming_helper
    {
        void operator()(const std::string& topic_name, const std::string& body, const connection_ptr& conn)
        {
            router::singleton::get()->subscriber_coming_(topic_name, body, conn);
        }
    };

private:
    template<typename Function>
    void bind_non_member_func(const std::string& protocol, const Function& func)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.emplace(protocol, invoker_function{ std::bind(&invoker<Function>::apply,
                                                                   func, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function, typename Self>
    void bind_member_func(const std::string& protocol, const Function& func, Self* self)
    {
        std::lock_guard<std::mutex> lock(map_mutex_);
        invoker_map_.emplace(protocol, invoker_function{ std::bind(&invoker<Function>::template apply_member<Self>,
                                                                   func, self, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function>
    void bind_non_member_func_raw(const std::string& protocol, const Function& func)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.emplace(protocol, invoker_function_raw{ std::bind(&invoker_raw<Function>::apply,
                                                                           func, std::placeholders::_1, std::placeholders::_2) });
    }

    template<typename Function, typename Self>
    void bind_member_func_raw(const std::string& protocol, const Function& func, Self* self)
    {
        std::lock_guard<std::mutex> lock(raw_map_mutex_);
        invoker_raw_map_.emplace(protocol, invoker_function_raw{ std::bind(&invoker_raw<Function>::template apply_member<Self>,
                                                                           func, self, std::placeholders::_1, std::placeholders::_2) });
    }

    bool route_rpc_client(const request_content& content, const client_flag& flag, const connection_ptr& conn)
    {
        if (flag.mode == serialize_mode::serialize)
        {
            std::lock_guard<std::mutex> lock(map_mutex_);
            auto iter = invoker_map_.find(content.protocol);
            if (iter != invoker_map_.end())
            {
                threadpool_.add_task(iter->second, content, conn);
                return true;
            }
        }
        else if (flag.mode == serialize_mode::non_serialize)
        {
            std::lock_guard<std::mutex> lock(raw_map_mutex_);
            auto iter = invoker_raw_map_.find(content.protocol);
            if (iter != invoker_raw_map_.end())
            {
                threadpool_.add_task(iter->second, content, conn);
                return true;
            }
        }
        log_warn("Route failed, not found this protocol: {}", content.protocol);
        return false;
    }

    bool route_pub_client(const request_content& content, const client_flag& flag)
    {
        push_content ctx { content.protocol, content.message_name, content.body };
        threadpool_.add_task(pub_coming_helper_, flag.mode, ctx);
        return true;
    }

    bool route_sub_client(const request_content& content, const connection_ptr& conn)
    {
        threadpool_.add_task(sub_coming_helper_, content.protocol, content.body, conn);
        return true;
    }

public:
    using pub_comming_callback = std::function<void(serialize_mode, const push_content&)>;
    using sub_comming_callback = std::function<void(const std::string&, const std::string&, const connection_ptr&)>;
    pub_comming_callback publisher_coming_ = nullptr;
    sub_comming_callback subscriber_coming_ = nullptr;

private:
    thread_pool threadpool_;
    std::unordered_map<std::string, invoker_function> invoker_map_;
    std::unordered_map<std::string, invoker_function_raw> invoker_raw_map_;
    std::mutex map_mutex_;
    std::mutex raw_map_mutex_;
    pub_coming_helper pub_coming_helper_;
    sub_coming_helper sub_coming_helper_;
};

}
}

<|endoftext|>


<commit_before>#include "stdio.h"
#include "BVS.h"

int main(int argc, char** argv)
{
    // start BVS
    BVS bvs(argc, argv);
    bvs.setLogSystemVerbosity(3);
    bvs.enableLogFile("BVSLog.txt");

    //bvs.setup(); // load and apply options from config

    BVSLogger logger("BVSDaemon");
    LOG(2, "starting!");

    bvs.loadModules();

    // TODO either cleanup or turn into conditional test
    LOG(0, "CLI");
    LOG(0, "CLI FILE");
    bvs.disableLogConsole();
    LOG(0, "FILE");
    BVSLogger file("FILE", 3, BVSLogger::TO_FILE);
    file.out(0) << "FILE ONLY" << std::endl;
    bvs.enableLogConsole();
    BVSLogger cli("CLI", 3, BVSLogger::TO_CLI);
    cli.out(0) << "CLI ONLY" << std::endl;
    bvs.disableLogConsole();
    bvs.disableLogFile();
    LOG(0, "NOOP");
    bvs.enableLogConsole();
    LOG(0, "CLI");
    bvs.disableLogConsole();
    bvs.enableLogFile("BVSLog.txt", true);
    LOG(0, "FILE AGAIN");
    bvs.enableLogConsole();
    BVSLogger both("BOTH", 3, BVSLogger::TO_CLI_AND_FILE);
    both.out(0) << "CLI AND FILE" << std::endl;

    int foo;
    std::string bar;
    bool test;
    bvs.config.getValue("core.foo", foo)
        .getValue("core.bar", bar)
        .getValue("core.test", test);

    LOG(0, "Getting foo: " << foo);
    LOG(0, "Getting bar: " << bar);
    LOG(0, "BOOL: " << test);

    foo = bvs.config.getValue<int>("core.foo");
    bar = bvs.config.getValue<std::string>("core.bar");
    test = bvs.config.getValue<bool>("core.test");
    LOG(0, "Getting foo directly: " << foo);
    LOG(0, "Getting bar directly: " << bar);
    LOG(0, "BOOL directly: " << test);

    std::string bar2;
    std::string bar3;
    bvs.config.getValue("core.bar", bar2);
    bar3 = bvs.config.getValue<std::string>("core.bar");
    LOG(0, "bar2: " << bar2);
    LOG(0, "bar3: " << bar3);

    bool test2;
    bool test3;
    bvs.config.getValue("core.test", test2);
    test3 = bvs.config.getValue<bool>("core.test");
    LOG(0, "test2: " << test2);
    LOG(0, "test3: " << test3);

    std::vector<std::string> list;
    bvs.config.getValue("core.list", list);
    for (auto it : list)
    {
        LOG(0, it);
    }

    return 0;
}
<commit_msg>test: remove<commit_after>#include "stdio.h"
#include "BVS.h"

int main(int argc, char** argv)
{
    // start BVS
    BVS bvs(argc, argv);
    bvs.enableLogFile("BVSLog.txt");

    BVSLogger logger("BVSDaemon");
    LOG(2, "starting!");

    //LOG(2, "dump all config options!");
    //bvs.config.showOptionStore();

    LOG(2, "loading Modules!");
    bvs.loadModules();

    LOG(2, "run!");
    //bvs.run();

    //std::string s = "core.list";
    //std::vector<int> foo;
    //bvs.config.getValue(s, foo);
    //for (auto it : foo)
    //{
        //std::cout << foo[it] << std::endl;
    //}

    return 0;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include "gtest/gtest.h"
#include "braincloud/BrainCloudClient.h"
#include "braincloud/BrainCloudEntity.h"
#include "TestResult.h"
#include "json/json.h"
#include "TestBCEntity.h"

using namespace BrainCloud;

TEST_F(TestBCEntity, Create)
{
    TestResult tr;

    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), "", &tr);
    if (tr.run(m_bc))
    {
        m_entityId = tr.m_response["data"]["entityId"].asString();
        ASSERT_NE("", m_entityId);
    }

    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, Update)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    CreateDefaultEntity();

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateEntity(m_entityId.c_str(), m_entityType, fw.write(entityData), "", -1, &tr);
    tr.run(m_bc);

    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, BadUpdate)
{
    TestResult tr;
    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";
    std::string badEntityId = "wakawaka";

    Json::FastWriter fw;
    m_bc->getEntityService()->updateEntity(badEntityId.c_str(), m_entityType, fw.write(entityData), "", -1, &tr);
    // TODO : put in the correct error code constant
    tr.runExpectFail(m_bc, HTTP_NOT_FOUND, 40332);
}

TEST_F(TestBCEntity, Delete)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->deleteEntity(m_entityId.c_str(), -1, &tr);
    tr.run(m_bc);
}

TEST_F(TestBCEntity, GetEntity)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getEntity(m_entityId.c_str(), &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, GetSingleton)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getSingleton(m_entityType, &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, GetSharedEntityForPlayerId)
{
    TestResult tr;
    CreateDefaultEntity();
    m_bc->getEntityService()->getSharedEntityForPlayerId(GetUser(UserA)->m_profileId, m_entityId.c_str(), &tr);
    tr.run(m_bc);
    DeleteEntity();
}

TEST_F(TestBCEntity, GetSharedEntitiesForPlayerId)
{
    TestResult tr;
    CreateDefaultEntity();
    m_bc->getEntityService()->getSharedEntitiesForPlayerId(GetUser(UserA)->m_profileId, &tr);
    tr.run(m_bc);
    DeleteEntity();
}

TEST_F(TestBCEntity, GetEntitesByType)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getEntitiesByType(m_entityType, &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, DeleteSingleton)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->deleteSingleton(m_entityType, -1, &tr);
    tr.run(m_bc);
}

TEST_F(TestBCEntity, UpdateSharedEntity)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    CreateDefaultEntity();

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateSharedEntity(m_entityId.c_str(), GetUser(UserA)->m_profileId, m_entityType, fw.write(entityData), -1, &tr);
    tr.run(m_bc);

    DeleteEntity();
}

TEST_F(TestBCEntity, UpdateSingleton)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateSingleton(m_entityType, fw.write(entityData), "", -1, &tr);
    tr.run(m_bc);

    DeleteEntity();
}

TEST_F(TestBCEntity, GetList)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value whereJson;
    whereJson["entityType"] = m_entityType;

    m_bc->getEntityService()->getList(fw.write(whereJson), "", 100, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetSharedEntitiesListForPlayerId)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value whereJson;
    whereJson["entityType"] = m_entityType;

    m_bc->getEntityService()->getSharedEntitiesListForPlayerId(
        GetUser(UserA)->m_profileId,
        fw.write(whereJson), "", 100, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetListCount)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value searchType;
    searchType["entityType"] = m_entityType;
    std::string searchTypeStr = fw.write(searchType);

    m_bc->getEntityService()->getListCount(searchTypeStr, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetPage)
{
    GenerateDefaultEntites(20);

    Json::Value context;
    Json::FastWriter fw;

    context["pagination"]["rowsPerPage"] = 12;
    context["pagination"]["pageNumber"] = 1;
    context["searchCriteria"]["entityType"] = m_entityType;

    TestResult tr;
    m_bc->getEntityService()->getPage(fw.write(context).c_str(), &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetPageOffset)
{
    GenerateDefaultEntites(20);

    Json::Value context;
    Json::FastWriter fw;

    context["pagination"]["rowsPerPage"] = 12;
    context["pagination"]["pageNumber"] = 1;
    context["searchCriteria"]["entityType"] = m_entityType;

    TestResult tr;
    m_bc->getEntityService()->getPage(fw.write(context).c_str(), &tr);
    tr.run(m_bc);

    std::string context_str = tr.m_response["data"]["context"].asString();

    tr.reset();
    m_bc->getEntityService()->getPageOffset(context_str.c_str(), 1, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, IncrementUserEntityData)
{
    TestResult tr;
    Json::Value entityData;
    entityData["test"] = 1233;

    std::string entityId;

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), "", &tr);
    if (tr.run(m_bc)) entityId = tr.m_response["data"]["entityId"].asString();

    m_bc->getEntityService()->incrementUserEntityData(entityId.c_str(), GetUser(UserA)->m_profileId, fw.write(entityData), true, &tr);
    tr.run(m_bc);

    DeleteEntity(entityId);
}

void TestBCEntity::CreateDefaultEntity()
{
    TestResult tr;
    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";
    Json::Value entityAcl;
    entityAcl["other"] = 2;

    std::string entityId;

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), fw.write(entityAcl), &tr);
    if (tr.run(m_bc))
    {
        m_entityId = tr.m_response["data"]["entityId"].asString();
    }
}

void TestBCEntity::DeleteEntity(std::string entityId)
{
    if (entityId.length() <= 0) entityId = m_entityId;
    TestResult tr;
    m_bc->getEntityService()->deleteEntity(entityId.c_str(), -1, &tr);
    tr.run(m_bc);
}

void TestBCEntity::GenerateDefaultEntites(int numToGenerate)
{
    TestResult tr;

    Json::FastWriter fw;
    Json::Value searchType;
    searchType["entityType"] = m_entityType;
    std::string searchTypeStr = fw.write(searchType);

    for (int i = 0; i < numToGenerate; i++) {
        CreateDefaultEntity();
    }
}

void TestBCEntity::DeleteAllDefaultEntities()
{
    TestResult tr;
    m_bc->getEntityService()->getEntitiesByType(m_entityType, &tr);
    if (tr.run(m_bc))
    {
        Json::Value entityArray = tr.m_response["data"]["entities"];

        /* for some reason, marmalade goes past entityArray.end() so we do this via indices
        Json::Value::iterator it;
        for (it = entityArray.begin(); it !=entityArray.end(); ++it)
        {
        Json::Value key = it.key(); // why get this?
        Json::Value value = (*it);

        DeleteEntity(value["entityId"].asString());
        }
        */

        for (int i = 0, isize = entityArray.size(); i < isize; ++i)
        {
            Json::Value value = entityArray[i];
            DeleteEntity(value["entityId"].asString());
        }
        m_entityId = tr.m_response["data"]["entityId"].asString();
    }
}

<commit_msg>Added method to inc packet timeout and send up a large entity packet. Just a useful debugging tool...<commit_after>#include <stdlib.h>
#include "gtest/gtest.h"
#include "braincloud/BrainCloudClient.h"
#include "braincloud/BrainCloudEntity.h"
#include "TestResult.h"
#include "json/json.h"
#include "TestBCEntity.h"

using namespace BrainCloud;

TEST_F(TestBCEntity, Create)
{
    TestResult tr;

    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), "", &tr);
    if (tr.run(m_bc))
    {
        m_entityId = tr.m_response["data"]["entityId"].asString();
        ASSERT_NE("", m_entityId);
    }

    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, Update)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    CreateDefaultEntity();

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateEntity(m_entityId.c_str(), m_entityType, fw.write(entityData), "", -1, &tr);
    tr.run(m_bc);

    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, BadUpdate)
{
    TestResult tr;
    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";
    std::string badEntityId = "wakawaka";

    Json::FastWriter fw;
    m_bc->getEntityService()->updateEntity(badEntityId.c_str(), m_entityType, fw.write(entityData), "", -1, &tr);
    // TODO : put in the correct error code constant
    tr.runExpectFail(m_bc, HTTP_NOT_FOUND, 40332);
}

TEST_F(TestBCEntity, Delete)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->deleteEntity(m_entityId.c_str(), -1, &tr);
    tr.run(m_bc);
}

TEST_F(TestBCEntity, GetEntity)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getEntity(m_entityId.c_str(), &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, GetSingleton)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getSingleton(m_entityType, &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, GetSharedEntityForPlayerId)
{
    TestResult tr;
    CreateDefaultEntity();
    m_bc->getEntityService()->getSharedEntityForPlayerId(GetUser(UserA)->m_profileId, m_entityId.c_str(), &tr);
    tr.run(m_bc);
    DeleteEntity();
}

TEST_F(TestBCEntity, GetSharedEntitiesForPlayerId)
{
    TestResult tr;
    CreateDefaultEntity();
    m_bc->getEntityService()->getSharedEntitiesForPlayerId(GetUser(UserA)->m_profileId, &tr);
    tr.run(m_bc);
    DeleteEntity();
}

TEST_F(TestBCEntity, GetEntitesByType)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->getEntitiesByType(m_entityType, &tr);
    tr.run(m_bc);
    TestBCEntity::DeleteEntity();
}

TEST_F(TestBCEntity, DeleteSingleton)
{
    TestResult tr;
    TestBCEntity::CreateDefaultEntity();
    m_bc->getEntityService()->deleteSingleton(m_entityType, -1, &tr);
    tr.run(m_bc);
}

TEST_F(TestBCEntity, UpdateSharedEntity)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    CreateDefaultEntity();

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateSharedEntity(m_entityId.c_str(), GetUser(UserA)->m_profileId, m_entityType, fw.write(entityData), -1, &tr);
    tr.run(m_bc);

    DeleteEntity();
}

TEST_F(TestBCEntity, UpdateSingleton)
{
    TestResult tr;
    Json::Value entityData;
    Json::FastWriter fw;

    entityData["address"] = "1309a Carling Ave, Ottawa ON";
    m_bc->getEntityService()->updateSingleton(m_entityType, fw.write(entityData), "", -1, &tr);
    tr.run(m_bc);

    DeleteEntity();
}

TEST_F(TestBCEntity, GetList)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value whereJson;
    whereJson["entityType"] = m_entityType;

    m_bc->getEntityService()->getList(fw.write(whereJson), "", 100, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetSharedEntitiesListForPlayerId)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value whereJson;
    whereJson["entityType"] = m_entityType;

    m_bc->getEntityService()->getSharedEntitiesListForPlayerId(
        GetUser(UserA)->m_profileId,
        fw.write(whereJson), "", 100, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetListCount)
{
    GenerateDefaultEntites(2);
    TestResult tr;

    Json::FastWriter fw;
    Json::Value searchType;
    searchType["entityType"] = m_entityType;
    std::string searchTypeStr = fw.write(searchType);

    m_bc->getEntityService()->getListCount(searchTypeStr, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetPage)
{
    GenerateDefaultEntites(20);

    Json::Value context;
    Json::FastWriter fw;

    context["pagination"]["rowsPerPage"] = 12;
    context["pagination"]["pageNumber"] = 1;
    context["searchCriteria"]["entityType"] = m_entityType;

    TestResult tr;
    m_bc->getEntityService()->getPage(fw.write(context).c_str(), &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, GetPageOffset)
{
    GenerateDefaultEntites(20);

    Json::Value context;
    Json::FastWriter fw;

    context["pagination"]["rowsPerPage"] = 12;
    context["pagination"]["pageNumber"] = 1;
    context["searchCriteria"]["entityType"] = m_entityType;

    TestResult tr;
    m_bc->getEntityService()->getPage(fw.write(context).c_str(), &tr);
    tr.run(m_bc);

    std::string context_str = tr.m_response["data"]["context"].asString();

    tr.reset();
    m_bc->getEntityService()->getPageOffset(context_str.c_str(), 1, &tr);
    tr.run(m_bc);

    DeleteAllDefaultEntities();
}

TEST_F(TestBCEntity, IncrementUserEntityData)
{
    TestResult tr;
    Json::Value entityData;
    entityData["test"] = 1233;

    std::string entityId;

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), "", &tr);
    if (tr.run(m_bc)) entityId = tr.m_response["data"]["entityId"].asString();

    m_bc->getEntityService()->incrementUserEntityData(entityId.c_str(), GetUser(UserA)->m_profileId, fw.write(entityData), true, &tr);
    tr.run(m_bc);

    DeleteEntity(entityId);
}

void TestBCEntity::CreateDefaultEntity()
{
    TestResult tr;
    Json::Value entityData;
    entityData["address"] = "1309 Carling Ave";
    Json::Value entityAcl;
    entityAcl["other"] = 2;

    std::string entityId;

    Json::FastWriter fw;
    m_bc->getEntityService()->createEntity(m_entityType, fw.write(entityData), fw.write(entityAcl), &tr);
    if (tr.run(m_bc))
    {
        m_entityId = tr.m_response["data"]["entityId"].asString();
    }
}

void TestBCEntity::DeleteEntity(std::string entityId)
{
    if (entityId.length() <= 0) entityId = m_entityId;
    TestResult tr;
    m_bc->getEntityService()->deleteEntity(entityId.c_str(), -1, &tr);
    tr.run(m_bc);
}

void TestBCEntity::GenerateDefaultEntites(int numToGenerate)
{
    TestResult tr;

    Json::FastWriter fw;
    Json::Value searchType;
    searchType["entityType"] = m_entityType;
    std::string searchTypeStr = fw.write(searchType);

    for (int i = 0; i < numToGenerate; i++) {
        CreateDefaultEntity();
    }
}

void TestBCEntity::DeleteAllDefaultEntities()
{
    TestResult tr;
    m_bc->getEntityService()->getEntitiesByType(m_entityType, &tr);
    if (tr.run(m_bc))
    {
        Json::Value entityArray = tr.m_response["data"]["entities"];

        /* for some reason, marmalade goes past entityArray.end() so we do this via indices
        Json::Value::iterator it;
        for (it = entityArray.begin(); it !=entityArray.end(); ++it)
        {
        Json::Value key = it.key(); // why get this?
        Json::Value value = (*it);

        DeleteEntity(value["entityId"].asString());
        }
        */

        for (int i = 0, isize = entityArray.size(); i < isize; ++i)
        {
            Json::Value value = entityArray[i];
            DeleteEntity(value["entityId"].asString());
        }
        m_entityId = tr.m_response["data"]["entityId"].asString();
    }
}

/*
 TEST_F(TestBCTime, LargePacket)
 {
 TestResult tr;

 std::vector<int> hugeTimeout;
 hugeTimeout.push_back(180);
 m_bc->setPacketTimeouts(hugeTimeout);

 Json::Value entityData;
 int mbs = 1;
 for (int i = 0; i < mbs; ++i)
 {
 std::ostringstream oss;
 oss << i;
 std::string key = oss.str();
 oss.clear();
 for (int j = 0; j < (1024/8)*1024; ++j)
 {
 oss << "01234567";
 }
 std::string data = oss.str();
 entityData[key] = data;
 }
 Json::FastWriter fw;
 m_bc->getEntityService()->createEntity("largepacket", fw.write(entityData), "", &tr);
 if (tr.run(m_bc))
 {
 // m_entityId = tr.m_response["data"]["entityId"].asString();
 // ASSERT_NE("", m_entityId);
 }

 m_bc->setPacketTimeoutsToDefault();
 }
 */

<|endoftext|>


<commit_before>/*
 ** Author(s):
 **  - Laurent Lec <llec@aldebaran-robotics.com>
 **
 ** Copyright (C) 2010, 2012 Aldebaran Robotics
 */

#include <gtest/gtest.h>
#include <qi/application.hpp>
#include <qitype/genericobject.hpp>
#include <qitype/genericobjectbuilder.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/servicedirectory.hpp>

int    _argc;
char** _argv;

TEST(Test, TestApplicationDestruction)
{
  qi::ServiceDirectory     sd;
  qi::Session              server, client;
  qi::GenericObjectBuilder ob1;
  qi::ObjectPtr            oclient1;

  {
    qi::Application app(_argc, _argv);

    sd.listen("tcp://127.0.0.1:0");
    server.connect(sd.endpoints()[0].str());
    server.listen("tcp://0.0.0.0:0");
    client.connect(sd.endpoints()[0].str());

    qi::ObjectPtr    oserver1(ob1.object());

    server.registerService("coin1", oserver1).wait();

    oclient1 = client.service("coin1");
  }
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  _argc = argc;
  _argv = argv;
  return RUN_ALL_TESTS();
}
<commit_msg>test_application: Change behavior to test something that must work.<commit_after>/*
 ** Author(s):
 **  - Laurent Lec <llec@aldebaran-robotics.com>
 **
 ** Copyright (C) 2010, 2012 Aldebaran Robotics
 */

#include <gtest/gtest.h>
#include <qi/application.hpp>
#include <qitype/genericobject.hpp>
#include <qitype/genericobjectbuilder.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/servicedirectory.hpp>

int    _argc;
char** _argv;

TEST(Test, TestApplicationDestruction)
{
  qi::ServiceDirectory     sd;
  qi::Session              server, client;
  qi::GenericObjectBuilder ob1;
  qi::ObjectPtr            oclient1;

  {
    qi::Application app(_argc, _argv);

    sd.listen("tcp://127.0.0.1:0");
    server.connect(sd.endpoints()[0].str());
    server.listen("tcp://0.0.0.0:0");
    client.connect(sd.endpoints()[0].str());

    qi::ObjectPtr    oserver1(ob1.object());

    server.registerService("coin1", oserver1).wait();

    oclient1 = client.service("coin1");
    // will fall with the others client.close();
    server.close();
    sd.close();
  }
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  _argc = argc;
  _argv = argv;
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include <combinations.hpp>

#include <vector>
#include <string>
#include <iostream>
#include <array>

using iter::combinations;
int main() {
    std::vector<int> v = {1,2,3,4,5};
    //doesn't work with 0
    for (auto i : combinations(v,0)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,1)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,5)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations({1,2,3,4},3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    return 0;
}
<commit_msg>tests combinations with temporary and static array<commit_after>#include <combinations.hpp>

#include <vector>
#include <string>
#include <iostream>
#include <array>

using iter::combinations;
int main() {
    std::vector<int> v = {1,2,3,4,5};
    //doesn't work with 0
    for (auto i : combinations(v,0)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,1)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,5)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    std::cout << "initializer list\n";
    for (auto i : combinations({1,2,3,4},3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }

    std::cout << "temporary\n";
    for (auto i : combinations(std::vector<int>{1,2,3,4,5}, 3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }

    std::cout << "static array\n";
    int array[] = {1,2,3,4,5};
    for (auto i : combinations(array, 3)) {
        for (auto j : i) std::cout << j << " ";
        std::cout << '\n';
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <combinations.hpp>

#include <vector>
#include <string>
#include <iostream>
#include <array>

using iter::combinations;
int main() {
    std::vector<int> v = {1,2,3,4,5};
    //doesn't work with 0
    for (auto i : combinations(v,0)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }

    return 0;
}
<commit_msg>added temp test to combinations<commit_after>#include <combinations.hpp>

#include <vector>
#include <string>
#include <iostream>
#include <array>

using iter::combinations;
int main() {
    std::vector<int> v = {1,2,3,4,5};
    //doesn't work with 0
    for (auto i : combinations(v,0)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(v,3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    for (auto i : combinations(std::vector<int>{1,2,3,4},3)) {
        for (auto j : i ) std::cout << j << " ";
        std::cout<<std::endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2010 Michael Jansen <kde@michael-jansen.biz>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "metatype.h"
#include "engine.h"
#include "grantlee_paths.h"
#include "template.h"

#include <QtTest/QtTest>
#include <QtCore/QVariant>
#include <QtCore/QVariantHash>
#include <QtCore/QMetaType>

#include <string>

class TestGenericTypes : public QObject
{
  Q_OBJECT

private Q_SLOTS:

  void testGenericClassType();

}; // class TestGenericTypes

class Person
{
public:
  Person() :age(0) {}
  Person(std::string _name, int _age)
    : name(_name), age(_age)
  {

  }

 std::string name;
 int age;
};

Q_DECLARE_METATYPE(Person)

GRANTLEE_BEGIN_LOOKUP(Person)
  if ( property == QLatin1String( "name" ) )
    return QString::fromStdString( object.name );
  else if ( property == QLatin1String( "age" ) )
    return object.age;
GRANTLEE_END_LOOKUP

void TestGenericTypes::testGenericClassType()
{
  Grantlee::Engine engine;

  engine.setPluginPaths( QStringList() << QLatin1String( GRANTLEE_PLUGIN_PATH ) );

  Grantlee::Template t1 = engine.newTemplate(
      QLatin1String( "Person: \nName: {{p.name}}\nAge: {{p.age}}\nUnknown: {{p.unknown}}" ),
      QLatin1String( "template1" ) );

  // Register the handler for our custom type
  Grantlee::registerMetaType<Person>();

  // Check it
  QVariantHash h;
  Person p( "Grant Lee", 2);
  h.insert( QLatin1String( "p" ), QVariant::fromValue(p) );
  Grantlee::Context c( h );
  QCOMPARE(
      t1->render( &c ),
      QLatin1String( "Person: \nName: Grant Lee\nAge: 2\nUnknown: " ));
}

QTEST_MAIN( TestGenericTypes )
#include "testgenerictypes.moc"

<commit_msg>Move type registration to the initTestCase slot<commit_after>/*
  This file is part of the Grantlee template system.

  Copyright (c) 2010 Michael Jansen <kde@michael-jansen.biz>

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either version
  2.1 of the Licence, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "metatype.h"
#include "engine.h"
#include "grantlee_paths.h"
#include "template.h"

#include <QtTest/QtTest>
#include <QtCore/QVariant>
#include <QtCore/QVariantHash>
#include <QtCore/QMetaType>

#include <string>

class TestGenericTypes : public QObject
{
  Q_OBJECT

private Q_SLOTS:

  void initTestCase();

  void testGenericClassType();

}; // class TestGenericTypes

class Person
{
public:
  Person() :age(0) {}
  Person(std::string _name, int _age)
    : name(_name), age(_age)
  {

  }

 std::string name;
 int age;
};

Q_DECLARE_METATYPE(Person)

GRANTLEE_BEGIN_LOOKUP(Person)
  if ( property == QLatin1String( "name" ) )
    return QString::fromStdString( object.name );
  else if ( property == QLatin1String( "age" ) )
    return object.age;
GRANTLEE_END_LOOKUP

void TestGenericTypes::initTestCase()
{
  // Register the handler for our custom type
  Grantlee::registerMetaType<Person>();
}

void TestGenericTypes::testGenericClassType()
{
  Grantlee::Engine engine;

  engine.setPluginPaths( QStringList() << QLatin1String( GRANTLEE_PLUGIN_PATH ) );

  Grantlee::Template t1 = engine.newTemplate(
      QLatin1String( "Person: \nName: {{p.name}}\nAge: {{p.age}}\nUnknown: {{p.unknown}}" ),
      QLatin1String( "template1" ) );

  // Check it
  QVariantHash h;
  Person p( "Grant Lee", 2);
  h.insert( QLatin1String( "p" ), QVariant::fromValue(p) );
  Grantlee::Context c( h );
  QCOMPARE(
      t1->render( &c ),
      QLatin1String( "Person: \nName: Grant Lee\nAge: 2\nUnknown: " ));
}

QTEST_MAIN( TestGenericTypes )
#include "testgenerictypes.moc"

<|endoftext|>