2 (c) 2003-2017 The Music Player Daemon Project
3 This project's homepage is: http://www.musicpd.org
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 - Neither the name of the Music Player Daemon nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <mpd/client.h>
34 #include <mpd/status.h>
36 #include <mpd/entity.h>
37 #include <mpd/search.h>
49 #define COLOR_CODE 0x1B
51 #define LOG_INFO(x, ...) {printf(" [info]" x "\n", __VA_ARGS__);}
52 #define LOG_WARNING(x, ...) \
54 fprintf(stderr, "%c[%d;%d;%dm[WARNING](%s:%d) : " x "\n", COLOR_CODE, BRIGHT, YELLOW, BG_BLACK, __FILE__, __LINE__, __VA_ARGS__);\
55 printf("%c[%dm", 0x1B, 0);\
58 #define LOG_ERROR(x, ...) \
60 fprintf(stderr, "%c[%d;%d;%dm[ERROR](%s:%d) : " x "\n", COLOR_CODE, BRIGHT, RED, BG_BLACK, __FILE__, __LINE__, __VA_ARGS__);\
61 printf("%c[%dm", 0x1B, 0);\
64 #define START_TEST(description, method, ...) \
66 printf("[Start Test] " description "\n");\
67 if (method(__VA_ARGS__) < 0)\
68 printf("%c[%d;%d;%dm[End Test: ERROR]\n", COLOR_CODE, BRIGHT, RED, BG_BLACK);\
70 printf("%c[%d;%d;%dm[End Test: OK]\n", COLOR_CODE, BRIGHT, GREEN, BG_BLACK);\
71 printf("%c[%dm", 0x1B, 0);\
74 #define CHECK_CONNECTION(conn) \
75 if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { \
76 LOG_ERROR("%s", mpd_connection_get_error_message(conn)); \
81 test_new_connection(struct mpd_connection
**conn
)
83 *conn
= mpd_connection_new(NULL
, 0, 30000);
85 LOG_ERROR("%s", "Out of memory");
89 if (mpd_connection_get_error(*conn
) != MPD_ERROR_SUCCESS
) {
90 LOG_ERROR("%s", mpd_connection_get_error_message(*conn
));
91 mpd_connection_free(*conn
);
99 test_version(struct mpd_connection
*conn
)
102 for (i
=0; i
<3; ++i
) {
103 LOG_INFO("version[%i]: %i", i
,
104 mpd_connection_get_server_version(conn
)[i
]);
105 total
+= mpd_connection_get_server_version(conn
)[i
];
107 /* Check if at least one of the three number is positive */
112 print_status(struct mpd_status
*status
)
114 const struct mpd_audio_format
*audio_format
;
116 LOG_INFO("volume: %i", mpd_status_get_volume(status
));
117 LOG_INFO("repeat: %i", mpd_status_get_repeat(status
));
118 LOG_INFO("single: %i", mpd_status_get_single(status
));
119 LOG_INFO("consume: %i", mpd_status_get_consume(status
));
120 LOG_INFO("random: %i", mpd_status_get_random(status
));
121 LOG_INFO("queue version: %u", mpd_status_get_queue_version(status
));
122 LOG_INFO("queue length: %i", mpd_status_get_queue_length(status
));
124 if (mpd_status_get_state(status
) == MPD_STATE_PLAY
||
125 mpd_status_get_state(status
) == MPD_STATE_PAUSE
) {
126 LOG_INFO("song: %i", mpd_status_get_song_pos(status
));
127 LOG_INFO("elaspedTime: %i", mpd_status_get_elapsed_time(status
));
128 LOG_INFO("elasped_ms: %u\n", mpd_status_get_elapsed_ms(status
));
129 LOG_INFO("totalTime: %i", mpd_status_get_total_time(status
));
130 LOG_INFO("bitRate: %i", mpd_status_get_kbit_rate(status
));
133 audio_format
= mpd_status_get_audio_format(status
);
134 if (audio_format
!= NULL
) {
135 printf("sampleRate: %i\n", audio_format
->sample_rate
);
136 printf("bits: %i\n", audio_format
->bits
);
137 printf("channels: %i\n", audio_format
->channels
);
142 print_tag(const struct mpd_song
*song
, enum mpd_tag_type type
,
148 while ((value
= mpd_song_get_tag(song
, type
, i
++)) != NULL
)
149 LOG_INFO("%s: %s", label
, value
);
153 print_song(const struct mpd_song
*song
)
155 LOG_INFO("uri: %s\n", mpd_song_get_uri(song
));
156 print_tag(song
, MPD_TAG_ARTIST
, "artist");
157 print_tag(song
, MPD_TAG_ALBUM
, "album");
158 print_tag(song
, MPD_TAG_TITLE
, "title");
159 print_tag(song
, MPD_TAG_TRACK
, "track");
160 print_tag(song
, MPD_TAG_NAME
, "name");
161 print_tag(song
, MPD_TAG_DATE
, "date");
163 if (mpd_song_get_duration(song
) > 0)
164 LOG_INFO("time: %i", mpd_song_get_duration(song
));
166 if (mpd_song_get_duration_ms(song
) > 0)
167 LOG_INFO("duration: %i", mpd_song_get_duration_ms(song
));
169 LOG_INFO("pos: %u", mpd_song_get_pos(song
));
173 test_status(struct mpd_connection
*conn
)
175 struct mpd_status
*status
;
177 status
= mpd_run_status(conn
);
179 LOG_ERROR("%s", mpd_connection_get_error_message(conn
));
183 print_status(status
);
184 mpd_status_free(status
);
186 mpd_response_finish(conn
);
187 CHECK_CONNECTION(conn
);
193 test_currentsong(struct mpd_connection
*conn
)
195 struct mpd_song
*song
;
197 song
= mpd_run_current_song(conn
);
204 mpd_response_finish(conn
);
205 CHECK_CONNECTION(conn
);
212 test_list_status_currentsong(struct mpd_connection
*conn
)
214 struct mpd_status
*status
;
215 const struct mpd_song
*song
;
216 struct mpd_entity
*entity
;
218 mpd_command_list_begin(conn
, true);
219 mpd_send_status(conn
);
220 mpd_send_current_song(conn
);
221 mpd_command_list_end(conn
);
223 CHECK_CONNECTION(conn
);
225 status
= mpd_recv_status(conn
);
227 LOG_ERROR("%s", mpd_connection_get_error_message(conn
));
230 if (mpd_status_get_error(status
)) {
231 LOG_WARNING("status error: %s", mpd_status_get_error(status
));
234 print_status(status
);
235 mpd_status_free(status
);
237 mpd_response_next(conn
);
239 entity
= mpd_recv_entity(conn
);
241 if (mpd_entity_get_type(entity
) != MPD_ENTITY_TYPE_SONG
) {
242 LOG_ERROR("entity doesn't have the expected type (song)i :%d",
243 mpd_entity_get_type(entity
));
244 mpd_entity_free(entity
);
248 song
= mpd_entity_get_song(entity
);
252 mpd_entity_free(entity
);
255 mpd_response_finish(conn
);
256 CHECK_CONNECTION(conn
);
262 test_lsinfo(struct mpd_connection
*conn
, const char *path
)
264 struct mpd_entity
*entity
;
266 mpd_send_list_meta(conn
, path
);
267 CHECK_CONNECTION(conn
);
269 while ((entity
= mpd_recv_entity(conn
)) != NULL
) {
270 const struct mpd_song
*song
;
271 const struct mpd_directory
*dir
;
272 const struct mpd_playlist
*pl
;
274 switch (mpd_entity_get_type(entity
)) {
275 case MPD_ENTITY_TYPE_UNKNOWN
:
276 printf("Unknown type\n");
279 case MPD_ENTITY_TYPE_SONG
:
280 song
= mpd_entity_get_song(entity
);
284 case MPD_ENTITY_TYPE_DIRECTORY
:
285 dir
= mpd_entity_get_directory(entity
);
286 printf("directory: %s\n", mpd_directory_get_path(dir
));
289 case MPD_ENTITY_TYPE_PLAYLIST
:
290 pl
= mpd_entity_get_playlist(entity
);
291 LOG_INFO("playlist: %s", mpd_playlist_get_path(pl
));
295 mpd_entity_free(entity
);
298 mpd_response_finish(conn
);
299 CHECK_CONNECTION(conn
);
305 test_list_artists(struct mpd_connection
*conn
)
307 struct mpd_pair
*pair
;
310 mpd_search_db_tags(conn
, MPD_TAG_ARTIST
);
311 mpd_search_commit(conn
);
312 CHECK_CONNECTION(conn
);
314 LOG_INFO("%s: ", "Artists list");
315 while ((pair
= mpd_recv_pair_tag(conn
, MPD_TAG_ARTIST
)) != NULL
) {
317 printf(" %s", pair
->value
);
320 printf(", %s", pair
->value
);
322 mpd_return_pair(conn
, pair
);
326 mpd_response_finish(conn
);
327 CHECK_CONNECTION(conn
);
333 test_close_connection(struct mpd_connection
*conn
)
335 mpd_connection_free(conn
);
340 main(int argc
, char ** argv
)
342 struct mpd_connection
*conn
= NULL
;
343 const char *lsinfo_path
= "/";
346 lsinfo_path
= argv
[1];
348 START_TEST("Test connection to MPD server", test_new_connection
, &conn
);
352 START_TEST("Check MPD versions", test_version
, conn
);
353 START_TEST("'status' command", test_status
, conn
);
354 START_TEST("'currentsong' command", test_currentsong
, conn
);
355 START_TEST("List commands: 'status' and 'currentsong'", test_list_status_currentsong
, conn
);
356 START_TEST("'lsinfo' command", test_lsinfo
, conn
, lsinfo_path
);
357 START_TEST("'list artist' command", test_list_artists
, conn
);
358 START_TEST("Test connection closing", test_close_connection
, conn
);