DBus server: apply temporary configs (MB#8116)

Apply temporary configs when calling other APIs
of sessions. This makes configs that users temporarily
set affect other APIs.

All sources filters in m_sourceFilters must be set
to config not only for existing sources in config but also
for non-existing sources. This could help users temporarily
do some operations without flushing any configs.

Currently affected APIs are Session.CheckSource,
Session.GetDatabases, Session.GetConfig, Session.Sync.

Also add 3 unit tests for CheckSource, GetDatabases
and GetConfig to test the temporary config is in
effect for them. They all are passed.
This commit is contained in:
Zhu, Yongsheng 2009-11-26 16:37:19 +08:00
parent 65d40441df
commit 108bcf3bf3
2 changed files with 70 additions and 8 deletions

View File

@ -207,6 +207,12 @@ public:
void getDatabases(const string &sourceName, SourceDatabases_t &databases);
private:
/**
* This virtual function is used to let subclass set
* filters to config. Only used internally.
*/
virtual void setFilters(SyncConfig &config) {}
/** utility method which constructs a SyncConfig which references a local configuration (never a template) */
boost::shared_ptr<SyncConfig> getLocalConfig(const std::string &configName);
};
@ -802,11 +808,11 @@ private:
*/
class Session : public DBusObjectHelper,
public Resource,
private ReadOperations,
private boost::noncopyable
{
DBusServer &m_server;
const std::string m_sessionID;
ReadOperations m_operations;
std::string m_peerDeviceID;
bool m_serverMode;
@ -820,7 +826,11 @@ class Session : public DBusObjectHelper,
/** temporary config changes */
FilterConfigNode::ConfigFilter m_syncFilter;
FilterConfigNode::ConfigFilter m_sourceFilter;
std::map<std::string, FilterConfigNode::ConfigFilter> m_sourceFilters;
typedef std::map<std::string, FilterConfigNode::ConfigFilter> SourceFilters_t;
SourceFilters_t m_sourceFilters;
/** whether dbus clients set temporary configs */
bool m_tempConfig;
/**
* True while clients are allowed to make calls other than Detach(),
@ -953,7 +963,7 @@ public:
DBusServer &getServer() { return m_server; }
std::string getConfigName() { return m_operations.m_configName; }
std::string getConfigName() { return m_configName; }
std::string getSessionID() const { return m_sessionID; }
std::string getPeerDeviceID() const { return m_peerDeviceID; }
@ -990,6 +1000,10 @@ public:
bool isSuspend() { return m_syncStatus == SYNC_SUSPEND; }
bool isAbort() { return m_syncStatus == SYNC_ABORT; }
private:
/** set m_syncFilter and m_sourceFilters to config */
virtual void setFilters(SyncConfig &config);
};
@ -1220,6 +1234,7 @@ void ReadOperations::getConfig(bool getTemplate,
} else {
syncConfig = getLocalConfig(m_configName);
}
setFilters(*syncConfig);
/** get sync properties and their values */
ConfigPropertyRegistry &syncRegistry = SyncConfig::getRegistry();
@ -1289,6 +1304,8 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
void ReadOperations::checkSource(const std::string &sourceName)
{
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
setFilters(*config);
list<std::string> sourceNames = config->getSyncSources();
list<std::string>::iterator it;
for(it = sourceNames.begin(); it != sourceNames.end(); ++it) {
@ -1312,6 +1329,8 @@ void ReadOperations::checkSource(const std::string &sourceName)
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
{
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName));
setFilters(*config);
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName));
const SourceRegistry &registry(SyncSource::getSourceRegistry());
BOOST_FOREACH(const RegisterSyncSource *sourceInfo, registry) {
@ -1450,7 +1469,9 @@ void Session::setConfig(bool update, bool temporary,
return;
}
if(temporary) {
/* save temporary configs in session filters */
setSyncFilters(config, m_syncFilter, m_sourceFilters);
m_tempConfig = true;
} else {
FilterConfigNode::ConfigFilter syncFilter;
std::map<std::string, FilterConfigNode::ConfigFilter> sourceFilters;
@ -1661,12 +1682,13 @@ Session::Session(DBusServer &server,
DBusObjectHelper(server.getConnection(),
std::string("/org/syncevolution/Session/") + session,
"org.syncevolution.Session"),
ReadOperations(config_name),
m_server(server),
m_sessionID(session),
m_operations(config_name),
m_peerDeviceID(peerDeviceID),
m_serverMode(false),
m_useConnection(false),
m_tempConfig(false),
m_active(false),
m_syncStatus(SYNC_QUEUEING),
m_priority(PRI_DEFAULT),
@ -1680,11 +1702,11 @@ Session::Session(DBusServer &server,
{
add(this, &Session::detach, "Detach");
add(&ReadOperations::getConfigs, "GetConfigs");
add(&m_operations, &ReadOperations::getConfig, "GetConfig");
add(static_cast<ReadOperations *>(this), &ReadOperations::getConfig, "GetConfig");
add(this, &Session::setConfig, "SetConfig");
add(&m_operations, &ReadOperations::getReports, "GetReports");
add(&m_operations, &ReadOperations::checkSource, "CheckSource");
add(&m_operations, &ReadOperations::getDatabases, "GetDatabases");
add(static_cast<ReadOperations *>(this), &ReadOperations::getReports, "GetReports");
add(static_cast<ReadOperations *>(this), &ReadOperations::checkSource, "CheckSource");
add(static_cast<ReadOperations *>(this), &ReadOperations::getDatabases, "GetDatabases");
add(this, &Session::sync, "Sync");
add(this, &Session::abort, "Abort");
add(this, &Session::suspend, "Suspend");
@ -1847,6 +1869,16 @@ void Session::run()
}
}
void Session::setFilters(SyncConfig &config)
{
/** apply temporary configs to config */
config.setConfigFilter(true, "", m_syncFilter);
// set all sources in the filter to config
BOOST_FOREACH(const SourceFilters_t::value_type &value, m_sourceFilters) {
config.setConfigFilter(false, value.first, value.second);
}
}
/************************ ProgressData implementation *****************/
ProgressData::ProgressData(int32_t &progress)
: m_progress(progress),

View File

@ -768,10 +768,24 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
self.setupConfig()
""" set config temporary """
self.session.SetConfig(True, True, self.updateConfig, utf8_strings=True)
self.session.Detach()
""" creat a new session to lose the temporary configs """
self.setUpSession("dummy-test")
config = self.session.GetConfig(False, utf8_strings=True)
""" no change of any properties """
self.failUnlessEqual(config, self.config)
def testGetConfigUpdateConfigTemp(self):
""" test the config is temporary updated and in effect for GetConfig in the current session. """
self.setupConfig()
""" set config temporary """
self.session.SetConfig(True, True, self.updateConfig, utf8_strings=True)
""" GetConfig is affected """
config = self.session.GetConfig(False, utf8_strings=True)
""" no change of any properties """
self.failUnlessEqual(config[""]["password"], "nosecret")
self.failUnlessEqual(config["source/addressbook"]["sync"], "slow")
def testUpdateConfigError(self):
""" test the right error is reported when an invalid property value is set """
self.setupConfig()
@ -855,6 +869,13 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
for source in self.sources:
self.session.CheckSource(source, utf8_strings=True)
def testCheckSourceUpdateConfigTemp(self):
""" test the config is temporary updated and in effect for GetDatabases in the current session. """
self.setupConfig()
tempConfig = {"source/temp" : { "type" : "calendar"}}
self.session.SetConfig(True, True, tempConfig, utf8_strings=True)
databases2 = self.session.CheckSource("temp", utf8_strings=True)
def testGetDatabasesNoConfig(self):
""" test the right error is reported when the server doesn't exist """
# make sure the config doesn't exist """
@ -896,6 +917,15 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
databases2.sort()
self.failUnlessEqual(databases1, databases2)
def testGetDatabasesUpdateConfigTemp(self):
""" test the config is temporary updated and in effect for GetDatabases in the current session. """
self.setupConfig()
databases1 = self.session.GetDatabases("calendar", utf8_strings=True)
tempConfig = {"source/temp" : { "type" : "calendar"}}
self.session.SetConfig(True, True, tempConfig, utf8_strings=True)
databases2 = self.session.GetDatabases("temp", utf8_strings=True)
self.failUnlessEqual(databases2, databases1)
def testGetReportsNoConfig(self):
""" Test nothing is gotten when the given server doesn't exist. Also covers boundaries """
reports = self.session.GetReports(0, 0, utf8_strings=True)