Merge lp:~mandel/ubuntu-download-manager/add-mng-class into lp:ubuntu-download-manager
- add-mng-class
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 276 |
Proposed branch: | lp:~mandel/ubuntu-download-manager/add-mng-class |
Merge into: | lp:ubuntu-download-manager |
Prerequisite: | lp:~mandel/ubuntu-download-manager/add-factory |
Diff against target: |
364 lines (+178/-47) 5 files modified
ubuntu-upload-manager-priv/ubuntu/uploads/daemon.cpp (+4/-4) ubuntu-upload-manager-priv/ubuntu/uploads/daemon.h (+4/-4) ubuntu-upload-manager-priv/ubuntu/uploads/file_upload.cpp (+10/-2) ubuntu-upload-manager-priv/ubuntu/uploads/manager.cpp (+131/-35) ubuntu-upload-manager-priv/ubuntu/uploads/manager.h (+29/-2) |
To merge this branch: | bzr merge lp:~mandel/ubuntu-download-manager/add-mng-class |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu One hackers | Pending | ||
Review via email:
|
Commit message
Add uploads manager implementation.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
- 318. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:317
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:318
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 319. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 320. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:319
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:320
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 321. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:321
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 322. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 323. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:322
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:323
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 324. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:324
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 325. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:325
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 326. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:326
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 327. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:327
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 328. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:328
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 329. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 330. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 331. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:331
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 332. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:332
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 333. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:333
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 334. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 335. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:334
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:334
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 336. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 337. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:337
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 338. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
- 339. By Manuel de la Peña
-
Merged add-factory into add-mng-class.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:339
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'ubuntu-upload-manager-priv/ubuntu/uploads/daemon.cpp' |
2 | --- ubuntu-upload-manager-priv/ubuntu/uploads/daemon.cpp 2014-04-15 15:31:31 +0000 |
3 | +++ ubuntu-upload-manager-priv/ubuntu/uploads/daemon.cpp 2014-04-15 15:31:32 +0000 |
4 | @@ -36,10 +36,10 @@ |
5 | } |
6 | |
7 | UploadDaemon::UploadDaemon(ManagerFactory* managerFactory, |
8 | - System::Application* app, |
9 | - System::DBusConnection* conn, |
10 | - System::Timer* timer, |
11 | - QObject *parent) |
12 | + System::Application* app, |
13 | + System::DBusConnection* conn, |
14 | + System::Timer* timer, |
15 | + QObject *parent) |
16 | : BaseDaemon(managerFactory, |
17 | new UploadAdaptorFactory(), |
18 | app, conn, timer, parent) { |
19 | |
20 | === modified file 'ubuntu-upload-manager-priv/ubuntu/uploads/daemon.h' |
21 | --- ubuntu-upload-manager-priv/ubuntu/uploads/daemon.h 2014-04-15 15:31:31 +0000 |
22 | +++ ubuntu-upload-manager-priv/ubuntu/uploads/daemon.h 2014-04-15 15:31:32 +0000 |
23 | @@ -35,10 +35,10 @@ |
24 | public: |
25 | UploadDaemon(QObject *parent = 0); |
26 | UploadDaemon(ManagerFactory* managerFactory, |
27 | - System::Application* app, |
28 | - System::DBusConnection* conn, |
29 | - System::Timer* timer, |
30 | - QObject *parent = 0); |
31 | + System::Application* app, |
32 | + System::DBusConnection* conn, |
33 | + System::Timer* timer, |
34 | + QObject *parent = 0); |
35 | |
36 | public slots: |
37 | virtual void start(); |
38 | |
39 | === modified file 'ubuntu-upload-manager-priv/ubuntu/uploads/file_upload.cpp' |
40 | --- ubuntu-upload-manager-priv/ubuntu/uploads/file_upload.cpp 2014-04-15 15:31:31 +0000 |
41 | +++ ubuntu-upload-manager-priv/ubuntu/uploads/file_upload.cpp 2014-04-15 15:31:32 +0000 |
42 | @@ -56,10 +56,18 @@ |
43 | // we must make sure that the path is absolute |
44 | QFileInfo info(filePath); |
45 | if (!info.isAbsolute()) { |
46 | + UP_LOG(INFO) << "Path is not absolute: " << filePath; |
47 | setIsValid(false); |
48 | setLastError(QString("Path is not absolute: '%1'").arg(filePath)); |
49 | } |
50 | - _currentData = FileManager::instance()->copyToTempFile(filePath); |
51 | + |
52 | + if (!info.exists()) { |
53 | + UP_LOG(INFO) << "Path does not exist: " << filePath; |
54 | + setIsValid(false); |
55 | + setLastError(QString("Path does not exist: '%1'").arg(filePath)); |
56 | + } else { |
57 | + _currentData = FileManager::instance()->createFile(filePath); |
58 | + } |
59 | _requestFactory = RequestFactory::instance(); |
60 | } |
61 | |
62 | @@ -181,7 +189,7 @@ |
63 | request.setHeader(QNetworkRequest::ContentTypeHeader, |
64 | CONTENT_TYPE_HEADER); |
65 | request.setHeader(QNetworkRequest::ContentLengthHeader, |
66 | - QString::number(_currentData->size())); |
67 | + _currentData->size()); |
68 | |
69 | return request; |
70 | } |
71 | |
72 | === modified file 'ubuntu-upload-manager-priv/ubuntu/uploads/manager.cpp' |
73 | --- ubuntu-upload-manager-priv/ubuntu/uploads/manager.cpp 2014-04-15 15:31:31 +0000 |
74 | +++ ubuntu-upload-manager-priv/ubuntu/uploads/manager.cpp 2014-04-15 15:31:32 +0000 |
75 | @@ -16,6 +16,12 @@ |
76 | * Boston, MA 02110-1301, USA. |
77 | */ |
78 | |
79 | +#include <functional> |
80 | +#include <QRegExp> |
81 | +#include <ubuntu/transfers/system/apparmor.h> |
82 | +#include <ubuntu/transfers/system/logger.h> |
83 | +#include <ubuntu/transfers/system/request_factory.h> |
84 | +#include <ubuntu/upload_manager/metatypes.h> |
85 | #include "manager.h" |
86 | |
87 | namespace Ubuntu { |
88 | @@ -33,40 +39,89 @@ |
89 | DBusConnection* connection, |
90 | bool stoppable, |
91 | QObject *parent) |
92 | - : BaseManager(app, stoppable, parent) { |
93 | - Q_UNUSED(connection); |
94 | + : BaseManager(app, stoppable, parent), |
95 | + _throttle(0) { |
96 | + _conn = connection; |
97 | + RequestFactory::setStoppable(_stoppable); |
98 | + _factory = new Factory(this); |
99 | + _queue = new Queue(this); |
100 | + init(); |
101 | } |
102 | |
103 | -/* |
104 | UploadManager::UploadManager(Application* app, |
105 | DBusConnection* connection, |
106 | - Factory* downloadFactory, |
107 | + Factory* uploadFactory, |
108 | Queue* queue, |
109 | bool stoppable, |
110 | - QObject *parent) { |
111 | -} |
112 | -*/ |
113 | + QObject *parent) |
114 | + : BaseManager(app, stoppable, parent), |
115 | + _throttle(0), |
116 | + _factory(uploadFactory), |
117 | + _queue(queue) { |
118 | + _conn = connection; |
119 | + init(); |
120 | +} |
121 | + |
122 | +void |
123 | +UploadManager::init() { |
124 | + // register the required types |
125 | + qDBusRegisterMetaType<StringMap>(); |
126 | + qDBusRegisterMetaType<UploadStruct>(); |
127 | + qDBusRegisterMetaType<AuthErrorStruct>(); |
128 | + qDBusRegisterMetaType<HttpErrorStruct>(); |
129 | + qDBusRegisterMetaType<NetworkErrorStruct>(); |
130 | + qDBusRegisterMetaType<ProcessErrorStruct>(); |
131 | + |
132 | + connect(_queue, &Queue::transferRemoved, |
133 | + this, &UploadManager::onUploadsChanged); |
134 | + connect(_queue, &Queue::transferAdded, |
135 | + this, &UploadManager::onUploadsChanged); |
136 | +} |
137 | |
138 | UploadManager::~UploadManager() { |
139 | + delete _queue; |
140 | + delete _factory; |
141 | } |
142 | |
143 | QList<QSslCertificate> |
144 | UploadManager::acceptedCertificates() { |
145 | - // TODO: Most be implemented |
146 | - QList<QSslCertificate> certs; |
147 | - return certs; |
148 | + return _factory->acceptedCertificates(); |
149 | } |
150 | |
151 | void |
152 | UploadManager::setAcceptedCertificates(const QList<QSslCertificate>& certs) { |
153 | - // TODO: Most be implemented |
154 | - Q_UNUSED(certs); |
155 | + LOG(INFO) << __PRETTY_FUNCTION__; |
156 | + _factory->setAcceptedCertificates(certs); |
157 | } |
158 | |
159 | void |
160 | UploadManager::allowMobileUpload(bool allowed) { |
161 | - // TODO: Most be implemented |
162 | - Q_UNUSED(allowed); |
163 | + _allowMobileData = allowed; |
164 | + QHash<QString, Transfer*> uploads = _queue->transfers(); |
165 | + foreach(const QString& path, uploads.keys()) { |
166 | + uploads[path]->allowGSMData(allowed); |
167 | + } |
168 | +} |
169 | + |
170 | +QDBusObjectPath |
171 | +UploadManager::createUpload(UploadCreationFunc createUploadFunc) { |
172 | + QString owner = ""; |
173 | + |
174 | + auto wasCalledFromDBus = calledFromDBus(); |
175 | + if (wasCalledFromDBus) { |
176 | + owner = connection().interface()->serviceOwner( |
177 | + message().service()); |
178 | + LOG(INFO) << "Owner is: " << owner; |
179 | + } |
180 | + |
181 | + auto upload = createUploadFunc(owner); |
182 | + |
183 | + if (wasCalledFromDBus && !upload->isValid()) { |
184 | + sendErrorReply(QDBusError::InvalidArgs, upload->lastError()); |
185 | + // the result will be ignored thanks to the sendErrorReply |
186 | + return QDBusObjectPath(); |
187 | + } |
188 | + return registerUpload(upload); |
189 | } |
190 | |
191 | QDBusObjectPath |
192 | @@ -76,27 +131,45 @@ |
193 | int port, |
194 | const QString& username, |
195 | const QString& password) { |
196 | - // TODO: Most be implemented |
197 | - Q_UNUSED(url); |
198 | - Q_UNUSED(file); |
199 | - Q_UNUSED(hostname); |
200 | - Q_UNUSED(port); |
201 | - Q_UNUSED(username); |
202 | - Q_UNUSED(password); |
203 | - return QDBusObjectPath(); |
204 | -} |
205 | - |
206 | -QDBusObjectPath |
207 | -UploadManager::createUpload(UploadStruct upload) { |
208 | - // TODO: Most be implemented |
209 | - Q_UNUSED(upload); |
210 | - return QDBusObjectPath(); |
211 | + LOG(INFO) << "Create MMS upload == {url:" << url << " filePath: " |
212 | + << file << " hostname:" << hostname << " port:" |
213 | + << port << " username:" << username << " pwd: " << password << "}"; |
214 | + UploadCreationFunc createUploadFunc = |
215 | + [this, url, file, hostname, port, username, password](QString owner) { |
216 | + auto upload = _factory->createMmsUpload(owner, url, file, hostname, |
217 | + port, username, password); |
218 | + return upload; |
219 | + }; |
220 | + return createUpload(createUploadFunc); |
221 | +} |
222 | + |
223 | +QDBusObjectPath |
224 | +UploadManager::createUpload(const QString& url, |
225 | + const QString& filePath, |
226 | + const QVariantMap& metadata, |
227 | + StringMap headers) { |
228 | + |
229 | + LOG(INFO) << "Create upload == {url:" << url << " filePath: " |
230 | + << filePath << " metadata: " << metadata << " headers: " |
231 | + << headers << "}"; |
232 | + UploadCreationFunc createUploadFunc = |
233 | + [this, url, filePath, metadata, headers](QString owner) { |
234 | + return _factory->createUpload(owner, url, filePath, |
235 | + metadata, headers); |
236 | + }; |
237 | + return createUpload(createUploadFunc); |
238 | +} |
239 | + |
240 | +QDBusObjectPath |
241 | +UploadManager::createUpload(UploadStruct uploadStruct) { |
242 | + return createUpload(uploadStruct.getUrl(), |
243 | + uploadStruct.getFilePath(), uploadStruct.getMetadata(), |
244 | + uploadStruct.getHeaders()); |
245 | } |
246 | |
247 | qulonglong |
248 | UploadManager::defaultThrottle() { |
249 | - // TODO: Most be implemented |
250 | - return 0; |
251 | + return _throttle; |
252 | } |
253 | |
254 | QList<QDBusObjectPath> |
255 | @@ -118,14 +191,37 @@ |
256 | |
257 | bool |
258 | UploadManager::isMobileUploadAllowed() { |
259 | - // TODO: Most be implemented |
260 | - return false; |
261 | + return _allowMobileData; |
262 | } |
263 | |
264 | void |
265 | UploadManager::setDefaultThrottle(qulonglong speed) { |
266 | - // TODO: Most be implemented |
267 | - Q_UNUSED(speed); |
268 | + _throttle = speed; |
269 | + QHash<QString, Transfer*> uploads = _queue->transfers(); |
270 | + foreach(const QString& path, uploads.keys()) { |
271 | + uploads[path]->setThrottle(speed); |
272 | + } |
273 | +} |
274 | + |
275 | +void |
276 | +UploadManager::onUploadsChanged(QString path) { |
277 | + LOG(INFO) << __PRETTY_FUNCTION__ << path; |
278 | + emit sizeChanged(_queue->size()); |
279 | +} |
280 | + |
281 | +QDBusObjectPath |
282 | +UploadManager::registerUpload(FileUpload* upload) { |
283 | + LOG(INFO) << "Registering upload to path " << upload->path(); |
284 | + upload->setThrottle(_throttle); |
285 | + upload->allowMobileUpload(_allowMobileData); |
286 | + _queue->add(upload); |
287 | + _conn->registerObject(upload->path(), upload); |
288 | + QDBusObjectPath objectPath = QDBusObjectPath(upload->path()); |
289 | + |
290 | + // emit that the upload was created. Useful in case other |
291 | + // processes are interested in them |
292 | + emit uploadCreated(objectPath); |
293 | + return objectPath; |
294 | } |
295 | |
296 | } // Daemon |
297 | |
298 | === modified file 'ubuntu-upload-manager-priv/ubuntu/uploads/manager.h' |
299 | --- ubuntu-upload-manager-priv/ubuntu/uploads/manager.h 2014-04-15 15:31:31 +0000 |
300 | +++ ubuntu-upload-manager-priv/ubuntu/uploads/manager.h 2014-04-15 15:31:32 +0000 |
301 | @@ -28,6 +28,7 @@ |
302 | #include <ubuntu/transfers/system/dbus_connection.h> |
303 | #include <ubuntu/transfers/queue.h> |
304 | #include <ubuntu/transfers/base_manager.h> |
305 | +#include "factory.h" |
306 | |
307 | namespace Ubuntu { |
308 | |
309 | @@ -45,13 +46,13 @@ |
310 | DBusConnection* connection, |
311 | bool stoppable = false, |
312 | QObject *parent = 0); |
313 | -/* UploadManager(Application* app, |
314 | + UploadManager(Application* app, |
315 | DBusConnection* connection, |
316 | Factory* downloadFactory, |
317 | Queue* queue, |
318 | bool stoppable = false, |
319 | QObject *parent = 0); |
320 | -*/ |
321 | + |
322 | virtual ~UploadManager(); |
323 | |
324 | virtual QList<QSslCertificate> acceptedCertificates(); |
325 | @@ -66,6 +67,10 @@ |
326 | int port, |
327 | const QString& username, |
328 | const QString& password); |
329 | + QDBusObjectPath createUpload(const QString& url, |
330 | + const QString& filePath, |
331 | + const QVariantMap& metadata, |
332 | + StringMap headers); |
333 | QDBusObjectPath createUpload(UploadStruct upload); |
334 | qulonglong defaultThrottle(); |
335 | QList<QDBusObjectPath> getAllUploads(); |
336 | @@ -75,6 +80,28 @@ |
337 | bool isMobileUploadAllowed(); |
338 | void setDefaultThrottle(qulonglong speed); |
339 | |
340 | + signals: |
341 | + void uploadCreated(const QDBusObjectPath& path); |
342 | + void sizeChanged(int size); |
343 | + |
344 | + private: |
345 | + typedef std::function<FileUpload*(QString)> UploadCreationFunc; |
346 | + |
347 | + QDBusObjectPath createUpload(UploadCreationFunc createUploadFunc); |
348 | + void onUploadsChanged(QString); |
349 | + QDBusObjectPath registerUpload(FileUpload* upload); |
350 | + |
351 | + void init(); |
352 | + |
353 | + |
354 | + private: |
355 | + Application* _app = nullptr; |
356 | + qulonglong _throttle; |
357 | + Factory* _factory = nullptr; |
358 | + Queue* _queue = nullptr; |
359 | + DBusConnection* _conn = nullptr; |
360 | + bool _stoppable = false; |
361 | + bool _allowMobileData = true; |
362 | }; |
363 | |
364 | } // Daemon |
FAILED: Continuous integration, rev:317 jenkins. qa.ubuntu. com/job/ ubuntu- download- manager- ci/390/ jenkins. qa.ubuntu. com/job/ ubuntu- download- manager- trusty- amd64-ci/ 279/console jenkins. qa.ubuntu. com/job/ ubuntu- download- manager- trusty- armhf-ci/ 279/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- download- manager- ci/390/ rebuild
http://