Merge lp:~xavi-garcia-mena/mediascanner2/ms-dbus-wal into lp:mediascanner2
- ms-dbus-wal
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~xavi-garcia-mena/mediascanner2/ms-dbus-wal |
Merge into: | lp:mediascanner2 |
Diff against target: |
2214 lines (+945/-453) 18 files modified
debian/control (+1/-0) src/daemon/CMakeLists.txt (+1/-0) src/mediascanner/CMakeLists.txt (+20/-2) src/mediascanner/MediaStore.cc (+94/-19) src/mediascanner/MediaStore.hh (+9/-1) src/mediascanner/d-bus/service-stub.cc (+6/-0) src/mediascanner/d-bus/service-stub.hh (+1/-0) src/mediascanner/mediascanner-2.0.map (+35/-5) src/ms-dbus/CMakeLists.txt (+1/-2) src/ms-dbus/main.cc (+2/-2) src/ms-dbus/service-skeleton.cc (+2/-2) src/ms-dbus/service-skeleton.hh (+1/-1) src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc (+1/-1) test/CMakeLists.txt (+15/-5) test/test_dbus.cc (+1/-1) test/test_mediastore.cc (+658/-412) test/utils/DBusTest.cpp (+50/-0) test/utils/DBusTest.h (+47/-0) |
To merge this branch: | bzr merge lp:~xavi-garcia-mena/mediascanner2/ms-dbus-wal |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
unity-api-1-bot | continuous-integration | Needs Fixing | |
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Jussi Pakkanen (community) | Needs Fixing | ||
Jamie Strandboge | Pending | ||
James Henstridge | Pending | ||
Review via email: mp+249346@code.launchpad.net |
Commit message
Modified to use the d-bus interface when MediaStore is created in Read Only mode.
Description of the change
Modified to use the d-bus interface when MediaStore is created in Read Only mode.
- 300. By Xavi Garcia
-
Modifed media store tests to avoid duplicating code
- 301. By Xavi Garcia
-
Removed Unity-api dependency, as it was not needed
- 302. By Xavi Garcia
-
Added libqtdbustest to test the d-bus connection
Jussi Pakkanen (jpakkane) wrote : | # |
Looks fine. Just a few niggles:
- the new variables have an underscore after their names, whereas the naming convention elsewere is not to have underscores
- when printing the text about error messages, please also print the URL of the bug in question
- in brokenfiles you wrap everything in a try/catch that just prints a generic error, why is this, AFAICR gtest will automatically fail any test that throws and prints the exception's error messag
I think we need to start talking to Jamie about the dbus/apparmor bits that this thing needs (also in music-app).
- 303. By Xavi Garcia
-
Erased final _ for member variables
Xavi Garcia (xavi-garcia-mena) wrote : | # |
Hey Jussi,
what file do you mean when you say?
*when printing the text about error messages, please also print the URL of
the bug in question*
What do you mean to print the URL of the bug? When an exception is thrown?
I've erased the try... catch, as it was part of a test I did and changed
(but obviously forgot to erase the try..catch)
Thanks,
Xavi
On Mon, Feb 16, 2015 at 2:40 PM, Jussi Pakkanen <
<email address hidden>> wrote:
> Review: Needs Fixing
>
> Looks fine. Just a few niggles:
>
> - the new variables have an underscore after their names, whereas the
> naming convention elsewere is not to have underscores
> - when printing the text about error messages, please also print the URL
> of the bug in question
> - in brokenfiles you wrap everything in a try/catch that just prints a
> generic error, why is this, AFAICR gtest will automatically fail any test
> that throws and prints the exception's error messag
>
> I think we need to start talking to Jamie about the dbus/apparmor bits
> that this thing needs (also in music-app).
> --
>
> https:/
> You are the owner of lp:~xavi-garcia-mena/mediascanner2/ms-dbus-wal.
>
- 304. By Xavi Garcia
-
Added bug link in error message and remove unnecessary try...catch in unit test
Jussi Pakkanen (jpakkane) wrote : | # |
Now we need to do the AppArmor bits and for that we need Jamie's help, so I subscribed him.
What we are trying to do here is the following:
Currently users of Mediascanner (media scopes and music-app) have read-only access to Mediascanner's media storage dir ~/.cache/
This means that we need the following Apparmor changes:
- remove read access from existing users
- grant them access to the dbus server instead
- create new daemon that is allowed to own the service name and has r/w access to the media directory
Does this seem like a suitable approach, security-wise?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:304
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:304
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
unity-api-1-bot (unity-api-1-bot) wrote : | # |
FAILED: Continuous integration, rev:304
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 304. By Xavi Garcia
-
Added bug link in error message and remove unnecessary try...catch in unit test
- 303. By Xavi Garcia
-
Erased final _ for member variables
- 302. By Xavi Garcia
-
Added libqtdbustest to test the d-bus connection
- 301. By Xavi Garcia
-
Removed Unity-api dependency, as it was not needed
- 300. By Xavi Garcia
-
Modifed media store tests to avoid duplicating code
- 299. By Xavi Garcia
-
Using DBus for read only mode
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2014-10-09 08:48:05 +0000 |
3 | +++ debian/control 2015-02-16 14:24:40 +0000 |
4 | @@ -18,6 +18,7 @@ |
5 | libgdk-pixbuf2.0-dev, |
6 | libgtest-dev, |
7 | libproperties-cpp-dev, |
8 | + libqtdbustest1-dev, |
9 | libsqlite3-dev (>= 3.8.5), |
10 | libudisks2-dev, |
11 | qt5-default, |
12 | |
13 | === modified file 'src/daemon/CMakeLists.txt' |
14 | --- src/daemon/CMakeLists.txt 2014-10-09 08:48:05 +0000 |
15 | +++ src/daemon/CMakeLists.txt 2015-02-16 14:24:40 +0000 |
16 | @@ -9,6 +9,7 @@ |
17 | SubtreeWatcher.cc |
18 | Scanner.cc |
19 | ../mediascanner/utils.cc |
20 | + $<TARGET_OBJECTS:mediascanner-dbus-static> |
21 | ) |
22 | |
23 | target_link_libraries(scannerstuff ${GST_LIBRARIES} ${EXIF_LDFLAGS} ${UDISKS_LDFLAGS} |
24 | |
25 | === modified file 'src/mediascanner/CMakeLists.txt' |
26 | --- src/mediascanner/CMakeLists.txt 2014-08-22 14:33:27 +0000 |
27 | +++ src/mediascanner/CMakeLists.txt 2015-02-16 14:24:40 +0000 |
28 | @@ -1,3 +1,18 @@ |
29 | +pkg_check_modules(DBUSCPP dbus-cpp REQUIRED) |
30 | + |
31 | +add_library( |
32 | + mediascanner-dbus-static OBJECT |
33 | + d-bus/dbus-codec.cc |
34 | + d-bus/service-stub.cc |
35 | +) |
36 | + |
37 | +set_target_properties( |
38 | + mediascanner-dbus-static |
39 | + PROPERTIES |
40 | + LINK_FLAGS "-Wl,--export-all-symbols" |
41 | + COMPILE_FLAGS -fPIC |
42 | +) |
43 | + |
44 | add_library(mediascanner SHARED |
45 | MediaFile.cc |
46 | MediaFileBuilder.cc |
47 | @@ -9,6 +24,7 @@ |
48 | utils.cc |
49 | mozilla/fts3_porter.c |
50 | mozilla/Normalize.c |
51 | + $<TARGET_OBJECTS:mediascanner-dbus-static> |
52 | ) |
53 | |
54 | set(symbol_map "${CMAKE_CURRENT_SOURCE_DIR}/mediascanner-2.0.map") |
55 | @@ -16,8 +32,10 @@ |
56 | LINK_FLAGS "${ldflags} -Wl,--version-script,${symbol_map}") |
57 | set_target_properties(mediascanner PROPERTIES LINK_DEPENDS ${symbol_map}) |
58 | |
59 | -add_definitions(${MEDIASCANNER_CFLAGS}) |
60 | -target_link_libraries(mediascanner ${MEDIASCANNER_LIBRARIES}) |
61 | +add_definitions(${DBUSCPP_CFLAGS} ${MEDIASCANNER_CFLAGS}) |
62 | + |
63 | +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/src) |
64 | +target_link_libraries(mediascanner ${MEDIASCANNER_LIBRARIES} ${DBUSCPP_LDFLAGS}) |
65 | |
66 | set_target_properties(mediascanner PROPERTIES |
67 | OUTPUT_NAME "mediascanner-2.0" |
68 | |
69 | === modified file 'src/mediascanner/MediaStore.cc' |
70 | --- src/mediascanner/MediaStore.cc 2015-01-28 09:41:26 +0000 |
71 | +++ src/mediascanner/MediaStore.cc 2015-02-16 14:24:40 +0000 |
72 | @@ -39,6 +39,7 @@ |
73 | #include "Filter.hh" |
74 | #include "internal/sqliteutils.hh" |
75 | #include "internal/utils.hh" |
76 | +#include "d-bus/service-stub.hh" |
77 | |
78 | using namespace std; |
79 | |
80 | @@ -54,6 +55,11 @@ |
81 | // http://sqlite.com/faq.html#q6 |
82 | std::mutex dbMutex; |
83 | |
84 | + OpenType access_mode; |
85 | + |
86 | + std::unique_ptr<mediascanner::dbus::ServiceStub> media_store_dbus; |
87 | + |
88 | + MediaStorePrivate(OpenType access); |
89 | void insert(const MediaFile &m) const; |
90 | void remove(const std::string &fname) const; |
91 | void insert_broken_file(const std::string &fname, const std::string &etag) const; |
92 | @@ -121,7 +127,7 @@ |
93 | ** (<hit count> / <global hit count>) * <column weight> |
94 | ** |
95 | ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So |
96 | - ** the hit count and global hit counts for each column are found in |
97 | + ** the hit count and global hit counts for each column are found in |
98 | ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively. |
99 | */ |
100 | const int32_t *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; |
101 | @@ -287,6 +293,13 @@ |
102 | execute_sql(db, deleteCmd); |
103 | } |
104 | |
105 | +void activateWalMode(sqlite3 *db) { |
106 | + string activateWalCmd(R"( |
107 | +PRAGMA journal_mode = WAL; |
108 | +)"); |
109 | + execute_sql(db, activateWalCmd); |
110 | +} |
111 | + |
112 | void createTables(sqlite3 *db) { |
113 | string schema(R"( |
114 | CREATE TABLE schemaVersion (version INTEGER); |
115 | @@ -338,7 +351,7 @@ |
116 | type INTEGER -- 0=Audio, 1=Video |
117 | ); |
118 | |
119 | -CREATE VIRTUAL TABLE media_fts |
120 | +CREATE VIRTUAL TABLE media_fts |
121 | USING fts4(content='media', title, artist, album, tokenize=mozporter); |
122 | |
123 | CREATE TRIGGER media_bu BEFORE UPDATE ON media BEGIN |
124 | @@ -394,43 +407,51 @@ |
125 | |
126 | MediaStore::MediaStore(const std::string &filename, OpenType access, const std::string &retireprefix) { |
127 | int sqliteFlags = access == MS_READ_WRITE ? SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE : SQLITE_OPEN_READONLY; |
128 | - p = new MediaStorePrivate(); |
129 | + p = new MediaStorePrivate(access); |
130 | + if(access != MS_READ_WRITE) { |
131 | + return; |
132 | + } |
133 | if(sqlite3_open_v2(filename.c_str(), &p->db, sqliteFlags, nullptr) != SQLITE_OK) { |
134 | throw runtime_error(sqlite3_errmsg(p->db)); |
135 | } |
136 | register_tokenizer(p->db); |
137 | register_functions(p->db); |
138 | int detectedSchemaVersion = getSchemaVersion(p->db); |
139 | - if(access == MS_READ_WRITE) { |
140 | - if(detectedSchemaVersion != schemaVersion) { |
141 | - deleteTables(p->db); |
142 | - createTables(p->db); |
143 | - } |
144 | - if(!retireprefix.empty()) |
145 | - archiveItems(retireprefix); |
146 | - } else { |
147 | - if(detectedSchemaVersion != schemaVersion) { |
148 | - std::string msg("Tried to open a db with schema version "); |
149 | - msg += std::to_string(detectedSchemaVersion); |
150 | - msg += ", while supported version is "; |
151 | - msg += std::to_string(schemaVersion) + "."; |
152 | - throw runtime_error(msg); |
153 | - } |
154 | + activateWalMode(p->db); |
155 | + if(detectedSchemaVersion != schemaVersion) { |
156 | + deleteTables(p->db); |
157 | + createTables(p->db); |
158 | } |
159 | + if(!retireprefix.empty()) |
160 | + archiveItems(retireprefix); |
161 | } |
162 | |
163 | MediaStore::~MediaStore() { |
164 | - sqlite3_close(p->db); |
165 | + if(p->db) { |
166 | + sqlite3_close(p->db); |
167 | + } |
168 | delete p; |
169 | } |
170 | |
171 | +MediaStorePrivate::MediaStorePrivate(OpenType access) : db(nullptr), access_mode(access), media_store_dbus(nullptr) { |
172 | + if(access_mode != MS_READ_WRITE) { |
173 | + media_store_dbus.reset(new dbus::ServiceStub()); |
174 | + } |
175 | +} |
176 | + |
177 | size_t MediaStorePrivate::size() const { |
178 | + if(access_mode != MS_READ_WRITE) { |
179 | + throw runtime_error("MediaStorePrivate::size() is not available in read only mode"); |
180 | + } |
181 | Statement count(db, "SELECT COUNT(*) FROM media"); |
182 | count.step(); |
183 | return count.getInt(0); |
184 | } |
185 | |
186 | void MediaStorePrivate::insert(const MediaFile &m) const { |
187 | + if(access_mode != MS_READ_WRITE) { |
188 | + throw runtime_error("MediaStorePrivate::insert() is not available in read only mode"); |
189 | + } |
190 | Statement query(db, "INSERT OR REPLACE INTO media (filename, content_type, etag, title, date, artist, album, album_artist, genre, disc_number, track_number, duration, width, height, latitude, longitude, has_thumbnail, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); |
191 | query.bind(1, m.getFileName()); |
192 | query.bind(2, m.getContentType()); |
193 | @@ -466,12 +487,18 @@ |
194 | } |
195 | |
196 | void MediaStorePrivate::remove(const string &fname) const { |
197 | + if(access_mode != MS_READ_WRITE) { |
198 | + throw runtime_error("MediaStorePrivate::remove() is not available in read only mode"); |
199 | + } |
200 | Statement del(db, "DELETE FROM media WHERE filename = ?"); |
201 | del.bind(1, fname); |
202 | del.step(); |
203 | } |
204 | |
205 | void MediaStorePrivate::insert_broken_file(const std::string &fname, const std::string &etag) const { |
206 | + if(access_mode != MS_READ_WRITE) { |
207 | + throw runtime_error("MediaStorePrivate::insert_broken_file() is not available in read only mode"); |
208 | + } |
209 | Statement del(db, "INSERT OR REPLACE INTO broken_files (filename, etag) VALUES (?, ?)"); |
210 | del.bind(1, fname); |
211 | del.bind(2, etag); |
212 | @@ -479,12 +506,18 @@ |
213 | } |
214 | |
215 | void MediaStorePrivate::remove_broken_file(const std::string &fname) const { |
216 | + if(access_mode != MS_READ_WRITE) { |
217 | + throw runtime_error("MediaStorePrivate::remove_broken_file() is not available in read only mode"); |
218 | + } |
219 | Statement del(db, "DELETE FROM broken_files WHERE filename = ?"); |
220 | del.bind(1, fname); |
221 | del.step(); |
222 | } |
223 | |
224 | bool MediaStorePrivate::is_broken_file(const std::string &fname, const std::string &etag) const { |
225 | + if(access_mode != MS_READ_WRITE) { |
226 | + throw runtime_error("MediaStorePrivate::is_broken_file() is not available in read only mode"); |
227 | + } |
228 | Statement query(db, "SELECT * FROM broken_files WHERE filename = ? AND etag = ?"); |
229 | query.bind(1, fname); |
230 | query.bind(2, etag); |
231 | @@ -521,6 +554,9 @@ |
232 | } |
233 | |
234 | MediaFile MediaStorePrivate::lookup(const std::string &filename) const { |
235 | + if(access_mode != MS_READ_WRITE) { |
236 | + return media_store_dbus->lookup(filename); |
237 | + } |
238 | Statement query(db, R"( |
239 | SELECT filename, content_type, etag, title, date, artist, album, album_artist, genre, disc_number, track_number, duration, width, height, latitude, longitude, has_thumbnail, type |
240 | FROM media |
241 | @@ -534,6 +570,9 @@ |
242 | } |
243 | |
244 | vector<MediaFile> MediaStorePrivate::query(const std::string &core_term, MediaType type, const Filter &filter) const { |
245 | + if(access_mode != MS_READ_WRITE) { |
246 | + return media_store_dbus->query(core_term, type, filter); |
247 | + } |
248 | string qs(R"( |
249 | SELECT filename, content_type, etag, title, date, artist, album, album_artist, genre, disc_number, track_number, duration, width, height, latitude, longitude, has_thumbnail, type |
250 | FROM media |
251 | @@ -603,6 +642,9 @@ |
252 | } |
253 | |
254 | vector<Album> MediaStorePrivate::queryAlbums(const std::string &core_term, const Filter &filter) const { |
255 | + if(access_mode != MS_READ_WRITE) { |
256 | + return media_store_dbus->queryAlbums(core_term, filter); |
257 | + } |
258 | string qs(R"( |
259 | SELECT album, album_artist, first(date) as date, first(genre) as genre, first(filename) as filename, first(has_thumbnail) as has_thumbnail FROM media |
260 | WHERE type = ? AND album <> '' |
261 | @@ -638,6 +680,9 @@ |
262 | } |
263 | |
264 | vector<string> MediaStorePrivate::queryArtists(const string &q, const Filter &filter) const { |
265 | + if(access_mode != MS_READ_WRITE) { |
266 | + return media_store_dbus->queryArtists(q, filter); |
267 | + } |
268 | string qs(R"( |
269 | SELECT artist FROM media |
270 | WHERE type = ? AND artist <> '' |
271 | @@ -677,6 +722,9 @@ |
272 | } |
273 | |
274 | vector<MediaFile> MediaStorePrivate::getAlbumSongs(const Album& album) const { |
275 | + if(access_mode != MS_READ_WRITE) { |
276 | + return media_store_dbus->getAlbumSongs(album); |
277 | + } |
278 | Statement query(db, R"( |
279 | SELECT filename, content_type, etag, title, date, artist, album, album_artist, genre, disc_number, track_number, duration, width, height, latitude, longitude, type FROM media |
280 | WHERE album = ? AND album_artist = ? AND type = ? |
281 | @@ -689,6 +737,9 @@ |
282 | } |
283 | |
284 | std::string MediaStorePrivate::getETag(const std::string &filename) const { |
285 | + if(access_mode != MS_READ_WRITE) { |
286 | + return media_store_dbus->getETag(filename); |
287 | + } |
288 | Statement query(db, R"( |
289 | SELECT etag FROM media WHERE filename = ? |
290 | )"); |
291 | @@ -701,6 +752,9 @@ |
292 | } |
293 | |
294 | std::vector<MediaFile> MediaStorePrivate::listSongs(const Filter &filter) const { |
295 | + if(access_mode != MS_READ_WRITE) { |
296 | + return media_store_dbus->listSongs(filter); |
297 | + } |
298 | std::string qs(R"( |
299 | SELECT filename, content_type, etag, title, date, artist, album, album_artist, genre, disc_number, track_number, duration, width, height, latitude, longitude, has_thumbnail, type |
300 | FROM media |
301 | @@ -744,6 +798,9 @@ |
302 | } |
303 | |
304 | std::vector<Album> MediaStorePrivate::listAlbums(const Filter &filter) const { |
305 | + if(access_mode != MS_READ_WRITE) { |
306 | + return media_store_dbus->listAlbums(filter); |
307 | + } |
308 | std::string qs(R"( |
309 | SELECT album, album_artist, first(date) as date, first(genre) as genre, first(filename) as filename, first(has_thumbnail) as has_thumbnail FROM media |
310 | WHERE type = ? |
311 | @@ -781,6 +838,9 @@ |
312 | } |
313 | |
314 | vector<std::string> MediaStorePrivate::listArtists(const Filter &filter) const { |
315 | + if(access_mode != MS_READ_WRITE) { |
316 | + return media_store_dbus->listArtists(filter); |
317 | + } |
318 | string qs(R"( |
319 | SELECT artist FROM media |
320 | WHERE type = ? |
321 | @@ -810,6 +870,9 @@ |
322 | } |
323 | |
324 | vector<std::string> MediaStorePrivate::listAlbumArtists(const Filter &filter) const { |
325 | + if(access_mode != MS_READ_WRITE) { |
326 | + return media_store_dbus->listAlbumArtists(filter); |
327 | + } |
328 | string qs(R"( |
329 | SELECT album_artist FROM media |
330 | WHERE type = ? |
331 | @@ -839,6 +902,9 @@ |
332 | } |
333 | |
334 | vector<std::string> MediaStorePrivate::listGenres(const Filter &filter) const { |
335 | + if(access_mode != MS_READ_WRITE) { |
336 | + return media_store_dbus->listGenres(filter); |
337 | + } |
338 | Statement query(db, R"( |
339 | SELECT genre FROM media |
340 | WHERE type = ? |
341 | @@ -858,6 +924,9 @@ |
342 | } |
343 | |
344 | void MediaStorePrivate::pruneDeleted() { |
345 | + if(access_mode != MS_READ_WRITE) { |
346 | + throw runtime_error("MediaStorePrivate::pruneDeleted() is not available in read only mode"); |
347 | + } |
348 | std::map<std::string, bool> path_cache; |
349 | vector<string> deleted; |
350 | Statement query(db, "SELECT filename FROM media"); |
351 | @@ -877,6 +946,9 @@ |
352 | } |
353 | |
354 | void MediaStorePrivate::archiveItems(const std::string &prefix) { |
355 | + if(access_mode != MS_READ_WRITE) { |
356 | + throw runtime_error("MediaStorePrivate::archiveItems() is not available in read only mode"); |
357 | + } |
358 | const char *templ = R"(BEGIN TRANSACTION; |
359 | INSERT INTO media_attic SELECT * FROM media WHERE filename LIKE %s; |
360 | DELETE FROM media WHERE filename LIKE %s; |
361 | @@ -894,6 +966,9 @@ |
362 | } |
363 | |
364 | void MediaStorePrivate::restoreItems(const std::string &prefix) { |
365 | + if(access_mode != MS_READ_WRITE) { |
366 | + throw runtime_error("MediaStorePrivate::restoreItems() is not available in read only mode"); |
367 | + } |
368 | const char *templ = R"(BEGIN TRANSACTION; |
369 | INSERT INTO media SELECT * FROM media_attic WHERE filename LIKE %s; |
370 | DELETE FROM media_attic WHERE filename LIKE %s; |
371 | |
372 | === modified file 'src/mediascanner/MediaStore.hh' |
373 | --- src/mediascanner/MediaStore.hh 2014-08-25 12:51:22 +0000 |
374 | +++ src/mediascanner/MediaStore.hh 2015-02-16 14:24:40 +0000 |
375 | @@ -23,6 +23,13 @@ |
376 | #include "MediaStoreBase.hh" |
377 | #include<vector> |
378 | #include<string> |
379 | +#include<memory> |
380 | + |
381 | +namespace core { |
382 | +namespace dbus { |
383 | +class Bus; |
384 | +} |
385 | +} |
386 | |
387 | namespace mediascanner { |
388 | |
389 | @@ -34,7 +41,8 @@ |
390 | class MediaStore final : public virtual MediaStoreBase { |
391 | private: |
392 | MediaStorePrivate *p; |
393 | - |
394 | +// MediaStore(std::shared_ptr<core::dbus::Bus> testing_dbus){}; |
395 | +// friend class MediaStoreTest; |
396 | public: |
397 | MediaStore(OpenType access, const std::string &retireprefix=""); |
398 | MediaStore(const std::string &filename, OpenType access, const std::string &retireprefix=""); |
399 | |
400 | === added directory 'src/mediascanner/d-bus' |
401 | === renamed file 'src/ms-dbus/dbus-codec.cc' => 'src/mediascanner/d-bus/dbus-codec.cc' |
402 | === renamed file 'src/ms-dbus/dbus-codec.hh' => 'src/mediascanner/d-bus/dbus-codec.hh' |
403 | === renamed file 'src/ms-dbus/dbus-interface.hh' => 'src/mediascanner/d-bus/dbus-interface.hh' |
404 | === renamed file 'src/ms-dbus/service-stub.cc' => 'src/mediascanner/d-bus/service-stub.cc' |
405 | --- src/ms-dbus/service-stub.cc 2014-08-21 03:55:40 +0000 |
406 | +++ src/mediascanner/d-bus/service-stub.cc 2015-02-16 14:24:40 +0000 |
407 | @@ -43,6 +43,12 @@ |
408 | core::dbus::types::ObjectPath(core::dbus::traits::Service<MediaStoreService>::object_path()))}) { |
409 | } |
410 | |
411 | +ServiceStub::ServiceStub() |
412 | + : core::dbus::Stub<MediaStoreService>(std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session)), |
413 | + p(new Private{access_service()->object_for_path( |
414 | + core::dbus::types::ObjectPath(core::dbus::traits::Service<MediaStoreService>::object_path()))}) { |
415 | +} |
416 | + |
417 | ServiceStub::~ServiceStub() { |
418 | } |
419 | |
420 | |
421 | === renamed file 'src/ms-dbus/service-stub.hh' => 'src/mediascanner/d-bus/service-stub.hh' |
422 | --- src/ms-dbus/service-stub.hh 2014-08-21 03:55:40 +0000 |
423 | +++ src/mediascanner/d-bus/service-stub.hh 2015-02-16 14:24:40 +0000 |
424 | @@ -40,6 +40,7 @@ |
425 | class ServiceStub : public core::dbus::Stub<MediaStoreService>, public virtual MediaStoreBase { |
426 | public: |
427 | explicit ServiceStub(core::dbus::Bus::Ptr bus); |
428 | + explicit ServiceStub(); |
429 | virtual ~ServiceStub(); |
430 | |
431 | virtual MediaFile lookup(const std::string &filename) const override; |
432 | |
433 | === renamed file 'src/ms-dbus/service.hh' => 'src/mediascanner/d-bus/service.hh' |
434 | === modified file 'src/mediascanner/mediascanner-2.0.map' |
435 | --- src/mediascanner/mediascanner-2.0.map 2014-06-24 11:10:39 +0000 |
436 | +++ src/mediascanner/mediascanner-2.0.map 2015-02-16 14:24:40 +0000 |
437 | @@ -11,11 +11,41 @@ |
438 | mediascanner::MediaStoreBase::*; |
439 | mediascanner::Filter::*; |
440 | |
441 | - typeinfo?for?mediascanner::*; |
442 | - typeinfo?name?for?mediascanner::*; |
443 | - VTT?for?mediascanner::*; |
444 | - virtual?thunk?to?mediascanner::*; |
445 | - vtable?for?mediascanner::*; |
446 | + typeinfo?for?mediascanner::MediaFile*; |
447 | + typeinfo?name?for?mediascanner::MediaFile*; |
448 | + VTT?for?mediascanner::MediaFile*; |
449 | + virtual?thunk?to?mediascanner::MediaFile*; |
450 | + vtable?for?mediascanner::MediaFile*; |
451 | + |
452 | + typeinfo?for?mediascanner::Album*; |
453 | + typeinfo?name?for?mediascanner::Album*; |
454 | + VTT?for?mediascanner::Album*; |
455 | + virtual?thunk?to?mediascanner::Album*; |
456 | + vtable?for?mediascanner::Album*; |
457 | + |
458 | + typeinfo?for?mediascanner::MediaFileBuilder*; |
459 | + typeinfo?name?for?mediascanner::MediaFileBuilder*; |
460 | + VTT?for?mediascanner::MediaFileBuilder*; |
461 | + virtual?thunk?to?mediascanner::MediaFileBuilder*; |
462 | + vtable?for?mediascanner::MediaFileBuilder*; |
463 | + |
464 | + typeinfo?for?mediascanner::MediaStore*; |
465 | + typeinfo?name?for?mediascanner::MediaStore*; |
466 | + VTT?for?mediascanner::MediaStore*; |
467 | + virtual?thunk?to?mediascanner::MediaStore*; |
468 | + vtable?for?mediascanner::MediaStore*; |
469 | + |
470 | + typeinfo?for?mediascanner::MediaStoreBase*; |
471 | + typeinfo?name?for?mediascanner::MediaStoreBase*; |
472 | + VTT?for?mediascanner::MediaStoreBase*; |
473 | + virtual?thunk?to?mediascanner::MediaStoreBase*; |
474 | + vtable?for?mediascanner::MediaStoreBase*; |
475 | + |
476 | + typeinfo?for?mediascanner::Filter*; |
477 | + typeinfo?name?for?mediascanner::Filter*; |
478 | + VTT?for?mediascanner::Filter*; |
479 | + virtual?thunk?to?mediascanner::Filter*; |
480 | + vtable?for?mediascanner::Filter*; |
481 | }; |
482 | |
483 | local: |
484 | |
485 | === modified file 'src/ms-dbus/CMakeLists.txt' |
486 | --- src/ms-dbus/CMakeLists.txt 2014-05-29 07:29:58 +0000 |
487 | +++ src/ms-dbus/CMakeLists.txt 2015-02-16 14:24:40 +0000 |
488 | @@ -2,9 +2,7 @@ |
489 | add_definitions(${MEDIASCANNER_CFLAGS} ${DBUSCPP_CFLAGS} ${APPARMOR_CFLAGS}) |
490 | |
491 | add_library(ms-dbus STATIC |
492 | - dbus-codec.cc |
493 | service-skeleton.cc |
494 | - service-stub.cc |
495 | ) |
496 | |
497 | target_link_libraries(ms-dbus |
498 | @@ -16,6 +14,7 @@ |
499 | |
500 | add_executable(mediascanner-dbus |
501 | main.cc |
502 | + $<TARGET_OBJECTS:mediascanner-dbus-static> |
503 | ) |
504 | target_link_libraries(mediascanner-dbus ms-dbus) |
505 | set_target_properties(mediascanner-dbus |
506 | |
507 | === modified file 'src/ms-dbus/main.cc' |
508 | --- src/ms-dbus/main.cc 2014-05-20 09:01:59 +0000 |
509 | +++ src/ms-dbus/main.cc 2015-02-16 14:24:40 +0000 |
510 | @@ -27,10 +27,10 @@ |
511 | using namespace mediascanner; |
512 | |
513 | int main(int , char **) { |
514 | - auto bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session); |
515 | + auto bus = std::make_shared<core::dbus::Bus>(getenv("DBUS_SESSION_BUS_ADDRESS")); |
516 | bus->install_executor(core::dbus::asio::make_executor(bus)); |
517 | |
518 | - auto store = std::make_shared<MediaStore>(MS_READ_ONLY); |
519 | + auto store = std::make_shared<MediaStore>(MS_READ_WRITE); |
520 | |
521 | dbus::ServiceSkeleton service(bus, store); |
522 | service.run(); |
523 | |
524 | === modified file 'src/ms-dbus/service-skeleton.cc' |
525 | --- src/ms-dbus/service-skeleton.cc 2014-08-21 03:55:40 +0000 |
526 | +++ src/ms-dbus/service-skeleton.cc 2015-02-16 14:24:40 +0000 |
527 | @@ -12,8 +12,8 @@ |
528 | #include <mediascanner/MediaFile.hh> |
529 | #include <mediascanner/MediaStore.hh> |
530 | |
531 | -#include "dbus-interface.hh" |
532 | -#include "dbus-codec.hh" |
533 | +#include <mediascanner/d-bus/dbus-interface.hh> |
534 | +#include <mediascanner/d-bus/dbus-codec.hh> |
535 | |
536 | using core::dbus::Message; |
537 | |
538 | |
539 | === modified file 'src/ms-dbus/service-skeleton.hh' |
540 | --- src/ms-dbus/service-skeleton.hh 2014-05-22 09:26:44 +0000 |
541 | +++ src/ms-dbus/service-skeleton.hh 2015-02-16 14:24:40 +0000 |
542 | @@ -24,7 +24,7 @@ |
543 | #include <core/dbus/bus.h> |
544 | #include <core/dbus/skeleton.h> |
545 | |
546 | -#include "service.hh" |
547 | +#include "mediascanner/d-bus/service.hh" |
548 | |
549 | namespace mediascanner { |
550 | |
551 | |
552 | === modified file 'src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc' |
553 | --- src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc 2014-08-21 03:55:40 +0000 |
554 | +++ src/qml/Ubuntu/MediaScanner/MediaStoreWrapper.cc 2015-02-16 14:24:40 +0000 |
555 | @@ -28,7 +28,7 @@ |
556 | #include <core/dbus/asio/executor.h> |
557 | #include <mediascanner/Filter.hh> |
558 | #include <mediascanner/MediaStore.hh> |
559 | -#include <ms-dbus/service-stub.hh> |
560 | +#include <mediascanner/d-bus/service-stub.hh> |
561 | |
562 | using namespace mediascanner::qml; |
563 | |
564 | |
565 | === modified file 'test/CMakeLists.txt' |
566 | --- test/CMakeLists.txt 2014-06-24 11:23:31 +0000 |
567 | +++ test/CMakeLists.txt 2015-02-16 14:24:40 +0000 |
568 | @@ -2,6 +2,9 @@ |
569 | set(GTEST_ROOT /usr/src/gtest) |
570 | endif() |
571 | |
572 | +set(SOURCE_BINARY_DIR "${CMAKE_BINARY_DIR}/src") |
573 | +add_definitions(-DMS_DBUS_BINARY="${SOURCE_BINARY_DIR}/ms-dbus/mediascanner-dbus-2.0") |
574 | + |
575 | set(GTEST_SRC_DIR "${GTEST_ROOT}/src") |
576 | set(GTEST_INCLUDE_DIR ${GTEST_ROOT}) |
577 | |
578 | @@ -9,6 +12,9 @@ |
579 | ${GTEST_SRC_DIR}/gtest-all.cc |
580 | ) |
581 | |
582 | +pkg_check_modules(QTDBUSTEST REQUIRED libqtdbustest-1 REQUIRED) |
583 | +include_directories(${QTDBUSTEST_INCLUDE_DIRS}) |
584 | + |
585 | set_target_properties(gtest PROPERTIES INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR}) |
586 | target_link_libraries(gtest ${CMAKE_THREAD_LIBS_INIT}) |
587 | |
588 | @@ -25,10 +31,14 @@ |
589 | |
590 | add_executable(basic basic.cc) |
591 | target_link_libraries(basic mediascanner scannerstuff gtest) |
592 | -add_test(basic basic) |
593 | +#add_test(basic basic) |
594 | |
595 | -add_executable(test_mediastore test_mediastore.cc ../src/mediascanner/utils.cc) |
596 | -target_link_libraries(test_mediastore mediascanner gtest) |
597 | +add_executable(test_mediastore |
598 | + test_mediastore.cc |
599 | + ../src/mediascanner/utils.cc |
600 | + utils/DBusTest.cpp) |
601 | +qt5_use_modules(test_mediastore Core DBus) |
602 | +target_link_libraries(test_mediastore mediascanner gtest ${QTDBUSTEST_LDFLAGS}) |
603 | add_test(test_mediastore test_mediastore) |
604 | |
605 | add_executable(test_metadataextractor test_metadataextractor.cc) |
606 | @@ -43,11 +53,11 @@ |
607 | target_link_libraries(test_mfbuilder gtest mediascanner) |
608 | add_test(test_mfbuilder test_mfbuilder) |
609 | |
610 | -add_executable(test_dbus test_dbus.cc) |
611 | +add_executable(test_dbus test_dbus.cc $<TARGET_OBJECTS:mediascanner-dbus-static>) |
612 | target_link_libraries(test_dbus gtest mediascanner ms-dbus) |
613 | add_test(test_dbus test_dbus) |
614 | |
615 | -add_executable(test_qml test_qml.cc) |
616 | +add_executable(test_qml test_qml.cc $<TARGET_OBJECTS:mediascanner-dbus-static>) |
617 | qt5_use_modules(test_qml QuickTest) |
618 | target_link_libraries(test_qml mediascanner ${DBUSCPP_LDFLAGS}) |
619 | add_test(test_qml test_qml -input ${CMAKE_CURRENT_SOURCE_DIR}/qml -import ${CMAKE_BINARY_DIR}/src/qml) |
620 | |
621 | === modified file 'test/test_dbus.cc' |
622 | --- test/test_dbus.cc 2014-09-03 07:00:02 +0000 |
623 | +++ test/test_dbus.cc 2015-02-16 14:24:40 +0000 |
624 | @@ -7,7 +7,7 @@ |
625 | #include <mediascanner/MediaFile.hh> |
626 | #include <mediascanner/MediaFileBuilder.hh> |
627 | #include <mediascanner/Filter.hh> |
628 | -#include <ms-dbus/dbus-codec.hh> |
629 | +#include <mediascanner/d-bus/dbus-codec.hh> |
630 | |
631 | class MediaStoreDBusTests : public ::testing::Test { |
632 | protected: |
633 | |
634 | === modified file 'test/test_mediastore.cc' |
635 | --- test/test_mediastore.cc 2014-09-02 10:43:05 +0000 |
636 | +++ test/test_mediastore.cc 2015-02-16 14:24:40 +0000 |
637 | @@ -29,33 +29,27 @@ |
638 | #include<string> |
639 | #include <gtest/gtest.h> |
640 | |
641 | +#include <core/dbus/fixture.h> |
642 | + |
643 | +#include <QProcess> |
644 | +#include <QProcessEnvironment> |
645 | +#include <QCoreApplication> |
646 | + |
647 | +#include "test_config.h" |
648 | +#include "utils/DBusTest.h" |
649 | + |
650 | using namespace std; |
651 | using namespace mediascanner; |
652 | |
653 | -class MediaStoreTest : public ::testing::Test { |
654 | - protected: |
655 | - MediaStoreTest() { |
656 | - } |
657 | - |
658 | - virtual ~MediaStoreTest() { |
659 | - } |
660 | - |
661 | - virtual void SetUp() { |
662 | - } |
663 | - |
664 | - virtual void TearDown() { |
665 | - } |
666 | -}; |
667 | - |
668 | -TEST_F(MediaStoreTest, init) { |
669 | +TEST(MediaStoreTest, init) { |
670 | MediaStore store(":memory:", MS_READ_WRITE); |
671 | } |
672 | -TEST_F(MediaStoreTest, mediafile_uri) { |
673 | +TEST(MediaStoreTest, mediafile_uri) { |
674 | MediaFile media = MediaFileBuilder("/path/to/file.ogg"); |
675 | EXPECT_EQ(media.getUri(), "file:///path/to/file.ogg"); |
676 | } |
677 | |
678 | -TEST_F(MediaStoreTest, equality) { |
679 | +TEST(MediaStoreTest, equality) { |
680 | MediaFile audio1 = MediaFileBuilder("a") |
681 | .setContentType("type") |
682 | .setETag("etag") |
683 | @@ -136,7 +130,7 @@ |
684 | EXPECT_NE(video1, image1); |
685 | } |
686 | |
687 | -TEST_F(MediaStoreTest, lookup) { |
688 | +TEST(MediaStoreTest, lookup) { |
689 | MediaFile audio = MediaFileBuilder("/aaa") |
690 | .setContentType("type") |
691 | .setETag("etag") |
692 | @@ -155,9 +149,11 @@ |
693 | |
694 | EXPECT_EQ(store.lookup("/aaa"), audio); |
695 | EXPECT_THROW(store.lookup("not found"), std::runtime_error); |
696 | + |
697 | + store.remove(audio.getFileName()); |
698 | } |
699 | |
700 | -TEST_F(MediaStoreTest, roundtrip) { |
701 | +TEST(MediaStoreTest, roundtrip) { |
702 | MediaFile audio = MediaFileBuilder("/aaa") |
703 | .setContentType("type") |
704 | .setETag("etag") |
705 | @@ -208,41 +204,75 @@ |
706 | result = store.query("bbb", ImageMedia, filter); |
707 | ASSERT_EQ(1, result.size()); |
708 | EXPECT_EQ(image, result[0]); |
709 | + |
710 | + store.remove(audio.getFileName()); |
711 | + store.remove(video.getFileName()); |
712 | + store.remove(image.getFileName()); |
713 | } |
714 | |
715 | -TEST_F(MediaStoreTest, query_by_album) { |
716 | - MediaFile audio = MediaFileBuilder("/path/foo.ogg") |
717 | - .setType(AudioMedia) |
718 | - .setTitle("title") |
719 | - .setAuthor("artist") |
720 | - .setAlbum("album") |
721 | - .setAlbumArtist("albumartist"); |
722 | - MediaStore store(":memory:", MS_READ_WRITE); |
723 | - store.insert(audio); |
724 | - |
725 | +void check_query_by_album(MediaStore const &store, MediaFile const &audio) { |
726 | Filter filter; |
727 | vector<MediaFile> result = store.query("album", AudioMedia, filter); |
728 | ASSERT_EQ(result.size(), 1); |
729 | EXPECT_EQ(result[0], audio); |
730 | } |
731 | |
732 | -TEST_F(MediaStoreTest, query_by_artist) { |
733 | +TEST(MediaStoreTest, query_by_album) { |
734 | MediaFile audio = MediaFileBuilder("/path/foo.ogg") |
735 | .setType(AudioMedia) |
736 | .setTitle("title") |
737 | .setAuthor("artist") |
738 | .setAlbum("album") |
739 | .setAlbumArtist("albumartist"); |
740 | - MediaStore store(":memory:", MS_READ_WRITE); |
741 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
742 | store.insert(audio); |
743 | |
744 | + check_query_by_album(store, audio); |
745 | + |
746 | + // test read only |
747 | + MediaStore store2(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
748 | + check_query_by_album(store2, audio); |
749 | + |
750 | + store.remove(audio.getFileName()); |
751 | + |
752 | +} |
753 | + |
754 | +void check_query_by_artist(MediaStore const &store, MediaFile const &audio) { |
755 | Filter filter; |
756 | vector<MediaFile> result = store.query("artist", AudioMedia, filter); |
757 | ASSERT_EQ(result.size(), 1); |
758 | EXPECT_EQ(result[0], audio); |
759 | - } |
760 | - |
761 | -TEST_F(MediaStoreTest, query_ranking) { |
762 | +} |
763 | + |
764 | +TEST(MediaStoreTest, query_by_artist) { |
765 | + MediaFile audio = MediaFileBuilder("/path/foo.ogg") |
766 | + .setType(AudioMedia) |
767 | + .setTitle("title") |
768 | + .setAuthor("artist") |
769 | + .setAlbum("album") |
770 | + .setAlbumArtist("albumartist"); |
771 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
772 | + store.insert(audio); |
773 | + |
774 | + check_query_by_artist(store, audio); |
775 | + |
776 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
777 | + check_query_by_artist(store_ro, audio); |
778 | + |
779 | + store.remove(audio.getFileName()); |
780 | +} |
781 | + |
782 | +void check_query_ranking(MediaStore const &store, std::vector<MediaFile> const &files) { |
783 | + Filter filter; |
784 | + vector<MediaFile> result = store.query("aaa", AudioMedia, filter); |
785 | + ASSERT_EQ(result.size(), 4); |
786 | + EXPECT_EQ(result[0], files[4]); // Term appears in title, artist and album |
787 | + EXPECT_EQ(result[1], files[1]); // title has highest weighting |
788 | + EXPECT_EQ(result[2], files[3]); // then album |
789 | + EXPECT_EQ(result[3], files[2]); // then artist |
790 | +} |
791 | + |
792 | +TEST(MediaStoreTest, query_ranking) { |
793 | MediaFile audio1 = MediaFileBuilder("/path/foo1.ogg") |
794 | .setType(AudioMedia) |
795 | .setTitle("title") |
796 | @@ -274,47 +304,38 @@ |
797 | .setAlbum("album aaa") |
798 | .setAlbumArtist("albumartist"); |
799 | |
800 | - MediaStore store(":memory:", MS_READ_WRITE); |
801 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
802 | + |
803 | + std::vector<MediaFile> files; |
804 | store.insert(audio1); |
805 | + files.push_back(audio1); |
806 | + |
807 | store.insert(audio2); |
808 | + files.push_back(audio2); |
809 | + |
810 | store.insert(audio3); |
811 | + files.push_back(audio3); |
812 | + |
813 | store.insert(audio4); |
814 | + files.push_back(audio4); |
815 | + |
816 | store.insert(audio5); |
817 | - |
818 | - Filter filter; |
819 | - vector<MediaFile> result = store.query("aaa", AudioMedia, filter); |
820 | - ASSERT_EQ(result.size(), 4); |
821 | - EXPECT_EQ(result[0], audio5); // Term appears in title, artist and album |
822 | - EXPECT_EQ(result[1], audio2); // title has highest weighting |
823 | - EXPECT_EQ(result[2], audio4); // then album |
824 | - EXPECT_EQ(result[3], audio3); // then artist |
825 | + files.push_back(audio5); |
826 | + |
827 | + check_query_ranking(store, files); |
828 | + |
829 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
830 | + check_query_ranking(store_ro, files); |
831 | + |
832 | + for(auto item: files) { |
833 | + store.remove(item.getFileName()); |
834 | + } |
835 | } |
836 | |
837 | -TEST_F(MediaStoreTest, query_limit) { |
838 | - MediaFile audio1 = MediaFileBuilder("/path/foo5.ogg") |
839 | - .setType(AudioMedia) |
840 | - .setTitle("title aaa") |
841 | - .setAuthor("artist aaa") |
842 | - .setAlbum("album aaa") |
843 | - .setAlbumArtist("albumartist"); |
844 | - MediaFile audio2 = MediaFileBuilder("/path/foo2.ogg") |
845 | - .setType(AudioMedia) |
846 | - .setTitle("title aaa") |
847 | - .setAuthor("artist") |
848 | - .setAlbum("album") |
849 | - .setAlbumArtist("albumartist"); |
850 | - MediaFile audio3 = MediaFileBuilder("/path/foo4.ogg") |
851 | - .setType(AudioMedia) |
852 | - .setTitle("title") |
853 | - .setAuthor("artist") |
854 | - .setAlbum("album aaa") |
855 | - .setAlbumArtist("albumartist"); |
856 | - |
857 | - MediaStore store(":memory:", MS_READ_WRITE); |
858 | - store.insert(audio1); |
859 | - store.insert(audio2); |
860 | - store.insert(audio3); |
861 | - |
862 | +void check_query_limit(MediaStore const &store, |
863 | + MediaFile const &audio1, |
864 | + MediaFile const &audio2, |
865 | + MediaFile const &) { |
866 | Filter filter; |
867 | filter.setLimit(2); |
868 | vector<MediaFile> result = store.query("aaa", AudioMedia, filter); |
869 | @@ -323,24 +344,42 @@ |
870 | EXPECT_EQ(result[1], audio2); // title has highest weighting |
871 | } |
872 | |
873 | -TEST_F(MediaStoreTest, query_short) { |
874 | +TEST(MediaStoreTest, query_limit) { |
875 | MediaFile audio1 = MediaFileBuilder("/path/foo5.ogg") |
876 | .setType(AudioMedia) |
877 | - .setTitle("title xyz") |
878 | - .setAuthor("artist") |
879 | - .setAlbum("album") |
880 | + .setTitle("title aaa") |
881 | + .setAuthor("artist aaa") |
882 | + .setAlbum("album aaa") |
883 | .setAlbumArtist("albumartist"); |
884 | MediaFile audio2 = MediaFileBuilder("/path/foo2.ogg") |
885 | .setType(AudioMedia) |
886 | - .setTitle("title xzy") |
887 | + .setTitle("title aaa") |
888 | .setAuthor("artist") |
889 | .setAlbum("album") |
890 | .setAlbumArtist("albumartist"); |
891 | + MediaFile audio3 = MediaFileBuilder("/path/foo4.ogg") |
892 | + .setType(AudioMedia) |
893 | + .setTitle("title") |
894 | + .setAuthor("artist") |
895 | + .setAlbum("album aaa") |
896 | + .setAlbumArtist("albumartist"); |
897 | |
898 | - MediaStore store(":memory:", MS_READ_WRITE); |
899 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
900 | store.insert(audio1); |
901 | store.insert(audio2); |
902 | - |
903 | + store.insert(audio3); |
904 | + |
905 | + check_query_limit(store, audio1, audio2, audio3); |
906 | + |
907 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
908 | + check_query_limit(store_ro, audio1, audio2, audio3); |
909 | + |
910 | + store.remove(audio1.getFileName()); |
911 | + store.remove(audio2.getFileName()); |
912 | + store.remove(audio3.getFileName()); |
913 | +} |
914 | + |
915 | +void check_query_short(MediaStore const &store, MediaFile const &, MediaFile const &) { |
916 | Filter filter; |
917 | vector<MediaFile> result = store.query("x", AudioMedia, filter); |
918 | EXPECT_EQ(result.size(), 2); |
919 | @@ -348,31 +387,34 @@ |
920 | EXPECT_EQ(result.size(), 1); |
921 | } |
922 | |
923 | -TEST_F(MediaStoreTest, query_empty) { |
924 | +TEST(MediaStoreTest, query_short) { |
925 | MediaFile audio1 = MediaFileBuilder("/path/foo5.ogg") |
926 | .setType(AudioMedia) |
927 | - .setTitle("title aaa") |
928 | - .setAuthor("artist aaa") |
929 | - .setAlbum("album aaa") |
930 | + .setTitle("title xyz") |
931 | + .setAuthor("artist") |
932 | + .setAlbum("album") |
933 | .setAlbumArtist("albumartist"); |
934 | MediaFile audio2 = MediaFileBuilder("/path/foo2.ogg") |
935 | .setType(AudioMedia) |
936 | - .setTitle("title aaa") |
937 | + .setTitle("title xzy") |
938 | .setAuthor("artist") |
939 | .setAlbum("album") |
940 | .setAlbumArtist("albumartist"); |
941 | - MediaFile audio3 = MediaFileBuilder("/path/foo4.ogg") |
942 | - .setType(AudioMedia) |
943 | - .setTitle("title") |
944 | - .setAuthor("artist") |
945 | - .setAlbum("album aaa") |
946 | - .setAlbumArtist("albumartist"); |
947 | |
948 | - MediaStore store(":memory:", MS_READ_WRITE); |
949 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
950 | store.insert(audio1); |
951 | store.insert(audio2); |
952 | - store.insert(audio3); |
953 | - |
954 | + |
955 | + check_query_short(store, audio1, audio2); |
956 | + |
957 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
958 | + check_query_short(store_ro, audio1, audio2); |
959 | + |
960 | + store.remove(audio1.getFileName()); |
961 | + store.remove(audio2.getFileName()); |
962 | +} |
963 | + |
964 | +void check_query_empty(MediaStore const &store) { |
965 | // An empty query should return some results |
966 | Filter filter; |
967 | filter.setLimit(2); |
968 | @@ -380,91 +422,140 @@ |
969 | ASSERT_EQ(result.size(), 2); |
970 | } |
971 | |
972 | -TEST_F(MediaStoreTest, query_order) { |
973 | - MediaFile audio1 = MediaFileBuilder("/path/foo1.ogg") |
974 | +TEST(MediaStoreTest, query_empty) { |
975 | + MediaFile audio1 = MediaFileBuilder("/path/foo5.ogg") |
976 | .setType(AudioMedia) |
977 | - .setTitle("foo") |
978 | - .setDate("2010-01-01") |
979 | - .setAuthor("artist") |
980 | - .setAlbum("album"); |
981 | + .setTitle("title aaa") |
982 | + .setAuthor("artist aaa") |
983 | + .setAlbum("album aaa") |
984 | + .setAlbumArtist("albumartist"); |
985 | MediaFile audio2 = MediaFileBuilder("/path/foo2.ogg") |
986 | .setType(AudioMedia) |
987 | - .setTitle("foo foo") |
988 | - .setDate("2010-01-03") |
989 | + .setTitle("title aaa") |
990 | .setAuthor("artist") |
991 | - .setAlbum("album"); |
992 | - MediaFile audio3 = MediaFileBuilder("/path/foo3.ogg") |
993 | + .setAlbum("album") |
994 | + .setAlbumArtist("albumartist"); |
995 | + MediaFile audio3 = MediaFileBuilder("/path/foo4.ogg") |
996 | .setType(AudioMedia) |
997 | - .setTitle("foo foo foo") |
998 | - .setDate("2010-01-02") |
999 | + .setTitle("title") |
1000 | .setAuthor("artist") |
1001 | - .setAlbum("album"); |
1002 | + .setAlbum("album aaa") |
1003 | + .setAlbumArtist("albumartist"); |
1004 | |
1005 | - MediaStore store(":memory:", MS_READ_WRITE); |
1006 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1007 | store.insert(audio1); |
1008 | store.insert(audio2); |
1009 | store.insert(audio3); |
1010 | |
1011 | + check_query_empty(store); |
1012 | + |
1013 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1014 | + check_query_empty(store_ro); |
1015 | + |
1016 | + store.remove(audio1.getFileName()); |
1017 | + store.remove(audio2.getFileName()); |
1018 | + store.remove(audio3.getFileName()); |
1019 | +} |
1020 | + |
1021 | +void check_query_order(MediaStore const &store, |
1022 | + std::string const &name1, |
1023 | + std::string const &name2, |
1024 | + std::string const &name3) { |
1025 | Filter filter; |
1026 | // Default sort order is by rank |
1027 | vector<MediaFile> result = store.query("foo", AudioMedia, filter); |
1028 | ASSERT_EQ(3, result.size()); |
1029 | - EXPECT_EQ("/path/foo3.ogg", result[0].getFileName()); |
1030 | - EXPECT_EQ("/path/foo2.ogg", result[1].getFileName()); |
1031 | - EXPECT_EQ("/path/foo1.ogg", result[2].getFileName()); |
1032 | + EXPECT_EQ(name3, result[0].getFileName()); |
1033 | + EXPECT_EQ(name2, result[1].getFileName()); |
1034 | + EXPECT_EQ(name1, result[2].getFileName()); |
1035 | |
1036 | // Sorting by rank (same as default) |
1037 | filter.setOrder(MediaOrder::Rank); |
1038 | result = store.query("foo", AudioMedia, filter); |
1039 | ASSERT_EQ(3, result.size()); |
1040 | - EXPECT_EQ("/path/foo3.ogg", result[0].getFileName()); |
1041 | - EXPECT_EQ("/path/foo2.ogg", result[1].getFileName()); |
1042 | - EXPECT_EQ("/path/foo1.ogg", result[2].getFileName()); |
1043 | + EXPECT_EQ(name3, result[0].getFileName()); |
1044 | + EXPECT_EQ(name2, result[1].getFileName()); |
1045 | + EXPECT_EQ(name1, result[2].getFileName()); |
1046 | |
1047 | // Sorting by rank, reversed |
1048 | filter.setReverse(true); |
1049 | result = store.query("foo", AudioMedia, filter); |
1050 | ASSERT_EQ(3, result.size()); |
1051 | - EXPECT_EQ("/path/foo1.ogg", result[0].getFileName()); |
1052 | - EXPECT_EQ("/path/foo2.ogg", result[1].getFileName()); |
1053 | - EXPECT_EQ("/path/foo3.ogg", result[2].getFileName()); |
1054 | + EXPECT_EQ(name1, result[0].getFileName()); |
1055 | + EXPECT_EQ(name2, result[1].getFileName()); |
1056 | + EXPECT_EQ(name3, result[2].getFileName()); |
1057 | |
1058 | // Sorting by title |
1059 | filter.setReverse(false); |
1060 | filter.setOrder(MediaOrder::Title); |
1061 | result = store.query("foo", AudioMedia, filter); |
1062 | ASSERT_EQ(3, result.size()); |
1063 | - EXPECT_EQ("/path/foo1.ogg", result[0].getFileName()); |
1064 | - EXPECT_EQ("/path/foo2.ogg", result[1].getFileName()); |
1065 | - EXPECT_EQ("/path/foo3.ogg", result[2].getFileName()); |
1066 | + EXPECT_EQ(name1, result[0].getFileName()); |
1067 | + EXPECT_EQ(name2, result[1].getFileName()); |
1068 | + EXPECT_EQ(name3, result[2].getFileName()); |
1069 | |
1070 | // Sorting by title, reversed |
1071 | filter.setReverse(true); |
1072 | result = store.query("foo", AudioMedia, filter); |
1073 | ASSERT_EQ(3, result.size()); |
1074 | - EXPECT_EQ("/path/foo3.ogg", result[0].getFileName()); |
1075 | - EXPECT_EQ("/path/foo2.ogg", result[1].getFileName()); |
1076 | - EXPECT_EQ("/path/foo1.ogg", result[2].getFileName()); |
1077 | + EXPECT_EQ(name3, result[0].getFileName()); |
1078 | + EXPECT_EQ(name2, result[1].getFileName()); |
1079 | + EXPECT_EQ(name1, result[2].getFileName()); |
1080 | |
1081 | // Sorting by date |
1082 | filter.setReverse(false); |
1083 | filter.setOrder(MediaOrder::Date); |
1084 | result = store.query("foo", AudioMedia, filter); |
1085 | ASSERT_EQ(3, result.size()); |
1086 | - EXPECT_EQ("/path/foo1.ogg", result[0].getFileName()); |
1087 | - EXPECT_EQ("/path/foo3.ogg", result[1].getFileName()); |
1088 | - EXPECT_EQ("/path/foo2.ogg", result[2].getFileName()); |
1089 | + EXPECT_EQ(name1, result[0].getFileName()); |
1090 | + EXPECT_EQ(name3, result[1].getFileName()); |
1091 | + EXPECT_EQ(name2, result[2].getFileName()); |
1092 | |
1093 | // Sorting by date, reversed |
1094 | filter.setReverse(true); |
1095 | result = store.query("foo", AudioMedia, filter); |
1096 | ASSERT_EQ(3, result.size()); |
1097 | - EXPECT_EQ("/path/foo2.ogg", result[0].getFileName()); |
1098 | - EXPECT_EQ("/path/foo3.ogg", result[1].getFileName()); |
1099 | - EXPECT_EQ("/path/foo1.ogg", result[2].getFileName()); |
1100 | -} |
1101 | - |
1102 | -TEST_F(MediaStoreTest, unmount) { |
1103 | + EXPECT_EQ(name2, result[0].getFileName()); |
1104 | + EXPECT_EQ(name3, result[1].getFileName()); |
1105 | + EXPECT_EQ(name1, result[2].getFileName()); |
1106 | +} |
1107 | + |
1108 | +TEST(MediaStoreTest, query_order) { |
1109 | + MediaFile audio1 = MediaFileBuilder("/path/foo1.ogg") |
1110 | + .setType(AudioMedia) |
1111 | + .setTitle("foo") |
1112 | + .setDate("2010-01-01") |
1113 | + .setAuthor("artist") |
1114 | + .setAlbum("album"); |
1115 | + MediaFile audio2 = MediaFileBuilder("/path/foo2.ogg") |
1116 | + .setType(AudioMedia) |
1117 | + .setTitle("foo foo") |
1118 | + .setDate("2010-01-03") |
1119 | + .setAuthor("artist") |
1120 | + .setAlbum("album"); |
1121 | + MediaFile audio3 = MediaFileBuilder("/path/foo3.ogg") |
1122 | + .setType(AudioMedia) |
1123 | + .setTitle("foo foo foo") |
1124 | + .setDate("2010-01-02") |
1125 | + .setAuthor("artist") |
1126 | + .setAlbum("album"); |
1127 | + |
1128 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1129 | + store.insert(audio1); |
1130 | + store.insert(audio2); |
1131 | + store.insert(audio3); |
1132 | + |
1133 | + check_query_order(store, "/path/foo1.ogg", "/path/foo2.ogg", "/path/foo3.ogg"); |
1134 | + |
1135 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1136 | + check_query_order(store_ro, "/path/foo1.ogg", "/path/foo2.ogg", "/path/foo3.ogg"); |
1137 | + |
1138 | + store.remove(audio1.getFileName()); |
1139 | + store.remove(audio2.getFileName()); |
1140 | + store.remove(audio3.getFileName()); |
1141 | +} |
1142 | + |
1143 | +TEST(MediaStoreTest, unmount) { |
1144 | MediaFile audio1 = MediaFileBuilder("/media/username/dir/fname.ogg") |
1145 | .setType(AudioMedia) |
1146 | .setTitle("bbb bbb"); |
1147 | @@ -488,7 +579,7 @@ |
1148 | ASSERT_EQ(result.size(), 2); |
1149 | } |
1150 | |
1151 | -TEST_F(MediaStoreTest, utils) { |
1152 | +TEST(MediaStoreTest, utils) { |
1153 | string source("_a.b(c)[d]{e}f.mp3"); |
1154 | string correct = {" a b c d e f"}; |
1155 | string result = filenameToTitle(source); |
1156 | @@ -499,54 +590,7 @@ |
1157 | EXPECT_EQ(sqlQuote(unquoted), quoted); |
1158 | } |
1159 | |
1160 | -TEST_F(MediaStoreTest, queryAlbums) { |
1161 | - MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1162 | - .setType(AudioMedia) |
1163 | - .setTitle("TitleOne") |
1164 | - .setAuthor("ArtistOne") |
1165 | - .setAlbum("AlbumOne") |
1166 | - .setAlbumArtist("Various Artists") |
1167 | - .setDate("2000-01-01") |
1168 | - .setDiscNumber(1) |
1169 | - .setTrackNumber(1) |
1170 | - .setGenre("GenreOne"); |
1171 | - MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1172 | - .setType(AudioMedia) |
1173 | - .setTitle("TitleTwo") |
1174 | - .setAuthor("ArtistTwo") |
1175 | - .setAlbum("AlbumOne") |
1176 | - .setAlbumArtist("Various Artists") |
1177 | - .setDate("2000-01-01") |
1178 | - .setDiscNumber(1) |
1179 | - .setTrackNumber(2) |
1180 | - .setGenre("GenreOne"); |
1181 | - MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1182 | - .setType(AudioMedia) |
1183 | - .setTitle("TitleThree") |
1184 | - .setAuthor("ArtistThree") |
1185 | - .setAlbum("AlbumOne") |
1186 | - .setAlbumArtist("Various Artists") |
1187 | - .setDate("2000-01-01") |
1188 | - .setDiscNumber(2) |
1189 | - .setTrackNumber(1) |
1190 | - .setGenre("GenreOne"); |
1191 | - MediaFile audio4 = MediaFileBuilder("/home/username/Music/fname.ogg") |
1192 | - .setType(AudioMedia) |
1193 | - .setTitle("TitleFour") |
1194 | - .setAuthor("ArtistFour") |
1195 | - .setAlbum("AlbumTwo") |
1196 | - .setAlbumArtist("ArtistFour") |
1197 | - .setDate("2014-06-01") |
1198 | - .setTrackNumber(1) |
1199 | - .setGenre("GenreTwo") |
1200 | - .setHasThumbnail(true); |
1201 | - |
1202 | - MediaStore store(":memory:", MS_READ_WRITE); |
1203 | - store.insert(audio1); |
1204 | - store.insert(audio2); |
1205 | - store.insert(audio3); |
1206 | - store.insert(audio4); |
1207 | - |
1208 | +void check_query_albums(MediaStore const &store) { |
1209 | // Query a track title |
1210 | Filter filter; |
1211 | vector<Album> albums = store.queryAlbums("TitleOne", filter); |
1212 | @@ -573,45 +617,66 @@ |
1213 | EXPECT_EQ(albums[0].getArtist(), "Various Artists"); |
1214 | } |
1215 | |
1216 | -TEST_F(MediaStoreTest, queryAlbums_limit) { |
1217 | +TEST(MediaStoreTest, queryAlbums) { |
1218 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1219 | .setType(AudioMedia) |
1220 | .setTitle("TitleOne") |
1221 | .setAuthor("ArtistOne") |
1222 | .setAlbum("AlbumOne") |
1223 | .setAlbumArtist("Various Artists") |
1224 | + .setDate("2000-01-01") |
1225 | .setDiscNumber(1) |
1226 | - .setTrackNumber(1); |
1227 | + .setTrackNumber(1) |
1228 | + .setGenre("GenreOne"); |
1229 | MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1230 | .setType(AudioMedia) |
1231 | .setTitle("TitleTwo") |
1232 | .setAuthor("ArtistTwo") |
1233 | .setAlbum("AlbumOne") |
1234 | .setAlbumArtist("Various Artists") |
1235 | + .setDate("2000-01-01") |
1236 | .setDiscNumber(1) |
1237 | - .setTrackNumber(2); |
1238 | + .setTrackNumber(2) |
1239 | + .setGenre("GenreOne"); |
1240 | MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1241 | .setType(AudioMedia) |
1242 | .setTitle("TitleThree") |
1243 | .setAuthor("ArtistThree") |
1244 | .setAlbum("AlbumOne") |
1245 | .setAlbumArtist("Various Artists") |
1246 | + .setDate("2000-01-01") |
1247 | .setDiscNumber(2) |
1248 | - .setTrackNumber(1); |
1249 | + .setTrackNumber(1) |
1250 | + .setGenre("GenreOne"); |
1251 | MediaFile audio4 = MediaFileBuilder("/home/username/Music/fname.ogg") |
1252 | .setType(AudioMedia) |
1253 | .setTitle("TitleFour") |
1254 | .setAuthor("ArtistFour") |
1255 | .setAlbum("AlbumTwo") |
1256 | .setAlbumArtist("ArtistFour") |
1257 | - .setTrackNumber(1); |
1258 | + .setDate("2014-06-01") |
1259 | + .setTrackNumber(1) |
1260 | + .setGenre("GenreTwo") |
1261 | + .setHasThumbnail(true); |
1262 | |
1263 | - MediaStore store(":memory:", MS_READ_WRITE); |
1264 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1265 | store.insert(audio1); |
1266 | store.insert(audio2); |
1267 | store.insert(audio3); |
1268 | store.insert(audio4); |
1269 | |
1270 | + check_query_albums(store); |
1271 | + |
1272 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1273 | + check_query_albums(store_ro); |
1274 | + |
1275 | + store.remove(audio1.getFileName()); |
1276 | + store.remove(audio2.getFileName()); |
1277 | + store.remove(audio3.getFileName()); |
1278 | + store.remove(audio4.getFileName()); |
1279 | +} |
1280 | + |
1281 | +void check_query_albums_limit(MediaStore const &store) { |
1282 | Filter filter; |
1283 | vector<Album> albums = store.queryAlbums("Artist", filter); |
1284 | EXPECT_EQ(2, albums.size()); |
1285 | @@ -620,7 +685,7 @@ |
1286 | EXPECT_EQ(1, albums.size()); |
1287 | } |
1288 | |
1289 | -TEST_F(MediaStoreTest, queryAlbums_empty) { |
1290 | +TEST(MediaStoreTest, queryAlbums_limit) { |
1291 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1292 | .setType(AudioMedia) |
1293 | .setTitle("TitleOne") |
1294 | @@ -653,12 +718,24 @@ |
1295 | .setAlbumArtist("ArtistFour") |
1296 | .setTrackNumber(1); |
1297 | |
1298 | - MediaStore store(":memory:", MS_READ_WRITE); |
1299 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1300 | store.insert(audio1); |
1301 | store.insert(audio2); |
1302 | store.insert(audio3); |
1303 | store.insert(audio4); |
1304 | |
1305 | + check_query_albums_limit(store); |
1306 | + |
1307 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1308 | + check_query_albums_limit(store_ro); |
1309 | + |
1310 | + store.remove(audio1.getFileName()); |
1311 | + store.remove(audio2.getFileName()); |
1312 | + store.remove(audio3.getFileName()); |
1313 | + store.remove(audio4.getFileName()); |
1314 | +} |
1315 | + |
1316 | +void check_query_albums_empty(MediaStore const &store) { |
1317 | Filter filter; |
1318 | vector<Album> albums = store.queryAlbums("", filter); |
1319 | EXPECT_EQ(2, albums.size()); |
1320 | @@ -667,7 +744,89 @@ |
1321 | EXPECT_EQ(1, albums.size()); |
1322 | } |
1323 | |
1324 | -TEST_F(MediaStoreTest, queryAlbums_order) { |
1325 | +TEST(MediaStoreTest, queryAlbums_empty) { |
1326 | + MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1327 | + .setType(AudioMedia) |
1328 | + .setTitle("TitleOne") |
1329 | + .setAuthor("ArtistOne") |
1330 | + .setAlbum("AlbumOne") |
1331 | + .setAlbumArtist("Various Artists") |
1332 | + .setDiscNumber(1) |
1333 | + .setTrackNumber(1); |
1334 | + MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1335 | + .setType(AudioMedia) |
1336 | + .setTitle("TitleTwo") |
1337 | + .setAuthor("ArtistTwo") |
1338 | + .setAlbum("AlbumOne") |
1339 | + .setAlbumArtist("Various Artists") |
1340 | + .setDiscNumber(1) |
1341 | + .setTrackNumber(2); |
1342 | + MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1343 | + .setType(AudioMedia) |
1344 | + .setTitle("TitleThree") |
1345 | + .setAuthor("ArtistThree") |
1346 | + .setAlbum("AlbumOne") |
1347 | + .setAlbumArtist("Various Artists") |
1348 | + .setDiscNumber(2) |
1349 | + .setTrackNumber(1); |
1350 | + MediaFile audio4 = MediaFileBuilder("/home/username/Music/fname.ogg") |
1351 | + .setType(AudioMedia) |
1352 | + .setTitle("TitleFour") |
1353 | + .setAuthor("ArtistFour") |
1354 | + .setAlbum("AlbumTwo") |
1355 | + .setAlbumArtist("ArtistFour") |
1356 | + .setTrackNumber(1); |
1357 | + |
1358 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1359 | + store.insert(audio1); |
1360 | + store.insert(audio2); |
1361 | + store.insert(audio3); |
1362 | + store.insert(audio4); |
1363 | + |
1364 | + check_query_albums_empty(store); |
1365 | + |
1366 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1367 | + check_query_albums_empty(store_ro); |
1368 | + |
1369 | + store.remove(audio1.getFileName()); |
1370 | + store.remove(audio2.getFileName()); |
1371 | + store.remove(audio3.getFileName()); |
1372 | + store.remove(audio4.getFileName()); |
1373 | +} |
1374 | + |
1375 | +void check_query_albums_order(MediaStore const &store) { |
1376 | + // Default sort |
1377 | + Filter filter; |
1378 | + vector<Album> albums = store.queryAlbums("foo", filter); |
1379 | + ASSERT_EQ(3, albums.size()); |
1380 | + EXPECT_EQ("foo", albums[0].getTitle()); |
1381 | + EXPECT_EQ("foo foo", albums[1].getTitle()); |
1382 | + EXPECT_EQ("foo foo foo", albums[2].getTitle()); |
1383 | + |
1384 | + // Sort by title (same as default) |
1385 | + filter.setOrder(MediaOrder::Title); |
1386 | + albums = store.queryAlbums("foo", filter); |
1387 | + ASSERT_EQ(3, albums.size()); |
1388 | + EXPECT_EQ("foo", albums[0].getTitle()); |
1389 | + EXPECT_EQ("foo foo", albums[1].getTitle()); |
1390 | + EXPECT_EQ("foo foo foo", albums[2].getTitle()); |
1391 | + |
1392 | + // Sort by title, reversed |
1393 | + filter.setReverse(true); |
1394 | + albums = store.queryAlbums("foo", filter); |
1395 | + ASSERT_EQ(3, albums.size()); |
1396 | + EXPECT_EQ("foo foo foo", albums[0].getTitle()); |
1397 | + EXPECT_EQ("foo foo", albums[1].getTitle()); |
1398 | + EXPECT_EQ("foo", albums[2].getTitle()); |
1399 | + |
1400 | + // Other orders are not supported |
1401 | + filter.setOrder(MediaOrder::Rank); |
1402 | + EXPECT_THROW(store.queryAlbums("foo", filter), std::runtime_error); |
1403 | + filter.setOrder(MediaOrder::Date); |
1404 | + EXPECT_THROW(store.queryAlbums("foo", filter), std::runtime_error); |
1405 | +} |
1406 | + |
1407 | +TEST(MediaStoreTest, queryAlbums_order) { |
1408 | MediaFile audio1 = MediaFileBuilder("/path/foo1.ogg") |
1409 | .setType(AudioMedia) |
1410 | .setTitle("title") |
1411 | @@ -687,81 +846,22 @@ |
1412 | .setAuthor("artist") |
1413 | .setAlbum("foo foo foo"); |
1414 | |
1415 | - MediaStore store(":memory:", MS_READ_WRITE); |
1416 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1417 | store.insert(audio1); |
1418 | store.insert(audio2); |
1419 | store.insert(audio3); |
1420 | |
1421 | - // Default sort |
1422 | - Filter filter; |
1423 | - vector<Album> albums = store.queryAlbums("foo", filter); |
1424 | - ASSERT_EQ(3, albums.size()); |
1425 | - EXPECT_EQ("foo", albums[0].getTitle()); |
1426 | - EXPECT_EQ("foo foo", albums[1].getTitle()); |
1427 | - EXPECT_EQ("foo foo foo", albums[2].getTitle()); |
1428 | - |
1429 | - // Sort by title (same as default) |
1430 | - filter.setOrder(MediaOrder::Title); |
1431 | - albums = store.queryAlbums("foo", filter); |
1432 | - ASSERT_EQ(3, albums.size()); |
1433 | - EXPECT_EQ("foo", albums[0].getTitle()); |
1434 | - EXPECT_EQ("foo foo", albums[1].getTitle()); |
1435 | - EXPECT_EQ("foo foo foo", albums[2].getTitle()); |
1436 | - |
1437 | - // Sort by title, reversed |
1438 | - filter.setReverse(true); |
1439 | - albums = store.queryAlbums("foo", filter); |
1440 | - ASSERT_EQ(3, albums.size()); |
1441 | - EXPECT_EQ("foo foo foo", albums[0].getTitle()); |
1442 | - EXPECT_EQ("foo foo", albums[1].getTitle()); |
1443 | - EXPECT_EQ("foo", albums[2].getTitle()); |
1444 | - |
1445 | - // Other orders are not supported |
1446 | - filter.setOrder(MediaOrder::Rank); |
1447 | - EXPECT_THROW(store.queryAlbums("foo", filter), std::runtime_error); |
1448 | - filter.setOrder(MediaOrder::Date); |
1449 | - EXPECT_THROW(store.queryAlbums("foo", filter), std::runtime_error); |
1450 | + check_query_albums_order(store); |
1451 | + |
1452 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1453 | + check_query_albums_order(store_ro); |
1454 | + |
1455 | + store.remove(audio1.getFileName()); |
1456 | + store.remove(audio2.getFileName()); |
1457 | + store.remove(audio3.getFileName()); |
1458 | } |
1459 | |
1460 | -TEST_F(MediaStoreTest, queryArtists) { |
1461 | - MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1462 | - .setType(AudioMedia) |
1463 | - .setTitle("TitleOne") |
1464 | - .setAuthor("ArtistOne") |
1465 | - .setAlbum("AlbumOne") |
1466 | - .setAlbumArtist("Various Artists") |
1467 | - .setDiscNumber(1) |
1468 | - .setTrackNumber(1); |
1469 | - MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1470 | - .setType(AudioMedia) |
1471 | - .setTitle("TitleTwo") |
1472 | - .setAuthor("ArtistTwo") |
1473 | - .setAlbum("AlbumOne") |
1474 | - .setAlbumArtist("Various Artists") |
1475 | - .setDiscNumber(1) |
1476 | - .setTrackNumber(2); |
1477 | - MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1478 | - .setType(AudioMedia) |
1479 | - .setTitle("TitleThree") |
1480 | - .setAuthor("ArtistThree") |
1481 | - .setAlbum("AlbumOne") |
1482 | - .setAlbumArtist("Various Artists") |
1483 | - .setDiscNumber(2) |
1484 | - .setTrackNumber(1); |
1485 | - MediaFile audio4 = MediaFileBuilder("/home/username/Music/fname.ogg") |
1486 | - .setType(AudioMedia) |
1487 | - .setTitle("TitleFour") |
1488 | - .setAuthor("ArtistFour") |
1489 | - .setAlbum("AlbumTwo") |
1490 | - .setAlbumArtist("ArtistFour") |
1491 | - .setTrackNumber(1); |
1492 | - |
1493 | - MediaStore store(":memory:", MS_READ_WRITE); |
1494 | - store.insert(audio1); |
1495 | - store.insert(audio2); |
1496 | - store.insert(audio3); |
1497 | - store.insert(audio4); |
1498 | - |
1499 | +void check_query_artists(MediaStore const &store) { |
1500 | // Query a track title |
1501 | Filter filter; |
1502 | vector<string> artists = store.queryArtists("TitleOne", filter); |
1503 | @@ -779,7 +879,7 @@ |
1504 | EXPECT_EQ(artists[0], "ArtistTwo"); |
1505 | } |
1506 | |
1507 | -TEST_F(MediaStoreTest, queryArtists_limit) { |
1508 | +TEST(MediaStoreTest, queryArtists) { |
1509 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1510 | .setType(AudioMedia) |
1511 | .setTitle("TitleOne") |
1512 | @@ -796,11 +896,40 @@ |
1513 | .setAlbumArtist("Various Artists") |
1514 | .setDiscNumber(1) |
1515 | .setTrackNumber(2); |
1516 | + MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1517 | + .setType(AudioMedia) |
1518 | + .setTitle("TitleThree") |
1519 | + .setAuthor("ArtistThree") |
1520 | + .setAlbum("AlbumOne") |
1521 | + .setAlbumArtist("Various Artists") |
1522 | + .setDiscNumber(2) |
1523 | + .setTrackNumber(1); |
1524 | + MediaFile audio4 = MediaFileBuilder("/home/username/Music/fname.ogg") |
1525 | + .setType(AudioMedia) |
1526 | + .setTitle("TitleFour") |
1527 | + .setAuthor("ArtistFour") |
1528 | + .setAlbum("AlbumTwo") |
1529 | + .setAlbumArtist("ArtistFour") |
1530 | + .setTrackNumber(1); |
1531 | |
1532 | - MediaStore store(":memory:", MS_READ_WRITE); |
1533 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1534 | store.insert(audio1); |
1535 | store.insert(audio2); |
1536 | - |
1537 | + store.insert(audio3); |
1538 | + store.insert(audio4); |
1539 | + |
1540 | + check_query_artists(store); |
1541 | + |
1542 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1543 | + check_query_artists(store_ro); |
1544 | + |
1545 | + store.remove(audio1.getFileName()); |
1546 | + store.remove(audio2.getFileName()); |
1547 | + store.remove(audio3.getFileName()); |
1548 | + store.remove(audio4.getFileName()); |
1549 | +} |
1550 | + |
1551 | +void check_query_artists_limit(MediaStore const &store) { |
1552 | Filter filter; |
1553 | vector<string> artists = store.queryArtists("Artist", filter); |
1554 | EXPECT_EQ(2, artists.size()); |
1555 | @@ -809,7 +938,7 @@ |
1556 | EXPECT_EQ(1, artists.size()); |
1557 | } |
1558 | |
1559 | -TEST_F(MediaStoreTest, queryArtists_empty) { |
1560 | +TEST(MediaStoreTest, queryArtists_limit) { |
1561 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1562 | .setType(AudioMedia) |
1563 | .setTitle("TitleOne") |
1564 | @@ -827,10 +956,20 @@ |
1565 | .setDiscNumber(1) |
1566 | .setTrackNumber(2); |
1567 | |
1568 | - MediaStore store(":memory:", MS_READ_WRITE); |
1569 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1570 | store.insert(audio1); |
1571 | store.insert(audio2); |
1572 | |
1573 | + check_query_artists_limit(store); |
1574 | + |
1575 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1576 | + check_query_artists_limit(store_ro); |
1577 | + |
1578 | + store.remove(audio1.getFileName()); |
1579 | + store.remove(audio2.getFileName()); |
1580 | +} |
1581 | + |
1582 | +void check_query_artists_empty(MediaStore const &store) { |
1583 | Filter filter; |
1584 | vector<string> artists = store.queryArtists("", filter); |
1585 | EXPECT_EQ(2, artists.size()); |
1586 | @@ -839,7 +978,70 @@ |
1587 | EXPECT_EQ(1, artists.size()); |
1588 | } |
1589 | |
1590 | -TEST_F(MediaStoreTest, queryArtists_order) { |
1591 | +TEST(MediaStoreTest, queryArtists_empty) { |
1592 | + MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1593 | + .setType(AudioMedia) |
1594 | + .setTitle("TitleOne") |
1595 | + .setAuthor("ArtistOne") |
1596 | + .setAlbum("AlbumOne") |
1597 | + .setAlbumArtist("Various Artists") |
1598 | + .setDiscNumber(1) |
1599 | + .setTrackNumber(1); |
1600 | + MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1601 | + .setType(AudioMedia) |
1602 | + .setTitle("TitleTwo") |
1603 | + .setAuthor("ArtistTwo") |
1604 | + .setAlbum("AlbumOne") |
1605 | + .setAlbumArtist("Various Artists") |
1606 | + .setDiscNumber(1) |
1607 | + .setTrackNumber(2); |
1608 | + |
1609 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1610 | + store.insert(audio1); |
1611 | + store.insert(audio2); |
1612 | + |
1613 | + check_query_artists_empty(store); |
1614 | + |
1615 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1616 | + check_query_artists_empty(store_ro); |
1617 | + |
1618 | + store.remove(audio1.getFileName()); |
1619 | + store.remove(audio2.getFileName()); |
1620 | +} |
1621 | + |
1622 | +void check_query_artists_order(MediaStore const &store) { |
1623 | + // Default sort |
1624 | + Filter filter; |
1625 | + vector<std::string> artists = store.queryArtists("foo", filter); |
1626 | + ASSERT_EQ(3, artists.size()); |
1627 | + EXPECT_EQ("foo", artists[0]); |
1628 | + EXPECT_EQ("foo foo", artists[1]); |
1629 | + EXPECT_EQ("foo foo foo", artists[2]); |
1630 | + |
1631 | + // Sort by title (same as default) |
1632 | + filter.setOrder(MediaOrder::Title); |
1633 | + artists = store.queryArtists("foo", filter); |
1634 | + ASSERT_EQ(3, artists.size()); |
1635 | + EXPECT_EQ("foo", artists[0]); |
1636 | + EXPECT_EQ("foo foo", artists[1]); |
1637 | + EXPECT_EQ("foo foo foo", artists[2]); |
1638 | + |
1639 | + // Sort by title, reversed |
1640 | + filter.setReverse(true); |
1641 | + artists = store.queryArtists("foo", filter); |
1642 | + ASSERT_EQ(3, artists.size()); |
1643 | + EXPECT_EQ("foo foo foo", artists[0]); |
1644 | + EXPECT_EQ("foo foo", artists[1]); |
1645 | + EXPECT_EQ("foo", artists[2]); |
1646 | + |
1647 | + // Other orders are not supported |
1648 | + filter.setOrder(MediaOrder::Rank); |
1649 | + EXPECT_THROW(store.queryArtists("foo", filter), std::runtime_error); |
1650 | + filter.setOrder(MediaOrder::Date); |
1651 | + EXPECT_THROW(store.queryArtists("foo", filter), std::runtime_error); |
1652 | +} |
1653 | + |
1654 | +TEST(MediaStoreTest, queryArtists_order) { |
1655 | MediaFile audio1 = MediaFileBuilder("/path/foo1.ogg") |
1656 | .setType(AudioMedia) |
1657 | .setTitle("title") |
1658 | @@ -859,73 +1061,22 @@ |
1659 | .setAuthor("foo foo foo") |
1660 | .setAlbum("album"); |
1661 | |
1662 | - MediaStore store(":memory:", MS_READ_WRITE); |
1663 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1664 | store.insert(audio1); |
1665 | store.insert(audio2); |
1666 | store.insert(audio3); |
1667 | |
1668 | - // Default sort |
1669 | - Filter filter; |
1670 | - vector<std::string> artists = store.queryArtists("foo", filter); |
1671 | - ASSERT_EQ(3, artists.size()); |
1672 | - EXPECT_EQ("foo", artists[0]); |
1673 | - EXPECT_EQ("foo foo", artists[1]); |
1674 | - EXPECT_EQ("foo foo foo", artists[2]); |
1675 | - |
1676 | - // Sort by title (same as default) |
1677 | - filter.setOrder(MediaOrder::Title); |
1678 | - artists = store.queryArtists("foo", filter); |
1679 | - ASSERT_EQ(3, artists.size()); |
1680 | - EXPECT_EQ("foo", artists[0]); |
1681 | - EXPECT_EQ("foo foo", artists[1]); |
1682 | - EXPECT_EQ("foo foo foo", artists[2]); |
1683 | - |
1684 | - // Sort by title, reversed |
1685 | - filter.setReverse(true); |
1686 | - artists = store.queryArtists("foo", filter); |
1687 | - ASSERT_EQ(3, artists.size()); |
1688 | - EXPECT_EQ("foo foo foo", artists[0]); |
1689 | - EXPECT_EQ("foo foo", artists[1]); |
1690 | - EXPECT_EQ("foo", artists[2]); |
1691 | - |
1692 | - // Other orders are not supported |
1693 | - filter.setOrder(MediaOrder::Rank); |
1694 | - EXPECT_THROW(store.queryArtists("foo", filter), std::runtime_error); |
1695 | - filter.setOrder(MediaOrder::Date); |
1696 | - EXPECT_THROW(store.queryArtists("foo", filter), std::runtime_error); |
1697 | + check_query_artists_order(store); |
1698 | + |
1699 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1700 | + check_query_artists_order(store_ro); |
1701 | + |
1702 | + store.remove(audio1.getFileName()); |
1703 | + store.remove(audio2.getFileName()); |
1704 | + store.remove(audio3.getFileName()); |
1705 | } |
1706 | |
1707 | -TEST_F(MediaStoreTest, getAlbumSongs) { |
1708 | - MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1709 | - .setType(AudioMedia) |
1710 | - .setTitle("TitleOne") |
1711 | - .setAuthor("ArtistOne") |
1712 | - .setAlbum("AlbumOne") |
1713 | - .setAlbumArtist("Various Artists") |
1714 | - .setDiscNumber(1) |
1715 | - .setTrackNumber(1); |
1716 | - MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1717 | - .setType(AudioMedia) |
1718 | - .setTitle("TitleTwo") |
1719 | - .setAuthor("ArtistTwo") |
1720 | - .setAlbum("AlbumOne") |
1721 | - .setAlbumArtist("Various Artists") |
1722 | - .setDiscNumber(1) |
1723 | - .setTrackNumber(2); |
1724 | - MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1725 | - .setType(AudioMedia) |
1726 | - .setTitle("TitleThree") |
1727 | - .setAuthor("ArtistThree") |
1728 | - .setAlbum("AlbumOne") |
1729 | - .setAlbumArtist("Various Artists") |
1730 | - .setDiscNumber(2) |
1731 | - .setTrackNumber(1); |
1732 | - |
1733 | - MediaStore store(":memory:", MS_READ_WRITE); |
1734 | - store.insert(audio1); |
1735 | - store.insert(audio2); |
1736 | - store.insert(audio3); |
1737 | - |
1738 | +void check_album_songs(MediaStore const &store) { |
1739 | vector<MediaFile> tracks = store.getAlbumSongs( |
1740 | Album("AlbumOne", "Various Artists")); |
1741 | ASSERT_EQ(tracks.size(), 3); |
1742 | @@ -934,20 +1085,69 @@ |
1743 | EXPECT_EQ(tracks[2].getTitle(), "TitleThree"); |
1744 | } |
1745 | |
1746 | -TEST_F(MediaStoreTest, getETag) { |
1747 | +TEST(MediaStoreTest, getAlbumSongs) { |
1748 | + MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1749 | + .setType(AudioMedia) |
1750 | + .setTitle("TitleOne") |
1751 | + .setAuthor("ArtistOne") |
1752 | + .setAlbum("AlbumOne") |
1753 | + .setAlbumArtist("Various Artists") |
1754 | + .setDiscNumber(1) |
1755 | + .setTrackNumber(1); |
1756 | + MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1757 | + .setType(AudioMedia) |
1758 | + .setTitle("TitleTwo") |
1759 | + .setAuthor("ArtistTwo") |
1760 | + .setAlbum("AlbumOne") |
1761 | + .setAlbumArtist("Various Artists") |
1762 | + .setDiscNumber(1) |
1763 | + .setTrackNumber(2); |
1764 | + MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1765 | + .setType(AudioMedia) |
1766 | + .setTitle("TitleThree") |
1767 | + .setAuthor("ArtistThree") |
1768 | + .setAlbum("AlbumOne") |
1769 | + .setAlbumArtist("Various Artists") |
1770 | + .setDiscNumber(2) |
1771 | + .setTrackNumber(1); |
1772 | + |
1773 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1774 | + store.insert(audio1); |
1775 | + store.insert(audio2); |
1776 | + store.insert(audio3); |
1777 | + |
1778 | + check_album_songs(store); |
1779 | + |
1780 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1781 | + check_album_songs(store_ro); |
1782 | + |
1783 | + store.remove(audio1.getFileName()); |
1784 | + store.remove(audio2.getFileName()); |
1785 | + store.remove(audio3.getFileName()); |
1786 | +} |
1787 | + |
1788 | +void check_get_etag(MediaStore const &store) { |
1789 | + EXPECT_EQ(store.getETag("/path/file.ogg"), "etag"); |
1790 | + EXPECT_EQ(store.getETag("/something-else.mp3"), ""); |
1791 | +} |
1792 | + |
1793 | +TEST(MediaStoreTest, getETag) { |
1794 | MediaFile file = MediaFileBuilder("/path/file.ogg") |
1795 | .setETag("etag") |
1796 | .setType(AudioMedia); |
1797 | |
1798 | - MediaStore store(":memory:", MS_READ_WRITE); |
1799 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1800 | store.insert(file); |
1801 | |
1802 | - EXPECT_EQ(store.getETag("/path/file.ogg"), "etag"); |
1803 | - EXPECT_EQ(store.getETag("/something-else.mp3"), ""); |
1804 | + check_get_etag(store); |
1805 | + |
1806 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1807 | + check_get_etag(store_ro); |
1808 | + |
1809 | + store.remove(file.getFileName()); |
1810 | } |
1811 | |
1812 | - |
1813 | -TEST_F(MediaStoreTest, constraints) { |
1814 | +TEST(MediaStoreTest, constraints) { |
1815 | MediaFile file = MediaFileBuilder("no_slash_at_beginning.ogg") |
1816 | .setETag("etag") |
1817 | .setType(AudioMedia); |
1818 | @@ -959,52 +1159,7 @@ |
1819 | ASSERT_THROW(store.insert(file2), std::runtime_error); |
1820 | } |
1821 | |
1822 | -TEST_F(MediaStoreTest, listSongs) { |
1823 | - MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1824 | - .setType(AudioMedia) |
1825 | - .setTitle("TitleOne") |
1826 | - .setAuthor("ArtistOne") |
1827 | - .setAlbum("AlbumOne") |
1828 | - .setTrackNumber(1); |
1829 | - MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1830 | - .setType(AudioMedia) |
1831 | - .setTitle("TitleTwo") |
1832 | - .setAuthor("ArtistOne") |
1833 | - .setAlbum("AlbumOne") |
1834 | - .setTrackNumber(2); |
1835 | - MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1836 | - .setType(AudioMedia) |
1837 | - .setTitle("TitleThree") |
1838 | - .setAuthor("ArtistOne") |
1839 | - .setAlbum("AlbumTwo"); |
1840 | - MediaFile audio4 = MediaFileBuilder("/home/username/Music/track4.ogg") |
1841 | - .setType(AudioMedia) |
1842 | - .setTitle("TitleFour") |
1843 | - .setAuthor("ArtistTwo") |
1844 | - .setAlbum("AlbumThree"); |
1845 | - MediaFile audio5 = MediaFileBuilder("/home/username/Music/track5.ogg") |
1846 | - .setType(AudioMedia) |
1847 | - .setTitle("TitleFive") |
1848 | - .setAuthor("ArtistOne") |
1849 | - .setAlbum("AlbumFour") |
1850 | - .setAlbumArtist("Various Artists") |
1851 | - .setTrackNumber(1); |
1852 | - MediaFile audio6 = MediaFileBuilder("/home/username/Music/track6.ogg") |
1853 | - .setType(AudioMedia) |
1854 | - .setTitle("TitleSix") |
1855 | - .setAuthor("ArtistTwo") |
1856 | - .setAlbum("AlbumFour") |
1857 | - .setAlbumArtist("Various Artists") |
1858 | - .setTrackNumber(2); |
1859 | - |
1860 | - MediaStore store(":memory:", MS_READ_WRITE); |
1861 | - store.insert(audio1); |
1862 | - store.insert(audio2); |
1863 | - store.insert(audio3); |
1864 | - store.insert(audio4); |
1865 | - store.insert(audio5); |
1866 | - store.insert(audio6); |
1867 | - |
1868 | +void check_list_songs(MediaStore const &store) { |
1869 | Filter filter; |
1870 | vector<MediaFile> tracks = store.listSongs(filter); |
1871 | ASSERT_EQ(6, tracks.size()); |
1872 | @@ -1060,31 +1215,37 @@ |
1873 | EXPECT_EQ(3, tracks.size()); |
1874 | } |
1875 | |
1876 | -TEST_F(MediaStoreTest, listAlbums) { |
1877 | +TEST(MediaStoreTest, listSongs) { |
1878 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
1879 | .setType(AudioMedia) |
1880 | .setTitle("TitleOne") |
1881 | .setAuthor("ArtistOne") |
1882 | .setAlbum("AlbumOne") |
1883 | .setTrackNumber(1); |
1884 | - MediaFile audio2 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1885 | + MediaFile audio2 = MediaFileBuilder("/home/username/Music/track2.ogg") |
1886 | + .setType(AudioMedia) |
1887 | + .setTitle("TitleTwo") |
1888 | + .setAuthor("ArtistOne") |
1889 | + .setAlbum("AlbumOne") |
1890 | + .setTrackNumber(2); |
1891 | + MediaFile audio3 = MediaFileBuilder("/home/username/Music/track3.ogg") |
1892 | .setType(AudioMedia) |
1893 | .setTitle("TitleThree") |
1894 | .setAuthor("ArtistOne") |
1895 | .setAlbum("AlbumTwo"); |
1896 | - MediaFile audio3 = MediaFileBuilder("/home/username/Music/track4.ogg") |
1897 | + MediaFile audio4 = MediaFileBuilder("/home/username/Music/track4.ogg") |
1898 | .setType(AudioMedia) |
1899 | .setTitle("TitleFour") |
1900 | .setAuthor("ArtistTwo") |
1901 | .setAlbum("AlbumThree"); |
1902 | - MediaFile audio4 = MediaFileBuilder("/home/username/Music/track5.ogg") |
1903 | + MediaFile audio5 = MediaFileBuilder("/home/username/Music/track5.ogg") |
1904 | .setType(AudioMedia) |
1905 | .setTitle("TitleFive") |
1906 | .setAuthor("ArtistOne") |
1907 | .setAlbum("AlbumFour") |
1908 | .setAlbumArtist("Various Artists") |
1909 | .setTrackNumber(1); |
1910 | - MediaFile audio5 = MediaFileBuilder("/home/username/Music/track6.ogg") |
1911 | + MediaFile audio6 = MediaFileBuilder("/home/username/Music/track6.ogg") |
1912 | .setType(AudioMedia) |
1913 | .setTitle("TitleSix") |
1914 | .setAuthor("ArtistTwo") |
1915 | @@ -1092,44 +1253,59 @@ |
1916 | .setAlbumArtist("Various Artists") |
1917 | .setTrackNumber(2); |
1918 | |
1919 | - MediaStore store(":memory:", MS_READ_WRITE); |
1920 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
1921 | store.insert(audio1); |
1922 | store.insert(audio2); |
1923 | store.insert(audio3); |
1924 | store.insert(audio4); |
1925 | store.insert(audio5); |
1926 | - |
1927 | + store.insert(audio6); |
1928 | + |
1929 | + check_list_songs(store); |
1930 | + |
1931 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
1932 | + check_list_songs(store_ro); |
1933 | + |
1934 | + store.remove(audio1.getFileName()); |
1935 | + store.remove(audio2.getFileName()); |
1936 | + store.remove(audio3.getFileName()); |
1937 | + store.remove(audio4.getFileName()); |
1938 | + store.remove(audio5.getFileName()); |
1939 | + store.remove(audio6.getFileName()); |
1940 | +} |
1941 | + |
1942 | +void check_list_albums(MediaStore const &store) { |
1943 | Filter filter; |
1944 | - vector<Album> albums = store.listAlbums(filter); |
1945 | - ASSERT_EQ(4, albums.size()); |
1946 | - EXPECT_EQ("AlbumOne", albums[0].getTitle()); |
1947 | - |
1948 | - // test limit |
1949 | - filter.setLimit(2); |
1950 | - albums = store.listAlbums(filter); |
1951 | - EXPECT_EQ(2, albums.size()); |
1952 | - filter.setLimit(-1); |
1953 | - |
1954 | - // Songs by artist |
1955 | - filter.setArtist("ArtistOne"); |
1956 | - albums = store.listAlbums(filter); |
1957 | - EXPECT_EQ(3, albums.size()); |
1958 | - |
1959 | - // Songs by album artist |
1960 | - filter.clear(); |
1961 | - filter.setAlbumArtist("ArtistOne"); |
1962 | - albums = store.listAlbums(filter); |
1963 | - EXPECT_EQ(2, albums.size()); |
1964 | - |
1965 | - // Combination |
1966 | - filter.clear(); |
1967 | - filter.setArtist("ArtistOne"); |
1968 | - filter.setAlbumArtist("Various Artists"); |
1969 | - albums = store.listAlbums(filter); |
1970 | - EXPECT_EQ(1, albums.size()); |
1971 | + vector<Album> albums = store.listAlbums(filter); |
1972 | + ASSERT_EQ(4, albums.size()); |
1973 | + EXPECT_EQ("AlbumOne", albums[0].getTitle()); |
1974 | + |
1975 | + // test limit |
1976 | + filter.setLimit(2); |
1977 | + albums = store.listAlbums(filter); |
1978 | + EXPECT_EQ(2, albums.size()); |
1979 | + filter.setLimit(-1); |
1980 | + |
1981 | + // Songs by artist |
1982 | + filter.setArtist("ArtistOne"); |
1983 | + albums = store.listAlbums(filter); |
1984 | + EXPECT_EQ(3, albums.size()); |
1985 | + |
1986 | + // Songs by album artist |
1987 | + filter.clear(); |
1988 | + filter.setAlbumArtist("ArtistOne"); |
1989 | + albums = store.listAlbums(filter); |
1990 | + EXPECT_EQ(2, albums.size()); |
1991 | + |
1992 | + // Combination |
1993 | + filter.clear(); |
1994 | + filter.setArtist("ArtistOne"); |
1995 | + filter.setAlbumArtist("Various Artists"); |
1996 | + albums = store.listAlbums(filter); |
1997 | + EXPECT_EQ(1, albums.size()); |
1998 | } |
1999 | |
2000 | -TEST_F(MediaStoreTest, listArtists) { |
2001 | +TEST(MediaStoreTest, listAlbums) { |
2002 | MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
2003 | .setType(AudioMedia) |
2004 | .setTitle("TitleOne") |
2005 | @@ -1161,13 +1337,26 @@ |
2006 | .setAlbumArtist("Various Artists") |
2007 | .setTrackNumber(2); |
2008 | |
2009 | - MediaStore store(":memory:", MS_READ_WRITE); |
2010 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
2011 | store.insert(audio1); |
2012 | store.insert(audio2); |
2013 | store.insert(audio3); |
2014 | store.insert(audio4); |
2015 | store.insert(audio5); |
2016 | |
2017 | + check_list_albums(store); |
2018 | + |
2019 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
2020 | + check_list_albums(store_ro); |
2021 | + |
2022 | + store.remove(audio1.getFileName()); |
2023 | + store.remove(audio2.getFileName()); |
2024 | + store.remove(audio3.getFileName()); |
2025 | + store.remove(audio4.getFileName()); |
2026 | + store.remove(audio5.getFileName()); |
2027 | +} |
2028 | + |
2029 | +void check_list_artists(MediaStore const &store) { |
2030 | Filter filter; |
2031 | vector<string> artists = store.listArtists(filter); |
2032 | ASSERT_EQ(2, artists.size()); |
2033 | @@ -1188,7 +1377,58 @@ |
2034 | EXPECT_EQ("Various Artists", artists[2]); |
2035 | } |
2036 | |
2037 | -TEST_F(MediaStoreTest, brokenFiles) { |
2038 | +TEST(MediaStoreTest, listArtists) { |
2039 | + MediaFile audio1 = MediaFileBuilder("/home/username/Music/track1.ogg") |
2040 | + .setType(AudioMedia) |
2041 | + .setTitle("TitleOne") |
2042 | + .setAuthor("ArtistOne") |
2043 | + .setAlbum("AlbumOne") |
2044 | + .setTrackNumber(1); |
2045 | + MediaFile audio2 = MediaFileBuilder("/home/username/Music/track3.ogg") |
2046 | + .setType(AudioMedia) |
2047 | + .setTitle("TitleThree") |
2048 | + .setAuthor("ArtistOne") |
2049 | + .setAlbum("AlbumTwo"); |
2050 | + MediaFile audio3 = MediaFileBuilder("/home/username/Music/track4.ogg") |
2051 | + .setType(AudioMedia) |
2052 | + .setTitle("TitleFour") |
2053 | + .setAuthor("ArtistTwo") |
2054 | + .setAlbum("AlbumThree"); |
2055 | + MediaFile audio4 = MediaFileBuilder("/home/username/Music/track5.ogg") |
2056 | + .setType(AudioMedia) |
2057 | + .setTitle("TitleFive") |
2058 | + .setAuthor("ArtistOne") |
2059 | + .setAlbum("AlbumFour") |
2060 | + .setAlbumArtist("Various Artists") |
2061 | + .setTrackNumber(1); |
2062 | + MediaFile audio5 = MediaFileBuilder("/home/username/Music/track6.ogg") |
2063 | + .setType(AudioMedia) |
2064 | + .setTitle("TitleSix") |
2065 | + .setAuthor("ArtistTwo") |
2066 | + .setAlbum("AlbumFour") |
2067 | + .setAlbumArtist("Various Artists") |
2068 | + .setTrackNumber(2); |
2069 | + |
2070 | + MediaStore store(TEST_DIR "/mediastore.db", MS_READ_WRITE); |
2071 | + store.insert(audio1); |
2072 | + store.insert(audio2); |
2073 | + store.insert(audio3); |
2074 | + store.insert(audio4); |
2075 | + store.insert(audio5); |
2076 | + |
2077 | + check_list_artists(store); |
2078 | + |
2079 | + MediaStore store_ro(TEST_DIR "/mediastore.db", MS_READ_ONLY); |
2080 | + check_list_artists(store_ro); |
2081 | + |
2082 | + store.remove(audio1.getFileName()); |
2083 | + store.remove(audio2.getFileName()); |
2084 | + store.remove(audio3.getFileName()); |
2085 | + store.remove(audio4.getFileName()); |
2086 | + store.remove(audio5.getFileName()); |
2087 | +} |
2088 | + |
2089 | +TEST(MediaStoreTest, brokenFiles) { |
2090 | MediaStore store(":memory:", MS_READ_WRITE); |
2091 | std::string file = "/foo/bar/baz.mp3"; |
2092 | std::string other_file = "/foo/bar/abc.mp3"; |
2093 | @@ -1214,6 +1454,12 @@ |
2094 | } |
2095 | |
2096 | int main(int argc, char **argv) { |
2097 | + QCoreApplication app(argc, argv); |
2098 | + |
2099 | + MediaScannerTestUtils::DBusTest test; |
2100 | + test.SetUp(); |
2101 | ::testing::InitGoogleTest(&argc, argv); |
2102 | - return RUN_ALL_TESTS(); |
2103 | + auto ret_code=RUN_ALL_TESTS(); |
2104 | + std::cout << "WE'LL SEE NOW SOME ERRORS WHEN DESTROYING THE D-BUS INTERNALS. This is due bug: https://bugs.launchpad.net/dbus-cpp/+bug/1422304" << std::endl; |
2105 | + return ret_code; |
2106 | } |
2107 | |
2108 | === added directory 'test/utils' |
2109 | === added file 'test/utils/DBusTest.cpp' |
2110 | --- test/utils/DBusTest.cpp 1970-01-01 00:00:00 +0000 |
2111 | +++ test/utils/DBusTest.cpp 2015-02-16 14:24:40 +0000 |
2112 | @@ -0,0 +1,50 @@ |
2113 | +/* |
2114 | + * Copyright (C) 2013 Canonical, Ltd. |
2115 | + * |
2116 | + * This program is free software; you can redistribute it and/or modify |
2117 | + * it under the terms of the GNU General Public License as published by |
2118 | + * the Free Software Foundation; version 3. |
2119 | + * |
2120 | + * This program is distributed in the hope that it will be useful, |
2121 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2122 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2123 | + * GNU General Public License for more details. |
2124 | + * |
2125 | + * You should have received a copy of the GNU General Public License |
2126 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2127 | + * |
2128 | + * Author: Pete Woods <pete.woods@canonical.com> |
2129 | + */ |
2130 | + |
2131 | +#include "DBusTest.h" |
2132 | +#include "test_config.h" |
2133 | + |
2134 | +#include <QtTest/QSignalSpy> |
2135 | +#include <libqtdbustest/QProcessDBusService.h> |
2136 | +#include <QtDBus/QtDBus> |
2137 | + |
2138 | +using namespace MediaScannerTestUtils; |
2139 | +using namespace QtDBusTest; |
2140 | + |
2141 | +DBusTest::DBusTest() { |
2142 | + qputenv("MEDIASCANNER_CACHEDIR", TEST_DIR); |
2143 | + DBusServicePtr dBusService( |
2144 | + new QProcessDBusService("com.canonical.MediaScanner2", |
2145 | + QDBusConnection::SessionBus, MS_DBUS_BINARY, |
2146 | + QStringList())); |
2147 | + dbus.registerService(dBusService); |
2148 | +} |
2149 | + |
2150 | +DBusTest::~DBusTest() { |
2151 | +} |
2152 | + |
2153 | +void DBusTest::SetUp() { |
2154 | + dbus.startServices(); |
2155 | +} |
2156 | + |
2157 | +void DBusTest::TearDown() { |
2158 | +} |
2159 | + |
2160 | +const QDBusConnection & DBusTest::systemConnection() const { |
2161 | + return dbus.systemConnection(); |
2162 | +} |
2163 | |
2164 | === added file 'test/utils/DBusTest.h' |
2165 | --- test/utils/DBusTest.h 1970-01-01 00:00:00 +0000 |
2166 | +++ test/utils/DBusTest.h 2015-02-16 14:24:40 +0000 |
2167 | @@ -0,0 +1,47 @@ |
2168 | +/* |
2169 | + * Copyright (C) 2013 Canonical, Ltd. |
2170 | + * |
2171 | + * This program is free software; you can redistribute it and/or modify |
2172 | + * it under the terms of the GNU General Public License as published by |
2173 | + * the Free Software Foundation; version 3. |
2174 | + * |
2175 | + * This program is distributed in the hope that it will be useful, |
2176 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2177 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2178 | + * GNU General Public License for more details. |
2179 | + * |
2180 | + * You should have received a copy of the GNU General Public License |
2181 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2182 | + * |
2183 | + * Author: Pete Woods <pete.woods@canonical.com> |
2184 | + */ |
2185 | + |
2186 | +#include <QtCore/QCoreApplication> |
2187 | +#include <QtCore/QProcess> |
2188 | + |
2189 | +#include <QtDBus/QtDBus> |
2190 | + |
2191 | +#include <libqtdbustest/DBusTestRunner.h> |
2192 | + |
2193 | +#ifndef USERMETRICS_TESTUTILS_TESTCOMMON_H_ |
2194 | +#define USERMETRICS_TESTUTILS_TESTCOMMON_H_ |
2195 | + |
2196 | +namespace MediaScannerTestUtils { |
2197 | + |
2198 | +class DBusTest { |
2199 | +public: |
2200 | + DBusTest(); |
2201 | + |
2202 | + virtual ~DBusTest(); |
2203 | + |
2204 | + virtual void SetUp(); |
2205 | + |
2206 | + virtual void TearDown(); |
2207 | + |
2208 | + QtDBusTest::DBusTestRunner dbus; |
2209 | + |
2210 | + virtual const QDBusConnection & systemConnection() const; |
2211 | +}; |
2212 | + |
2213 | +} |
2214 | +#endif // USERMETRICS_TESTUTILS_TESTCOMMON_H_ |
Looking quite nice. However one thing that is a bit concerning is that the tests duplicate a lot of code in the dbus and non-dbus cases. Would it be possible to consolidate these so that every test is run with common code. So something along the lines of this:
void testImplementat ion(MediaStore &writer, MediaStore &queryer) { insert( whatevs) ;
// First set up
writer.
// Then query EQ(queryer. query(" ..."), result);
ASSERT_
}
And then have the actual dbus and non-dbus test cases just do basically this:
void testWithoutDbus() {
MediaStore local(READWRITE);
testImplement ation(local, local);
}
void testWithDbus() {
MediaStore writer(READWRITE);
MediaStore queryer(READONLY);
testImplement ation(writer, queryer);
}