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; } } }
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; }
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; }
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; } } } }
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; }
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(); }
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; }
/** * @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 (); }
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)); }
/** * @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; }
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; } } } }
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; } } } }
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; } } } }
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; } } } }
/** * @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)); }