Merge lp:~renatofilho/qtorganizer5-eds/fix-1440878 into lp:qtorganizer5-eds
- fix-1440878
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Charles Kerr | ||||
Approved revision: | 85 | ||||
Merged at revision: | 81 | ||||
Proposed branch: | lp:~renatofilho/qtorganizer5-eds/fix-1440878 | ||||
Merge into: | lp:qtorganizer5-eds | ||||
Prerequisite: | lp:~renatofilho/qtorganizer5-eds/fix-1426519 | ||||
Diff against target: |
301 lines (+164/-41) 5 files modified
organizer/qorganizer-eds-engine.cpp (+13/-9) tests/unittest/eds-base-test.cpp (+61/-0) tests/unittest/eds-base-test.h (+3/-0) tests/unittest/event-test.cpp (+45/-6) tests/unittest/run-eds-test.sh (+42/-26) |
||||
To merge this branch: | bzr merge lp:~renatofilho/qtorganizer5-eds/fix-1440878 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Charles Kerr (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+255725@code.launchpad.net |
This proposal supersedes a proposal from 2015-04-09.
Commit message
Save a trigger for reminders with with secondsBeforeStart equals 0.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
Charles Kerr (charlesk) wrote : Posted in a previous version of this proposal | # |
Some inline comments below.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:83
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Charles Kerr (charlesk) wrote : Posted in a previous version of this proposal | # |
The code changes LGTM.
Approving in comments, feel free to top-approve for me once you've got the Jenkins issue sorted
- 85. By Renato Araujo Oliveira Filho
-
Removed test workaround.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:85
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Charles Kerr (charlesk) : | # |
Preview Diff
1 | === modified file 'organizer/qorganizer-eds-engine.cpp' | |||
2 | --- organizer/qorganizer-eds-engine.cpp 2015-04-09 17:24:00 +0000 | |||
3 | +++ organizer/qorganizer-eds-engine.cpp 2015-04-09 17:24:00 +0000 | |||
4 | @@ -1798,11 +1798,17 @@ | |||
5 | 1798 | 1798 | ||
6 | 1799 | ECalComponentAlarmTrigger trigger; | 1799 | ECalComponentAlarmTrigger trigger; |
7 | 1800 | e_cal_component_alarm_get_trigger(alarm, &trigger); | 1800 | e_cal_component_alarm_get_trigger(alarm, &trigger); |
8 | 1801 | int relSecs = 0; | ||
9 | 1801 | if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) { | 1802 | if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) { |
13 | 1802 | aDetail->setSecondsBeforeStart(icaldurationtype_as_int(trigger.u.rel_duration) * -1); | 1803 | relSecs = - icaldurationtype_as_int(trigger.u.rel_duration); |
14 | 1803 | } else { | 1804 | if (relSecs < 0) { |
15 | 1804 | aDetail->setSecondsBeforeStart(0); | 1805 | relSecs = 0; |
16 | 1806 | qWarning() << "QOrganizer does not support triggers after event start"; | ||
17 | 1807 | } | ||
18 | 1808 | } else if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_NONE) { | ||
19 | 1809 | qWarning() << "QOrganizer only supports triggers relative to event start."; | ||
20 | 1805 | } | 1810 | } |
21 | 1811 | aDetail->setSecondsBeforeStart(relSecs); | ||
22 | 1806 | 1812 | ||
23 | 1807 | ECalComponentAlarmRepeat aRepeat; | 1813 | ECalComponentAlarmRepeat aRepeat; |
24 | 1808 | e_cal_component_alarm_get_repeat(alarm, &aRepeat); | 1814 | e_cal_component_alarm_get_repeat(alarm, &aRepeat); |
25 | @@ -2414,12 +2420,10 @@ | |||
26 | 2414 | break; | 2420 | break; |
27 | 2415 | } | 2421 | } |
28 | 2416 | 2422 | ||
35 | 2417 | if (reminder->secondsBeforeStart() > 0) { | 2423 | ECalComponentAlarmTrigger trigger; |
36 | 2418 | ECalComponentAlarmTrigger trigger; | 2424 | trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START; |
37 | 2419 | trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START; | 2425 | trigger.u.rel_duration = icaldurationtype_from_int(- reminder->secondsBeforeStart()); |
38 | 2420 | trigger.u.rel_duration = icaldurationtype_from_int(- reminder->secondsBeforeStart()); | 2426 | e_cal_component_alarm_set_trigger(alarm, trigger); |
33 | 2421 | e_cal_component_alarm_set_trigger(alarm, trigger); | ||
34 | 2422 | } | ||
39 | 2423 | 2427 | ||
40 | 2424 | ECalComponentAlarmRepeat aRepeat; | 2428 | ECalComponentAlarmRepeat aRepeat; |
41 | 2425 | // TODO: check if this is really necessary | 2429 | // TODO: check if this is really necessary |
42 | 2426 | 2430 | ||
43 | === modified file 'tests/unittest/eds-base-test.cpp' | |||
44 | --- tests/unittest/eds-base-test.cpp 2015-03-24 17:56:44 +0000 | |||
45 | +++ tests/unittest/eds-base-test.cpp 2015-04-09 17:24:00 +0000 | |||
46 | @@ -27,6 +27,26 @@ | |||
47 | 27 | 27 | ||
48 | 28 | using namespace QtOrganizer; | 28 | using namespace QtOrganizer; |
49 | 29 | 29 | ||
50 | 30 | class GScopedPointerUnref | ||
51 | 31 | { | ||
52 | 32 | public: | ||
53 | 33 | static inline void cleanup(void *pointer) | ||
54 | 34 | { | ||
55 | 35 | if (pointer) { | ||
56 | 36 | g_clear_object(&pointer); | ||
57 | 37 | } | ||
58 | 38 | } | ||
59 | 39 | }; | ||
60 | 40 | |||
61 | 41 | template<class KLASS> | ||
62 | 42 | class GScopedPointer : public QScopedPointer<KLASS, GScopedPointerUnref> | ||
63 | 43 | { | ||
64 | 44 | public: | ||
65 | 45 | GScopedPointer(KLASS* obj = 0) | ||
66 | 46 | : QScopedPointer<KLASS, GScopedPointerUnref>(obj) | ||
67 | 47 | {} | ||
68 | 48 | }; | ||
69 | 49 | |||
70 | 30 | EDSBaseTest::EDSBaseTest() | 50 | EDSBaseTest::EDSBaseTest() |
71 | 31 | { | 51 | { |
72 | 32 | qRegisterMetaType<QList<QOrganizerCollectionId> >(); | 52 | qRegisterMetaType<QList<QOrganizerCollectionId> >(); |
73 | @@ -52,6 +72,47 @@ | |||
74 | 52 | { | 72 | { |
75 | 53 | } | 73 | } |
76 | 54 | 74 | ||
77 | 75 | QString EDSBaseTest::getEventFromEvolution(const QOrganizerItemId &id, | ||
78 | 76 | const QOrganizerCollectionId &collectionId) | ||
79 | 77 | { | ||
80 | 78 | QString uid = id.toString().split("/").last(); | ||
81 | 79 | GError *error = 0; | ||
82 | 80 | GScopedPointer<ESourceRegistry> sourceRegistry(e_source_registry_new_sync(0, &error)); | ||
83 | 81 | if (error) { | ||
84 | 82 | qWarning() << "Fail to create source registry" << error->message; | ||
85 | 83 | g_error_free(error); | ||
86 | 84 | return QString(); | ||
87 | 85 | } | ||
88 | 86 | GScopedPointer<ESource> calendar; | ||
89 | 87 | if (collectionId.isNull()) { | ||
90 | 88 | calendar.reset(e_source_registry_ref_default_calendar(sourceRegistry.data())); | ||
91 | 89 | } else { | ||
92 | 90 | calendar.reset(e_source_registry_ref_source(sourceRegistry.data(), | ||
93 | 91 | collectionId.toString().toUtf8().data())); | ||
94 | 92 | } | ||
95 | 93 | GScopedPointer<EClient> client(e_cal_client_connect_sync(calendar.data(), | ||
96 | 94 | E_CAL_CLIENT_SOURCE_TYPE_EVENTS, | ||
97 | 95 | 0, | ||
98 | 96 | &error)); | ||
99 | 97 | if (error) { | ||
100 | 98 | qWarning() << "Fail to connect to calendar" << error->message; | ||
101 | 99 | g_error_free(error); | ||
102 | 100 | return QString(); | ||
103 | 101 | } | ||
104 | 102 | |||
105 | 103 | icalcomponent *obj = 0; | ||
106 | 104 | e_cal_client_get_object_sync(reinterpret_cast<ECalClient*>(client.data()), | ||
107 | 105 | uid.toUtf8().data(), 0, &obj, 0, &error); | ||
108 | 106 | if (error) { | ||
109 | 107 | qWarning() << "Fail to retrieve object:" << error->message; | ||
110 | 108 | g_error_free(error); | ||
111 | 109 | } | ||
112 | 110 | |||
113 | 111 | QString result = QString::fromUtf8(icalcomponent_as_ical_string(obj)); | ||
114 | 112 | icalcomponent_free (obj); | ||
115 | 113 | return result; | ||
116 | 114 | } | ||
117 | 115 | |||
118 | 55 | QString EDSBaseTest::uniqueCollectionName() const | 116 | QString EDSBaseTest::uniqueCollectionName() const |
119 | 56 | { | 117 | { |
120 | 57 | return QUuid::createUuid().toString(); | 118 | return QUuid::createUuid().toString(); |
121 | 58 | 119 | ||
122 | === modified file 'tests/unittest/eds-base-test.h' | |||
123 | --- tests/unittest/eds-base-test.h 2014-10-06 14:46:49 +0000 | |||
124 | +++ tests/unittest/eds-base-test.h 2015-04-09 17:24:00 +0000 | |||
125 | @@ -36,6 +36,9 @@ | |||
126 | 36 | virtual void init(); | 36 | virtual void init(); |
127 | 37 | virtual void cleanup(); | 37 | virtual void cleanup(); |
128 | 38 | 38 | ||
129 | 39 | |||
130 | 40 | QString getEventFromEvolution(const QtOrganizer::QOrganizerItemId &id, | ||
131 | 41 | const QtOrganizer::QOrganizerCollectionId &collectionId = QtOrganizer::QOrganizerCollectionId()); | ||
132 | 39 | QString uniqueCollectionName() const; | 42 | QString uniqueCollectionName() const; |
133 | 40 | }; | 43 | }; |
134 | 41 | 44 | ||
135 | 42 | 45 | ||
136 | === modified file 'tests/unittest/event-test.cpp' | |||
137 | --- tests/unittest/event-test.cpp 2015-04-09 17:24:00 +0000 | |||
138 | +++ tests/unittest/event-test.cpp 2015-04-09 17:24:00 +0000 | |||
139 | @@ -47,7 +47,6 @@ | |||
140 | 47 | void initTestCase() | 47 | void initTestCase() |
141 | 48 | { | 48 | { |
142 | 49 | EDSBaseTest::init(); | 49 | EDSBaseTest::init(); |
143 | 50 | qDebug() << "INIT TEST CASE"; | ||
144 | 51 | 50 | ||
145 | 52 | m_engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>()); | 51 | m_engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>()); |
146 | 53 | 52 | ||
147 | @@ -61,8 +60,6 @@ | |||
148 | 61 | QVERIFY(saveResult); | 60 | QVERIFY(saveResult); |
149 | 62 | QCOMPARE(error, QtOrganizer::QOrganizerManager::NoError); | 61 | QCOMPARE(error, QtOrganizer::QOrganizerManager::NoError); |
150 | 63 | QTRY_COMPARE(createdCollection.count(), 1); | 62 | QTRY_COMPARE(createdCollection.count(), 1); |
151 | 64 | |||
152 | 65 | qDebug() << "END TEST CASE"; | ||
153 | 66 | } | 63 | } |
154 | 67 | 64 | ||
155 | 68 | void cleanupTestCase() | 65 | void cleanupTestCase() |
156 | @@ -377,7 +374,6 @@ | |||
157 | 377 | 374 | ||
158 | 378 | QList<QOrganizerItemId> ids; | 375 | QList<QOrganizerItemId> ids; |
159 | 379 | ids << items[0].id(); | 376 | ids << items[0].id(); |
160 | 380 | qDebug() << "Check for item id:" << ids; | ||
161 | 381 | items = m_engine->items(ids, hint, 0, 0); | 377 | items = m_engine->items(ids, hint, 0, 0); |
162 | 382 | QCOMPARE(items.count(), 1); | 378 | QCOMPARE(items.count(), 1); |
163 | 383 | QOrganizerCollection collection = m_engine->defaultCollection(0); | 379 | QOrganizerCollection collection = m_engine->defaultCollection(0); |
164 | @@ -819,10 +815,53 @@ | |||
165 | 819 | QCOMPARE(newAttendee.participationStatus(), attendee.participationStatus()); | 815 | QCOMPARE(newAttendee.participationStatus(), attendee.participationStatus()); |
166 | 820 | } | 816 | } |
167 | 821 | 817 | ||
168 | 818 | // BUG: #1440878 | ||
169 | 819 | void testReminderOnTime() | ||
170 | 820 | { | ||
171 | 821 | static QString displayLabelValue = QStringLiteral("event reminder"); | ||
172 | 822 | static QString descriptionValue = QStringLiteral("event with reminder"); | ||
173 | 823 | |||
174 | 824 | QOrganizerEvent event; | ||
175 | 825 | QOrganizerItemAudibleReminder aReminder; | ||
176 | 826 | event.setStartDateTime(QDateTime::currentDateTime()); | ||
177 | 827 | event.setDisplayLabel(displayLabelValue); | ||
178 | 828 | event.setDescription(descriptionValue); | ||
179 | 829 | aReminder.setSecondsBeforeStart(0); | ||
180 | 830 | aReminder.setDataUrl(QString()); | ||
181 | 831 | event.saveDetail(&aReminder); | ||
182 | 832 | |||
183 | 833 | QOrganizerEvent event2; | ||
184 | 834 | aReminder = QOrganizerItemAudibleReminder(); | ||
185 | 835 | event2.setStartDateTime(QDateTime::currentDateTime().addDays(2)); | ||
186 | 836 | event2.setDisplayLabel(displayLabelValue + "_2"); | ||
187 | 837 | event2.setDescription(descriptionValue); | ||
188 | 838 | aReminder.setSecondsBeforeStart(60); | ||
189 | 839 | aReminder.setDataUrl(QString()); | ||
190 | 840 | event2.saveDetail(&aReminder); | ||
191 | 841 | |||
192 | 842 | QtOrganizer::QOrganizerManager::Error error; | ||
193 | 843 | QMap<int, QtOrganizer::QOrganizerManager::Error> errorMap; | ||
194 | 844 | QList<QOrganizerItem> items; | ||
195 | 845 | QSignalSpy createdItem(m_engine, SIGNAL(itemsAdded(QList<QOrganizerItemId>))); | ||
196 | 846 | items << event << event2; | ||
197 | 847 | bool saveResult = m_engine->saveItems(&items, | ||
198 | 848 | QList<QtOrganizer::QOrganizerItemDetail::DetailType>(), | ||
199 | 849 | &errorMap, | ||
200 | 850 | &error); | ||
201 | 851 | QTRY_COMPARE(createdItem.count(), 1); | ||
202 | 852 | QVERIFY(saveResult); | ||
203 | 853 | |||
204 | 854 | QString vcard = getEventFromEvolution(items[0].id()); | ||
205 | 855 | QVERIFY(vcard.contains("TRIGGER;VALUE=DURATION;RELATED=START:PT0S")); | ||
206 | 856 | |||
207 | 857 | vcard = getEventFromEvolution(items[1].id()); | ||
208 | 858 | QVERIFY(vcard.contains("TRIGGER;VALUE=DURATION;RELATED=START:-PT1M")); | ||
209 | 859 | } | ||
210 | 860 | |||
211 | 822 | void testExtendedProperties() | 861 | void testExtendedProperties() |
212 | 823 | { | 862 | { |
215 | 824 | static QString displayLabelValue = QStringLiteral("event with collection attendee"); | 863 | static QString displayLabelValue = QStringLiteral("event with extended property"); |
216 | 825 | static QString descriptionValue = QStringLiteral("event without collection"); | 864 | static QString descriptionValue = QStringLiteral("event with extended property"); |
217 | 826 | QOrganizerItemId itemId; | 865 | QOrganizerItemId itemId; |
218 | 827 | QDateTime currentTime = QDateTime::currentDateTime(); | 866 | QDateTime currentTime = QDateTime::currentDateTime(); |
219 | 828 | 867 | ||
220 | 829 | 868 | ||
221 | === modified file 'tests/unittest/run-eds-test.sh' | |||
222 | --- tests/unittest/run-eds-test.sh 2015-04-09 17:24:00 +0000 | |||
223 | +++ tests/unittest/run-eds-test.sh 2015-04-09 17:24:00 +0000 | |||
224 | @@ -1,35 +1,51 @@ | |||
225 | 1 | #!/bin/sh | 1 | #!/bin/sh |
226 | 2 | 2 | ||
236 | 3 | #ARG1 - DBUS RUNNERN PATH | 3 | echo ARG0=$0 # this script |
237 | 4 | #ARG2 - TEST EXECUTABLE FULL PATH | 4 | echo ARG1=$1 # full executable path of dbus-test-runner |
238 | 5 | #ARG3 - TEST NAME | 5 | echo ARG2=$2 # full executable path of test app |
239 | 6 | #ARG4 - EVOLUTION_CALENDAR_FACTORY FULL PATH | 6 | echo ARG3=$3 # test name |
240 | 7 | #ARG5 - EVOLUTION_CALENDAR_FACTORY SERVICE NAME | 7 | echo ARG4=$4 # full executable path of evolution-calendar-factory |
241 | 8 | #ARG6 - EVOLUTION_SOURCE_REGISTRY FULL PATH | 8 | echo ARG5=$5 # bus service name of calendar factory |
242 | 9 | 9 | echo ARG6=$6 # full exectuable path of evolution-source-registry | |
243 | 10 | 10 | echo ARG7=$7 # full executable path of gvfs | |
244 | 11 | export TEST_TMP_DIR=$(mktemp -d /tmp/$3_XXXX) | 11 | echo ARG8=$8 # config files |
245 | 12 | |||
246 | 13 | # set up the tmpdir and tell the shell to purge it when we exit | ||
247 | 14 | export TEST_TMP_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d $3-XXXXXXXXXX) || exit 1 | ||
248 | 15 | echo "running test '$3' in ${TEST_TMP_DIR}" | ||
249 | 16 | |||
250 | 17 | # set up the environment variables | ||
251 | 12 | export QT_QPA_PLATFORM=minimal | 18 | export QT_QPA_PLATFORM=minimal |
265 | 13 | export HOME=$TEST_TMP_DIR | 19 | export HOME=${TEST_TMP_DIR} |
266 | 14 | export XDG_RUNTIME_DIR=$TEST_TMP_DIR | 20 | export XDG_RUNTIME_DIR=${TEST_TMP_DIR} |
267 | 15 | export XDG_CACHE_HOME=$TEST_TMP_DIR/.cache | 21 | export XDG_CACHE_HOME=${TEST_TMP_DIR}/.cache |
268 | 16 | export XDG_CONFIG_HOME=$TEST_TMP_DIR/.config | 22 | export XDG_CONFIG_HOME=${TEST_TMP_DIR}/.config |
269 | 17 | export XDG_DATA_HOME=$TEST_TMP_DIR/.local/share | 23 | export XDG_DATA_HOME=${TEST_TMP_DIR}/.local/share |
270 | 18 | export XDG_DESKTOP_DIR=$TEST_TMP_DIR | 24 | export XDG_DESKTOP_DIR=${TEST_TMP_DIR} |
271 | 19 | export XDG_DOCUMENTS_DIR=$TEST_TMP_DIR | 25 | export XDG_DOCUMENTS_DIR=${TEST_TMP_DIR} |
272 | 20 | export XDG_DOWNLOAD_DIR=$TEST_TMP_DIR | 26 | export XDG_DOWNLOAD_DIR=${TEST_TMP_DIR} |
273 | 21 | export XDG_MUSIC_DIR=$TEST_TMP_DIR | 27 | export XDG_MUSIC_DIR=${TEST_TMP_DIR} |
274 | 22 | export XDG_PICTURES_DIR=$TEST_TMP_DIR | 28 | export XDG_PICTURES_DIR=${TEST_TMP_DIR} |
275 | 23 | export XDG_PUBLICSHARE_DIR=$TEST_TMP_DIR | 29 | export XDG_PUBLICSHARE_DIR=${TEST_TMP_DIR} |
276 | 24 | export XDG_TEMPLATES_DIR=$TEST_TMP_DIR | 30 | export XDG_TEMPLATES_DIR=${TEST_TMP_DIR} |
277 | 25 | export XDG_VIDEOS_DIR=$TEST_TMP_DIR | 31 | export XDG_VIDEOS_DIR=${TEST_TMP_DIR} |
278 | 26 | export QORGANIZER_EDS_DEBUG=On | 32 | export QORGANIZER_EDS_DEBUG=On |
282 | 27 | 33 | export GIO_USE_VFS=local # needed to ensure GVFS shuts down cleanly after the test is over | |
283 | 28 | echo HOMEDIR=$HOME | 34 | |
284 | 29 | rm -rf $XDG_DATA_HOME | 35 | echo HOMEDIR=${HOME} |
285 | 36 | rm -rf ${XDG_DATA_HOME} | ||
286 | 37 | |||
287 | 38 | # run dbus-test-runner | ||
288 | 30 | $1 --keep-env --max-wait=90 \ | 39 | $1 --keep-env --max-wait=90 \ |
289 | 31 | --task $2 --task-name $3 --wait-until-complete --wait-for=org.gnome.evolution.dataserver.Calendar4 \ | 40 | --task $2 --task-name $3 --wait-until-complete --wait-for=org.gnome.evolution.dataserver.Calendar4 \ |
290 | 32 | --task $4 --task-name "evolution" --wait-until-complete -r | 41 | --task $4 --task-name "evolution" --wait-until-complete -r |
291 | 33 | #--task $6 --task-name "source-registry" --wait-for=org.gtk.vfs.Daemon -r \ | 42 | #--task $6 --task-name "source-registry" --wait-for=org.gtk.vfs.Daemon -r \ |
292 | 34 | #--task $7 --task-name "gvfsd" -r | 43 | #--task $7 --task-name "gvfsd" -r |
294 | 35 | return $? | 44 | rv=$? |
295 | 45 | |||
296 | 46 | # if the test passed, blow away the tmpdir | ||
297 | 47 | if [ $rv -eq 0 ]; then | ||
298 | 48 | rm -rf $TEST_TMP_DIR | ||
299 | 49 | fi | ||
300 | 50 | |||
301 | 51 | return $rv |
FAILED: Continuous integration, rev:80 jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-ci/ 202/ jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- amd64-ci/ 9/console jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- armhf-ci/ 9/console jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- i386-ci/ 9/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtorganizer 5-eds-ci/ 202/rebuild
http://