Exemple #1
0
void TestCommand::doBasicTest ()
{
	{
		KDB kdb;
		Key t = root.dup ();
		t.addBaseName ("basic");
		t.setString ("BasicString");
		KeySet basic;
		basic.append (t);

		KeySet test;
		kdb.get (test, root);
		kdb.set (basic, root);
	}

	{
		KDB kdb;
		Key t = root.dup ();
		t.addBaseName ("basic");
		t.setString ("BasicString");

		KeySet test;
		kdb.get (test, root);

		nrTest++;
		if (!test.lookup (t))
		{
			nrError++;
			cerr << "Basic test failed" << endl;
		}
	}
}
Exemple #2
0
std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromGenconf (PluginSpec const & whichplugin, KeySet const & genconf,
									     KeySet const & sysconf) const
{
	std::vector<PluginSpec> result;

	KeySet ksToIterate (genconf);
	for (auto kCurrent : ksToIterate)
	{
		Key kCurrentTest (kCurrent.getNamespace () + "/", KEY_END);
		kCurrentTest.addBaseName (kCurrent.getBaseName ()); // e.g. system/space
		if (kCurrentTest == kCurrent)
		{
			PluginSpec variant (whichplugin);
			KeySet ksVariantConfToAdd;

			// new base for plugin conf
			Key kVariantPluginConf ("system/", KEY_END);

			// take variant config from genconf and transform it to proper plugin conf,
			// e.g. system/space/config/format -> system/format
			Key kVariantConf (kCurrentTest);
			kVariantConf.addBaseName ("config"); // e.g. system/space/config
			this->addKeysBelowKeyToConf (kVariantConf, genconf, kVariantPluginConf, ksVariantConfToAdd);

			// TODO plugin infos

			// check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable
			Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable"));
			if (kDisable && kDisable.getString () == "1")
			{
				continue; // skip this variant
			}

			// check if an override is available : system/elektra/plugins/simpleini/variants/space/override
			Key kOverride = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "override"));
			if (kOverride && kOverride.getString () == "1")
			{
				// first delete config from genconf entirely
				ksVariantConfToAdd.clear ();
				Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config"));
				this->addKeysBelowKeyToConf (kVariantSysconf, sysconf, kVariantPluginConf, ksVariantConfToAdd);
			}

			if (ksVariantConfToAdd.size () == 0)
			{
				continue; // no config means no variant
			}

			variant.appendConfig (ksVariantConfToAdd);
			result.push_back (variant);
		}
	}

	std::vector<PluginSpec> resFromSysconf (this->getPluginVariantsFromSysconf (whichplugin, sysconf, genconf));
	result.insert (result.end (), resFromSysconf.begin (), resFromSysconf.end ());

	return result;
}
Exemple #3
0
std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromSysconf (PluginSpec const & whichplugin, KeySet const & sysconf,
									     KeySet const & genconfToIgnore) const
{
	std::vector<PluginSpec> result;

	KeySet ksSysconf (sysconf);

	// first find possible variants
	Key kVariantBase ("system/elektra/plugins", KEY_END);
	kVariantBase.addBaseName (whichplugin.getName ());
	kVariantBase.addBaseName ("variants");

	KeySet ksPluginVariantSysconf (ksSysconf.cut (kVariantBase));
	KeySet ksToIterate (ksPluginVariantSysconf);
	for (auto kCurrent : ksToIterate)
	{
		Key kCurrentTest (kVariantBase);
		kCurrentTest.addBaseName (kCurrent.getBaseName ());
		if (kCurrentTest == kCurrent)
		{
			PluginSpec variant (whichplugin);
			KeySet ksVariantConfToAdd;

			// new base for plugin conf
			Key kVariantPluginConf ("system/", KEY_END);

			// add system conf for plugin variant
			Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config"));
			this->addKeysBelowKeyToConf (kVariantSysconf, ksPluginVariantSysconf, kVariantPluginConf, ksVariantConfToAdd);

			// check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable
			Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable"));
			if (kDisable && kDisable.getString () == "1")
			{
				continue; // skip this variant
			}

			// check if the variant is in the genconfToIgnore list
			Key kGenconfVariant (kVariantPluginConf);
			kGenconfVariant.addBaseName (kCurrent.getBaseName ());
			Key kIgnore = genconfToIgnore.lookup (kGenconfVariant);
			if (kIgnore)
			{
				continue; // this variant was added by genconf already
			}

			if (ksVariantConfToAdd.size () == 0)
			{
				continue; // no config means no variant
			}

			variant.appendConfig (ksVariantConfToAdd);
			result.push_back (variant);
		}
	}

	return result;
}
Exemple #4
0
void TestCommand::doStringTest ()
{
	vector<string> teststrings;
	teststrings.push_back ("");
	teststrings.push_back ("value");
	teststrings.push_back ("value with spaces");
	teststrings.push_back (" a very long value with many spaces and basically very very long, but only text ... ");
	for (int i = 1; i < 256; ++i)
		teststrings.back () += " very very long, but only text ... ";


	for (auto & teststring : teststrings)
	{
		{
			KDB kdb;
			Key t = root.dup ();
			t.addBaseName ("string");
			t.setString (teststring);

			KeySet basic;
			basic.append (t);

			KeySet test;
			kdb.get (test, root);
			kdb.set (basic, root);
		}

		{
			KDB kdb;

			KeySet test;
			kdb.get (test, root);

			Key t = root.dup ();
			t.addBaseName ("string");

			Key res = test.lookup (t);

			nrTest++;
			if (!res)
			{
				nrError++;
				cerr << "String test failed (key not found)" << t.getName () << endl;
				continue;
			}

			nrTest++;
			if (res.getString () != teststring)
			{
				nrError++;
				cerr << "String test failed (value is not equal)" << endl;
				cerr << "We got: \"" << res.getString () << "\"" << endl;
				cerr << "We wanted: \"" << teststring << "\"" << endl;
			}
		}
	}
}
Exemple #5
0
Key PluginVariantDatabase::buildVariantSysconfKey (PluginSpec const & whichplugin, std::string const & variant,
						   std::string const & attr) const
{
	Key result ("system/elektra/plugins", KEY_END);
	result.addBaseName (whichplugin.getName ());
	result.addBaseName ("variants");
	result.addBaseName (variant);
	result.addBaseName (attr);
	return result;
}
Exemple #6
0
std::string Plugin::lookupInfo(std::string item, std::string section)
{
	Key k ("system/elektra/modules", KEY_END);
	k.addBaseName(pluginName);
	k.addBaseName(section);
	k.addBaseName(item);
	Key ret = info.lookup(k);

	if (!ret) return ""; /* TODO Lets say missing info is ok for now */

	return ret.getString();
}
Exemple #7
0
std::vector<std::string> PluginVariantDatabase::listAllPlugins () const
{
	std::vector<std::string> plugins (ModulesPluginDatabase::listAllPlugins ());
	plugins.erase (std::remove_if (plugins.begin (), plugins.end (),
				       [this](const std::string & elem) {
					       Key k ("system/elektra/plugins", KEY_END);
					       k.addBaseName (elem);
					       k.addBaseName ("disable");
					       Key res = this->variantImpl->pluginconf.lookup (k);
					       return res && res.getString () == "1";
				       }),
		       plugins.end ());
	return plugins;
}
Exemple #8
0
/**
 * @brief returns the base path of a mounted backend
 * below system/elektra/mountpoints
 *
 * @param mp the mountpoint (name will be derived from it)
 *
 * @return the properly prefixed and escaped name
 */
std::string Backends::getBasePath (std::string mp)
{
	Key k (Backends::mountpointsPath, KEY_END);
	Key kmp (mp, KEY_CASCADING_NAME, KEY_END); // canonify name
	k.addBaseName (kmp.getName ());		   // escape name
	return k.getName ();
}
Exemple #9
0
void GlobalPlugins::serialize (kdb::KeySet & ret)
{
	// transform to suitable data structure
	std::map<std::shared_ptr<Plugin>, Placements> pp;
	for (auto const & placements : plugins)
	{
		for (auto const & plugin : placements.second)
		{
			std::istringstream ss (plugin->lookupInfo ("status"));
			std::string status;
			bool isglobal = false;
			while (ss >> status)
			{
				if (status == "global") isglobal = true;
			}

			if (!isglobal)
			{
				throw NoGlobalPlugin (plugin->name ());
			}

			pp[plugin].addPlacement (placements.first);
		}
	}

	ret.append (Key ("system/elektra/globalplugins", KEY_VALUE, "", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements", KEY_VALUE, "", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements/set", KEY_VALUE, "presetstorage precommit postcommit",
			 KEY_END));
	ret.append (
		Key ("system/elektra/globalplugins/postcommit/user/placements/get", KEY_VALUE, "pregetstorage postgetstorage", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/placements/error", KEY_VALUE, "prerollback postrollback", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postcommit/user/plugins", KEY_VALUE, "", KEY_END));
	Key i ("system/elektra/globalplugins/postcommit/user/plugins/#0", KEY_END);
	for (auto const & plugin : pp)
	{
		i.setString (plugin.first->name ());
		ret.append (i.dup ());
		Key placements (i.dup ());
		placements.addBaseName ("placements");
		ret.append (placements);

		ret.append (g (placements, "get", plugin.second.get));
		ret.append (g (placements, "set", plugin.second.set));
		ret.append (g (placements, "error", plugin.second.error));

		serializeConf (ret, Key (i.getName () + "/config", KEY_VALUE, "", KEY_END), plugin.first->getConfig ());
		ckdb::elektraArrayIncName (*i);
	}
	ret.append (Key ("system/elektra/globalplugins/postrollback", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/precommit", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/pregetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/postgetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/presetstorage", KEY_VALUE, "list", KEY_END));
	ret.append (Key ("system/elektra/globalplugins/prerollback", KEY_VALUE, "list", KEY_END));
}
Exemple #10
0
/**
 * @brief Unmount a backend by given mountPath
 *
 * @param mountPath the given mountpoint
 *
 * Uses findBackend() to locate the backend.
 *
 * @retval true if something was done
 * @retval false if nothing was done (but also no error)
 */
bool Backends::umount (std::string const & mountPath, KeySet & mountConf)
{
	BackendInfo bi = Backends::findBackend (mountPath, mountConf);
	if (!bi.name.empty ())
	{
		Key x (Backends::mountpointsPath, KEY_END);
		;
		x.addBaseName (bi.name);
		mountConf.cut (x);
		return true;
	}

	return false;
}
Exemple #11
0
void TestCommand::doMetaTest ()
{
	vector<string> teststrings;
	teststrings.push_back ("");
	teststrings.push_back ("value");
	teststrings.push_back ("value with spaces");
	teststrings.push_back (" a very long value with many spaces and basically very very long, but only text ... ");
	for (int i = 1; i < 256; ++i)
		teststrings.back () += " very very long, but only text ... ";
	teststrings.push_back ("ascii umlauts !\"§$%&/()=?`\\}][{");
	teststrings.push_back ("utf8 umlauts ¸¬½¼³²¹ł€¶øæßð𳽫»¢“”nµ─·");
	teststrings.push_back ("all chars:");
	for (int i = 1; i < 256; ++i)
		teststrings.back ().push_back (i);
	teststrings.push_back ("€");
	for (int i = 1; i < 256; ++i)
	{
		string s;
		s.push_back (i);
		teststrings.push_back (s);
	}

	vector<string> testnames;
	testnames.push_back ("keyname");
	testnames.push_back ("deep/below/keyname");
	testnames.push_back ("keyname with spaces");
	testnames.push_back ("deep/belowkeyname with spaces");
	testnames.push_back (" a very long value with many spaces and basically very very long, but only text ");
	for (int i = 1; i < 256; ++i)
		testnames.back () += "/ very very long, but only text ... ";
	testnames.push_back ("ascii umlauts !\"§$%&/()=?`\\}][{");
	testnames.push_back ("utf8 umlauts ¸¬½¼³²¹ł€¶øæßð𳽫»¢“”nµ─·");
	testnames.push_back ("all chars:");
	for (int i = 1; i < 256; ++i)
		testnames.back ().push_back (i);
	testnames.push_back ("€");
	for (int i = 1; i < 256; ++i)
	{
		if (i == 46) continue; // ignore .
		string s;
		s.push_back (i);
		testnames.push_back (s);
	}


	for (auto & testname : testnames)
		for (auto & teststring : teststrings)
		{
			{
				KDB kdb;
				Key t = root.dup ();
				t.addBaseName (testname);
				t.setMeta<string> ("key", teststring);

				KeySet basic;
				basic.append (t);

				KeySet test;
				kdb.get (test, root);
				kdb.set (basic, root);
			}

			{
				KDB kdb;

				KeySet test;
				kdb.get (test, root);

				Key t = root.dup ();
				t.addBaseName (testname);
				Key res = test.lookup (t);

				nrTest++;
				if (!res)
				{
					nrError++;
					cerr << "Meta test failed (key not found)" << t.getName () << endl;
					continue;
				}

				std::string meta = res.getMeta<std::string> ("key");

				nrTest++;
				if (meta != teststring)
				{
					nrError++;
					cerr << "Meta test failed (name is not equal)" << endl;
					cerr << "We got: \"" << meta << "\"" << endl;
					cerr << "We wanted: \"" << teststring << "\"" << endl;
				}
			}
		}
}
Exemple #12
0
void TestCommand::doNamingTest ()
{
	vector<string> teststrings;
	teststrings.push_back ("keyname");
	teststrings.push_back ("deep/below/keyname");
	teststrings.push_back ("keyname with spaces");
	teststrings.push_back ("deep/belowkeyname with spaces");
	teststrings.push_back (" a very long value with many spaces and basically very very long, but only text ");
	for (int i = 1; i < 256; ++i)
		teststrings.back () += "/ very very long, but only text ... ";
	teststrings.push_back ("ascii umlauts !\"§$%&/()=?`\\}][{");
	teststrings.push_back ("utf8 umlauts ¸¬½¼³²¹ł€¶øæßð𳽫»¢“”nµ─·");
	teststrings.push_back ("all chars:");
	for (int i = 1; i < 256; ++i)
		teststrings.back ().push_back (i);
	teststrings.push_back ("€");
	for (int i = 1; i < 256; ++i)
	{
		if (i == '.') continue;
		string s;
		s.push_back (i);
		teststrings.push_back (s);
	}


	for (auto & teststring : teststrings)
	{
		{
			KDB kdb;
			Key t = root.dup ();
			t.addBaseName (teststring);

			KeySet basic;
			basic.append (t);

			KeySet test;
			kdb.get (test, root);
			kdb.set (basic, root);
		}

		{
			KDB kdb;

			KeySet test;
			kdb.get (test, root);

			test.rewind ();
			Key res = test.next ();

			nrTest++;
			if (!res)
			{
				nrError++;
				cerr << "Naming test failed (no key in keyset)" << endl;
				continue;
			}

			nrTest++;
			Key cmp = root.dup ();
			cmp.addBaseName (teststring);
			if (res != cmp)
			{
				nrError++;
				cerr << "Naming test failed (name is not equal)" << endl;
				cerr << "We got: \"" << res.getName () << "\"" << endl;
				cerr << "We wanted: \"" << cmp.getName () << "\"" << endl;
			}
		}
	}
}
Exemple #13
0
void TestCommand::doBinaryTest ()
{
	vector<string> teststrings;
	teststrings.push_back ("binary value");
	teststrings.push_back ("binary value with null");
	teststrings.back ().push_back ('\0');

	teststrings.push_back ("binary value with null");
	teststrings.back ().push_back ('\0');
	teststrings.back () += "in the middle";

	teststrings.push_back (" a very long value with many spaces and basically very very long, but only binary text ... ");
	for (int i = 0; i < 256; ++i)
	{
		teststrings.back ().push_back ('\0');
		teststrings.back () += " very very long, but only binary text ... ";
	}

	teststrings.push_back ("all chars:");
	for (int i = 0; i < 256; ++i)
		teststrings.back ().push_back (i);
	teststrings.push_back ("€");
	for (int i = 0; i < 256; ++i)
	{
		string s;
		s.push_back (i);
		teststrings.push_back (s);
	}


	for (auto & teststring : teststrings)
	{
		{
			KDB kdb;
			Key t = root.dup ();
			t.addBaseName ("binary");
			t.setBinary (teststring.c_str (), teststring.length ());

			KeySet basic;
			basic.append (t);

			KeySet test;
			kdb.get (test, root);
			kdb.set (basic, root);
		}

		{
			KDB kdb;

			KeySet test;
			kdb.get (test, root);

			Key t = root.dup ();
			t.addBaseName ("binary");

			Key res = test.lookup (t);
			nrTest++;
			if (!res)
			{
				nrError++;
				cerr << "Binary test failed (key not found)" << t.getName () << endl;
				continue;
			}

			nrTest++;
			if (res.getBinarySize () > 0 && static_cast<size_t> (res.getBinarySize ()) != teststring.length ())
			{
				nrError++;
				cerr << "Binary test failed (length is not equal)" << endl;
				cerr << "We got: \"" << res.getBinary () << "\"" << endl;
				cerr << "We wanted: \"" << teststring << "\"" << endl;
			}

			nrTest++;
			if (res.getBinary () != teststring)
			{
				nrError++;
				cerr << "Binary test failed (value is not equal)" << endl;
				cerr << "We got: \"" << res.getBinary () << "\"" << endl;
				cerr << "We wanted: \"" << teststring << "\"" << endl;
			}
		}
	}
}
Exemple #14
0
void TestCommand::doUmlautsTest ()
{
	vector<string> teststrings;
	teststrings.push_back ("ascii umlauts !\"§$%&/()=?`\\}][{");
	teststrings.push_back ("utf8 umlauts ¸¬½¼³²¹ł€¶øæßð𳽫»¢“”nµ─·");
	teststrings.push_back ("all chars:");
	for (int i = 1; i < 256; ++i)
		teststrings.back ().push_back (i);
	teststrings.push_back ("€");
	for (int i = 1; i < 256; ++i)
	{
		string s;
		s.push_back (i);
		teststrings.push_back (s);
	}


	for (auto & teststring : teststrings)
	{
		{
			KDB kdb;
			Key t = root.dup ();
			t.addBaseName ("string");
			t.setString (teststring);

			KeySet basic;
			basic.append (t);

			KeySet test;
			kdb.get (test, root);
			kdb.set (basic, root);
		}

		{
			KDB kdb;

			KeySet test;
			kdb.get (test, root);

			Key t = root.dup ();
			t.addBaseName ("string");

			Key res = test.lookup (t);

			nrTest++;
			if (!res)
			{
				nrError++;
				cerr << "String test failed (key not found)" << t.getName () << endl;
				continue;
			}

			nrTest++;
			if (res.getString () != teststring)
			{
				nrError++;
				cerr << "String test failed (value is not equal)" << endl;
				cerr << "We got: \"" << res.getString () << "\"" << endl;
				cerr << "We wanted: \"" << teststring << "\"" << endl;
			}
		}
	}
}
Exemple #15
0
/**
 * @pre name and mountpoint set
 * Add plugin serialization into keyset ret.
 *
 * Only can be done once!
 * (see firstRef in Plugin)
 * */
void Backend::serialize (kdb::KeySet & ret)
{
	assert (!mp.empty ());
	Key backendRootKey (Backends::mountpointsPath, KEY_END);
	backendRootKey.addBaseName (mp);
	backendRootKey.setString ("This is a configuration for a backend, see subkeys for more information");
	ret.append (backendRootKey);


	if (mp == "/")
	{
		ret.append (*Key (backendRootKey.getName () + "/mountpoint", KEY_VALUE, "/", KEY_COMMENT,
				  "The mountpoint says the location where the backend should be mounted.\n"
				  "This is the root mountpoint.\n",
				  KEY_END));
	}
	else if (mp.at (0) == '/')
	{
		Key k ("system" + mp, KEY_END);
		Key restrictedPath ("system/elektra", KEY_END);
		if (!k) throw MountpointInvalidException ();
		if (restrictedPath.isBelow (k)) throw MountpointInvalidException ();
		ret.append (*Key (backendRootKey.getName () + "/mountpoint", KEY_VALUE, mp.c_str (), KEY_COMMENT,
				  "The mountpoint says the location where the backend should be mounted.\n"
				  "This is a cascading mountpoint.\n"
				  "That means it is both mounted to dir, user and system.",
				  KEY_END));
	}
	else
	{
		Key k (mp, KEY_END);
		Key restrictedPath ("system/elektra", KEY_END);
		if (!k) throw MountpointInvalidException ();
		if (restrictedPath.isBelow (k)) throw MountpointInvalidException ();
		ret.append (*Key (backendRootKey.getName () + "/mountpoint", KEY_VALUE, mp.c_str (), KEY_COMMENT,
				  "The mountpoint says the location where the backend should be mounted.\n"
				  "This is a normal mountpoint.\n",
				  KEY_END));
	}

	const string configBasePath = Backends::getBasePath (mp) + "/config";
	ret.append (Key (configBasePath, KEY_END));

	config.rewind ();
	Key common = config.next ();
	Key oldParent ("system", KEY_END);
	Key newParent (configBasePath, KEY_END);

	for (KeySet::iterator i = config.begin (); i != config.end (); ++i)
	{
		Key k (i->dup ());
		ret.append (kdb::tools::helper::rebaseKey (k, oldParent, newParent));
	}


	errorplugins.serialise (backendRootKey, ret);
	getplugins.serialise (backendRootKey, ret);
	setplugins.serialise (backendRootKey, ret);

	ret.append (*Key (backendRootKey.getName () + "/config/path", KEY_VALUE, configFile.c_str (), KEY_COMMENT,
			  "The path for this backend. Note that plugins can override that with more specific configuration.", KEY_END));
}