PIM: ViewAgent.Quiescent() optional (FDO #56428)

Document the new callback, make it optional and add tests, also for
the old behavior of "close view when ViewAgent methods return error".
This commit is contained in:
Patrick Ohly 2012-11-30 14:42:22 +01:00
parent 175a436839
commit 7bfa3f63eb
3 changed files with 96 additions and 5 deletions

View file

@ -259,7 +259,11 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
ids,
boost::bind(ViewResource::sendDone,
m_self,
_1));
_1,
&call == &m_contactsModified ? "ContactsModified()" :
&call == &m_contactsAdded ? "ContactsAdded()" :
&call == &m_contactsRemoved ? "ContactsRemoved()" : "???",
true));
}
/**
@ -461,7 +465,9 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
m_quiescent.start(getObject(),
boost::bind(ViewResource::sendDone,
m_self,
_1));
_1,
"Quiescent()",
false));
}
/**
@ -470,11 +476,13 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
* or client.
*/
static void sendDone(const boost::weak_ptr<ViewResource> &self,
const std::string &error)
const std::string &error,
const char *method,
bool required)
{
if (!error.empty()) {
if (required && !error.empty()) {
// remove view because it is no longer needed
SE_LOG_DEBUG(NULL, NULL, "ViewAgent method call failed, deleting view: %s", error.c_str());
SE_LOG_DEBUG(NULL, NULL, "ViewAgent %s method call failed, deleting view: %s", method, error.c_str());
boost::shared_ptr<ViewResource> r = self.lock();
if (r) {
r->close();

View file

@ -447,3 +447,21 @@ Methods:
Some contacts were removed from the view.
The contact which previous had index #start + count
(if there was one) now has index #start, etc.
void Quiescent(object view)
The current content of the view is complete. No further
updates are expected until something changes again
(underlying data, ordering, active address books,
filter).
Changing data (directly or via syncing) can trigger
multiple "Quiescent" signals, depending on when these
changes are reported by the underlying storage.
Changing multiple settings will trigger one "Quiescent"
per change.
Implementing the Quiescent() method in a ViewAgent
is optional.

View file

@ -3015,6 +3015,71 @@ END:VCARD''']):
('quiescent',),
],
self.view.events)
@timeout(60)
def testDeadAgent(self):
'''TestContacts.testDeadAgent - an error from the agent kills the view'''
self.setUpView(search=None, peers=[], withSystemAddressBook=True)
# Insert new contact.
#
# The names are chosen so that sorting by first name and sorting by last name needs to
# reverse the list.
for i, contact in enumerate([u'''BEGIN:VCARD
VERSION:3.0
FN:John Doe
N:Doe;John
END:VCARD''',
]):
item = os.path.join(self.contacts, 'contact.vcf')
output = codecs.open(item, "w", "utf-8")
output.write(contact)
output.close()
logging.printf('inserting contact %d', i)
out, err, returncode = self.runCmdline(['--import', self.contacts, 'backend=evolution-contacts'])
# Plug into "ContactsAdded" method so that it throws an error.
original = self.view.processEvent
def intercept(message, event):
original(message, event)
if event[0] == 'added':
raise Exception('fake error')
self.view.processEvent = intercept
self.view.search([])
self.runUntil('phone results',
check=lambda: self.assertEqual([], self.view.errors),
until=lambda: self.view.quiescentCount > 0)
self.assertEqual([('added', 0, 1),
('quiescent',)],
self.view.events)
# Expect an error, view should have been closed already.
with self.assertRaisesRegexp(dbus.DBusException,
"org.freedesktop.DBus.Error.UnknownMethod: No such interface `org._01.pim.contacts.ViewControl' on object at path .*"):
self.view.close()
@timeout(60)
def testQuiescentOptional(self):
'''TestContacts.testQuiescentOptional - the Quiescent() method is allowed to fail'''
self.setUpView(search=None, peers=[], withSystemAddressBook=True)
# Plug into "Quiescent" method so that it throws an error.
original = self.view.processEvent
def intercept(message, event):
original(message, event)
if event[0] == 'quiescent':
raise Exception('fake error')
self.view.processEvent = intercept
self.view.search([])
self.runUntil('phone results',
check=lambda: self.assertEqual([], self.view.errors),
until=lambda: self.view.quiescentCount > 0)
self.assertEqual([('quiescent',)],
self.view.events)
self.view.close()
if __name__ == '__main__':
xdg = (os.path.join(os.path.abspath('.'), 'temp-testpim', 'config'),
os.path.join(os.path.abspath('.'), 'temp-testpim', 'local', 'cache'))