DBus server: change the behavior of GetReports(MB#8049)

Reports returned to dbus clients are not what we
expect. Many keys are not included.

Current keys in dictionaries are conforming to
those in SyncML.cpp. They are defined formally in
BNF to be more accurate.

For statistics related reports, if value is 0,
it won't be put in the dictonaries to save time
and space.

Also refresh the unit test of GetReports in
test-dbus.py to make it successful.
This commit is contained in:
Zhu, Yongsheng 2009-11-25 17:01:06 +08:00 committed by Patrick Ohly
parent 776a8093e3
commit e78b931696
3 changed files with 54 additions and 51 deletions

View File

@ -136,7 +136,21 @@
</arg>
<arg type="aa{ss}" name="reports" direction="out">
<doc:doc><doc:summary>synchronization reports</doc:summary></doc:doc>
<doc:doc><doc:description>The array contains report dictionaries. The dictionary keys are generated by joining a list of hardcode strings and report categories. The separator is the charactor "-". The list of strings is: "source", "[source name]", "stat", "[ItemLocation]", "[ItemState]" and "[ItemResult]". The dictionary values are directly converted from numbers in sync reports. The value will be "0" if there is no data in sync reports.
<doc:doc><doc:description>The array contains report dictionaries. The dictionary keys can be defined by below BNFs:
Key ::= 'start' | 'end' | 'status' | SourceKey
SourceKey ::= SourcePrefix SourcePart
SourcePrefix ::= 'source' Sep SourceName
SourceName ::= character+
SourcePart ::= Sep ('mode' | 'first' | 'resume' | 'status' | 'backup-before'
| 'backup-after' | StatPart)
StatPart ::= 'stat' Sep LocName Sep StateName Sep ResultName
LocName ::= 'local' | 'remote'
StateName ::= 'added' | 'updated' | 'removed' | 'any'
ResultName ::= 'total' | 'reject' | 'match' | 'conflict_server_won' | 'conflict_client_won'
| 'conflict_duplicated' | 'sent' | 'received'
Sep ::= '-'
It is highlighted that if SourceName has characters '_' and '-', they will be escaped with '__' and '_+' respectively.
For a key which contains StatPart, if its value is 0, its pair-value won't be included in the dictionary.
</doc:description></doc:doc>
</arg>
</method>

View File

@ -27,6 +27,8 @@
#include <syncevo/SyncContext.h>
#include <syncevo/SoupTransportAgent.h>
#include <syncevo/SyncSource.h>
#include <syncevo/SyncML.h>
#include <syncevo/FileConfigNode.h>
#include <synthesis/san.h>
@ -1248,59 +1250,21 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
client.getSessions(dirs);
uint32_t index = 0;
/** add this table to send custormized reports to client */
static int statTable[SyncSourceReport::ITEM_LOCATION_MAX]
[SyncSourceReport::ITEM_STATE_MAX]
[SyncSourceReport::ITEM_RESULT_MAX] =
{{{1, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 1}},
{{1, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 1, 0, 0}} };
/** separator when joining strings as key */
static char sep = '-';
BOOST_FOREACH( const string &dir, dirs) {
/** if start plus count is bigger than actual size, then return actual - size reports */
if(index >= start && index - start < count) {
std::map<string, string> aReport;
SyncReport report;
client.readSessionInfo(dir,report);
for (SyncReport::iterator it = report.begin(); it != report.end(); ++it) {
const string &sourceName = it->first;
SyncSourceReport sourceReport = it->second;
for(uint32_t i = 0; i < SyncSourceReport::ITEM_LOCATION_MAX; i++) {
string locStr = SyncSourceReport::LocationToString((SyncSourceReport::ItemLocation)i);
for(uint32_t j = 0; j < SyncSourceReport::ITEM_STATE_MAX; j++) {
string stateStr = SyncSourceReport::StateToString((SyncSourceReport::ItemState)j);
for(uint32_t k = 0; k < SyncSourceReport::ITEM_RESULT_MAX; k++) {
if(statTable[i][j][k] == 0) {
continue;
}
string resultStr = SyncSourceReport::ResultToString((SyncSourceReport::ItemResult)k);
int stat = sourceReport.getItemStat((SyncSourceReport::ItemLocation)i,
(SyncSourceReport::ItemState)j,
(SyncSourceReport::ItemResult)k);
/** generate key */
string key = "source";
key += sep;
key += sourceName;
key += sep;
key += "stat";
key += sep;
key += locStr;
key += sep;
key += stateStr;
key += sep;
key += resultStr;
stringstream value;
value << stat;
aReport.insert(pair<string, string>(key, value.str()));
}
}
}
/** serialize report to ConfigProps and then copy them to reports */
HashFileConfigNode node("/dev/null","",true);
node << report;
ConfigProps props;
node.readProperties(props);
BOOST_FOREACH(const ConfigProps::value_type &entry, props) {
aReport.insert(entry);
}
reports.push_back(aReport);
}

View File

@ -912,7 +912,16 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
""" Test the reports are gotten correctly from reference files. Also covers boundaries """
""" This could be extractly compared since the reference files are known """
self.setupFiles('reports')
report0 = { "source-addressbook-stat-local-any-sent" : "9168",
report0 = { "start" : "1258519955",
"end" : "1258519964",
"status" : "200",
"source-addressbook-mode" : "slow",
"source-addressbook-first" : "true",
"source-addressbook-resume" : "false",
"source-addressbook-status" : "0",
"source-addressbook-backup-before" : "0",
"source-addressbook-backup-after" : "0",
"source-addressbook-stat-local-any-sent" : "9168",
"source-addressbook-stat-remote-added-total" : "71",
"source-addressbook-stat-remote-updated-total" : "100",
"source-addressbook-stat-local-updated-total" : "632",
@ -925,6 +934,12 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
"source-addressbook-stat-local-any-reject" : "77",
"source-addressbook-stat-local-added-total" : "84",
"source-addressbook-stat-remote-removed-total" : "66",
"source-calendar-mode" : "slow",
"source-calendar-first" : "true",
"source-calendar-resume" : "false",
"source-calendar-status" : "0",
"source-calendar-backup-before" : "17",
"source-calendar-backup-after" : "17",
"source-calendar-stat-local-any-sent" : "8619",
"source-calendar-stat-remote-added-total": "17",
"source-calendar-stat-remote-updated-total" : "10",
@ -938,6 +953,12 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
"source-calendar-stat-local-any-reject" : "7",
"source-calendar-stat-local-added-total" : "42",
"source-calendar-stat-remote-removed-total" : "6",
"source-memo-mode" : "slow",
"source-memo-first" : "true",
"source-memo-resume" : "false",
"source-memo-status" : "0",
"source-memo-backup-before" : "3",
"source-memo-backup-after" : "4",
"source-memo-stat-local-any-sent" : "8123",
"source-memo-stat-remote-added-total" : "15",
"source-memo-stat-remote-updated-total" : "6",
@ -951,6 +972,12 @@ class TestSessionAPIsDummy(unittest.TestCase, DBusUtil):
"source-memo-stat-local-any-reject" : "40",
"source-memo-stat-local-added-total" : "34",
"source-memo-stat-remote-removed-total" : "5",
"source-todo-mode" : "slow",
"source-todo-first" : "true",
"source-todo-resume" : "false",
"source-todo-status" : "0",
"source-todo-backup-before" : "2",
"source-todo-backup-after" : "2",
"source-todo-stat-local-any-sent" : "619",
"source-todo-stat-remote-added-total" : "71",
"source-todo-stat-remote-updated-total" : "1",
@ -1039,8 +1066,6 @@ class TestSessionAPIsReal(unittest.TestCase, DBusUtil):
# GetReports should return one report starting from index 0
reports = self.session.GetReports(0, 1, utf8_strings=True)
self.assertTrue(len(reports) == 1)
# each source contains 13 stat items, so the total number should be multiples of 13
self.assertTrue(len(reports[0]) % 13 == 0)
# test the returned reports should be less than maximum and greater than 1
reports = self.session.GetReports(0, 0xFFFFFFFF, utf8_strings=True)