~dobey/keeper/cleanup

« back to all changes in this revision

Viewing changes to src/client/client.cpp

  • Committer: Bileto Bot
  • Author(s): Charles Kerr, Xavi Garcia Mena, Xavi Garcia
  • Date: 2017-02-13 08:57:25 UTC
  • mfrom: (126.1.21 keeper-tests-charles)
  • Revision ID: ci-train-bot@canonical.com-20170213085725-rpsp9eg86dk2zlvi
Adds integration tests for restore and restore cancellation.

Approved by: Charles Kerr, unity-api-1-bot

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include <qdbus-stubs/keeper_user_interface.h>
25
25
#include <qdbus-stubs/DBusPropertiesInterface.h>
 
26
#include <qdbus-stubs/dbus-types.h>
26
27
 
27
28
struct KeeperClientPrivate final
28
29
{
57
58
        return (stateString == "complete" || stateString == "cancelled" || stateString == "failed");
58
59
    }
59
60
 
60
 
    static bool checkAllTasksFinished(QMap<QString, QVariantMap> const & state)
 
61
    bool checkAllTasksFinished(keeper::Items const & state) const
61
62
    {
62
63
        bool ret = true;
63
64
        for (auto iter = state.begin(); ret && (iter != state.end()); ++iter)
64
65
        {
65
 
            auto statusString = (*iter).value("action").toString();
 
66
            auto statusString = (*iter).get_status();
66
67
            ret = stateIsFinal(statusString);
67
68
        }
68
69
        return ret;
69
70
    }
70
71
 
 
72
    static keeper::Items getValue(QDBusMessage const & message, keeper::Error & error)
 
73
    {
 
74
        if (message.errorMessage().isEmpty())
 
75
        {
 
76
            if (message.arguments().count() != 1)
 
77
            {
 
78
                error = keeper::Error::UNKNOWN;
 
79
                return keeper::Items();
 
80
            }
 
81
 
 
82
            auto value = message.arguments().at(0);
 
83
            if (value.typeName() != QStringLiteral("QDBusArgument"))
 
84
            {
 
85
                error = keeper::Error::UNKNOWN;
 
86
                return keeper::Items();
 
87
            }
 
88
            auto dbus_arg = value.value<QDBusArgument>();
 
89
            error = keeper::Error::OK;
 
90
            keeper::Items ret;
 
91
            dbus_arg >> ret;
 
92
            return ret;
 
93
        }
 
94
        if (message.arguments().count() != 2)
 
95
        {
 
96
            error = keeper::Error::UNKNOWN;
 
97
            return keeper::Items();
 
98
        }
 
99
 
 
100
        // pick up the error
 
101
        bool valid;
 
102
        error = keeper::convert_from_dbus_variant(message.arguments().at(1), &valid);
 
103
        if (!valid)
 
104
        {
 
105
            error = keeper::Error::UNKNOWN;
 
106
        }
 
107
        return keeper::Items();
 
108
    }
 
109
 
71
110
    QScopedPointer<DBusInterfaceKeeperUser> userIface;
72
111
    QScopedPointer<DBusPropertiesInterface> propertiesIface;
73
112
    QString status;
74
 
    QMap<QString, QVariantMap> backups;
75
 
    QMap<QString, QVariantMap> restores;
 
113
    keeper::Items backups;
76
114
    double progress = 0;
77
115
    bool readyToBackup = false;
78
116
    bool backupBusy = false;
79
 
    QMap<QString, TaskStatus> task_status;
 
117
    QMap<QString, TaskStatus> taskStatus;
80
118
    TasksMode mode = TasksMode::IDLE_MODE;
81
119
};
82
120
 
88
126
 
89
127
    // Store backups list locally with an additional "enabled" pair to keep track enabled states
90
128
    // TODO: We should be listening to a backupChoicesChanged signal to keep this list updated
91
 
    d->backups = getBackupChoices();
 
129
    keeper::Error error;
 
130
    d->backups = getBackupChoices(error);
 
131
 
92
132
    for(auto iter = d->backups.begin(); iter != d->backups.end(); ++iter)
93
133
    {
94
134
        iter.value()["enabled"] = false;
105
145
    for(auto iter = d->backups.begin(); iter != d->backups.end(); ++iter)
106
146
    {
107
147
        // TODO: We currently only support "folder" type backups
108
 
        if (iter.value().value("type").toString() == "folder")
 
148
        if (iter.value().get_type() == keeper::Item::FOLDER_VALUE)
109
149
        {
110
150
            returnList.append(iter.key());
111
151
        }
148
188
        }
149
189
    }
150
190
 
151
 
    d->task_status[uuid] = KeeperClientPrivate::TaskStatus{"", 0.0};
 
191
    d->taskStatus[uuid] = KeeperClientPrivate::TaskStatus{"", 0.0};
152
192
 
153
193
    Q_EMIT readyToBackupChanged();
154
194
}
159
199
    enableBackup(uuid, enabled);
160
200
}
161
201
 
162
 
void KeeperClient::startBackup()
 
202
void KeeperClient::startBackup(QString const & storage)
163
203
{
164
204
    // Determine which backups are enabled, and start only those
165
205
    QStringList backupList;
173
213
 
174
214
    if (!backupList.empty())
175
215
    {
176
 
        startBackup(backupList);
 
216
        startBackup(backupList, storage);
177
217
 
178
218
        d->mode = KeeperClientPrivate::TasksMode::BACKUP_MODE;
179
219
        d->status = "Preparing Backup...";
183
223
    }
184
224
}
185
225
 
186
 
void KeeperClient::startRestore()
 
226
void KeeperClient::startRestore(QString const & storage)
187
227
{
188
228
    // Determine which restores are enabled, and start only those
189
229
    QStringList restoreList;
197
237
 
198
238
    if (!restoreList.empty())
199
239
    {
200
 
        startRestore(restoreList);
 
240
        startRestore(restoreList, storage);
201
241
 
202
242
        d->mode = KeeperClientPrivate::TasksMode::RESTORE_MODE;
203
243
        d->status = "Preparing Restore...";
207
247
    }
208
248
}
209
249
 
 
250
void KeeperClient::cancel()
 
251
{
 
252
    QDBusReply<void> cancelReply = d->userIface->call("Cancel");
 
253
 
 
254
    if (!cancelReply.isValid())
 
255
    {
 
256
        qWarning() << "Error canceling" << cancelReply.error().message();
 
257
    }
 
258
}
 
259
 
210
260
QString KeeperClient::getBackupName(QString uuid)
211
261
{
212
 
    return d->backups.value(uuid).value("display-name").toString();
213
 
}
214
 
 
215
 
QMap<QString, QVariantMap> KeeperClient::getBackupChoices() const
216
 
{
217
 
    QDBusReply<QMap<QString, QVariantMap>> choices = d->userIface->call("GetBackupChoices");
218
 
 
219
 
    if (!choices.isValid())
220
 
    {
221
 
        qWarning() << "Error getting backup choices:" << choices.error().message();
222
 
        return QMap<QString, QVariantMap>();
223
 
    }
224
 
 
225
 
    return choices.value();
226
 
}
227
 
 
228
 
QMap<QString, QVariantMap> KeeperClient::getRestoreChoices() const
229
 
{
230
 
    QDBusPendingReply<QMap<QString, QVariantMap>> choices = d->userIface->call("GetRestoreChoices");
231
 
 
232
 
    choices.waitForFinished();
233
 
    if (!choices.isValid())
234
 
    {
235
 
        qWarning() << "Error getting restore choices:" << choices.error().message();
236
 
        return QMap<QString, QVariantMap>();
237
 
    }
238
 
 
239
 
    return choices.value();
240
 
}
241
 
 
242
 
void KeeperClient::startBackup(const QStringList& uuids) const
243
 
{
244
 
    QDBusReply<void> backupReply = d->userIface->call("StartBackup", uuids);
 
262
    return d->backups.value(uuid).get_display_name();
 
263
}
 
264
 
 
265
keeper::Items KeeperClient::getBackupChoices(keeper::Error & error) const
 
266
{
 
267
    QDBusMessage choices = d->userIface->call("GetBackupChoices");
 
268
    return KeeperClientPrivate::getValue(choices, error);
 
269
}
 
270
 
 
271
keeper::Items KeeperClient::getRestoreChoices(QString const & storage, keeper::Error & error) const
 
272
{
 
273
    QDBusMessage choices = d->userIface->call("GetRestoreChoices", storage);
 
274
    return KeeperClientPrivate::getValue(choices, error);
 
275
}
 
276
 
 
277
void KeeperClient::startBackup(const QStringList& uuids, QString const & storage) const
 
278
{
 
279
    QDBusReply<void> backupReply = d->userIface->call("StartBackup", uuids, storage);
245
280
 
246
281
    if (!backupReply.isValid())
247
282
    {
249
284
    }
250
285
}
251
286
 
252
 
void KeeperClient::startRestore(const QStringList& uuids) const
 
287
void KeeperClient::startRestore(const QStringList& uuids, QString const & storage) const
253
288
{
254
 
    QDBusReply<void> backupReply = d->userIface->call("StartRestore", uuids);
 
289
    QDBusReply<void> backupReply = d->userIface->call("StartRestore", uuids, storage);
255
290
 
256
291
    if (!backupReply.isValid())
257
292
    {
259
294
    }
260
295
}
261
296
 
262
 
QMap<QString, QVariantMap> KeeperClient::getState() const
 
297
keeper::Items KeeperClient::getState() const
263
298
{
264
299
    return d->userIface->state();
265
300
}
266
301
 
 
302
QStringList KeeperClient::getStorageAccounts() const
 
303
{
 
304
     QDBusPendingReply<QStringList> accountsReply = d->userIface->call("GetStorageAccounts");
 
305
 
 
306
     accountsReply.waitForFinished();
 
307
     if (!accountsReply.isValid())
 
308
     {
 
309
         qWarning() << "Error retrieving storage accounts:" << accountsReply.error().message();
 
310
     }
 
311
 
 
312
     return accountsReply.value();
 
313
}
 
314
 
267
315
void KeeperClient::stateUpdated()
268
316
{
269
317
    auto states = getState();
270
318
 
271
319
    if (!states.empty())
272
320
    {
273
 
        for (auto const & uuid : d->task_status.keys())
 
321
        for (auto const & uuid : d->taskStatus.keys())
274
322
        {
275
323
            auto iter_state = states.find(uuid);
276
324
            if (iter_state == states.end())
277
325
            {
278
326
                qWarning() << "State for uuid: " << uuid << " was not found";
279
327
            }
280
 
            auto state = (*iter_state);
281
 
            double progress = state.value("percent-done").toDouble();
282
 
            auto status = state.value("action").toString();
283
 
 
284
 
            keeper::KeeperError keeper_error = keeper::KeeperError::OK;
285
 
            auto iter_error = state.find("error");
286
 
            if (iter_error != state.end())
287
 
            {
288
 
                bool conversion_ok;
289
 
                keeper_error = keeper::convertFromDBusVariant(state.value("error"), &conversion_ok);
290
 
            }
291
 
 
292
 
            auto current_state = d->task_status[uuid];
 
328
            keeper::Item keeper_item((*iter_state));
 
329
            auto progress = keeper_item.get_percent_done();
 
330
            auto status = keeper_item.get_status();
 
331
            auto keeper_error = keeper_item.get_error();
 
332
 
 
333
            auto current_state = d->taskStatus[uuid];
293
334
            if (current_state.status != status || current_state.percentage < progress)
294
335
            {
295
 
                d->task_status[uuid].status = status;
296
 
                d->task_status[uuid].percentage = progress;
297
 
                Q_EMIT(taskStatusChanged(state.value("display-name").toString(), status, progress, keeper_error));
 
336
                d->taskStatus[uuid].status = status;
 
337
                d->taskStatus[uuid].percentage = progress;
 
338
                Q_EMIT(taskStatusChanged(keeper_item.get_display_name(), status, progress, keeper_error));
298
339
            }
299
340
        }
300
341
 
301
342
        double totalProgress = 0;
302
343
        for (auto const& state : states)
303
344
        {
304
 
            totalProgress += state.value("percent-done").toDouble();
 
345
            keeper::Item keeper_item(state);
 
346
            totalProgress += keeper_item.get_percent_done();
305
347
        }
306
348
 
307
349
        d->progress = totalProgress / states.count();