Merge lp:~mandel/ubuntu-download-manager/atomic-steps into lp:ubuntu-download-manager

Proposed by Manuel de la Peña
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 246
Merged at revision: 247
Proposed branch: lp:~mandel/ubuntu-download-manager/atomic-steps
Merge into: lp:ubuntu-download-manager
Diff against target: 1895 lines (+1198/-98)
32 files modified
debian/libubuntu-download-manager-common-dev.install (+1/-0)
download-manager.pro (+7/-1)
ubuntu-download-manager-common-tests/main.cpp (+25/-0)
ubuntu-download-manager-common-tests/test_metadata.cpp (+169/-0)
ubuntu-download-manager-common-tests/test_metadata.h (+55/-0)
ubuntu-download-manager-common-tests/ubuntu-download-manager-common-tests.pro (+36/-0)
ubuntu-download-manager-common/ubuntu-download-manager-common.pro (+2/-0)
ubuntu-download-manager-common/ubuntu/download_manager/metadata.cpp (+80/-0)
ubuntu-download-manager-common/ubuntu/download_manager/metadata.h (+56/-0)
ubuntu-download-manager-priv/downloads/daemon.cpp (+5/-2)
ubuntu-download-manager-priv/downloads/factory.cpp (+3/-8)
ubuntu-download-manager-priv/downloads/file_download.cpp (+61/-59)
ubuntu-download-manager-priv/downloads/file_download.h (+5/-4)
ubuntu-download-manager-priv/downloads/group_download.cpp (+2/-1)
ubuntu-download-manager-priv/system/file_manager.cpp (+5/-0)
ubuntu-download-manager-priv/system/file_manager.h (+1/-0)
ubuntu-download-manager-priv/system/filename_mutex.cpp (+133/-0)
ubuntu-download-manager-priv/system/filename_mutex.h (+64/-0)
ubuntu-download-manager-priv/ubuntu-download-manager-priv.pro (+4/-2)
ubuntu-download-manager-test-lib/ubuntu-download-manager-test-lib.pro (+4/-2)
ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/base_testcase.cpp (+1/-1)
ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/file_manager.cpp (+1/-1)
ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.cpp (+58/-0)
ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.h (+43/-0)
ubuntu-download-manager-tests/downloads/test_download.cpp (+197/-4)
ubuntu-download-manager-tests/downloads/test_download.h (+9/-0)
ubuntu-download-manager-tests/downloads/test_downloads_db.cpp (+5/-5)
ubuntu-download-manager-tests/downloads/test_downloads_db.h (+2/-0)
ubuntu-download-manager-tests/downloads/test_group_download.cpp (+7/-6)
ubuntu-download-manager-tests/system/test_filename_mutex.cpp (+108/-0)
ubuntu-download-manager-tests/system/test_filename_mutex.h (+45/-0)
ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro (+4/-2)
To merge this branch: bzr merge lp:~mandel/ubuntu-download-manager/atomic-steps
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Diego Sarmentero (community) Approve
Review via email: mp+207012@code.launchpad.net

Commit message

Ensure that we do no have race issues between the diff downloads. This is fixed in two ways:

1. Use a temp file.
2. USe a mutex to decide the final path of the download.

Description of the change

Ensure that we do no have race issues between the diff downloads. This is fixed in two ways:

1. Use a temp file.
2. USe a mutex to decide the final path of the download.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
240. By Manuel de la Peña

Auth errs.

241. By Manuel de la Peña

Client auth errors.

242. By Manuel de la Peña

Group downloads.

243. By Manuel de la Peña

Use log

244. By Manuel de la Peña

better logging.

245. By Manuel de la Peña

Abstract classes.

246. By Manuel de la Peña

Fix merge issues.

247. By Manuel de la Peña

Small logging fix lost in the merge.

248. By Manuel de la Peña

Fixed merge issues.

249. By Manuel de la Peña

Merge fix logs.

250. By Manuel de la Peña

Better implementation for the unconfined apps.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/libubuntu-download-manager-common-dev.install'
2--- debian/libubuntu-download-manager-common-dev.install 2014-02-11 15:35:52 +0000
3+++ debian/libubuntu-download-manager-common-dev.install 2014-02-22 10:42:10 +0000
4@@ -6,5 +6,6 @@
5 usr/include/ubuntu/download_manager/http_error_struct.h
6 usr/include/ubuntu/download_manager/network_error_struct.h
7 usr/include/ubuntu/download_manager/process_error_struct.h
8+usr/include/ubuntu/download_manager/metadata.h
9 usr/lib/*/pkgconfig/ubuntu-download-manager-common.pc
10 usr/lib/*/libubuntu-download-manager-common.so
11
12=== modified file 'download-manager.pro'
13--- download-manager.pro 2014-01-09 15:21:14 +0000
14+++ download-manager.pro 2014-02-22 10:42:10 +0000
15@@ -10,8 +10,10 @@
16 ubuntu-download-manager-client \
17 ubuntu-download-manager-test-lib \
18 ubuntu-download-manager-tests \
19+ ubuntu-download-manager-common-tests \
20 ubuntu-download-manager-test-daemon \
21- ubuntu-download-manager-client-tests \
22+ ubuntu-download-manager-client-tests
23+
24
25 ubuntu-download-manager-priv.depends = ubuntu-download-manager-common
26
27@@ -19,6 +21,10 @@
28
29 ubuntu-download-manager-client.depends = ubuntu-download-manager-common
30
31+ubuntu-download-manager-common-tests.depends += ubuntu-download-manager-test-daemon
32+ubuntu-download-manager-common-tests.depends += ubuntu-download-manager-common
33+ubuntu-download-manager-common-tests.depends += ubuntu-download-manager-test-lib
34+
35 ubuntu-download-manager-tests.depends += ubuntu-download-manager-test-lib
36 ubuntu-download-manager-tests.depends += ubuntu-download-manager-priv
37
38
39=== added directory 'ubuntu-download-manager-common-tests'
40=== added file 'ubuntu-download-manager-common-tests/main.cpp'
41--- ubuntu-download-manager-common-tests/main.cpp 1970-01-01 00:00:00 +0000
42+++ ubuntu-download-manager-common-tests/main.cpp 2014-02-22 10:42:10 +0000
43@@ -0,0 +1,25 @@
44+/*
45+ * Copyright 2014 Canonical Ltd.
46+ *
47+ * This library is free software; you can redistribute it and/or
48+ * modify it under the terms of version 3 of the GNU Lesser General Public
49+ * License as published by the Free Software Foundation.
50+ *
51+ * This program is distributed in the hope that it will be useful,
52+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54+ * General Public License for more details.
55+ *
56+ * You should have received a copy of the GNU Lesser General Public
57+ * License along with this library; if not, write to the
58+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
59+ * Boston, MA 02110-1301, USA.
60+ */
61+
62+#include <QCoreApplication>
63+#include <ubuntu/download_manager/tests/test_runner.h>
64+
65+int main(int argc, char *argv[]) {
66+ QCoreApplication a(argc, argv);
67+ return RUN_ALL_QTESTS(argc, argv);
68+}
69
70=== added file 'ubuntu-download-manager-common-tests/test_metadata.cpp'
71--- ubuntu-download-manager-common-tests/test_metadata.cpp 1970-01-01 00:00:00 +0000
72+++ ubuntu-download-manager-common-tests/test_metadata.cpp 2014-02-22 10:42:10 +0000
73@@ -0,0 +1,169 @@
74+/*
75+ * Copyright 2014 Canonical Ltd.
76+ *
77+ * This library is free software; you can redistribute it and/or
78+ * modify it under the terms of version 3 of the GNU Lesser General Public
79+ * License as published by the Free Software Foundation.
80+ *
81+ * This program is distributed in the hope that it will be useful,
82+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
83+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
84+ * General Public License for more details.
85+ *
86+ * You should have received a copy of the GNU Lesser General Public
87+ * License along with this library; if not, write to the
88+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
89+ * Boston, MA 02110-1301, USA.
90+ */
91+
92+#include "test_metadata.h"
93+
94+using namespace Ubuntu::DownloadManager;
95+
96+TestMetadata::TestMetadata(QObject *parent)
97+ : BaseTestCase("TestMetadata", parent) {
98+}
99+
100+void
101+TestMetadata::testCommnad_data() {
102+ QTest::addColumn<QString>("command");
103+
104+ QTest::newRow("mkdir") << "mkdir test";
105+ QTest::newRow("cd") << "cd test";
106+ QTest::newRow("ls") << "ls -la";
107+}
108+
109+void
110+TestMetadata::testCommnad() {
111+ QFETCH(QString, command);
112+
113+ Metadata metadata;
114+ metadata[Metadata::COMMAND_KEY] = command;
115+ QCOMPARE(command, metadata.command());
116+}
117+
118+void
119+TestMetadata::testSetCommnad_data() {
120+ QTest::addColumn<QString>("command");
121+
122+ QTest::newRow("mkdir") << "mkdir test";
123+ QTest::newRow("cd") << "cd test";
124+ QTest::newRow("ls") << "ls -la";
125+}
126+
127+void
128+TestMetadata::testSetCommnad() {
129+ QFETCH(QString, command);
130+
131+ Metadata metadata;
132+ metadata.setCommand(command);
133+ QCOMPARE(metadata[Metadata::COMMAND_KEY].toString(), command);
134+}
135+
136+void
137+TestMetadata::testHasCommnadTrue() {
138+ Metadata metadata;
139+ metadata.setCommand("command");
140+
141+ QVERIFY(metadata.hasCommand());
142+}
143+
144+void
145+TestMetadata::testHasCommnadFalse() {
146+ Metadata metadata;
147+ QVERIFY(!metadata.hasCommand());
148+}
149+
150+void
151+TestMetadata::testLocalPath_data() {
152+ QTest::addColumn<QString>("path");
153+
154+ QTest::newRow("/home/test") << "/home/test";
155+ QTest::newRow("second_file") << "second_file";
156+ QTest::newRow("/tmp/data") << "/tmp/data";
157+}
158+
159+void
160+TestMetadata::testLocalPath() {
161+ QFETCH(QString, path);
162+
163+ Metadata metadata;
164+ metadata[Metadata::LOCAL_PATH_KEY] = path;
165+ QCOMPARE(path, metadata.localPath());
166+}
167+
168+void
169+TestMetadata::testSetLocalPath_data() {
170+ QTest::addColumn<QString>("path");
171+
172+ QTest::newRow("/home/test") << "/home/test";
173+ QTest::newRow("second_file") << "second_file";
174+ QTest::newRow("/tmp/data") << "/tmp/data";
175+}
176+
177+void
178+TestMetadata::testSetLocalPath() {
179+ QFETCH(QString, path);
180+
181+ Metadata metadata;
182+ metadata.setLocalPath(path);
183+ QCOMPARE(metadata[Metadata::LOCAL_PATH_KEY].toString(), path);
184+}
185+
186+void
187+TestMetadata::testHasLocalPathTrue() {
188+ Metadata metadata;
189+ metadata.setLocalPath("command");
190+
191+ QVERIFY(metadata.hasLocalPath());
192+}
193+
194+void
195+TestMetadata::testHashLocalPathFalse() {
196+ Metadata metadata;
197+ QVERIFY(!metadata.hasLocalPath());
198+}
199+
200+void TestMetadata::testObjectPath_data() {
201+ QTest::addColumn<QString>("objectPath");
202+
203+ QTest::newRow("/com/canonica/si") << "/com/canonical/si";
204+ QTest::newRow("/com/testing") << "/com/testing";
205+ QTest::newRow("/com/data/download") << "/com/data/download";
206+}
207+
208+void TestMetadata::testObjectPath() {
209+ QFETCH(QString, objectPath);
210+
211+ Metadata metadata;
212+ metadata[Metadata::OBJECT_PATH_KEY] = objectPath;
213+ QCOMPARE(objectPath, metadata.objectPath());
214+}
215+
216+void TestMetadata::testSetObjectPath_data() {
217+ QTest::addColumn<QString>("objectPath");
218+
219+ QTest::newRow("/com/canonica/si") << "/com/canonical/si";
220+ QTest::newRow("/com/testing") << "/com/testing";
221+ QTest::newRow("/com/data/download") << "/com/data/download";
222+}
223+
224+void TestMetadata::testSetObjectPath() {
225+ QFETCH(QString, objectPath);
226+
227+ Metadata metadata;
228+ metadata.setObjectPath(objectPath);
229+ QCOMPARE(metadata[Metadata::OBJECT_PATH_KEY].toString(), objectPath);
230+}
231+
232+void TestMetadata::testHasObjectPathTrue() {
233+ Metadata metadata;
234+ metadata.setObjectPath("command");
235+
236+ QVERIFY(metadata.hasObjectPath());
237+}
238+
239+void TestMetadata::testHasObjectPathFalse() {
240+ Metadata metadata;
241+ QVERIFY(!metadata.hasObjectPath());
242+}
243
244=== added file 'ubuntu-download-manager-common-tests/test_metadata.h'
245--- ubuntu-download-manager-common-tests/test_metadata.h 1970-01-01 00:00:00 +0000
246+++ ubuntu-download-manager-common-tests/test_metadata.h 2014-02-22 10:42:10 +0000
247@@ -0,0 +1,55 @@
248+/*
249+ * Copyright 2014 Canonical Ltd.
250+ *
251+ * This library is free software; you can redistribute it and/or
252+ * modify it under the terms of version 3 of the GNU Lesser General Public
253+ * License as published by the Free Software Foundation.
254+ *
255+ * This program is distributed in the hope that it will be useful,
256+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
257+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
258+ * General Public License for more details.
259+ *
260+ * You should have received a copy of the GNU Lesser General Public
261+ * License along with this library; if not, write to the
262+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
263+ * Boston, MA 02110-1301, USA.
264+ */
265+
266+#ifndef TEST_METADATA_H
267+#define TEST_METADATA_H
268+
269+#include <QObject>
270+#include <ubuntu/download_manager/tests/base_testcase.h>
271+#include <ubuntu/download_manager/tests/test_runner.h>
272+#include <ubuntu/download_manager/metadata.h>
273+
274+class TestMetadata : public BaseTestCase {
275+ Q_OBJECT
276+
277+ public:
278+ explicit TestMetadata(QObject* parent = 0);
279+
280+ private slots: // NOLINT(whitespace/indent)
281+ void testCommnad_data();
282+ void testCommnad();
283+ void testSetCommnad_data();
284+ void testSetCommnad();
285+ void testHasCommnadTrue();
286+ void testHasCommnadFalse();
287+ void testLocalPath_data();
288+ void testLocalPath();
289+ void testSetLocalPath_data();
290+ void testSetLocalPath();
291+ void testHasLocalPathTrue();
292+ void testHashLocalPathFalse();
293+ void testObjectPath_data();
294+ void testObjectPath();
295+ void testSetObjectPath_data();
296+ void testSetObjectPath();
297+ void testHasObjectPathTrue();
298+ void testHasObjectPathFalse();
299+};
300+
301+DECLARE_TEST(TestMetadata)
302+#endif // TEST_METADATA_H
303
304=== added file 'ubuntu-download-manager-common-tests/ubuntu-download-manager-common-tests.pro'
305--- ubuntu-download-manager-common-tests/ubuntu-download-manager-common-tests.pro 1970-01-01 00:00:00 +0000
306+++ ubuntu-download-manager-common-tests/ubuntu-download-manager-common-tests.pro 2014-02-22 10:42:10 +0000
307@@ -0,0 +1,36 @@
308+include( ../common-project-config.pri )
309+include( ../common-vars.pri )
310+
311+QT += core testlib network
312+QT -= gui
313+
314+TARGET = ubuntu-download-manager-common-tests
315+CONFIG += console
316+CONFIG -= app_bundle
317+
318+TEMPLATE = app
319+
320+HEADERS += \
321+ test_metadata.h
322+
323+SOURCES += main.cpp \
324+ test_metadata.cpp
325+
326+LIBS += -L$$OUT_PWD/../ubuntu-download-manager-common/ -lubuntu-download-manager-common
327+
328+INCLUDEPATH += $$PWD/../ubuntu-download-manager-common
329+DEPENDPATH += $$PWD/../ubuntu-download-manager-common
330+
331+LIBS += -L$$OUT_PWD/../ubuntu-download-manager-test-lib/ -lubuntu-download-manager-test-lib
332+
333+INCLUDEPATH += $$PWD/../ubuntu-download-manager-test-lib
334+DEPENDPATH += $$PWD/../ubuntu-download-manager-test-lib
335+
336+LIBS += -L$$OUT_PWD/../ubuntu-download-manager-priv/ -lubuntu-download-manager-priv
337+
338+INCLUDEPATH += $$PWD/../ubuntu-download-manager-priv
339+DEPENDPATH += $$PWD/../ubuntu-download-manager-priv
340+
341+check.depends = $${TARGET}
342+check.commands = LD_LIBRARY_PATH=$$OUT_PWD/../ubuntu-download-manager-common:$$OUT_PWD/../ubuntu-download-manager-test-lib:$$OUT_PWD/../ubuntu-download-manager-priv ./$${TARGET}
343+QMAKE_EXTRA_TARGETS += check
344
345=== modified file 'ubuntu-download-manager-common/ubuntu-download-manager-common.pro'
346--- ubuntu-download-manager-common/ubuntu-download-manager-common.pro 2014-02-11 15:35:52 +0000
347+++ ubuntu-download-manager-common/ubuntu-download-manager-common.pro 2014-02-22 10:42:10 +0000
348@@ -17,6 +17,7 @@
349 ubuntu/download_manager/http_error_struct.cpp \
350 ubuntu/download_manager/network_error_struct.cpp \
351 ubuntu/download_manager/process_error_struct.cpp \
352+ ubuntu/download_manager/metadata.cpp \
353 ubuntu/download_manager/auth_error_struct.cpp
354
355 public_headers = \
356@@ -27,6 +28,7 @@
357 ubuntu/download_manager/http_error_struct.h \
358 ubuntu/download_manager/network_error_struct.h \
359 ubuntu/download_manager/process_error_struct.h \
360+ ubuntu/download_manager/metadata.h \
361 ubuntu/download_manager/auth_error_struct.h
362
363 private_headers = \
364
365=== added file 'ubuntu-download-manager-common/ubuntu/download_manager/metadata.cpp'
366--- ubuntu-download-manager-common/ubuntu/download_manager/metadata.cpp 1970-01-01 00:00:00 +0000
367+++ ubuntu-download-manager-common/ubuntu/download_manager/metadata.cpp 2014-02-22 10:42:10 +0000
368@@ -0,0 +1,80 @@
369+/*
370+ * Copyright 2014 Canonical Ltd.
371+ *
372+ * This library is free software; you can redistribute it and/or
373+ * modify it under the terms of version 3 of the GNU Lesser General Public
374+ * License as published by the Free Software Foundation.
375+ *
376+ * This program is distributed in the hope that it will be useful,
377+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
378+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
379+ * General Public License for more details.
380+ *
381+ * You should have received a copy of the GNU Lesser General Public
382+ * License along with this library; if not, write to the
383+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
384+ * Boston, MA 02110-1301, USA.
385+ */
386+
387+#include "metadata.h"
388+
389+namespace Ubuntu {
390+
391+namespace DownloadManager {
392+
393+const QString Metadata::COMMAND_KEY = "post-download-command";
394+const QString Metadata::COMMAND_FILE_KEY = "$file";
395+const QString Metadata::LOCAL_PATH_KEY = "local-path";
396+const QString Metadata::OBJECT_PATH_KEY = "objectpath";
397+
398+QString
399+Metadata::command() const {
400+ return (contains(Metadata::COMMAND_KEY))?
401+ value(COMMAND_KEY).toString():"";
402+}
403+
404+void
405+Metadata::setCommand(const QString& command) {
406+ insert(Metadata::COMMAND_KEY, command);
407+}
408+
409+bool
410+Metadata::hasCommand() const {
411+ return contains(Metadata::COMMAND_KEY);
412+}
413+
414+QString
415+Metadata::localPath() const {
416+ return (contains(Metadata::LOCAL_PATH_KEY))?
417+ value(LOCAL_PATH_KEY).toString():"";
418+}
419+
420+void
421+Metadata::setLocalPath(const QString& localPath) {
422+ insert(Metadata::LOCAL_PATH_KEY, localPath);
423+}
424+
425+bool
426+Metadata::hasLocalPath() const {
427+ return contains(Metadata::LOCAL_PATH_KEY);
428+}
429+
430+QString
431+Metadata::objectPath() const {
432+ return (contains(Metadata::OBJECT_PATH_KEY))?
433+ value(OBJECT_PATH_KEY).toString():"";
434+}
435+
436+void
437+Metadata::setObjectPath(const QString& path) {
438+ insert(Metadata::OBJECT_PATH_KEY, path);
439+}
440+
441+bool
442+Metadata::hasObjectPath() const {
443+ return contains(Metadata::OBJECT_PATH_KEY);
444+}
445+
446+} // DownloadManager
447+
448+} // Ubuntu
449
450=== added file 'ubuntu-download-manager-common/ubuntu/download_manager/metadata.h'
451--- ubuntu-download-manager-common/ubuntu/download_manager/metadata.h 1970-01-01 00:00:00 +0000
452+++ ubuntu-download-manager-common/ubuntu/download_manager/metadata.h 2014-02-22 10:42:10 +0000
453@@ -0,0 +1,56 @@
454+/*
455+ * Copyright 2014 Canonical Ltd.
456+ *
457+ * This library is free software; you can redistribute it and/or
458+ * modify it under the terms of version 3 of the GNU Lesser General Public
459+ * License as published by the Free Software Foundation.
460+ *
461+ * This program is distributed in the hope that it will be useful,
462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
464+ * General Public License for more details.
465+ *
466+ * You should have received a copy of the GNU Lesser General Public
467+ * License along with this library; if not, write to the
468+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
469+ * Boston, MA 02110-1301, USA.
470+ */
471+
472+#ifndef DOWNLOADER_LIB_METADATA_H
473+#define DOWNLOADER_LIB_METADATA_H
474+
475+#include <QMap>
476+#include <QVariant>
477+
478+namespace Ubuntu {
479+
480+namespace DownloadManager {
481+
482+class Metadata : public QVariantMap {
483+
484+ public:
485+
486+ static const QString COMMAND_KEY;
487+ static const QString COMMAND_FILE_KEY;
488+ static const QString LOCAL_PATH_KEY;
489+ static const QString OBJECT_PATH_KEY;
490+
491+ // accessors to simplify the use of the metadata
492+ QString command() const;
493+ void setCommand(const QString& command);
494+ bool hasCommand() const;
495+
496+ QString localPath() const;
497+ void setLocalPath(const QString& localPath);
498+ bool hasLocalPath() const;
499+
500+ QString objectPath() const;
501+ void setObjectPath(const QString& path);
502+ bool hasObjectPath() const;
503+};
504+
505+} // DownloadManager
506+
507+} // Ubuntu
508+
509+#endif // METADATA_H
510
511=== modified file 'ubuntu-download-manager-priv/downloads/daemon.cpp'
512--- ubuntu-download-manager-priv/downloads/daemon.cpp 2014-02-13 11:01:48 +0000
513+++ ubuntu-download-manager-priv/downloads/daemon.cpp 2014-02-22 10:42:10 +0000
514@@ -170,11 +170,14 @@
515 if (args.count() > index + 1) {
516 auto logPath = args[index + 1];
517 Logger::setupLogging(logPath);
518- LOG(INFO) << "Log path is" << logPath;
519+ LOG(INFO) << "Log path is" << logPath;
520 } else {
521+ Logger::setupLogging();
522 LOG(ERROR) << "Missing log dir path.";
523- Logger::setupLogging();
524 }
525+ } else {
526+ Logger::setupLogging();
527+ LOG(INFO) << "Using default log path.";
528 }
529
530 if (args.contains(SELFSIGNED_CERT)) {
531
532=== modified file 'ubuntu-download-manager-priv/downloads/factory.cpp'
533--- ubuntu-download-manager-priv/downloads/factory.cpp 2014-02-01 08:46:28 +0000
534+++ ubuntu-download-manager-priv/downloads/factory.cpp 2014-02-22 10:42:10 +0000
535@@ -18,6 +18,7 @@
536
537 #include <QNetworkProxy>
538 #include <QPair>
539+#include <ubuntu/download_manager/metadata.h>
540 #include "downloads/download_adaptor.h"
541 #include "downloads/group_download.h"
542 #include "downloads/group_download_adaptor.h"
543@@ -26,12 +27,6 @@
544 #include "downloads/factory.h"
545 #include "system/logger.h"
546
547-namespace {
548-
549- const QString OBJECT_PATH_KEY = "objectpath";
550-
551-}
552-
553 namespace Ubuntu {
554
555 namespace DownloadManager {
556@@ -61,9 +56,9 @@
557 QString& rootPath,
558 bool& isConfined) {
559 TRACE << dbusOwner;
560- if (metadata.contains(OBJECT_PATH_KEY)) {
561+ if (metadata.contains(Metadata::OBJECT_PATH_KEY)) {
562 // create a uuid using the string value form the metadata
563- id = metadata[OBJECT_PATH_KEY].toString();
564+ id = metadata[Metadata::OBJECT_PATH_KEY].toString();
565 if (id.isEmpty()) {
566 LOG(ERROR) << "Id sent by client is ''";
567 id = _apparmor->getSecurePath(dbusOwner, dbusPath, rootPath,
568
569=== modified file 'ubuntu-download-manager-priv/downloads/file_download.cpp'
570--- ubuntu-download-manager-priv/downloads/file_download.cpp 2014-02-20 13:12:04 +0000
571+++ ubuntu-download-manager-priv/downloads/file_download.cpp 2014-02-22 10:42:10 +0000
572@@ -23,8 +23,10 @@
573 #include <QFile>
574 #include <QFileInfo>
575 #include <QSslError>
576+#include <ubuntu/download_manager/metadata.h>
577 #include <ubuntu/download_manager/system/hash_algorithm.h>
578 #include "downloads/file_download.h"
579+#include "system/filename_mutex.h"
580 #include "system/logger.h"
581 #include "system/network_reply.h"
582
583@@ -34,18 +36,15 @@
584 namespace {
585
586 const QString DATA_FILE_NAME = "data.download";
587- const QString METADATA_FILE_NAME = "metadata";
588- const QString METADATA_COMMAND_KEY = "post-download-command";
589- const QString METADATA_COMMAND_FILE_KEY = "$file";
590 const QString NETWORK_ERROR = "NETWORK ERROR";
591 const QString HASH_ERROR = "HASH ERROR";
592 const QString COMMAND_ERROR = "COMMAND ERROR";
593 const QString SSL_ERROR = "SSL ERROR";
594 const QString FILE_SYSTEM_ERROR = "FILE SYSTEM ERROR: %1";
595+ const QString TEMP_EXTENSION = ".tmp";
596 const QString AUTH_ERROR = "AUTHENTICATION ERROR";
597 const QString PROXY_AUTH_ERROR = "PROXY_AUTHENTICATION ERROR";
598 const QString UNEXPECTED_ERROR = "UNEXPECTED_ERROR";
599-
600 }
601
602 namespace Ubuntu {
603@@ -116,6 +115,9 @@
604
605 // remove current data and metadata
606 cleanUpCurrentData();
607+ // unlock the file name so that other downloads can use it it if is
608+ // no used in the file system
609+ _fileNameMutex->unlockFileName(_filePath);
610 _downloading = false;
611 emit canceled(true);
612 }
613@@ -197,7 +199,7 @@
614
615 // create file that will be used to maintain the state of the
616 // download when resumed.
617- _currentData = FileManager::instance()->createFile(_filePath);
618+ _currentData = FileManager::instance()->createFile(_tempFilePath);
619 bool canWrite = _currentData->open(QIODevice::ReadWrite | QFile::Append);
620
621 if (!canWrite) {
622@@ -326,11 +328,13 @@
623 _reply->deleteLater();
624 _reply = nullptr;
625
626- // clean the local file
627+ // clean the local file without unlocking the file the reason for
628+ // this is that the file pat is going to be reused to store the
629+ // data from the redirect
630 cleanUpCurrentData();
631
632 // perform again the request but do not emit started signal
633- _currentData = FileManager::instance()->createFile(_filePath);
634+ _currentData = FileManager::instance()->createFile(_tempFilePath);
635 bool canWrite = _currentData->open(QIODevice::ReadWrite | QFile::Append);
636
637 if (!canWrite) {
638@@ -369,7 +373,7 @@
639 // means we are done here else we execute the command AND raise the
640 // finish signals once the command was done (or an error occurred in
641 // the command execution.
642- if (metadata().contains(METADATA_COMMAND_KEY)) {
643+ if (metadata().contains(Metadata::COMMAND_KEY)) {
644 // just emit processing if we DO NOT have a hash because else we
645 // already emitted it.
646 if (_hash.isEmpty()) {
647@@ -377,7 +381,7 @@
648 }
649 // toStringList will return an empty list if it cannot be converted
650 QStringList commandData =
651- metadata()[METADATA_COMMAND_KEY].toStringList();
652+ metadata()[Metadata::COMMAND_KEY].toStringList();
653 if (commandData.count() == 0) {
654 DOWN_LOG(ERROR) << "COMMAND DATA MISSING";
655 emitError(COMMAND_ERROR);
656@@ -390,7 +394,7 @@
657 QStringList args;
658
659 foreach(const QString& arg, commandData) {
660- if (arg == METADATA_COMMAND_FILE_KEY)
661+ if (arg == Metadata::COMMAND_FILE_KEY)
662 args << filePath();
663 else
664 args << arg;
665@@ -412,9 +416,7 @@
666 return;
667 }
668 } else {
669- setState(Download::FINISH);
670- DOWN_LOG(INFO) << "EMIT finished" << filePath();
671- emit finished(filePath());
672+ emitFinished();
673 }
674
675 // clean the reply
676@@ -467,9 +469,20 @@
677 if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
678 // remove the file since we are done with it
679 cleanUpCurrentData();
680- setState(Download::FINISH);
681- DOWN_LOG(INFO) << "EMIT finished" << filePath();
682- emit finished(filePath());
683+ emitFinished();
684+ // remove the file because that is the contract that we have with
685+ // the clients
686+ auto fileMan = FileManager::instance();
687+
688+ if (fileMan->exists(_tempFilePath)) {
689+ LOG(INFO) << "Removing '" << _tempFilePath << "'";
690+ fileMan->remove(_tempFilePath);
691+ }
692+
693+ if (fileMan->exists(_filePath)) {
694+ LOG(INFO) << "Removing '" << _filePath << "'";
695+ fileMan->remove(_filePath);
696+ }
697 } else {
698 auto standardOut = p->readAllStandardOutput();
699 auto standardErr = p->readAllStandardError();
700@@ -507,6 +520,7 @@
701 void
702 FileDownload::init() {
703 _requestFactory = RequestFactory::instance();
704+ _fileNameMutex = System::FileNameMutex::instance();
705 SystemNetworkInfo* networkInfo = SystemNetworkInfo::instance();
706 _connected = networkInfo->isOnline();
707 _downloading = false;
708@@ -515,7 +529,7 @@
709 connect(networkInfo, &SystemNetworkInfo::onlineStateChanged,
710 this, &FileDownload::onOnlineStateChanged);
711
712- _filePath = getSaveFileName();
713+ initFileNames();
714
715 // ensure that the download is valid
716 if (!_url.isValid()) {
717@@ -563,66 +577,52 @@
718 return flushed;
719 }
720
721-QString
722-FileDownload::getSaveFileName() {
723+void
724+FileDownload::initFileNames() {
725+ // the mutex will ensure that we do not have race conditions about
726+ // the file names in the download manager
727 QString path = _url.path();
728 QString basename = QFileInfo(path).fileName();
729
730 if (basename.isEmpty())
731 basename = DATA_FILE_NAME;
732
733- QVariantMap metadataMap = metadata();
734- QString finalPath;
735+ auto metadataMap = metadata();
736
737- if (!isConfined() && metadataMap.contains(LOCAL_PATH_KEY)) {
738- finalPath = metadataMap[LOCAL_PATH_KEY].toString();
739+ if (!isConfined() && metadataMap.contains(Metadata::LOCAL_PATH_KEY)) {
740+ _filePath = metadataMap[Metadata::LOCAL_PATH_KEY].toString();
741+ _tempFilePath = _fileNameMutex->lockFileName(
742+ _filePath + TEMP_EXTENSION);
743
744 // in this case and because the app is not confined we are
745 // going to check if the file exists, if it does we will
746 // raise an error
747- if (QFile::exists(finalPath)) {
748+ if (QFile::exists(_filePath)) {
749 setIsValid(false);
750 setLastError(QString("File already exists at: '%1'").arg(
751- finalPath));
752+ _filePath));
753 }
754 } else {
755- finalPath = rootPath() + QDir::separator() + basename;
756- if (QFile::exists(finalPath)) {
757- finalPath = uniqueFilePath(finalPath);
758- }
759-
760+ auto desiredPath = rootPath() + QDir::separator() + basename;
761+ _filePath = _fileNameMutex->lockFileName(desiredPath);
762+ _tempFilePath = _filePath + TEMP_EXTENSION;
763 }
764-
765- return finalPath;
766 }
767
768-QString
769-FileDownload::uniqueFilePath(QString path) {
770- QFileInfo fileInfo(path);
771-
772- // Split the file into 2 parts - dot+extension, and everything else. For
773- // example, "path/file.tar.gz" becomes "path/file"+".tar.gz", while
774- // "path/file" (note lack of extension) becomes "path/file"+"".
775- auto secondPart = fileInfo.completeSuffix();
776- auto firstPart = path;
777-
778- if (!secondPart.isEmpty()) {
779- secondPart = "." + secondPart;
780- firstPart = path.left(path.size() - secondPart.size());
781+void
782+FileDownload::emitFinished() {
783+ auto fileMan = FileManager::instance();
784+
785+ LOG(INFO) << "EMIT finished" << filePath();
786+ setState(Download::FINISH);
787+
788+ if (fileMan->exists(_tempFilePath)) {
789+ LOG(INFO) << "Rename '" << _tempFilePath << "' to '"
790+ << _filePath << "'";
791+ fileMan->rename(_tempFilePath, _filePath);
792 }
793-
794- // Try with an ever-increasing number suffix, until we've reached a file
795- // that does not yet exist.
796- for (int ii = 1; ; ii++) {
797- // Construct the new file name by adding the unique number between the
798- // first and second part.
799- auto finalPath = QString("%1 (%2)%3").arg(firstPart).arg(ii).arg(secondPart);
800- // If no file exists with the new name, return it.
801- if (!QFile::exists(finalPath)) {
802- return finalPath;
803- }
804- } // for
805- return path;
806+ _fileNameMutex->unlockFileName(_filePath);
807+ emit finished(_filePath);
808 }
809
810 void
811@@ -638,7 +638,7 @@
812 _currentData->deleteLater();
813 _currentData = nullptr;
814 } else {
815- QScopedPointer<QFile> tempFile(new QFile(_filePath));
816+ QScopedPointer<QFile> tempFile(new QFile(_tempFilePath));
817 success = tempFile->remove();
818 if (!success)
819 error = tempFile->error();
820@@ -674,6 +674,8 @@
821 _reply->deleteLater();
822 _reply = nullptr;
823 cleanUpCurrentData();
824+ // let other downloads use the same file name
825+ _fileNameMutex->unlockFileName(_filePath);
826 Download::emitError(error);
827 }
828
829
830=== modified file 'ubuntu-download-manager-priv/downloads/file_download.h'
831--- ubuntu-download-manager-priv/downloads/file_download.h 2014-02-11 15:35:52 +0000
832+++ ubuntu-download-manager-priv/downloads/file_download.h 2014-02-22 10:42:10 +0000
833@@ -30,8 +30,7 @@
834 #include <ubuntu/download_manager/process_error_struct.h>
835 #include "downloads/download.h"
836 #include "system/file_manager.h"
837-
838-#define LOCAL_PATH_KEY "local-path"
839+#include "system/filename_mutex.h"
840
841 namespace Ubuntu {
842
843@@ -121,8 +120,8 @@
844 void onProcessFinished(int exitCode,
845 QProcess::ExitStatus exitStatus);
846 void onOnlineStateChanged(bool);
847- QString getSaveFileName();
848- QString uniqueFilePath(QString path);
849+ void initFileNames();
850+ void emitFinished();
851
852 private:
853 bool _downloading = false;
854@@ -130,10 +129,12 @@
855 qulonglong _totalSize = 0;
856 QUrl _url;
857 QString _filePath;
858+ QString _tempFilePath;
859 QString _hash;
860 QCryptographicHash::Algorithm _algo;
861 NetworkReply* _reply = nullptr;
862 File* _currentData = nullptr;
863+ FileNameMutex* _fileNameMutex = nullptr;
864 QList<QUrl> _visitedUrls;
865 };
866
867
868=== modified file 'ubuntu-download-manager-priv/downloads/group_download.cpp'
869--- ubuntu-download-manager-priv/downloads/group_download.cpp 2014-02-20 13:12:04 +0000
870+++ ubuntu-download-manager-priv/downloads/group_download.cpp 2014-02-22 10:42:10 +0000
871@@ -16,6 +16,7 @@
872 * boston, ma 02110-1301, usa.
873 */
874
875+#include <ubuntu/download_manager/metadata.h>
876 #include <ubuntu/download_manager/system/hash_algorithm.h>
877 #include "downloads/download_adaptor.h"
878 #include "downloads/file_download.h"
879@@ -95,7 +96,7 @@
880
881 FileDownload* singleDownload;
882 QVariantMap downloadMetadata = QVariantMap(metadataMap);
883- downloadMetadata[LOCAL_PATH_KEY] = download.getLocalFile();
884+ downloadMetadata[Metadata::LOCAL_PATH_KEY] = download.getLocalFile();
885
886 if (hash.isEmpty()) {
887 singleDownload = qobject_cast<FileDownload*>(
888
889=== modified file 'ubuntu-download-manager-priv/system/file_manager.cpp'
890--- ubuntu-download-manager-priv/system/file_manager.cpp 2014-02-01 09:01:47 +0000
891+++ ubuntu-download-manager-priv/system/file_manager.cpp 2014-02-22 10:42:10 +0000
892@@ -107,6 +107,11 @@
893 return QFile::exists(path);
894 }
895
896+bool
897+FileManager::rename(const QString& oldName, const QString& newName) {
898+ return QFile::rename(oldName, newName);
899+}
900+
901 FileManager* FileManager::instance() {
902 if(_instance == nullptr) {
903 _mutex.lock();
904
905=== modified file 'ubuntu-download-manager-priv/system/file_manager.h'
906--- ubuntu-download-manager-priv/system/file_manager.h 2014-02-01 09:01:47 +0000
907+++ ubuntu-download-manager-priv/system/file_manager.h 2014-02-22 10:42:10 +0000
908@@ -66,6 +66,7 @@
909 virtual File* createFile(const QString& name);
910 virtual bool remove(const QString& path);
911 virtual bool exists(const QString& path);
912+ virtual bool rename(const QString& oldName, const QString& newName);
913
914 static FileManager* instance();
915
916
917=== added file 'ubuntu-download-manager-priv/system/filename_mutex.cpp'
918--- ubuntu-download-manager-priv/system/filename_mutex.cpp 1970-01-01 00:00:00 +0000
919+++ ubuntu-download-manager-priv/system/filename_mutex.cpp 2014-02-22 10:42:10 +0000
920@@ -0,0 +1,133 @@
921+/*
922+ * Copyright 2014 Canonical Ltd.
923+ *
924+ * This library is free software; you can redistribute it and/or
925+ * modify it under the terms of version 3 of the GNU Lesser General Public
926+ * License as published by the Free Software Foundation.
927+ *
928+ * This program is distributed in the hope that it will be useful,
929+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
930+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
931+ * General Public License for more details.
932+ *
933+ * You should have received a copy of the GNU Lesser General Public
934+ * License along with this library; if not, write to the
935+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
936+ * Boston, MA 02110-1301, USA.
937+ */
938+
939+#include <QFile>
940+#include <QFileInfo>
941+#include <ubuntu/download_manager/metadata.h>
942+#include "logger.h"
943+#include "filename_mutex.h"
944+
945+namespace Ubuntu {
946+
947+namespace DownloadManager {
948+
949+namespace System {
950+
951+FileNameMutex* FileNameMutex::_instance = nullptr;
952+QMutex FileNameMutex::_singletonMutex;
953+
954+FileNameMutex::FileNameMutex(QObject* parent)
955+ : QObject(parent) {
956+}
957+
958+QString
959+FileNameMutex::lockFileName(const QString& expectedName) {
960+ auto path = expectedName;
961+ _mutex.lock();
962+ QFileInfo fileInfo(expectedName);
963+ if (!_paths.contains(path) && !QFile::exists(path)) {
964+ _paths.insert(path);
965+ _mutex.unlock();
966+ return path;
967+ }
968+ // Split the file into 2 parts - dot+extension, and everything
969+ // else. For example, "path/file.tar.gz" becomes
970+ // "path/file"+".tar.gz", while "path/file" (note lack of
971+ // extension) becomes "path/file"+"".
972+ auto secondPart = fileInfo.completeSuffix();
973+ auto firstPart = expectedName;
974+
975+ if (!secondPart.isEmpty()) {
976+ secondPart = "." + secondPart;
977+ firstPart = expectedName.left(expectedName.size()
978+ - secondPart.size());
979+ }
980+
981+ // Try with an ever-increasing number suffix, until we've
982+ // reached a file that does not yet exist.
983+ for (int ii = 1; ; ii++) {
984+ // Construct the new file name by adding the unique
985+ // number between the first and second part.
986+ path = QString("%1 (%2)%3").arg(firstPart
987+ ).arg(ii).arg(secondPart);
988+ // If no file exists with the new name, return it.
989+ if (!_paths.contains(path) && !QFile::exists(path)) {
990+ _paths.insert(path);
991+ LOG(INFO) << "Locked path '" << path << "'";
992+ break;
993+ }
994+ } // for
995+
996+ _mutex.unlock();
997+ return path;
998+}
999+
1000+void
1001+FileNameMutex::unlockFileName(const QString& filename) {
1002+ _mutex.lock();
1003+ auto removed = _paths.remove(filename);
1004+ if (!removed) {
1005+ LOG(WARNING) << "Tired to remove filename '" << filename
1006+ << "' when it was not owned by any object.";
1007+ } else {
1008+ LOG(INFO) << "Released path '" << filename << "'";
1009+ }
1010+ _mutex.unlock();
1011+}
1012+
1013+bool
1014+FileNameMutex::isLocked(const QString& filename) {
1015+ _mutex.lock();
1016+ auto present = _paths.contains(filename);
1017+ _mutex.unlock();
1018+ return present;
1019+}
1020+
1021+FileNameMutex*
1022+FileNameMutex::instance() {
1023+ if(_instance == nullptr) {
1024+ _singletonMutex.lock();
1025+ if(_instance == nullptr)
1026+ _instance = new FileNameMutex();
1027+ _singletonMutex.unlock();
1028+ }
1029+ return _instance;
1030+}
1031+
1032+void
1033+FileNameMutex::deleteInstance() {
1034+ if(_instance != nullptr) {
1035+ _singletonMutex.lock();
1036+ if(_instance != nullptr) {
1037+ delete _instance;
1038+ _instance = nullptr;
1039+ }
1040+ _singletonMutex.unlock();
1041+ }
1042+}
1043+
1044+void
1045+FileNameMutex::setInstance(FileNameMutex* instance) {
1046+ _instance = instance;
1047+}
1048+
1049+} // System
1050+
1051+} // DownloadManager
1052+
1053+} // Ubuntu
1054
1055=== added file 'ubuntu-download-manager-priv/system/filename_mutex.h'
1056--- ubuntu-download-manager-priv/system/filename_mutex.h 1970-01-01 00:00:00 +0000
1057+++ ubuntu-download-manager-priv/system/filename_mutex.h 2014-02-22 10:42:10 +0000
1058@@ -0,0 +1,64 @@
1059+/*
1060+ * Copyright 2014 Canonical Ltd.
1061+ *
1062+ * This library is free software; you can redistribute it and/or
1063+ * modify it under the terms of version 3 of the GNU Lesser General Public
1064+ * License as published by the Free Software Foundation.
1065+ *
1066+ * This program is distributed in the hope that it will be useful,
1067+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1068+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1069+ * General Public License for more details.
1070+ *
1071+ * You should have received a copy of the GNU Lesser General Public
1072+ * License along with this library; if not, write to the
1073+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1074+ * Boston, MA 02110-1301, USA.
1075+ */
1076+
1077+#ifndef DOWNLOADER_LIB_FILENAME_MUTEX_H
1078+#define DOWNLOADER_LIB_FILENAME_MUTEX_H
1079+
1080+#include <QMutex>
1081+#include <QObject>
1082+#include <QVariant>
1083+#include <QSet>
1084+
1085+namespace Ubuntu {
1086+
1087+namespace DownloadManager {
1088+
1089+namespace System {
1090+
1091+class FileNameMutex : public QObject {
1092+ Q_OBJECT
1093+ public:
1094+ explicit FileNameMutex(QObject* parent = 0);
1095+ virtual QString lockFileName(const QString& expectedName);
1096+ virtual void unlockFileName(const QString& filename);
1097+ virtual bool isLocked(const QString& filename);
1098+
1099+ static FileNameMutex* instance();
1100+
1101+ // only used for testing so that we can inject a fake
1102+ static void setInstance(FileNameMutex* instance);
1103+ static void deleteInstance();
1104+
1105+ protected:
1106+ QSet<QString> _paths;
1107+
1108+ private:
1109+ // used for the singleton
1110+ static FileNameMutex* _instance;
1111+ static QMutex _singletonMutex;
1112+
1113+ QMutex _mutex;
1114+};
1115+
1116+} // System
1117+
1118+} // DownloadManager
1119+
1120+} // Ubuntu
1121+
1122+#endif // FILENAME_MUTEX_H
1123
1124=== modified file 'ubuntu-download-manager-priv/ubuntu-download-manager-priv.pro'
1125--- ubuntu-download-manager-priv/ubuntu-download-manager-priv.pro 2014-02-13 21:30:25 +0000
1126+++ ubuntu-download-manager-priv/ubuntu-download-manager-priv.pro 2014-02-22 10:42:10 +0000
1127@@ -41,7 +41,8 @@
1128 downloads/state_machines/final_state.cpp \
1129 system/apn_request_factory.cpp \
1130 downloads/mms_file_download.cpp \
1131- system/apn_proxy.cpp
1132+ system/apn_proxy.cpp \
1133+ system/filename_mutex.cpp
1134
1135 HEADERS +=\
1136 downloads/daemon.h \
1137@@ -74,7 +75,8 @@
1138 downloads/state_machines/final_state.h \
1139 system/apn_request_factory.h \
1140 downloads/mms_file_download.h \
1141- system/apn_proxy.h
1142+ system/apn_proxy.h \
1143+ system/filename_mutex.h
1144
1145 OTHER_FILES += \
1146 generate_adaptors.sh \
1147
1148=== modified file 'ubuntu-download-manager-test-lib/ubuntu-download-manager-test-lib.pro'
1149--- ubuntu-download-manager-test-lib/ubuntu-download-manager-test-lib.pro 2014-02-13 13:21:14 +0000
1150+++ ubuntu-download-manager-test-lib/ubuntu-download-manager-test-lib.pro 2014-02-22 10:42:10 +0000
1151@@ -35,7 +35,8 @@
1152 ubuntu/download_manager/tests/client/testing_interface.cpp \
1153 ubuntu/download_manager/tests/client/testing_file_download.cpp \
1154 ubuntu/download_manager/tests/server/apn_request_factory.cpp \
1155- ubuntu/download_manager/tests/server/group_download.cpp
1156+ ubuntu/download_manager/tests/server/filename_mutex.cpp \
1157+ ubuntu/download_manager/tests/server/group_download.cpp
1158
1159 HEADERS += ubuntu/download_manager/tests/base_testcase.h \
1160 ubuntu/download_manager/tests/fake.h\
1161@@ -64,7 +65,8 @@
1162 ubuntu/download_manager/tests/client/testing_interface.h \
1163 ubuntu/download_manager/tests/client/testing_file_download.h \
1164 ubuntu/download_manager/tests/server/apn_request_factory.h \
1165- ubuntu/download_manager/tests/server/group_download.h
1166+ ubuntu/download_manager/tests/server/filename_mutex.h \
1167+ ubuntu/download_manager/tests/server/group_download.h
1168
1169 LIBS += -L$$OUT_PWD/../ubuntu-download-manager-common/ -lubuntu-download-manager-common
1170
1171
1172=== modified file 'ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/base_testcase.cpp'
1173--- ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/base_testcase.cpp 2014-01-24 11:24:40 +0000
1174+++ ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/base_testcase.cpp 2014-02-22 10:42:10 +0000
1175@@ -46,7 +46,7 @@
1176 pathComponents << dataPath << objectName();
1177 QString path = pathComponents.join(QDir::separator());
1178
1179- if (!QDir().exists(path))
1180+ if (!QDir().exists(path))
1181 QDir().mkpath(path);
1182
1183 return path;
1184
1185=== modified file 'ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/file_manager.cpp'
1186--- ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/file_manager.cpp 2014-02-01 09:01:47 +0000
1187+++ ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/file_manager.cpp 2014-02-22 10:42:10 +0000
1188@@ -76,5 +76,5 @@
1189 MethodData methodData("remove", params);
1190 _called.append(methodData);
1191 }
1192- return true;
1193+ return QFile::remove(path);
1194 }
1195
1196=== added file 'ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.cpp'
1197--- ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.cpp 1970-01-01 00:00:00 +0000
1198+++ ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.cpp 2014-02-22 10:42:10 +0000
1199@@ -0,0 +1,58 @@
1200+/*
1201+ * Copyright 2014 Canonical Ltd.
1202+ *
1203+ * This library is free software; you can redistribute it and/or
1204+ * modify it under the terms of version 3 of the GNU Lesser General Public
1205+ * License as published by the Free Software Foundation.
1206+ *
1207+ * This program is distributed in the hope that it will be useful,
1208+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1209+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1210+ * General Public License for more details.
1211+ *
1212+ * You should have received a copy of the GNU Lesser General Public
1213+ * License along with this library; if not, write to the
1214+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1215+ * Boston, MA 02110-1301, USA.
1216+ */
1217+
1218+#include "filename_mutex.h"
1219+
1220+FakeFileNameMutex::FakeFileNameMutex(QObject* parent)
1221+ : FileNameMutex(parent),
1222+ Fake(){
1223+}
1224+
1225+QString
1226+FakeFileNameMutex::lockFileName(const QString& expectedName) {
1227+ if (_recording) {
1228+ QList<QObject*> inParams;
1229+ inParams.append(new StringWrapper(expectedName, this));
1230+ QList<QObject*> outParams;
1231+ MethodParams params(inParams, outParams);
1232+
1233+ MethodData methodData("lockFileName", params);
1234+ _called.append(methodData);
1235+ }
1236+
1237+ return FileNameMutex::lockFileName(expectedName);
1238+}
1239+
1240+void
1241+FakeFileNameMutex::unlockFileName(const QString& filename) {
1242+ if (_recording) {
1243+ QList<QObject*> inParams;
1244+ inParams.append(new StringWrapper(filename, this));
1245+ QList<QObject*> outParams;
1246+ MethodParams params(inParams, outParams);
1247+
1248+ MethodData methodData("unlockFileName", params);
1249+ _called.append(methodData);
1250+ }
1251+ FileNameMutex::unlockFileName(filename);
1252+}
1253+
1254+void
1255+FakeFileNameMutex::clearMutex() {
1256+ _paths.clear();
1257+}
1258
1259=== added file 'ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.h'
1260--- ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.h 1970-01-01 00:00:00 +0000
1261+++ ubuntu-download-manager-test-lib/ubuntu/download_manager/tests/server/filename_mutex.h 2014-02-22 10:42:10 +0000
1262@@ -0,0 +1,43 @@
1263+/*
1264+ * Copyright 2014 Canonical Ltd.
1265+ *
1266+ * This library is free software; you can redistribute it and/or
1267+ * modify it under the terms of version 3 of the GNU Lesser General Public
1268+ * License as published by the Free Software Foundation.
1269+ *
1270+ * This program is distributed in the hope that it will be useful,
1271+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1272+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1273+ * General Public License for more details.
1274+ *
1275+ * You should have received a copy of the GNU Lesser General Public
1276+ * License along with this library; if not, write to the
1277+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1278+ * Boston, MA 02110-1301, USA.
1279+ */
1280+
1281+#ifndef FILENAME_MUTEXT_H
1282+#define FILENAME_MUTEXT_H
1283+
1284+#include <QObject>
1285+#include <system/filename_mutex.h>
1286+#include "ubuntu/download_manager/tests/fake.h"
1287+
1288+using namespace Ubuntu::DownloadManager::System;
1289+
1290+class FakeFileNameMutex : public FileNameMutex, public Fake {
1291+ Q_OBJECT
1292+
1293+ public:
1294+ explicit FakeFileNameMutex(QObject *parent = 0);
1295+
1296+ /// override to keep track of the calls
1297+ QString lockFileName(const QString& expectedName) override;
1298+ void unlockFileName(const QString& filename) override;
1299+
1300+ // just for testing purposes
1301+ void clearMutex();
1302+
1303+};
1304+
1305+#endif // FILENAME_MUTEXT_H
1306
1307=== modified file 'ubuntu-download-manager-tests/downloads/test_download.cpp'
1308--- ubuntu-download-manager-tests/downloads/test_download.cpp 2014-02-11 15:35:52 +0000
1309+++ ubuntu-download-manager-tests/downloads/test_download.cpp 2014-02-22 10:42:10 +0000
1310@@ -50,6 +50,8 @@
1311 ProcessFactory::setInstance(_processFactory);
1312 _fileManager = new FakeFileManager();
1313 FileManager::setInstance(_fileManager);
1314+ _fileNameMutex = new FakeFileNameMutex();
1315+ FileNameMutex::setInstance(_fileNameMutex);
1316 }
1317
1318 void
1319@@ -60,6 +62,7 @@
1320 RequestFactory::deleteInstance();
1321 ProcessFactory::deleteInstance();
1322 FileManager::deleteInstance();
1323+ FileNameMutex::deleteInstance();
1324 }
1325
1326 void
1327@@ -711,7 +714,9 @@
1328 QCOMPARE(spy.count(), 1);
1329
1330 // assert that the files does exist in the system
1331- QFileInfo info = QFileInfo(download->filePath());
1332+ QFileInfo info(download->filePath());
1333+ QVERIFY(!info.exists());
1334+ info = QFileInfo(download->filePath() + ".tmp");
1335 QVERIFY(info.exists());
1336 }
1337
1338@@ -735,6 +740,8 @@
1339
1340 // assert that the files does exist in the system
1341 QFileInfo info = QFileInfo(download->filePath());
1342+ QVERIFY(!info.exists());
1343+ info = QFileInfo(download->filePath() + ".tmp");
1344 QVERIFY(info.exists());
1345 }
1346
1347@@ -1639,8 +1646,9 @@
1348
1349 _processFactory->record();
1350 _reqFactory->record();
1351- QScopedPointer<FileDownload> download(new FileDownload(_id, _path, _isConfined,
1352- _rootPath, _url, metadata, _headers));
1353+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path,
1354+ _isConfined, _rootPath, _url, metadata, _headers));
1355+ QSignalSpy finishedSpy(download.data(), SIGNAL(finished(QString)));
1356
1357 // write something in the expected file
1358 QString fileName = download->filePath();
1359@@ -1668,6 +1676,7 @@
1360
1361 // emit the finished signal with a result > 0 and ensure error is emitted
1362 process->emitFinished(0, QProcess::NormalExit);
1363+ QTRY_COMPARE(1, finishedSpy.count());
1364 // assert that the file does not longer exist in the system
1365 QVERIFY(!QFile::exists(fileName));
1366 }
1367@@ -1901,7 +1910,7 @@
1368
1369 QTest::newRow("One") << 1;
1370 QTest::newRow("Some") << 3;
1371- QTest::newRow("Several") << 10;
1372+ QTest::newRow("Several") << 10;
1373 QTest::newRow("Plenti") << 100;
1374 }
1375
1376@@ -1921,11 +1930,14 @@
1377
1378 QFileInfo fileInfo(filePath);
1379 auto suffix = "." + fileInfo.completeSuffix();
1380+ qDebug() << "SUFIX" << suffix;
1381 auto prefix = filePath.left(filePath.size() - suffix.size());
1382+ qDebug() << "PREFIX" << prefix;
1383
1384 // write the rest of the files
1385 for(int index=1; index < count; index++) {
1386 auto otherPath = QString("%1 (%2)%3").arg(prefix).arg(index).arg(suffix);
1387+ qDebug() << "Writing a new file" << otherPath;
1388 QScopedPointer<QFile> otherFile(new QFile(otherPath));
1389 otherFile->open(QIODevice::ReadWrite | QFile::Append);
1390 otherFile->write("data data data!");
1391@@ -2220,3 +2232,184 @@
1392 QTRY_COMPARE(finishedSpy.count(), 1);
1393 QCOMPARE(redirectCount, urls.count());
1394 }
1395+
1396+void
1397+TestDownload::testRedirectDoesNotUnlockPath() {
1398+ _fileNameMutex->record();
1399+
1400+ QUrl redirectUrl("http://redirect.example.com");
1401+ _reqFactory->record();
1402+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path,
1403+ _isConfined, _rootPath, _url, _metadata, _headers));
1404+
1405+ download->start(); // change state
1406+ download->startDownload();
1407+
1408+ QList<MethodData> calledMethods = _reqFactory->calledMethods();
1409+ QCOMPARE(1, calledMethods.count());
1410+ FakeNetworkReply* reply = qobject_cast<FakeNetworkReply*>(
1411+ calledMethods[0].params().outParams()[0]);
1412+
1413+ // set the attr for a redirect to a new url
1414+ // makes the process to be executed
1415+ reply->setAttribute(QNetworkRequest::RedirectionTargetAttribute,
1416+ redirectUrl);
1417+ QSignalSpy replySpy(_reqFactory, SIGNAL(requestCreated(NetworkReply*)));
1418+
1419+ // use a spy to wait for the second reply
1420+ reply->emitFinished();
1421+
1422+ // ensure that a second request is performed
1423+ QTRY_COMPARE(1, replySpy.count());
1424+
1425+ reply = qobject_cast<FakeNetworkReply*>(
1426+ replySpy.takeFirst().at(0).value<NetworkReply*>());
1427+
1428+ download->pause();
1429+
1430+ QSignalSpy errorSpy(download.data(), SIGNAL(error(QString)));
1431+ QSignalSpy networkErrorSpy(download.data(),
1432+ SIGNAL(networkError(NetworkErrorStruct)));
1433+ QSignalSpy finishedSpy(download.data(), SIGNAL(finished(QString)));
1434+
1435+ reply->emitFinished();
1436+
1437+ QTRY_COMPARE(networkErrorSpy.count(), 0);
1438+ QTRY_COMPARE(errorSpy.count(), 0);
1439+ QTRY_COMPARE(finishedSpy.count(), 1);
1440+
1441+ // ensure that we only called lock and unlock once and not several times
1442+ calledMethods = _fileNameMutex->calledMethods();
1443+ QCOMPARE(2, calledMethods.count());
1444+ auto methodName = calledMethods[0].methodName();
1445+ QCOMPARE(QString("lockFileName"), methodName);
1446+ methodName = calledMethods[1].methodName();
1447+ QCOMPARE(QString("unlockFileName"), methodName);
1448+}
1449+
1450+void
1451+TestDownload::testCancelUnlocksPath() {
1452+ _fileNameMutex->record();
1453+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path,
1454+ _isConfined, _rootPath, _url, _metadata, _headers));
1455+ QSignalSpy spy(download.data(),
1456+ SIGNAL(canceled(bool))); // NOLINT(readability/function)
1457+
1458+ download->start(); // change state
1459+ download->startDownload();
1460+ download->cancel(); // change state
1461+ download->cancelDownload(); // method under test
1462+
1463+ // assert that the filename was correctly managed
1464+ auto calledMethods = _fileNameMutex->calledMethods();
1465+ QCOMPARE(2, calledMethods.count());
1466+ auto methodName = calledMethods[0].methodName();
1467+ QCOMPARE(QString("lockFileName"), methodName);
1468+ methodName = calledMethods[1].methodName();
1469+ QCOMPARE(QString("unlockFileName"), methodName);
1470+}
1471+
1472+void
1473+TestDownload::testFinishUnlocksPath() {
1474+ _fileNameMutex->record();
1475+ _reqFactory->record();
1476+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path, _isConfined,
1477+ _rootPath, _url, _metadata, _headers));
1478+ QSignalSpy spy(download.data(), SIGNAL(finished(QString)));
1479+
1480+ download->start(); // change state
1481+ download->startDownload();
1482+
1483+ QList<MethodData> calledMethods = _reqFactory->calledMethods();
1484+ QCOMPARE(1, calledMethods.count());
1485+ FakeNetworkReply* reply = reinterpret_cast<FakeNetworkReply*>(
1486+ calledMethods[0].params().outParams()[0]);
1487+
1488+ // emit the finish signal and expect it to be raised
1489+ emit reply->finished();
1490+ QCOMPARE(spy.count(), 1);
1491+ QCOMPARE(download->state(), Download::FINISH);
1492+
1493+ calledMethods = _fileNameMutex->calledMethods();
1494+ QCOMPARE(2, calledMethods.count());
1495+ auto methodName = calledMethods[0].methodName();
1496+ QCOMPARE(QString("lockFileName"), methodName);
1497+ methodName = calledMethods[1].methodName();
1498+ QCOMPARE(QString("unlockFileName"), methodName);
1499+}
1500+
1501+void
1502+TestDownload::testProcessFinishUnlocksPath() {
1503+ _fileNameMutex->record();
1504+ _processFactory->record();
1505+ _reqFactory->record();
1506+
1507+ QString command = "cd";
1508+ QVariantMap metadata;
1509+ metadata["post-download-command"] = command;
1510+
1511+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path,
1512+ _isConfined, _rootPath, _url, metadata, _headers));
1513+ QSignalSpy spy(download.data(), SIGNAL(finished(QString)));
1514+
1515+ download->start(); // change state
1516+ download->startDownload();
1517+
1518+ // we need to set the data before we pause!!!
1519+ QList<MethodData> calledMethods = _reqFactory->calledMethods();
1520+ QCOMPARE(1, calledMethods.count());
1521+ FakeNetworkReply* reply = reinterpret_cast<FakeNetworkReply*>(
1522+ calledMethods[0].params().outParams()[0]);
1523+
1524+ // makes the process to be executed
1525+ reply->emitFinished();
1526+
1527+ calledMethods = _processFactory->calledMethods();
1528+ QCOMPARE(1, calledMethods.count());
1529+ FakeProcess* process = reinterpret_cast<FakeProcess*>(
1530+ calledMethods[0].params().outParams()[0]);
1531+
1532+ process->emitFinished(0, QProcess::NormalExit);
1533+ QTRY_COMPARE(spy.count(), 1);
1534+
1535+ calledMethods = _fileNameMutex->calledMethods();
1536+ QCOMPARE(2, calledMethods.count());
1537+ auto methodName = calledMethods[0].methodName();
1538+ QCOMPARE(QString("lockFileName"), methodName);
1539+ methodName = calledMethods[1].methodName();
1540+ QCOMPARE(QString("unlockFileName"), methodName);
1541+}
1542+
1543+void
1544+TestDownload::testErrorUnlocksPath() {
1545+ // fake an error and make sure that unlock is called
1546+ _fileNameMutex->record();
1547+ _reqFactory->record();
1548+ QScopedPointer<FileDownload> download(new FileDownload(_id, _path,
1549+ _isConfined, _rootPath, _url, _metadata, _headers));
1550+ QSignalSpy errorSpy(download.data(), SIGNAL(error(QString)));
1551+
1552+ download->start(); // change state
1553+ download->startDownload();
1554+
1555+ // we need to set the data before we pause!!!
1556+ QList<MethodData> calledMethods = _reqFactory->calledMethods();
1557+ QCOMPARE(1, calledMethods.count());
1558+ FakeNetworkReply* reply = reinterpret_cast<FakeNetworkReply*>(
1559+ calledMethods[0].params().outParams()[0]);
1560+
1561+ // set the attrs in the reply so that we do raise two signals
1562+ reply->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 404);
1563+ reply->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, "");
1564+
1565+ // emit the error and esure that the signals are raised
1566+ reply->emitHttpError(QNetworkReply::ContentAccessDenied);
1567+ QCOMPARE(errorSpy.count(), 1);
1568+
1569+ calledMethods = _fileNameMutex->calledMethods();
1570+ QCOMPARE(2, calledMethods.count());
1571+ auto methodName = calledMethods[0].methodName();
1572+ QCOMPARE(QString("lockFileName"), methodName);
1573+ methodName = calledMethods[1].methodName();
1574+ QCOMPARE(QString("unlockFileName"), methodName);
1575+}
1576
1577=== modified file 'ubuntu-download-manager-tests/downloads/test_download.h'
1578--- ubuntu-download-manager-tests/downloads/test_download.h 2014-02-11 15:35:52 +0000
1579+++ ubuntu-download-manager-tests/downloads/test_download.h 2014-02-22 10:42:10 +0000
1580@@ -24,6 +24,7 @@
1581 #include <downloads/file_download.h>
1582 #include <ubuntu/download_manager/metatypes.h>
1583 #include <ubuntu/download_manager/tests/server/file_manager.h>
1584+#include <ubuntu/download_manager/tests/server/filename_mutex.h>
1585 #include <ubuntu/download_manager/tests/server/system_network_info.h>
1586 #include <ubuntu/download_manager/tests/server/request_factory.h>
1587 #include <ubuntu/download_manager/tests/server/process_factory.h>
1588@@ -162,6 +163,13 @@
1589 void testSeveralRedirects_data();
1590 void testSeveralRedirects();
1591
1592+ // test lock of files
1593+ void testRedirectDoesNotUnlockPath();
1594+ void testCancelUnlocksPath();
1595+ void testFinishUnlocksPath();
1596+ void testProcessFinishUnlocksPath();
1597+ void testErrorUnlocksPath();
1598+
1599 private:
1600 QString _id;
1601 bool _isConfined;
1602@@ -175,6 +183,7 @@
1603 FakeRequestFactory* _reqFactory;
1604 FakeProcessFactory* _processFactory;
1605 FakeFileManager* _fileManager;
1606+ FakeFileNameMutex* _fileNameMutex;
1607 };
1608
1609 Q_DECLARE_METATYPE(QNetworkInfo::NetworkMode)
1610
1611=== modified file 'ubuntu-download-manager-tests/downloads/test_downloads_db.cpp'
1612--- ubuntu-download-manager-tests/downloads/test_downloads_db.cpp 2014-02-10 09:54:01 +0000
1613+++ ubuntu-download-manager-tests/downloads/test_downloads_db.cpp 2014-02-22 10:42:10 +0000
1614@@ -47,6 +47,8 @@
1615 void
1616 TestDownloadsDb::init() {
1617 BaseTestCase::init();
1618+ _fileNameMutex = new FakeFileNameMutex();
1619+ FileNameMutex::setInstance(_fileNameMutex);
1620 _db = DownloadsDb::instance();
1621 }
1622
1623@@ -62,6 +64,7 @@
1624 QFile::remove(dbFile);
1625 SystemNetworkInfo::deleteInstance();
1626 FileManager::deleteInstance();
1627+ FileNameMutex::deleteInstance();
1628 }
1629
1630 void
1631@@ -244,8 +247,8 @@
1632
1633 // create a second download with same id but a diff path to test is update
1634 QString newPath = path + path;
1635- QScopedPointer<FakeDownload> secondDownload(new FakeDownload(id, newPath, true, "",
1636- url, hash, hashAlgoString, metadata, headers));
1637+ QScopedPointer<FakeDownload> secondDownload(new FakeDownload(id,
1638+ newPath, true, "", url, hash, hashAlgoString, metadata, headers));
1639
1640 _db->storeSingleDownload(secondDownload.data());
1641
1642@@ -263,9 +266,6 @@
1643 QString dbDbusPath = query.value(1).toString();
1644 QCOMPARE(newPath, dbDbusPath);
1645
1646- QString dbLocalPath = query.value(2).toString();
1647- QCOMPARE(dbLocalPath, download->filePath());
1648-
1649 QString dbHash = query.value(3).toString();
1650 QCOMPARE(hash, dbHash);
1651
1652
1653=== modified file 'ubuntu-download-manager-tests/downloads/test_downloads_db.h'
1654--- ubuntu-download-manager-tests/downloads/test_downloads_db.h 2014-02-10 09:51:58 +0000
1655+++ ubuntu-download-manager-tests/downloads/test_downloads_db.h 2014-02-22 10:42:10 +0000
1656@@ -24,6 +24,7 @@
1657 #include <downloads/downloads_db.h>
1658 #include <ubuntu/download_manager/tests/base_testcase.h>
1659 #include <ubuntu/download_manager/tests/test_runner.h>
1660+#include <ubuntu/download_manager/tests/server/filename_mutex.h>
1661
1662 using namespace Ubuntu::DownloadManager::Daemon;
1663
1664@@ -68,6 +69,7 @@
1665
1666 private:
1667 DownloadsDb* _db;
1668+ FakeFileNameMutex* _fileNameMutex;
1669 };
1670
1671 DECLARE_TEST(TestDownloadsDb)
1672
1673=== modified file 'ubuntu-download-manager-tests/downloads/test_group_download.cpp'
1674--- ubuntu-download-manager-tests/downloads/test_group_download.cpp 2014-02-13 13:21:14 +0000
1675+++ ubuntu-download-manager-tests/downloads/test_group_download.cpp 2014-02-22 10:42:10 +0000
1676@@ -20,6 +20,7 @@
1677 #include <QSignalSpy>
1678 #include <downloads/group_download.h>
1679 #include <system/uuid_utils.h>
1680+#include <ubuntu/download_manager/metadata.h>
1681 #include <ubuntu/download_manager/tests/server/download.h>
1682 #include <ubuntu/download_manager/tests/server/group_download.h>
1683 #include "test_group_download.h"
1684@@ -667,18 +668,18 @@
1685
1686 // assert that each metadata has the local file set
1687 QVariantMap downMeta = downloads[0]->metadata();
1688- QVERIFY(downMeta.contains(LOCAL_PATH_KEY));
1689- QCOMPARE(downMeta[LOCAL_PATH_KEY].toString(),
1690+ QVERIFY(downMeta.contains(Metadata::LOCAL_PATH_KEY));
1691+ QCOMPARE(downMeta[Metadata::LOCAL_PATH_KEY].toString(),
1692 downloadsStruct[0].getLocalFile());
1693
1694 downMeta = downloads[1]->metadata();
1695- QVERIFY(downMeta.contains(LOCAL_PATH_KEY));
1696- QCOMPARE(downMeta[LOCAL_PATH_KEY].toString(),
1697+ QVERIFY(downMeta.contains(Metadata::LOCAL_PATH_KEY));
1698+ QCOMPARE(downMeta[Metadata::LOCAL_PATH_KEY].toString(),
1699 downloadsStruct[1].getLocalFile());
1700
1701 downMeta = downloads[2]->metadata();
1702- QVERIFY(downMeta.contains(LOCAL_PATH_KEY));
1703- QCOMPARE(downMeta[LOCAL_PATH_KEY].toString(),
1704+ QVERIFY(downMeta.contains(Metadata::LOCAL_PATH_KEY));
1705+ QCOMPARE(downMeta[Metadata::LOCAL_PATH_KEY].toString(),
1706 downloadsStruct[2].getLocalFile());
1707 }
1708
1709
1710=== added file 'ubuntu-download-manager-tests/system/test_filename_mutex.cpp'
1711--- ubuntu-download-manager-tests/system/test_filename_mutex.cpp 1970-01-01 00:00:00 +0000
1712+++ ubuntu-download-manager-tests/system/test_filename_mutex.cpp 2014-02-22 10:42:10 +0000
1713@@ -0,0 +1,108 @@
1714+/*
1715+ * Copyright 2014 Canonical Ltd.
1716+ *
1717+ * This library is free software; you can redistribute it and/or
1718+ * modify it under the terms of version 3 of the GNU Lesser General Public
1719+ * License as published by the Free Software Foundation.
1720+ *
1721+ * This program is distributed in the hope that it will be useful,
1722+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1723+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1724+ * General Public License for more details.
1725+ *
1726+ * You should have received a copy of the GNU Lesser General Public
1727+ * License along with this library; if not, write to the
1728+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1729+ * Boston, MA 02110-1301, USA.
1730+ */
1731+
1732+#include <QByteArray>
1733+#include <QDir>
1734+#include <QFile>
1735+#include <QScopedPointer>
1736+#include <system/filename_mutex.h>
1737+#include "test_filename_mutex.h"
1738+
1739+using namespace Ubuntu::DownloadManager::System;
1740+
1741+TestFileNameMutex::TestFileNameMutex(QObject *parent)
1742+ : BaseTestCase("TestFileNameMutex", parent) {
1743+}
1744+
1745+void
1746+TestFileNameMutex::testExpectedNameValid_data() {
1747+ QTest::addColumn<QString>("path");
1748+ auto dir = testDirectory();
1749+
1750+ QTest::newRow("First path") << dir + QDir::separator() + "first.zip";
1751+ QTest::newRow("Second path") << dir + QDir::separator() + "second.zip";
1752+ QTest::newRow("Last path") << dir + QDir::separator() + "last.zip";
1753+}
1754+
1755+void
1756+TestFileNameMutex::testExpectedNameValid() {
1757+ QFETCH(QString, path);
1758+
1759+ QScopedPointer<FileNameMutex> mutex(new FileNameMutex());
1760+ auto locked = mutex->lockFileName(path);
1761+ QCOMPARE(path, locked);
1762+ QVERIFY(mutex->isLocked(path));
1763+}
1764+
1765+void
1766+TestFileNameMutex::testExpectedNameLocked_data() {
1767+ QTest::addColumn<QString>("path");
1768+ auto dir = testDirectory();
1769+
1770+ QTest::newRow("First path") << dir + QDir::separator() + "first.zip";
1771+ QTest::newRow("Second path") << dir + QDir::separator() + "second.zip";
1772+ QTest::newRow("Last path") << dir + QDir::separator() + "last.zip";
1773+}
1774+
1775+void
1776+TestFileNameMutex::testExpectedNameLocked() {
1777+ QFETCH(QString, path);
1778+
1779+ QScopedPointer<FileNameMutex> mutex(new FileNameMutex());
1780+ mutex->lockFileName(path); // ensure that we already locked the path
1781+ auto locked = mutex->lockFileName(path);
1782+ QVERIFY(path != locked);
1783+ QVERIFY(mutex->isLocked(locked));
1784+}
1785+
1786+void
1787+TestFileNameMutex::testExpectedNameInFileSystem_data() {
1788+ QTest::addColumn<QString>("path");
1789+ auto dir = testDirectory();
1790+
1791+ QTest::newRow("First path") << dir + QDir::separator() + "first.zip";
1792+ QTest::newRow("Second path") << dir + QDir::separator() + "second_zip";
1793+ QTest::newRow("Last path") << dir + QDir::separator() + "last_zip";
1794+}
1795+
1796+void
1797+TestFileNameMutex::testExpectedNameInFileSystem() {
1798+ QFETCH(QString, path);
1799+ testDirectory(); // build temp dir
1800+ QScopedPointer<FileNameMutex> mutex(new FileNameMutex());
1801+
1802+ QFile file(path);
1803+ file.open(QIODevice::ReadWrite | QFile::Append);
1804+ file.write(QByteArray(400, 'f'));
1805+ file.flush();
1806+ file.close();
1807+
1808+ auto locked = mutex->lockFileName(path);
1809+ QVERIFY(path != locked);
1810+ QVERIFY(!mutex->isLocked(path));
1811+}
1812+
1813+void
1814+TestFileNameMutex::testUnlockPresent() {
1815+ auto path = testDirectory() + QDir::separator() + "test.txt";
1816+ QScopedPointer<FileNameMutex> mutex(new FileNameMutex());
1817+ auto locked = mutex->lockFileName(path);
1818+ QVERIFY(mutex->isLocked(locked));
1819+ mutex->unlockFileName(path);
1820+ QVERIFY(!mutex->isLocked(locked));
1821+}
1822
1823=== added file 'ubuntu-download-manager-tests/system/test_filename_mutex.h'
1824--- ubuntu-download-manager-tests/system/test_filename_mutex.h 1970-01-01 00:00:00 +0000
1825+++ ubuntu-download-manager-tests/system/test_filename_mutex.h 2014-02-22 10:42:10 +0000
1826@@ -0,0 +1,45 @@
1827+/*
1828+ * Copyright 2014 Canonical Ltd.
1829+ *
1830+ * This library is free software; you can redistribute it and/or
1831+ * modify it under the terms of version 3 of the GNU Lesser General Public
1832+ * License as published by the Free Software Foundation.
1833+ *
1834+ * This program is distributed in the hope that it will be useful,
1835+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1836+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1837+ * General Public License for more details.
1838+ *
1839+ * You should have received a copy of the GNU Lesser General Public
1840+ * License along with this library; if not, write to the
1841+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1842+ * Boston, MA 02110-1301, USA.
1843+ */
1844+
1845+#ifndef TEST_FILENAME_MUTEX_H
1846+#define TEST_FILENAME_MUTEX_H
1847+
1848+#include <QObject>
1849+#include <ubuntu/download_manager/tests/base_testcase.h>
1850+#include <ubuntu/download_manager/tests/test_runner.h>
1851+
1852+class TestFileNameMutex : public BaseTestCase {
1853+ Q_OBJECT
1854+
1855+ public:
1856+ explicit TestFileNameMutex(QObject *parent = 0);
1857+
1858+ private slots: // NOLINT(whitespace/indent)
1859+
1860+ void testExpectedNameValid_data();
1861+ void testExpectedNameValid();
1862+ void testExpectedNameLocked_data();
1863+ void testExpectedNameLocked();
1864+ void testExpectedNameInFileSystem_data();
1865+ void testExpectedNameInFileSystem();
1866+ void testUnlockPresent();
1867+};
1868+
1869+DECLARE_TEST(TestFileNameMutex)
1870+
1871+#endif // TEST_FILENAME_MUTEX_H
1872
1873=== modified file 'ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro'
1874--- ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro 2014-02-03 17:50:07 +0000
1875+++ ubuntu-download-manager-tests/ubuntu-download-manager-tests.pro 2014-02-22 10:42:10 +0000
1876@@ -28,7 +28,8 @@
1877 downloads/state_machines/test_file_download_sm.cpp \
1878 system/test_apn_request_factory.cpp \
1879 downloads/test_mms_download.cpp \
1880- downloads/test_base_download.cpp
1881+ downloads/test_base_download.cpp \
1882+ system/test_filename_mutex.cpp
1883
1884 HEADERS += \
1885 downloads/test_download.h \
1886@@ -48,7 +49,8 @@
1887 downloads/state_machines/test_file_download_sm.h \
1888 system/test_apn_request_factory.h \
1889 downloads/test_mms_download.h \
1890- downloads/test_base_download.h
1891+ downloads/test_base_download.h \
1892+ system/test_filename_mutex.h
1893
1894
1895 exists ($$OUT_PWD/data){

Subscribers

People subscribed via source and target branches