TEST_F (Simple, GetSystem)
{
	using namespace kdb;
	KDB kdb;
	KeySet ks;
	Key parentKey ("system" + testRoot, KEY_END);
	ks.append (Key (parentKey.getName () + "/key", KEY_END));
	EXPECT_NE (kdb.get (ks, parentKey), -1);
	ASSERT_EQ (ks.size (), 1) << "no key stayed" << ks;
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "system/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";

	ASSERT_NE (kdb.set (ks, parentKey), -1);
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "system/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	kdb.close (parentKey);

	KeySet ks2;
	kdb.open (parentKey);
	kdb.get (ks2, parentKey);
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "system/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
}
TEST_F (Simple, GetAppendMeta)
{
	using namespace kdb;
	KDB kdb;
	KeySet ks;
	ks.append (Key ("meta/key", KEY_META_NAME, KEY_END));
	Key parentKey (testRoot, KEY_END);
	kdb.get (ks, parentKey);
	ASSERT_EQ (ks.size (), 1) << "no key stayed";
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "meta/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	kdb.set (ks, parentKey);
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "meta/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	kdb.close (parentKey);

	KeySet ks2;
	kdb.open (parentKey);
	kdb.get (ks2, parentKey);
	ASSERT_EQ (ks2.size (), 0) << "got keys from freshly mounted backends";
}
Example #3
0
int CpCommand::execute (Cmdline const & cl)
{
	if (cl.arguments.size () != 2)
	{
		throw invalid_argument ("wrong number of arguments, 2 needed");
	}

	KeySet conf;
	Key sourceKey = cl.createKey (0);
	if (!sourceKey.isValid ())
	{
		throw invalid_argument ("Source given is not a valid keyname");
	}

	Key destKey = cl.createKey (1);
	if (!destKey.isValid ())
	{
		throw invalid_argument ("Destination given is not a valid keyname");
	}
	string newDirName = destKey.getName ();

	kdb.get (conf, sourceKey);
	kdb.get (conf, destKey);
	KeySet tmpConf = conf;
	KeySet oldConf;

	oldConf.append (tmpConf.cut (sourceKey));

	KeySet newConf;

	oldConf.rewind ();
	std::string sourceName = sourceKey.getName ();
	if (cl.verbose) cout << "common name: " << sourceName << endl;
	if (cl.recursive)
	{
		// copy all keys with new name
		Key k;
		while ((k = oldConf.next ()))
		{
			Key rk = rename_key (k, sourceName, newDirName, cl.verbose);
			copySingleKey (cl, rk, tmpConf, newConf);
		}
	}
	else
	{
		// just copy one key
		Key k = oldConf.next ();
		Key rk = rename_key (k, sourceName, newDirName, cl.verbose);
		copySingleKey (cl, rk, tmpConf, newConf);
	}

	newConf.append (tmpConf); // these are unrelated keys
	newConf.append (oldConf); // these are the original keys

	newConf.rewind ();
	kdb.set (newConf, destKey);

	return 0;
}
Example #4
0
/**
 * @brief give info about current mounted backends
 *
 * @param mountConf a keyset that contains everything below
 * Backends::mountpointsPath
 *
 * @return an vector of information about mounted backends
 */
Backends::BackendInfoVector Backends::getBackendInfo (KeySet mountConf)
{
	std::vector<BackendInfo> ret;
	Key rootKey (Backends::mountpointsPath, KEY_END);
	Key cur;

	mountConf.rewind ();
	while ((cur = mountConf.next ()))
	{
		if (cur.isDirectBelow (rootKey))
		{
			BackendInfo bi;

			Key path = mountConf.lookup (cur.getName () + "/config/path");
			if (path)
			{
				bi.path = path.getString ();
			}
			Key mp = mountConf.lookup (cur.getName () + "/mountpoint");
			if (mp)
			{
				bi.mountpoint = mp.getString ();
			}
			bi.name = cur.getBaseName ();

			ret.push_back (bi);
		}
	}
	return ret;
}
Example #5
0
void SpecReader::readSpecification (KeySet const & cks)
{
	KeySet ks;
	Key mp;

	// only accept keys in 'spec' namespace
	for (Key k : cks)
	{
		if (k.isSpec ())
		{
			ks.append (k);
		}
	}

	ks.rewind (); // we need old fashioned loop, because it can handle ks.cut during iteration
	for (Key k = ks.next (); k; k = ks.next ())
	{
		// search for mountpoint
		Key m = k.getMeta<const Key> ("mountpoint");
		if (m)
		{
			SpecMountpointReader smr (backends, bbi);
			backends[k] = smr.readMountpointSpecification (ks.cut (k));
		}
	}
}
Example #6
0
MergeResult ThreeWayMerge::mergeKeySet(const MergeTask& task)
{

	MergeResult result;
	detectConflicts (task, result);
	detectConflicts (task.reverse (), result, true);

	if (!result.hasConflicts()) return result;


	// TODO: test this behaviour (would probably need mocks)
	Key current;
	KeySet conflicts = result.getConflictSet();
	conflicts.rewind();
	while ((current = conflicts.next ()))
	{
		for (vector<MergeConflictStrategy *>::iterator it = strategies.begin (); it != strategies.end (); ++it)
		{
			(*it)->resolveConflict (task, current, result);

			if (!result.isConflict(current))
				break;
		}
	}

	return result;
}
TEST_F (Simple, SetSystemGetAppend2)
{
	using namespace kdb;
	KDB kdb;
	KeySet ks;
	Key parentKey (testRoot, KEY_END);
	ks.append (Key ("system" + testRoot + "key", KEY_VALUE, "value1", KEY_END));
	kdb.get (ks, parentKey);
	ASSERT_EQ (ks.size (), 1) << "got keys from freshly mounted backends";
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "system/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "value1") << "string of element in keyset wrong";
	kdb.set (ks, parentKey);
	kdb.close (parentKey);

	KeySet ks2;
	ks2.append (Key ("system" + testRoot + "key2", KEY_VALUE, "value2", KEY_END));
	kdb.open (parentKey);
	kdb.get (ks2, parentKey);
	ks2.rewind ();
	ks2.next ();
	ASSERT_EQ (ks2.size (), 1) << "wrong size";
	EXPECT_EQ (ks2.current ().getName (), "system/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks2.current ().getString (), "value1") << "string of element in keyset wrong";
}
MergeResult ThreeWayMerge::mergeKeySet (const MergeTask & task)
{

	MergeResult result;
	detectConflicts (task, result);
	detectConflicts (task.reverse (), result, true);

	if (!result.hasConflicts ()) return result;


	// TODO: test this behaviour (would probably need mocks)
	Key current;
	KeySet conflicts = result.getConflictSet ();
	conflicts.rewind ();
	while ((current = conflicts.next ()))
	{
		for (auto & elem : strategies)
		{
			(elem)->resolveConflict (task, current, result);

			if (!result.isConflict (current)) break;
		}
	}

	return result;
}
void RemountCommand::cloneMountpoint(Cmdline const & cl)
{
	Key existingParent (Backends::getBasePath(existingName), KEY_END);
	Key newParent (Backends::getBasePath(mp), KEY_END);

	KeySet existingBackend = mountConf.cut(existingParent);
	mountConf.append(existingBackend);
	KeySet newBackend(existingBackend.size(), KS_END);
	string configPath = newParent.getName() + "/config/path";
	string mpPath = newParent.getName() + "/mountpoint";
	existingBackend.rewind();
	while (Key current = existingBackend.next())
	{
		Key newKey = rebaseKey (current, existingParent, newParent);
		newBackend.append(newKey);

		if (newKey.getName() == mpPath)
		{
			newKey.setString(mp);
		}

		if (newKey.getName() == configPath)
		{
			newKey.setString(cl.arguments[0]);
		}
	}

	mountConf.append(newBackend);
}
Example #10
0
SpecBackendBuilder SpecMountpointReader::readMountpointSpecification (KeySet const & cks)
{
	ks = cks;
	mp = ks.head ().dup ();

	Key rmp (mp.dup ());
	helper::removeNamespace (rmp);

	bb.setMountpoint (rmp, mountConf);

	processKey (mp);
	bb.nodes++; // count mp

	ks.lookup (mp, KDB_O_POP);

	ks.rewind (); // we need old fashioned loop, because it can handle ks.cut during iteration
	for (Key k = ks.next (); k; k = ks.next ())
	{
		// search for mountpoint
		Key m = k.getMeta<const Key> ("mountpoint");
		if (m)
		{
			SpecMountpointReader smr (backends, bbi);
			backends[k] = smr.readMountpointSpecification (ks.cut (k));
			continue;
		}

		processKey (k);
		bb.nodes++;
	}

	bb.setBackendConfig (backendConfig);
	bb.useConfigFile (mp.getMeta<std::string> ("mountpoint"));
	return bb;
}
TEST(Backend, SimpleBackend)
{
	using namespace kdb;
	using namespace kdb::tools;
	Backend b;
	b.setMountpoint(Key("/", KEY_CASCADING_NAME, KEY_END), KeySet(0, KS_END));
	EXPECT_EQ(b.getMountpoint(), "/");
	b.addPlugin("resolver");
	b.addPlugin("dump");
	b.useConfigFile("abc");
	EXPECT_TRUE(b.validated());

	KeySet mountConfig;
	b.serialize(mountConfig);

	// outputGTest(mountConfig, "mountConfig");

	mountConfig.rewind();
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\/") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "This is a configuration for a backend, see subkeys for more information") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//config") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//config/path") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "abc") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//errorplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//errorplugins/#5#resolver#resolver#") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//getplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//getplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//getplugins/#5#dump#dump#") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//mountpoint") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "/") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//setplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//setplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//setplugins/#5#dump") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/\\//setplugins/#7#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
}
TEST_F (Simple, GetAppendCascading)
{
	using namespace kdb;
	KDB kdb;
	KeySet ks;
	ks.append (Key (testRoot + "key", KEY_END));
	Key parentKey (testRoot, KEY_END);
	std::string myRoot = testRoot.substr (0, testRoot.length () - 1);
	EXPECT_EQ (parentKey.getName (), myRoot);
	EXPECT_EQ (parentKey.getString (), "");
	kdb.get (ks, parentKey);
	EXPECT_EQ (parentKey.getName (), myRoot);
	std::string fn = parentKey.getString ();
	EXPECT_EQ (fn.substr (fn.find_last_of ('/') + 1), "kdbFile.dump");
	parentKey.setString ("");

	ASSERT_EQ (ks.size (), 1) << "no key stayed" << ks;
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	kdb.set (ks, parentKey);
	EXPECT_EQ (parentKey.getName (), myRoot);
	EXPECT_EQ (parentKey.getString (), "");
	ks.rewind ();
	ks.next ();
	EXPECT_EQ (ks.current ().getName (), "/tests/kdb/key") << "name of element in keyset wrong";
	EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	kdb.close (parentKey);
	EXPECT_EQ (parentKey.getName (), myRoot);
	EXPECT_EQ (parentKey.getString (), "");

	KeySet ks2;
	kdb.open (parentKey);
	EXPECT_EQ (parentKey.getName (), myRoot);
	EXPECT_EQ (parentKey.getString (), "");
	kdb.get (ks2, parentKey);
	EXPECT_EQ (parentKey.getName (), myRoot);
	fn = parentKey.getString ();
	EXPECT_EQ (fn.substr (fn.find_last_of ('/') + 1), "kdbFile.dump");
	ASSERT_EQ (ks2.size (), 0) << "got keys from freshly mounted backends";
}
Example #13
0
void MetaMergeStrategy::resolveConflict(const MergeTask& task, Key& conflictKey, MergeResult& result)
{
	conflictKey.rewindMeta();
	Key currentMeta;

	string baseLookup = rebasePath (conflictKey, task.mergeRoot, task.baseParent);
	string ourLookup = rebasePath (conflictKey, task.mergeRoot, task.ourParent);
	string theirLookup = rebasePath (conflictKey, task.mergeRoot, task.theirParent);

	Key baseKey = task.base.lookup(baseLookup);
	Key ourKey = task.ours.lookup(ourLookup);
	Key theirKey = task.theirs.lookup(theirLookup);

	Key root ("user/", KEY_END);
	KeySet baseMeta = getMetaKeys (baseKey);
	KeySet ourMeta = getMetaKeys (ourKey);
	KeySet theirMeta = getMetaKeys (theirKey);

	MergeTask metaTask(BaseMergeKeys (baseMeta, root), OurMergeKeys (ourMeta, root),
			TheirMergeKeys (theirMeta, root), root);

	MergeResult metaResult = innerMerger.mergeKeySet(metaTask);

	KeySet mergedMeta = metaResult.getMergedKeys();
	Key current;
	mergedMeta.rewind();
	while ((current = mergedMeta.next()))
	{
		string metaName = current.getName().substr(string("user/").length());
		conflictKey.setMeta(metaName, current.getString());
	}

	ConflictOperation ourOperation = getOurConflictOperation(conflictKey);
	ConflictOperation theirOperation = getTheirConflictOperation(conflictKey);

	if (!metaResult.hasConflicts ())
	{
		if (ourOperation == CONFLICT_META && theirOperation == CONFLICT_META)
		{
			// TODO: addConflict deletes the key content
			// without this strategy restoring the value the value would be lost
			// this happens only for CONFLICT_META <--> CONFLICT_META conflicts
			// add a test for this behaviour
			copyKeyValue(ourKey, conflictKey);
			result.resolveConflict (conflictKey);
			result.addMergeKey (conflictKey);
		}
	}

}
Example #14
0
TEST(MergeResult, ResolveConflictDeletesConflictMeta)
{
	using namespace kdb;
	using namespace kdb::tools;
	Backend b("my_backend", "/");
	b.addPlugin("resolver");
	b.addPlugin("dump");
	b.validated();

	Key rootKey(Backends::mountpointsPath, KEY_END);
	KeySet mountConfig;
	b.serialise(rootKey, mountConfig);

	// outputGTest(mountConfig, "mountConfig");

	mountConfig.rewind();
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "serialised Backend") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/errorplugins") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/errorplugins/#5#resolver#resolver#") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/getplugins") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/getplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/getplugins/#5#dump#dump#") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/mountpoint") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "/") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/setplugins") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/setplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/setplugins/#5#dump") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_TRUE(mountConfig.current().getName() == "system/elektra/mountpoints/my_backend/setplugins/#7#resolver") << "name of element in keyset wrong";
	EXPECT_TRUE(mountConfig.current().getString() == "") << "string of element in keyset wrong";
}
TEST_F (Simple, GetAppendNamespaces)
{
	using namespace kdb;
	for (size_t i = 0; i < namespaces.size (); ++i)
	{
		KDB kdb;
		KeySet ks;
		ks.append (Key (namespaces[i].name + testRoot + "key", KEY_END));
		kdb.get (ks, testRoot);
		ASSERT_EQ (ks.size (), 1) << "did not got key appended first with namespace " << namespaces[i].name;
		ks.rewind ();
		ks.next ();
		EXPECT_EQ (ks.current ().getName (), namespaces[i].name + "/tests/kdb/key") << "name of element in keyset wrong";
		EXPECT_EQ (ks.current ().getString (), "") << "string of element in keyset wrong";
	}
}
Example #16
0
TEST_F(ThreeWayMergeTest, CascadingParentsCauseNoCascadingKeys)
{
	Key root("/", KEY_END);
	MergeResult result = merger.mergeKeySet(MergeTask(BaseMergeKeys(base, Key("/parentb", KEY_END)),
			  OurMergeKeys(ours, Key("/parento", KEY_END)),
			  TheirMergeKeys (theirs, Key("/parentt", KEY_END)),
			  root));
	EXPECT_FALSE(result.hasConflicts()) << "Invalid conflict detected";

	Key current;
	KeySet merged = result.getMergedKeys ();
	merged.rewind();
	while ((current = merged.next ()))
	{
		EXPECT_FALSE(current.getNamespace() == "/");
	}
}
Example #17
0
void SpecReader::readSpecification (KeySet const & cks)
{
	KeySet ks (cks);
	Key mp;

	ks.rewind (); // we need old fashioned loop, because it can handle ks.cut during iteration
	for (Key k = ks.next (); k; k = ks.next ())
	{
		// search for mountpoint
		Key m = k.getMeta<const Key> ("mountpoint");
		if (m)
		{
			SpecMountpointReader smr (backends, bbi);
			backends[k] = smr.readMountpointSpecification (ks.cut (k));
		}
	}
}
Example #18
0
TEST_F(ThreeWayMergeTest, EqualKeySetsWontCauseSync)
{
	unsyncKeys(ours);
	unsyncKeys(theirs);
	unsyncKeys(base);

	MergeResult result = merger.mergeKeySet (base, ours, theirs, ourParent);
	EXPECT_FALSE(result.hasConflicts()) << "Invalid conflict detected";

	KeySet merged = result.getMergedKeys();

	Key current;
	merged.rewind();
	while ((current = merged.next ()))
	{
		EXPECT_FALSE(current.needSync());
	}
}
Example #19
0
int TestCommand::execute(Cmdline const& cl)
{
	if (cl.arguments.size() < 1)
	{
		throw invalid_argument ("need at least one argument");
	}

	// do a basic check on every argument
	for (size_t i=1; i<cl.arguments.size(); ++i)
	{
		string name = " ";
		name += cl.arguments[i];
		name += " ";
		if (testNames.find(name) == std::string::npos)
		{
			throw invalid_argument ("test name " +
					cl.arguments[i] +
					" does not exist in:" +
					testNames);
		}
	}

	printWarnings(cerr, root);

	root = cl.createKey(0);

	KDB kdb;
	KeySet original;
	kdb.get(original, root);
	original.rewind();

	doTests(cl.arguments);

	cerr << "We got " << nrError << " errors in " << nrTest << " testcases." << endl;

	cout << "Test suite is now finished." << endl;
	cout << "Now restoring the original keyset." << endl;
	kdb.set(original, root);

	printWarnings(cerr, root);

	return nrError;
}
Example #20
0
void serialise(ostream &ofs, KeySet & output)
{

	ofs << '{' << endl;
	output.rewind();
	while (Key k = output.next())
	{
		ofs << "\t{" << endl;
		ofs << "\t\t" <<  k.getName() << " = " << k.getString() << endl;
		k.rewindMeta();
		while (const Key m = k.nextMeta())
		{
			ofs << "\t\t{" << endl;
			ofs << "\t\t\t" << m.getName() << " = " << m.getString() << endl;
			ofs << "\t\t}" << endl;
		}
		ofs << "\t}" << endl;
	}
	ofs << '}' << endl;
}
TEST(Backend, SimpleBackendWithConf)
{
	using namespace kdb;
	using namespace kdb::tools;
	Backend b;
	b.setMountpoint(Key("user/somewhere", KEY_END), KeySet(0, KS_END));
	EXPECT_EQ(b.getMountpoint(), "user/somewhere");
	KeySet backendConf(5,
		*Key("system/globalConf", KEY_VALUE, "for everywhere", KEY_END),
		*Key("system/other_global_conf", KEY_VALUE, "more", KEY_END),
		KS_END);
	b.setBackendConfig(backendConf);
	KeySet resConf(5,
		*Key("user/res_conf", KEY_VALUE, "do resolving", KEY_END),
		*Key("user/other_res_conf", KEY_VALUE, "do resolving too", KEY_END),
		KS_END);
	b.addPlugin("resolver", resConf);
	KeySet dumpConf(5,
		*Key("user/file_format", KEY_VALUE, "1", KEY_END),
		*Key("user/other_dump_conf", KEY_VALUE, "some dump config", KEY_END),
		KS_END);
	b.addPlugin("dump", dumpConf);
	b.useConfigFile("abc");
	EXPECT_TRUE(b.validated());

	KeySet mountConfig;
	b.serialize(mountConfig);

	// outputGTest(mountConfig, "mountConfig");

	mountConfig.rewind();
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "This is a configuration for a backend, see subkeys for more information") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/config") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/config/globalConf") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "for everywhere") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/config/other_global_conf") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "more") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/config/path") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "abc") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/errorplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/errorplugins/#5#resolver#resolver#") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/errorplugins/#5#resolver#resolver#/config") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/errorplugins/#5#resolver#resolver#/config/other_res_conf") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "do resolving too") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/errorplugins/#5#resolver#resolver#/config/res_conf") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "do resolving") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins/#5#dump#dump#") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins/#5#dump#dump#/config") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins/#5#dump#dump#/config/file_format") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "1") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/getplugins/#5#dump#dump#/config/other_dump_conf") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "some dump config") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/mountpoint") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "user/somewhere") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/setplugins") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/setplugins/#0#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/setplugins/#5#dump") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
	mountConfig.next();
	EXPECT_EQ(mountConfig.current().getName(), "system/elektra/mountpoints/user\\/somewhere/setplugins/#7#resolver") << "name of element in keyset wrong";
	EXPECT_EQ(mountConfig.current().getString(), "") << "string of element in keyset wrong";
}
Example #22
0
int MvCommand::execute (Cmdline const & cl)
{
	if (cl.arguments.size () != 2)
	{
		throw invalid_argument ("wrong number of arguments, 2 needed");
	}

	KeySet conf;
	Key sourceKey = cl.createKey (0, false);

	Key destKey = cl.createKey (1, false);
	string newDirName = destKey.getName ();

	Key root = tools::helper::commonKeyName (sourceKey, destKey);
	if (cl.verbose) std::cout << "using common basename: " << root.getName () << std::endl;
	kdb.get (conf, root);
	KeySet tmpConf = conf;
	KeySet oldConf;

	oldConf.append (tmpConf.cut (sourceKey));
	std::string sourceName = sourceKey.getName ();

	if (!oldConf.size ())
	{
		std::cerr << "No key to copy found below '" << sourceName << "'" << std::endl;
		return 11;
	}

	KeySet newConf;

	Key k;
	oldConf.rewind ();

	if (cl.recursive)
	{
		while ((k = oldConf.next ()))
		{
			newConf.append (rename_key (k, sourceName, newDirName, cl.verbose));
		}
	}
	else
	{
		// just rename one key
		k = oldConf.next ();
		if (k != sourceKey)
		{
			cerr << "First key found " << k.getName () << " does not exactly match given key " << sourceKey.getName ()
			     << ", aborting (use -r to move hierarchy)\n";
			return 11;
		}
		newConf.append (rename_key (k, sourceName, newDirName, cl.verbose));
	}
	newConf.append (tmpConf); // these are unrelated keys
	// drop the original configuration

	newConf.rewind ();
	if (cl.verbose)
	{
		cout << "Will write out:" << endl;
		cout << newConf;
	}

	kdb.set (newConf, root);
	printWarnings (cerr, root);

	return 0;
}
Example #23
0
int main()
{
	KeySet ours;
	KeySet theirs;
	KeySet base;

	// the root of the subtree containing our keys (i.e. our side of the merge)
	Key oursRoot ("user/ours", KEY_END);

	// the root of the subtree containing their keys (i.e. their side of the merge)
	Key theirsRoot ("user/theirs", KEY_END);

	// the root of the subtree containing the base keys (i.e. the common ancestor of the merge)
	Key baseRoot ("user/base", KEY_END);

	// the root of the subtree that will contain the merge result
	Key resultRoot ("user/result", KEY_END);

	// Step 1: retrieve clean KeySets containing only those
	// keys that should be merged. This is a bit trickier than
	// it seems at first. Have a look at the documentation of kdbGet
	// for detailed information
	// things to note:
	//   * use blocks with local KDB instances so we don't have to worry about
	//     writing the keys back
	//   * remove the root key itself from the result KeySet because it usually
	//     contains the mounted filename and cannot be merged anyway
	// Also have a look at the documentation of kdbSet()
	// (http://doc.libelektra.org/api/latest/html/group__kdb.html#ga11436b058408f83d303ca5e996832bcf).
	// The merging framework can also be used to resolve conflicts resulting from
	// concurrent calls to kdbSet() as described in the example of kdbSet().
	{
		KDB lkdb;
		lkdb.get (ours, oursRoot);
		ours = ours.cut (oursRoot);
		ours.lookup(oursRoot, KDB_O_POP);
		lkdb.get (theirs, theirsRoot);
		theirs = theirs.cut (theirsRoot);
		theirs.lookup(theirsRoot, KDB_O_POP);
		lkdb.get (base, baseRoot);
		base = base.cut (baseRoot);
		base.lookup(baseRoot, KDB_O_POP);
	}


	// Step 2: Make sure that no keys reside below the intended merge result root
	// Usually the merge can be either aborted if this is the case or the existing
	// keys can be overwritten.
	KeySet resultKeys;
	kdb::KDB kdb;
	kdb.get (resultKeys, resultRoot);

	KeySet discard = resultKeys.cut (resultRoot);
	if (discard.size () != 0)
	{
		// handle existing keys below the result root
		return -1;
	}

	ThreeWayMerge merger;

	// Step 3: Decide which resolution strategies to use. The strategies are registered
	// with the merge and applied in order as soon as a conflict is detected. If a strategy
	// marks a conflict as resolved, no further strategies are consulted. Therefore the order
	// in which they are registered is absolutely crucial. With this chaining the strategies
	// remain simple, but can be combined to powerful resolution strategies.
	// Have a look at the strategy documentation for further details on what they do and how they work.
	// The unit tests also provide insight into how the strategies work.

	// In order to simplify the initialization, predefined merge configurations exist.
	// in this example we first resolve all the keys that can be automatically
	// resolved (e.g. only one side was modified). This is exactly the use case of the
	// AutoMergeConfiguration.

	AutoMergeConfiguration configuration;
	configuration.configureMerger(merger);

	// Step 4: Perform the actual merge
	MergeResult result = merger.mergeKeySet (
			MergeTask (BaseMergeKeys (base, baseRoot), OurMergeKeys (ours, oursRoot),
					TheirMergeKeys (theirs, theirsRoot), resultRoot));

	// Step 5: work with the result. The merger will return an object containing information
	// about the merge result.
	if (!result.hasConflicts ())
	{
		// output some statistical information
		cout << result.getMergedKeys().size() << " keys in the result" << endl;
		cout << result.getNumberOfEqualKeys() << " keys were equal" << endl;
		cout << result.getNumberOfResolvedKeys() << " keys were resolved" << endl;

		// write the result
		resultKeys.append(result.getMergedKeys());
		kdb.set (resultKeys, resultRoot);

		return 0;
	}
	else
	{
		KeySet conflicts = result.getConflictSet();

		cerr << conflicts.size() << " conflicts were detected that could not be resolved automatically:" << endl;
		conflicts.rewind();
		Key current;
		while ((current = conflicts.next()))
		{
			// For each unresolved conflict there is a conflict key in the merge result.
			// This conflict key contains meta information about the reason of the conflict.
			// In particular the metakeys conflict/operation/our and conflict/operation/their contain
			// the operations done on our version of the key and their version of the key relative to
			// the base version of the key.
			string ourConflict = current.getMeta<string> ("conflict/operation/our");
			string theirConflict = current.getMeta<string> ("conflict/operation/their");

			cerr << current << endl;
			cerr << "ours: " << ourConflict << ", theirs: " << theirConflict << endl;
			cerr << endl;
		}

		cerr << "Merge unsuccessful." << endl;

		return -1;
	}
}
Example #24
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;
			}
		}
	}
}